36 #include "libmesh/quadrature.h"
46 _p_pinning(input,physics_name),
55 libmesh_error_msg(
"ERROR: IncompressibleNavierStokes only valid for two or three dimensions! Make sure you have at least two components in your Velocity type variable.");
62 _p_pinning.check_pin_location(system.get_mesh());
71 if( input.have_variable(section) )
73 unsigned int n_vars = input.vector_variable_size(section);
75 for(
unsigned int v = 0; v < n_vars; v++ )
77 std::string name = input(section,
"DIE!",v);
79 if( name == std::string(
"mu") )
86 <<
" Found " << name << std::endl
87 <<
" Acceptable values are: mu" << std::endl;
98 (
bool compute_jacobian,
102 const unsigned int n_u_dofs = context.get_dof_indices(this->_flow_vars.u()).size();
103 const unsigned int n_p_dofs = context.get_dof_indices(this->_press_var.p()).size();
106 libmesh_assert (n_u_dofs == context.get_dof_indices(this->_flow_vars.v()).size());
108 if (this->_flow_vars.dim() == 3)
109 libmesh_assert (n_u_dofs == context.get_dof_indices(this->_flow_vars.w()).size());
115 const std::vector<libMesh::Real> &JxW =
116 context.get_element_fe(this->_flow_vars.u())->get_JxW();
119 const std::vector<std::vector<libMesh::Real> >& u_phi =
120 context.get_element_fe(this->_flow_vars.u())->get_phi();
124 const std::vector<std::vector<libMesh::RealGradient> >& u_gradphi =
125 context.get_element_fe(this->_flow_vars.u())->get_dphi();
128 const std::vector<std::vector<libMesh::Real> >& p_phi =
129 context.get_element_fe(this->_press_var.p())->get_phi();
131 const std::vector<libMesh::Point>& u_qpoint =
132 context.get_element_fe(this->_flow_vars.u())->get_xyz();
140 libMesh::DenseSubMatrix<libMesh::Number> &Kuu = context.get_elem_jacobian(this->_flow_vars.u(), this->_flow_vars.u());
141 libMesh::DenseSubMatrix<libMesh::Number> &Kuv = context.get_elem_jacobian(this->_flow_vars.u(), this->_flow_vars.v());
142 libMesh::DenseSubMatrix<libMesh::Number>* Kuw = NULL;
144 libMesh::DenseSubMatrix<libMesh::Number> &Kvu = context.get_elem_jacobian(this->_flow_vars.v(), this->_flow_vars.u());
145 libMesh::DenseSubMatrix<libMesh::Number> &Kvv = context.get_elem_jacobian(this->_flow_vars.v(), this->_flow_vars.v());
146 libMesh::DenseSubMatrix<libMesh::Number>* Kvw = NULL;
148 libMesh::DenseSubMatrix<libMesh::Number>* Kwu = NULL;
149 libMesh::DenseSubMatrix<libMesh::Number>* Kwv = NULL;
150 libMesh::DenseSubMatrix<libMesh::Number>* Kww = NULL;
152 libMesh::DenseSubMatrix<libMesh::Number> &Kup = context.get_elem_jacobian(this->_flow_vars.u(), this->_press_var.p());
153 libMesh::DenseSubMatrix<libMesh::Number> &Kvp = context.get_elem_jacobian(this->_flow_vars.v(), this->_press_var.p());
154 libMesh::DenseSubMatrix<libMesh::Number>* Kwp = NULL;
156 libMesh::DenseSubVector<libMesh::Number> &Fu = context.get_elem_residual(this->_flow_vars.u());
157 libMesh::DenseSubVector<libMesh::Number> &Fv = context.get_elem_residual(this->_flow_vars.v());
158 libMesh::DenseSubVector<libMesh::Number>* Fw = NULL;
160 if( this->_flow_vars.dim() == 3 )
162 Kuw = &context.get_elem_jacobian(this->_flow_vars.u(), this->_flow_vars.w());
163 Kvw = &context.get_elem_jacobian(this->_flow_vars.v(), this->_flow_vars.w());
164 Kwu = &context.get_elem_jacobian(this->_flow_vars.w(), this->_flow_vars.u());
165 Kwv = &context.get_elem_jacobian(this->_flow_vars.w(), this->_flow_vars.v());
166 Kww = &context.get_elem_jacobian(this->_flow_vars.w(), this->_flow_vars.w());
167 Kwp = &context.get_elem_jacobian(this->_flow_vars.w(), this->_press_var.p());
168 Fw = &context.get_elem_residual(this->_flow_vars.w());
177 unsigned int n_qpoints = context.get_element_qrule().n_points();
179 for (
unsigned int qp=0; qp != n_qpoints; qp++)
182 libMesh::Number p, u, v;
183 p = context.interior_value(this->_press_var.p(), qp);
184 u = context.interior_value(this->_flow_vars.u(), qp);
185 v = context.interior_value(this->_flow_vars.v(), qp);
187 libMesh::Gradient grad_u, grad_v, grad_w;
188 grad_u = context.interior_gradient(this->_flow_vars.u(), qp);
189 grad_v = context.interior_gradient(this->_flow_vars.v(), qp);
190 if (this->_flow_vars.dim() == 3)
191 grad_w = context.interior_gradient(this->_flow_vars.w(), qp);
193 libMesh::NumberVectorValue U(u,v);
194 if (this->_flow_vars.dim() == 3)
195 U(2) = context.interior_value(this->_flow_vars.w(), qp);
197 const libMesh::Number grad_u_x = grad_u(0);
198 const libMesh::Number grad_u_y = grad_u(1);
199 const libMesh::Number grad_u_z = (this->_flow_vars.dim() == 3)?grad_u(2):0;
200 const libMesh::Number grad_v_x = grad_v(0);
201 const libMesh::Number grad_v_y = grad_v(1);
202 const libMesh::Number grad_v_z = (this->_flow_vars.dim() == 3)?grad_v(2):0;
203 const libMesh::Number grad_w_x = (this->_flow_vars.dim() == 3)?grad_w(0):0;
204 const libMesh::Number grad_w_y = (this->_flow_vars.dim() == 3)?grad_w(1):0;
205 const libMesh::Number grad_w_z = (this->_flow_vars.dim() == 3)?grad_w(2):0;
207 const libMesh::Number r = u_qpoint[qp](0);
209 libMesh::Real jac = JxW[qp];
212 libMesh::Real _mu_qp = this->_mu(context, qp);
222 for (
unsigned int i=0; i != n_u_dofs; i++)
225 (-this->_rho*u_phi[i][qp]*(U*grad_u)
226 +p*u_gradphi[i][qp](0)
227 -_mu_qp*(u_gradphi[i][qp]*grad_u) );
232 Fu(i) += u_phi[i][qp]*( p/r - _mu_qp*U(0)/(r*r) )*jac;
236 (-this->_rho*u_phi[i][qp]*(U*grad_v)
237 +p*u_gradphi[i][qp](1)
238 -_mu_qp*(u_gradphi[i][qp]*grad_v) );
240 if (this->_flow_vars.dim() == 3)
243 (-this->_rho*u_phi[i][qp]*(U*grad_w)
244 +p*u_gradphi[i][qp](2)
245 -_mu_qp*(u_gradphi[i][qp]*grad_w) );
248 if (compute_jacobian)
250 for (
unsigned int j=0; j != n_u_dofs; j++)
257 Kuu(i,j) += jac * context.get_elem_solution_derivative() *
258 (-this->_rho*u_phi[i][qp]*(U*u_gradphi[j][qp])
259 -this->_rho*u_phi[i][qp]*grad_u_x*u_phi[j][qp]
260 -_mu_qp*(u_gradphi[i][qp]*u_gradphi[j][qp]));
265 Kuu(i,j) -= u_phi[i][qp]*_mu_qp*u_phi[j][qp]/(r*r)*jac * context.get_elem_solution_derivative();
268 Kuv(i,j) += jac * context.get_elem_solution_derivative() *
269 (-this->_rho*u_phi[i][qp]*grad_u_y*u_phi[j][qp]);
271 Kvv(i,j) += jac * context.get_elem_solution_derivative() *
272 (-this->_rho*u_phi[i][qp]*(U*u_gradphi[j][qp])
273 -this->_rho*u_phi[i][qp]*grad_v_y*u_phi[j][qp]
274 -_mu_qp*(u_gradphi[i][qp]*u_gradphi[j][qp]));
276 Kvu(i,j) += jac * context.get_elem_solution_derivative() *
277 (-this->_rho*u_phi[i][qp]*grad_v_x*u_phi[j][qp]);
279 if (this->_flow_vars.dim() == 3)
281 (*Kuw)(i,j) += jac * context.get_elem_solution_derivative() *
282 (-this->_rho*u_phi[i][qp]*grad_u_z*u_phi[j][qp]);
284 (*Kvw)(i,j) += jac * context.get_elem_solution_derivative() *
285 (-this->_rho*u_phi[i][qp]*grad_v_z*u_phi[j][qp]);
287 (*Kww)(i,j) += jac * context.get_elem_solution_derivative() *
288 (-this->_rho*u_phi[i][qp]*(U*u_gradphi[j][qp])
289 -this->_rho*u_phi[i][qp]*grad_w_z*u_phi[j][qp]
290 -_mu_qp*(u_gradphi[i][qp]*u_gradphi[j][qp]));
291 (*Kwu)(i,j) += jac * context.get_elem_solution_derivative() *
292 (-this->_rho*u_phi[i][qp]*grad_w_x*u_phi[j][qp]);
293 (*Kwv)(i,j) += jac * context.get_elem_solution_derivative() *
294 (-this->_rho*u_phi[i][qp]*grad_w_y*u_phi[j][qp]);
299 for (
unsigned int j=0; j != n_p_dofs; j++)
301 Kup(i,j) += u_gradphi[i][qp](0)*p_phi[j][qp]*jac * context.get_elem_solution_derivative();
302 Kvp(i,j) += u_gradphi[i][qp](1)*p_phi[j][qp]*jac * context.get_elem_solution_derivative();
304 if (this->_flow_vars.dim() == 3)
306 (*Kwp)(i,j) += u_gradphi[i][qp](2)*p_phi[j][qp]*jac * context.get_elem_solution_derivative();
311 Kup(i,j) += u_phi[i][qp]*p_phi[j][qp]/r*jac * context.get_elem_solution_derivative();
329 const unsigned int n_u_dofs = context.get_dof_indices(this->_flow_vars.u()).size();
330 const unsigned int n_p_dofs = context.get_dof_indices(this->_press_var.p()).size();
336 const std::vector<libMesh::Real> &JxW =
337 context.get_element_fe(this->_flow_vars.u())->get_JxW();
341 const std::vector<std::vector<libMesh::RealGradient> >& u_gradphi =
342 context.get_element_fe(this->_flow_vars.u())->get_dphi();
346 const std::vector<std::vector<libMesh::Real> >& u_phi =
347 context.get_element_fe(this->_flow_vars.u())->get_phi();
350 const std::vector<std::vector<libMesh::Real> >& p_phi =
351 context.get_element_fe(this->_press_var.p())->get_phi();
353 const std::vector<libMesh::Point>& u_qpoint =
354 context.get_element_fe(this->_flow_vars.u())->get_xyz();
360 libMesh::DenseSubMatrix<libMesh::Number> &Kpu = context.get_elem_jacobian(this->_press_var.p(), this->_flow_vars.u());
361 libMesh::DenseSubMatrix<libMesh::Number> &Kpv = context.get_elem_jacobian(this->_press_var.p(), this->_flow_vars.v());
362 libMesh::DenseSubMatrix<libMesh::Number>* Kpw = NULL;
364 libMesh::DenseSubVector<libMesh::Number> &Fp = context.get_elem_residual(this->_press_var.p());
367 if( this->_flow_vars.dim() == 3 )
369 Kpw = &context.get_elem_jacobian(this->_press_var.p(), this->_flow_vars.w());
373 unsigned int n_qpoints = context.get_element_qrule().n_points();
374 for (
unsigned int qp=0; qp != n_qpoints; qp++)
377 libMesh::Gradient grad_u, grad_v, grad_w;
378 grad_u = context.interior_gradient(this->_flow_vars.u(), qp);
379 grad_v = context.interior_gradient(this->_flow_vars.v(), qp);
380 if (this->_flow_vars.dim() == 3)
381 grad_w = context.interior_gradient(this->_flow_vars.w(), qp);
383 libMesh::Number divU = grad_u(0) + grad_v(1);
384 if (this->_flow_vars.dim() == 3)
387 const libMesh::Number r = u_qpoint[qp](0);
389 libMesh::Real jac = JxW[qp];
393 libMesh::Number u = context.interior_value( this->_flow_vars.u(), qp );
400 for (
unsigned int i=0; i != n_p_dofs; i++)
402 Fp(i) += p_phi[i][qp]*divU*jac;
404 if (compute_jacobian)
406 libmesh_assert_equal_to (context.get_elem_solution_derivative(), 1.0);
408 for (
unsigned int j=0; j != n_u_dofs; j++)
410 Kpu(i,j) += p_phi[i][qp]*u_gradphi[j][qp](0)*jac * context.get_elem_solution_derivative();
411 Kpv(i,j) += p_phi[i][qp]*u_gradphi[j][qp](1)*jac * context.get_elem_solution_derivative();
412 if (this->_flow_vars.dim() == 3)
413 (*Kpw)(i,j) += p_phi[i][qp]*u_gradphi[j][qp](2)*jac * context.get_elem_solution_derivative();
417 Kpu(i,j) += p_phi[i][qp]*u_phi[j][qp]/r*jac * context.get_elem_solution_derivative();
429 _p_pinning.pin_value( context, compute_jacobian, this->_press_var.p() );
439 const std::vector<libMesh::Real> &JxW =
440 context.get_element_fe(this->_flow_vars.u())->get_JxW();
444 const std::vector<std::vector<libMesh::Real> >& u_phi =
445 context.get_element_fe(this->_flow_vars.u())->get_phi();
447 const std::vector<libMesh::Point>& u_qpoint =
448 context.get_element_fe(this->_flow_vars.u())->get_xyz();
451 const unsigned int n_u_dofs = context.get_dof_indices(this->_flow_vars.u()).size();
454 libMesh::DenseSubVector<libMesh::Real> &F_u = context.get_elem_residual(this->_flow_vars.u());
455 libMesh::DenseSubVector<libMesh::Real> &F_v = context.get_elem_residual(this->_flow_vars.v());
456 libMesh::DenseSubVector<libMesh::Real>* F_w = NULL;
458 libMesh::DenseSubMatrix<libMesh::Real> &M_uu = context.get_elem_jacobian(this->_flow_vars.u(), this->_flow_vars.u());
459 libMesh::DenseSubMatrix<libMesh::Real> &M_vv = context.get_elem_jacobian(this->_flow_vars.v(), this->_flow_vars.v());
460 libMesh::DenseSubMatrix<libMesh::Real>* M_ww = NULL;
463 if( this->_flow_vars.dim() == 3 )
465 F_w = &context.get_elem_residual(this->_flow_vars.w());
466 M_ww = &context.get_elem_jacobian(this->_flow_vars.w(), this->_flow_vars.w());
469 unsigned int n_qpoints = context.get_element_qrule().n_points();
471 for (
unsigned int qp = 0; qp != n_qpoints; ++qp)
478 libMesh::Real u_dot, v_dot, w_dot = 0.0;
479 context.interior_rate(this->_flow_vars.u(), qp, u_dot);
480 context.interior_rate(this->_flow_vars.v(), qp, v_dot);
482 if(this->_flow_vars.dim() == 3 )
483 context.interior_rate(this->_flow_vars.w(), qp, w_dot);
485 const libMesh::Number r = u_qpoint[qp](0);
487 libMesh::Real jac = JxW[qp];
494 for (
unsigned int i = 0; i != n_u_dofs; ++i)
496 F_u(i) -= this->_rho*u_dot*u_phi[i][qp]*jac;
497 F_v(i) -= this->_rho*v_dot*u_phi[i][qp]*jac;
499 if( this->_flow_vars.dim() == 3 )
500 (*F_w)(i) -= this->_rho*w_dot*u_phi[i][qp]*jac;
502 if( compute_jacobian )
504 for (
unsigned int j=0; j != n_u_dofs; j++)
508 libMesh::Real value = this->_rho*u_phi[i][qp]*u_phi[j][qp]*jac * context.get_elem_solution_rate_derivative();
513 if( this->_flow_vars.dim() == 3)
515 (*M_ww)(i,j) -= value;
529 const libMesh::Point& point,
530 libMesh::Real& value )
532 if( quantity_index == this->_mu_index )
534 value = this->_mu(point, context.get_time());
virtual void mass_residual(bool compute_jacobian, AssemblyContext &context)
Mass matrix part(s) for element interiors. All boundary terms lie within the time_derivative part...
static bool is_axisymmetric()
virtual void compute_postprocessed_quantity(unsigned int quantity_index, const AssemblyContext &context, const libMesh::Point &point, libMesh::Real &value)
Compute value of postprocessed quantities at libMesh::Point.
unsigned int register_quantity(std::string name)
Register quantity to be postprocessed.
GRINS::ICHandlingBase * _ic_handler
bool _pin_pressure
Enable pressure pinning.
Physics class for Incompressible Navier-Stokes.
IncompressibleNavierStokes()
INSTANTIATE_INC_NS_SUBCLASS(IncompressibleNavierStokes)
virtual void element_constraint(bool compute_jacobian, AssemblyContext &context)
Constraint part(s) of physics for element interiors.
virtual void register_postprocessing_vars(const GetPot &input, PostProcessedQuantities< libMesh::Real > &postprocessing)
Register postprocessing variables for IncompressibleNavierStokes.
VelocityVariable & _flow_vars
Base class for reading and handling initial conditions for physics classes.
Interface with libMesh for solving Multiphysics problems.
static PhysicsName incompressible_navier_stokes()
virtual void auxiliary_init(MultiphysicsSystem &system)
Any auxillary initialization a Physics class may need.
virtual void element_time_derivative(bool compute_jacobian, AssemblyContext &context)
Time dependent part(s) of physics for element interiors.
unsigned int dim() const
Number of components.