34 #include "libmesh/libmesh_common.h"
35 #include "libmesh/point.h"
36 #include "libmesh/quadrature.h"
37 #include "libmesh/elem.h"
38 #include "libmesh/fe_interface.h"
53 template<
typename FEShape>
56 const libMesh::Real sign,
57 const typename libMesh::TensorTools::IncrementRank<FEShape>::type& value )
const
59 libMesh::FEGenericBase<FEShape>* side_fe = NULL;
60 context.get_side_fe( var, side_fe );
63 const unsigned int n_var_dofs = context.get_dof_indices(var).size();
66 const std::vector<libMesh::Real> &JxW_side = side_fe->get_JxW();
69 const std::vector<std::vector<FEShape> >& var_phi_side = side_fe->get_phi();
71 const std::vector<libMesh::Point> &normals = side_fe->get_normals();
73 libMesh::DenseSubVector<libMesh::Number> &F_var = context.get_elem_residual(var);
75 unsigned int n_qpoints = context.get_side_qrule().n_points();
76 for (
unsigned int qp=0; qp != n_qpoints; qp++)
78 for (
unsigned int i=0; i != n_var_dofs; i++)
80 F_var(i) += sign*JxW_side[qp]*value*normals[qp]*var_phi_side[i][qp];
87 template<
typename FEShape>
90 const libMesh::Real sign,
91 const FEShape& value )
const
93 libMesh::FEGenericBase<FEShape>* side_fe = NULL;
94 context.get_side_fe( var, side_fe );
97 const unsigned int n_var_dofs = context.get_dof_indices(var).size();
100 const std::vector<libMesh::Real> &JxW_side = side_fe->get_JxW();
103 const std::vector<std::vector<FEShape> >& var_phi_side = side_fe->get_phi();
105 libMesh::DenseSubVector<libMesh::Number> &F_var = context.get_elem_residual(var);
107 unsigned int n_qpoints = context.get_side_qrule().n_points();
108 for (
unsigned int qp=0; qp != n_qpoints; qp++)
110 for (
unsigned int i=0; i != n_var_dofs; i++)
112 F_var(i) += sign*value*var_phi_side[i][qp]*JxW_side[qp];
119 template<
typename FEShape>
122 const libMesh::Real sign,
123 const FEShape& value )
const
125 libMesh::FEGenericBase<FEShape>* side_fe = NULL;
126 context.get_side_fe( var, side_fe );
129 const unsigned int n_var_dofs = context.get_dof_indices(var).size();
132 const std::vector<libMesh::Real> &JxW_side = side_fe->get_JxW();
135 const std::vector<std::vector<FEShape> >& var_phi_side =
139 const std::vector<libMesh::Point>& var_qpoint =
142 libMesh::DenseSubVector<libMesh::Number> &F_var = context.get_elem_residual(var);
144 unsigned int n_qpoints = context.get_side_qrule().n_points();
146 for (
unsigned int qp=0; qp != n_qpoints; qp++)
148 const libMesh::Number r = var_qpoint[qp](0);
150 for (
unsigned int i=0; i != n_var_dofs; i++)
152 F_var(i) += sign*r*value*var_phi_side[i][qp]*JxW_side[qp];
159 template<
typename FEShape>
162 const libMesh::Real sign,
163 const typename libMesh::TensorTools::IncrementRank<FEShape>::type& value )
const
165 libMesh::FEGenericBase<FEShape>* side_fe = NULL;
166 context.get_side_fe( var, side_fe );
169 const unsigned int n_var_dofs = context.get_dof_indices(var).size();
172 const std::vector<libMesh::Real> &JxW_side = side_fe->get_JxW();
175 const std::vector<std::vector<FEShape> >& var_phi_side =
179 const std::vector<libMesh::Point>& var_qpoint =
182 const std::vector<libMesh::Point> &normals = side_fe->get_normals();
184 libMesh::DenseSubVector<libMesh::Number> &F_var = context.get_elem_residual(var);
186 unsigned int n_qpoints = context.get_side_qrule().n_points();
187 for (
unsigned int qp=0; qp != n_qpoints; qp++)
189 const libMesh::Number r = var_qpoint[qp](0);
191 for (
unsigned int i=0; i != n_var_dofs; i++)
193 F_var(i) += sign*r*JxW_side[qp]*value*normals[qp]*var_phi_side[i][qp];
200 template<
typename FEShape>
203 const bool request_jacobian,
205 const libMesh::Real sign,
206 const std::tr1::shared_ptr<NeumannFuncObj> neumann_func )
const
208 libMesh::FEGenericBase<libMesh::Real>* side_fe = NULL;
209 context.get_side_fe( var, side_fe );
212 const unsigned int n_var_dofs = context.get_dof_indices(var).size();
215 const std::vector<libMesh::Real> &JxW_side = side_fe->get_JxW();
218 const std::vector<std::vector<libMesh::Real> >& var_phi_side =
221 const std::vector<libMesh::Point> &normals = side_fe->get_normals();
223 libMesh::DenseSubVector<libMesh::Number> &F_var = context.get_elem_residual(var);
224 libMesh::DenseSubMatrix<libMesh::Number> &K_var = context.get_elem_jacobian(var,var);
226 unsigned int n_qpoints = context.get_side_qrule().n_points();
228 for (
unsigned int qp=0; qp != n_qpoints; qp++)
230 const libMesh::Point bc_value = neumann_func->value( context, cache, qp );
232 libMesh::Point jac_value;
235 jac_value = neumann_func->derivative( context, cache, qp );
238 for (
unsigned int i=0; i != n_var_dofs; i++)
240 F_var(i) += sign*JxW_side[qp]*bc_value*normals[qp]*var_phi_side[i][qp];
242 if (request_jacobian)
244 for (
unsigned int j=0; j != n_var_dofs; j++)
246 K_var(i,j) += sign*JxW_side[qp]*jac_value*normals[qp]*
247 var_phi_side[i][qp]*var_phi_side[j][qp];
255 std::vector<VariableIndex> other_jac_vars = neumann_func->get_other_jac_vars();
257 if( (other_jac_vars.size() > 0) && request_jacobian )
259 for( std::vector<VariableIndex>::const_iterator var2 = other_jac_vars.begin();
260 var2 != other_jac_vars.end();
263 libMesh::FEGenericBase<libMesh::Real>* side_fe2 = NULL;
264 context.get_side_fe( *var2, side_fe2 );
266 libMesh::DenseSubMatrix<libMesh::Number> &K_var2 = context.get_elem_jacobian(var,*var2);
268 const unsigned int n_var2_dofs = context.get_dof_indices(*var2).size();
269 const std::vector<std::vector<libMesh::Real> >& var2_phi_side =
272 for (
unsigned int qp=0; qp != n_qpoints; qp++)
274 const libMesh::Point jac_value = neumann_func->derivative( context, cache, qp, *var2 );
276 for (
unsigned int i=0; i != n_var_dofs; i++)
278 for (
unsigned int j=0; j != n_var2_dofs; j++)
280 K_var2(i,j) += sign*JxW_side[qp]*jac_value*normals[qp]*
281 var_phi_side[i][qp]*var2_phi_side[j][qp];
290 template<
typename FEShape>
293 const bool request_jacobian,
295 const libMesh::Real sign,
296 const std::tr1::shared_ptr<NeumannFuncObj> neumann_func )
const
298 libMesh::FEGenericBase<libMesh::Real>* side_fe = NULL;
299 context.get_side_fe( var, side_fe );
302 const unsigned int n_var_dofs = context.get_dof_indices(var).size();
305 const std::vector<libMesh::Real> &JxW_side = side_fe->get_JxW();
308 const std::vector<std::vector<libMesh::Real> >& var_phi_side =
311 libMesh::DenseSubVector<libMesh::Number> &F_var = context.get_elem_residual(var);
312 libMesh::DenseSubMatrix<libMesh::Number> &K_var = context.get_elem_jacobian(var,var);
314 unsigned int n_qpoints = context.get_side_qrule().n_points();
316 for (
unsigned int qp=0; qp != n_qpoints; qp++)
318 const libMesh::Real bc_value = neumann_func->normal_value( context, cache, qp );
319 libMesh::Real jac_value = 0.0;
322 jac_value = neumann_func->normal_derivative( context, cache, qp );
325 for (
unsigned int i=0; i != n_var_dofs; i++)
327 F_var(i) += sign*bc_value*var_phi_side[i][qp]*JxW_side[qp];
329 if (request_jacobian)
331 for (
unsigned int j=0; j != n_var_dofs; j++)
333 K_var(i,j) += sign*jac_value*
334 var_phi_side[i][qp]*var_phi_side[j][qp]*JxW_side[qp];
342 std::vector<VariableIndex> other_jac_vars = neumann_func->get_other_jac_vars();
344 if( (other_jac_vars.size() > 0) && request_jacobian )
346 for( std::vector<VariableIndex>::const_iterator var2 = other_jac_vars.begin();
347 var2 != other_jac_vars.end();
350 libMesh::FEGenericBase<libMesh::Real>* side_fe2 = NULL;
351 context.get_side_fe( *var2, side_fe2 );
353 libMesh::DenseSubMatrix<libMesh::Number> &K_var2 = context.get_elem_jacobian(var,*var2);
355 const unsigned int n_var2_dofs = context.get_dof_indices(*var2).size();
356 const std::vector<std::vector<libMesh::Real> >& var2_phi_side =
359 for (
unsigned int qp=0; qp != n_qpoints; qp++)
361 const libMesh::Real jac_value = neumann_func->normal_derivative( context, cache, qp, *var2 );
363 for (
unsigned int i=0; i != n_var_dofs; i++)
365 for (
unsigned int j=0; j != n_var2_dofs; j++)
367 K_var2(i,j) += sign*jac_value*
368 var_phi_side[i][qp]*var2_phi_side[j][qp]*JxW_side[qp];
377 template<
typename FEShape>
380 const bool request_jacobian,
382 const libMesh::Real sign,
383 const std::tr1::shared_ptr<NeumannFuncObj> neumann_func )
const
385 libMesh::FEGenericBase<libMesh::Real>* side_fe = NULL;
386 context.get_side_fe( var, side_fe );
389 const unsigned int n_var_dofs = context.get_dof_indices(var).size();
392 const std::vector<libMesh::Real> &JxW_side = side_fe->get_JxW();
395 const std::vector<std::vector<libMesh::Real> >& var_phi_side = side_fe->get_phi();
398 const std::vector<libMesh::Point>& var_qpoint = side_fe->get_xyz();
400 libMesh::DenseSubVector<libMesh::Number> &F_var = context.get_elem_residual(var);
401 libMesh::DenseSubMatrix<libMesh::Number> &K_var = context.get_elem_jacobian(var,var);
403 unsigned int n_qpoints = context.get_side_qrule().n_points();
405 for (
unsigned int qp=0; qp != n_qpoints; qp++)
407 const libMesh::Real bc_value = neumann_func->normal_value( context, cache, qp );
408 libMesh::Real jac_value = 0.0;
411 jac_value = neumann_func->normal_derivative( context, cache, qp );
414 const libMesh::Number r = var_qpoint[qp](0);
416 for (
unsigned int i=0; i != n_var_dofs; i++)
418 F_var(i) += sign*r*bc_value*var_phi_side[i][qp]*JxW_side[qp];
420 if (request_jacobian)
422 for (
unsigned int j=0; j != n_var_dofs; j++)
424 K_var(i,j) += sign*r*jac_value*
425 var_phi_side[i][qp]*var_phi_side[j][qp]*JxW_side[qp];
433 std::vector<VariableIndex> other_jac_vars = neumann_func->get_other_jac_vars();
435 if( (other_jac_vars.size() > 0) && request_jacobian )
437 for( std::vector<VariableIndex>::const_iterator var2 = other_jac_vars.begin();
438 var2 != other_jac_vars.end();
441 libMesh::FEGenericBase<libMesh::Real>* side_fe2 = NULL;
442 context.get_side_fe( *var2, side_fe2 );
444 libMesh::DenseSubMatrix<libMesh::Number> &K_var2 = context.get_elem_jacobian(var,*var2);
446 const unsigned int n_var2_dofs = context.get_dof_indices(*var2).size();
447 const std::vector<std::vector<libMesh::Real> >& var2_phi_side =
450 for (
unsigned int qp=0; qp != n_qpoints; qp++)
452 const libMesh::Real jac_value = neumann_func->normal_derivative( context, cache, qp, *var2 );
454 const libMesh::Number r = var_qpoint[qp](0);
456 for (
unsigned int i=0; i != n_var_dofs; i++)
458 for (
unsigned int j=0; j != n_var2_dofs; j++)
460 K_var2(i,j) += sign*r*jac_value*
461 var_phi_side[i][qp]*var2_phi_side[j][qp]*JxW_side[qp];
471 template<
typename FEShape>
474 const bool request_jacobian,
476 const libMesh::Real sign,
477 std::tr1::shared_ptr<NeumannFuncObj> neumann_func )
const
479 libMesh::FEGenericBase<libMesh::Real>* side_fe = NULL;
480 context.get_side_fe( var, side_fe );
483 const unsigned int n_var_dofs = context.get_dof_indices(var).size();
486 const std::vector<libMesh::Real> &JxW_side = side_fe->get_JxW();
489 const std::vector<std::vector<libMesh::Real> >& var_phi_side =
493 const std::vector<libMesh::Point>& var_qpoint =
496 const std::vector<libMesh::Point> &normals = side_fe->get_normals();
498 libMesh::DenseSubVector<libMesh::Number> &F_var = context.get_elem_residual(var);
499 libMesh::DenseSubMatrix<libMesh::Number> &K_var = context.get_elem_jacobian(var,var);
501 unsigned int n_qpoints = context.get_side_qrule().n_points();
503 for (
unsigned int qp=0; qp != n_qpoints; qp++)
505 const libMesh::Point bc_value = neumann_func->value( context, cache, qp );
506 libMesh::Point jac_value;
507 if (request_jacobian)
509 jac_value = neumann_func->derivative( context, cache, qp );
512 const libMesh::Number r = var_qpoint[qp](0);
514 for (
unsigned int i=0; i != n_var_dofs; i++)
516 F_var(i) += sign*r*JxW_side[qp]*bc_value*normals[qp]*var_phi_side[i][qp];
518 if (request_jacobian)
520 for (
unsigned int j=0; j != n_var_dofs; j++)
522 K_var(i,j) += sign*r*JxW_side[qp]*jac_value*normals[qp]*
523 var_phi_side[i][qp]*var_phi_side[j][qp];
531 std::vector<VariableIndex> other_jac_vars = neumann_func->get_other_jac_vars();
533 if( (other_jac_vars.size() > 0) && request_jacobian )
535 for( std::vector<VariableIndex>::const_iterator var2 = other_jac_vars.begin();
536 var2 != other_jac_vars.end();
539 libMesh::FEGenericBase<libMesh::Real>* side_fe2 = NULL;
540 context.get_side_fe( *var2, side_fe2 );
542 libMesh::DenseSubMatrix<libMesh::Number> &K_var2 = context.get_elem_jacobian(var,*var2);
544 const unsigned int n_var2_dofs = context.get_dof_indices(*var2).size();
545 const std::vector<std::vector<libMesh::Real> >& var2_phi_side =
548 for (
unsigned int qp=0; qp != n_qpoints; qp++)
550 const libMesh::Number r = var_qpoint[qp](0);
552 const libMesh::Point jac_value = neumann_func->derivative( context, cache, qp, *var2 );
554 for (
unsigned int i=0; i != n_var_dofs; i++)
556 for (
unsigned int j=0; j != n_var2_dofs; j++)
558 K_var2(i,j) += sign*r*JxW_side[qp]*jac_value*normals[qp]*
559 var_phi_side[i][qp]*var2_phi_side[j][qp];
568 template<
typename FEShape>
571 const bool request_jacobian,
573 const double pin_value,
574 const libMesh::Point& pin_location,
575 const double penalty )
577 if (context.get_elem().contains_point(pin_location))
579 libMesh::FEGenericBase<libMesh::Real>* elem_fe = NULL;
580 context.get_element_fe( var, elem_fe );
582 libMesh::DenseSubVector<libMesh::Number> &F_var = context.get_elem_residual(var);
583 libMesh::DenseSubMatrix<libMesh::Number> &K_var = context.get_elem_jacobian(var,var);
586 const unsigned int n_var_dofs = context.get_dof_indices(var).size();
588 libMesh::Number var_value = context.point_value(var, pin_location);
590 libMesh::FEType fe_type = elem_fe->get_fe_type();
592 libMesh::Point point_loc_in_masterelem =
593 libMesh::FEInterface::inverse_map(context.get_dim(), fe_type, &context.get_elem(), pin_location);
595 std::vector<libMesh::Real> phi(n_var_dofs);
597 for (
unsigned int i=0; i != n_var_dofs; i++)
599 phi[i] = libMesh::FEInterface::shape( context.get_dim(), fe_type, &context.get_elem(), i,
600 point_loc_in_masterelem );
603 for (
unsigned int i=0; i != n_var_dofs; i++)
605 F_var(i) += penalty*(var_value -
pin_value)*phi[i];
608 if (request_jacobian && context.get_elem_solution_derivative())
610 libmesh_assert (context.get_elem_solution_derivative() == 1.0);
612 for (
unsigned int j=0; j != n_var_dofs; j++)
613 K_var(i,j) += penalty*phi[i]*phi[j];
626 template void GRINS::BoundaryConditions::apply_neumann<libMesh::Real>(AssemblyContext&,
const GRINS::VariableIndex,
const libMesh::Real,
const libMesh::RealGradient&)
const;
627 template void GRINS::BoundaryConditions::apply_neumann<libMesh::RealGradient>(AssemblyContext&,
const GRINS::VariableIndex,
const libMesh::Real,
const libMesh::RealTensor&)
const;
629 template void GRINS::BoundaryConditions::apply_neumann_axisymmetric<libMesh::Real>(AssemblyContext&,
const GRINS::VariableIndex,
const libMesh::Real,
const libMesh::RealGradient&)
const;
630 template void GRINS::BoundaryConditions::apply_neumann_axisymmetric<libMesh::RealGradient>(AssemblyContext&,
const GRINS::VariableIndex,
const libMesh::Real,
const libMesh::RealTensor&)
const;
632 template void GRINS::BoundaryConditions::apply_neumann_normal<libMesh::Real>(AssemblyContext&,
const GRINS::VariableIndex,
const libMesh::Real,
const libMesh::Real& )
const;
633 template void GRINS::BoundaryConditions::apply_neumann_normal<libMesh::RealGradient>(AssemblyContext&,
const GRINS::VariableIndex,
const libMesh::Real,
const libMesh::RealGradient& )
const;
635 template void GRINS::BoundaryConditions::apply_neumann_normal_axisymmetric<libMesh::Real>(AssemblyContext&,
const GRINS::VariableIndex,
const libMesh::Real,
const libMesh::Real&)
const;
636 template void GRINS::BoundaryConditions::apply_neumann_normal_axisymmetric<libMesh::RealGradient>(AssemblyContext&,
const GRINS::VariableIndex,
const libMesh::Real,
const libMesh::RealGradient&)
const;
640 template void GRINS::BoundaryConditions::apply_neumann<libMesh::Real>(AssemblyContext&,
const GRINS::CachedValues&,
const bool,
const GRINS::VariableIndex,
const libMesh::Real, std::tr1::shared_ptr<GRINS::NeumannFuncObj>)
const;
641 template void GRINS::BoundaryConditions::apply_neumann<libMesh::RealGradient>(AssemblyContext&,
const GRINS::CachedValues&,
const bool,
const GRINS::VariableIndex,
const libMesh::Real, std::tr1::shared_ptr<GRINS::NeumannFuncObj>)
const;
643 template void GRINS::BoundaryConditions::apply_neumann_axisymmetric<libMesh::Real>(AssemblyContext&,
const GRINS::CachedValues&,
const bool,
const GRINS::VariableIndex,
const libMesh::Real, std::tr1::shared_ptr<GRINS::NeumannFuncObj>)
const;
644 template void GRINS::BoundaryConditions::apply_neumann_axisymmetric<libMesh::RealGradient>(AssemblyContext&,
const GRINS::CachedValues&,
const bool,
const GRINS::VariableIndex,
const libMesh::Real, std::tr1::shared_ptr<GRINS::NeumannFuncObj>)
const;
646 template void GRINS::BoundaryConditions::apply_neumann_normal<libMesh::Real>(AssemblyContext&,
const GRINS::CachedValues&,
const bool,
const GRINS::VariableIndex,
const libMesh::Real, std::tr1::shared_ptr<GRINS::NeumannFuncObj>)
const;
647 template void GRINS::BoundaryConditions::apply_neumann_normal<libMesh::RealGradient>(AssemblyContext&,
const GRINS::CachedValues&,
const bool,
const GRINS::VariableIndex,
const libMesh::Real, std::tr1::shared_ptr<GRINS::NeumannFuncObj>)
const;
649 template void GRINS::BoundaryConditions::apply_neumann_normal_axisymmetric<libMesh::Real>(AssemblyContext&,
const GRINS::CachedValues&,
const bool,
const GRINS::VariableIndex,
const libMesh::Real, std::tr1::shared_ptr<GRINS::NeumannFuncObj>)
const;
650 template void GRINS::BoundaryConditions::apply_neumann_normal_axisymmetric<libMesh::RealGradient>(AssemblyContext&,
const GRINS::CachedValues&,
const bool,
const GRINS::VariableIndex,
const libMesh::Real, std::tr1::shared_ptr<GRINS::NeumannFuncObj>)
const;
652 template void GRINS::BoundaryConditions::pin_value<libMesh::Real>( AssemblyContext&,
const GRINS::CachedValues&,
const bool,
const GRINS::VariableIndex,
const double,
const libMesh::Point&,
const double);
653 template void GRINS::BoundaryConditions::pin_value<libMesh::RealGradient>( AssemblyContext&,
const GRINS::CachedValues&,
const bool,
const GRINS::VariableIndex,
const double,
const libMesh::Point&,
const double);
unsigned int VariableIndex
More descriptive name of the type used for variable indices.
void apply_neumann_normal(AssemblyContext &context, const VariableIndex var, const libMesh::Real sign, const FEShape &value) const
Applies Neumann boundary conditions for the constant case.
void apply_neumann_axisymmetric(AssemblyContext &context, const VariableIndex var, const libMesh::Real sign, const typename libMesh::TensorTools::IncrementRank< FEShape >::type &value) const
Applies Neumann boundary conditions for the constant case.
void pin_value(AssemblyContext &context, const CachedValues &cache, const bool request_jacobian, const VariableIndex var, const double value, const libMesh::Point &pin_location, const double penalty=1.0)
The idea here is to pin a variable to a particular value if there is a null space - e...
void apply_neumann(AssemblyContext &context, const VariableIndex var, const libMesh::Real sign, const typename libMesh::TensorTools::IncrementRank< FEShape >::type &value) const
Applies Neumann boundary conditions for the constant case.
void apply_neumann_normal_axisymmetric(AssemblyContext &context, const VariableIndex var, const libMesh::Real sign, const FEShape &value) const
Applies Neumann boundary conditions for the constant case.