36 #include "libmesh/quadrature.h"
46 _p_pinning(input,physics_name),
59 _p_pinning.check_pin_location(system.get_mesh());
68 if( input.have_variable(section) )
70 unsigned int n_vars = input.vector_variable_size(section);
72 for(
unsigned int v = 0; v < n_vars; v++ )
74 std::string name = input(section,
"DIE!",v);
76 if( name == std::string(
"mu") )
83 <<
" Found " << name << std::endl
84 <<
" Acceptable values are: mu" << std::endl;
98 #ifdef GRINS_USE_GRVY_TIMERS
99 this->_timer->BeginTimer(
"IncompressibleNavierStokes::element_time_derivative");
103 const unsigned int n_u_dofs = context.get_dof_indices(this->_flow_vars.u()).size();
104 const unsigned int n_p_dofs = context.get_dof_indices(this->_press_var.p()).size();
107 libmesh_assert (n_u_dofs == context.get_dof_indices(this->_flow_vars.v()).size());
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->_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);
191 grad_w = context.interior_gradient(this->_flow_vars.w(), qp);
193 libMesh::NumberVectorValue U(u,v);
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->_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->_dim == 3)?grad_v(2):0;
203 const libMesh::Number grad_w_x = (this->_dim == 3)?grad_w(0):0;
204 const libMesh::Number grad_w_y = (this->_dim == 3)?grad_w(1):0;
205 const libMesh::Number grad_w_z = (this->_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) );
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]);
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();
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();
323 #ifdef GRINS_USE_GRVY_TIMERS
324 this->_timer->EndTimer(
"IncompressibleNavierStokes::element_time_derivative");
335 #ifdef GRINS_USE_GRVY_TIMERS
336 this->_timer->BeginTimer(
"IncompressibleNavierStokes::element_constraint");
340 const unsigned int n_u_dofs = context.get_dof_indices(this->_flow_vars.u()).size();
341 const unsigned int n_p_dofs = context.get_dof_indices(this->_press_var.p()).size();
347 const std::vector<libMesh::Real> &JxW =
348 context.get_element_fe(this->_flow_vars.u())->get_JxW();
352 const std::vector<std::vector<libMesh::RealGradient> >& u_gradphi =
353 context.get_element_fe(this->_flow_vars.u())->get_dphi();
357 const std::vector<std::vector<libMesh::Real> >& u_phi =
358 context.get_element_fe(this->_flow_vars.u())->get_phi();
361 const std::vector<std::vector<libMesh::Real> >& p_phi =
362 context.get_element_fe(this->_press_var.p())->get_phi();
364 const std::vector<libMesh::Point>& u_qpoint =
365 context.get_element_fe(this->_flow_vars.u())->get_xyz();
371 libMesh::DenseSubMatrix<libMesh::Number> &Kpu = context.get_elem_jacobian(this->_press_var.p(), this->_flow_vars.u());
372 libMesh::DenseSubMatrix<libMesh::Number> &Kpv = context.get_elem_jacobian(this->_press_var.p(), this->_flow_vars.v());
373 libMesh::DenseSubMatrix<libMesh::Number>* Kpw = NULL;
375 libMesh::DenseSubVector<libMesh::Number> &Fp = context.get_elem_residual(this->_press_var.p());
377 if( this->_dim == 3 )
379 Kpw = &context.get_elem_jacobian(this->_press_var.p(), this->_flow_vars.w());
383 unsigned int n_qpoints = context.get_element_qrule().n_points();
384 for (
unsigned int qp=0; qp != n_qpoints; qp++)
387 libMesh::Gradient grad_u, grad_v, grad_w;
388 grad_u = context.interior_gradient(this->_flow_vars.u(), qp);
389 grad_v = context.interior_gradient(this->_flow_vars.v(), qp);
391 grad_w = context.interior_gradient(this->_flow_vars.w(), qp);
393 libMesh::Number divU = grad_u(0) + grad_v(1);
397 const libMesh::Number r = u_qpoint[qp](0);
399 libMesh::Real jac = JxW[qp];
403 libMesh::Number u = context.interior_value( this->_flow_vars.u(), qp );
410 for (
unsigned int i=0; i != n_p_dofs; i++)
412 Fp(i) += p_phi[i][qp]*divU*jac;
414 if (compute_jacobian)
416 libmesh_assert_equal_to (context.get_elem_solution_derivative(), 1.0);
418 for (
unsigned int j=0; j != n_u_dofs; j++)
420 Kpu(i,j) += p_phi[i][qp]*u_gradphi[j][qp](0)*jac * context.get_elem_solution_derivative();
421 Kpv(i,j) += p_phi[i][qp]*u_gradphi[j][qp](1)*jac * context.get_elem_solution_derivative();
423 (*Kpw)(i,j) += p_phi[i][qp]*u_gradphi[j][qp](2)*jac * context.get_elem_solution_derivative();
427 Kpu(i,j) += p_phi[i][qp]*u_phi[j][qp]/r*jac * context.get_elem_solution_derivative();
439 _p_pinning.pin_value( context, compute_jacobian, this->_press_var.p() );
442 #ifdef GRINS_USE_GRVY_TIMERS
443 this->_timer->EndTimer(
"IncompressibleNavierStokes::element_constraint");
456 const std::vector<libMesh::Real> &JxW =
457 context.get_element_fe(this->_flow_vars.u())->get_JxW();
461 const std::vector<std::vector<libMesh::Real> >& u_phi =
462 context.get_element_fe(this->_flow_vars.u())->get_phi();
464 const std::vector<libMesh::Point>& u_qpoint =
465 context.get_element_fe(this->_flow_vars.u())->get_xyz();
468 const unsigned int n_u_dofs = context.get_dof_indices(this->_flow_vars.u()).size();
471 libMesh::DenseSubVector<libMesh::Real> &F_u = context.get_elem_residual(this->_flow_vars.u());
472 libMesh::DenseSubVector<libMesh::Real> &F_v = context.get_elem_residual(this->_flow_vars.v());
473 libMesh::DenseSubVector<libMesh::Real>* F_w = NULL;
475 libMesh::DenseSubMatrix<libMesh::Real> &M_uu = context.get_elem_jacobian(this->_flow_vars.u(), this->_flow_vars.u());
476 libMesh::DenseSubMatrix<libMesh::Real> &M_vv = context.get_elem_jacobian(this->_flow_vars.v(), this->_flow_vars.v());
477 libMesh::DenseSubMatrix<libMesh::Real>* M_ww = NULL;
479 if( this->_dim == 3 )
481 F_w = &context.get_elem_residual(this->_flow_vars.w());
482 M_ww = &context.get_elem_jacobian(this->_flow_vars.w(), this->_flow_vars.w());
485 unsigned int n_qpoints = context.get_element_qrule().n_points();
487 for (
unsigned int qp = 0; qp != n_qpoints; ++qp)
494 libMesh::Real u_dot, v_dot, w_dot = 0.0;
495 context.interior_rate(this->_flow_vars.u(), qp, u_dot);
496 context.interior_rate(this->_flow_vars.v(), qp, v_dot);
499 context.interior_rate(this->_flow_vars.w(), qp, w_dot);
501 const libMesh::Number r = u_qpoint[qp](0);
503 libMesh::Real jac = JxW[qp];
510 for (
unsigned int i = 0; i != n_u_dofs; ++i)
512 F_u(i) -= this->_rho*u_dot*u_phi[i][qp]*jac;
513 F_v(i) -= this->_rho*v_dot*u_phi[i][qp]*jac;
515 if( this->_dim == 3 )
516 (*F_w)(i) -= this->_rho*w_dot*u_phi[i][qp]*jac;
518 if( compute_jacobian )
520 for (
unsigned int j=0; j != n_u_dofs; j++)
524 libMesh::Real value = this->_rho*u_phi[i][qp]*u_phi[j][qp]*jac * context.get_elem_solution_rate_derivative();
531 (*M_ww)(i,j) -= value;
545 const libMesh::Point& point,
546 libMesh::Real& value )
548 if( quantity_index == this->_mu_index )
550 value = this->_mu(point, context.get_time());
static bool is_axisymmetric()
virtual void mass_residual(bool compute_jacobian, AssemblyContext &context, CachedValues &cache)
Mass matrix part(s) for element interiors. All boundary terms lie within the time_derivative part...
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 register_postprocessing_vars(const GetPot &input, PostProcessedQuantities< libMesh::Real > &postprocessing)
Register postprocessing variables for IncompressibleNavierStokes.
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 element_constraint(bool compute_jacobian, AssemblyContext &context, CachedValues &cache)
Constraint part(s) of physics for element interiors.
virtual void auxiliary_init(MultiphysicsSystem &system)
Any auxillary initialization a Physics class may need.
virtual void element_time_derivative(bool compute_jacobian, AssemblyContext &context, CachedValues &cache)
Time dependent part(s) of physics for element interiors.