void GRINS::BoundaryConditions::apply_neumann_normal( libMesh::FEMContext& context, const GRINS::VariableIndex var, const libMesh::Real sign, libMesh::Real value ) const { // The number of local degrees of freedom in each variable. const unsigned int n_var_dofs = context.dof_indices_var[var].size(); // Element Jacobian * quadrature weight for side integration. const std::vector<libMesh::Real> &JxW_side = context.side_fe_var[var]->get_JxW(); // The var shape functions at side quadrature points. const std::vector<std::vector<libMesh::Real> >& var_phi_side = context.side_fe_var[var]->get_phi(); libMesh::DenseSubVector<libMesh::Number> &F_var = *context.elem_subresiduals[var]; // residual unsigned int n_qpoints = context.side_qrule->n_points(); for (unsigned int qp=0; qp != n_qpoints; qp++) { for (unsigned int i=0; i != n_var_dofs; i++) { F_var(i) += sign*value*var_phi_side[i][qp]*JxW_side[qp]; } } return; }
void BoundaryConditions::apply_neumann_normal( AssemblyContext& context, const VariableIndex var, const libMesh::Real sign, const FEShape& value ) const { libMesh::FEGenericBase<FEShape>* side_fe = NULL; context.get_side_fe( var, side_fe ); // The number of local degrees of freedom in each variable. const unsigned int n_var_dofs = context.get_dof_indices(var).size(); // Element Jacobian * quadrature weight for side integration. const std::vector<libMesh::Real> &JxW_side = side_fe->get_JxW(); // The var shape functions at side quadrature points. const std::vector<std::vector<FEShape> >& var_phi_side = side_fe->get_phi(); libMesh::DenseSubVector<libMesh::Number> &F_var = context.get_elem_residual(var); // residual unsigned int n_qpoints = context.get_side_qrule().n_points(); for (unsigned int qp=0; qp != n_qpoints; qp++) { for (unsigned int i=0; i != n_var_dofs; i++) { F_var(i) += sign*value*var_phi_side[i][qp]*JxW_side[qp]; } } return; }
void PressurePinning::pin_value( libMesh::DiffContext &context, const bool request_jacobian, const VariableIndex var, const double penalty ) { // Make sure we've called check_pin_location() and that pin location // is in the mesh somewhere libmesh_assert_not_equal_to( _pinned_elem_id, libMesh::DofObject::invalid_id ); /** \todo pin_location needs to be const. Currently a libMesh restriction. */ AssemblyContext &c = libMesh::libmesh_cast_ref<AssemblyContext&>(context); if( c.get_elem().id() == _pinned_elem_id ) { // This is redundant for vast majority of cases, but we trying to // be prepared for cases involving, e.g. mesh motion that we're not // currently handling. if( !c.get_elem().contains_point(_pin_location) ) { libmesh_error_msg("ERROR: _pin_location not in the current element!"); } libMesh::DenseSubVector<libMesh::Number> &F_var = c.get_elem_residual(var); // residual libMesh::DenseSubMatrix<libMesh::Number> &K_var = c.get_elem_jacobian(var, var); // jacobian // The number of local degrees of freedom in p variable. const unsigned int n_var_dofs = c.get_dof_indices(var).size(); libMesh::Number var_value = c.point_value(var, _pin_location); libMesh::FEType fe_type = c.get_element_fe(var)->get_fe_type(); libMesh::Point point_loc_in_masterelem = libMesh::FEInterface::inverse_map(c.get_dim(), fe_type, &c.get_elem(), _pin_location); std::vector<libMesh::Real> phi(n_var_dofs); for (unsigned int i=0; i != n_var_dofs; i++) phi[i] = libMesh::FEInterface::shape( c.get_dim(), fe_type, &c.get_elem(), i, point_loc_in_masterelem ); for (unsigned int i=0; i != n_var_dofs; i++) { F_var(i) += penalty*(var_value - _pin_value)*phi[i]; /** \todo What the hell is the c.get_elem_solution_derivative() all about? */ if (request_jacobian && c.get_elem_solution_derivative()) { libmesh_assert (c.get_elem_solution_derivative() == 1.0); for (unsigned int j=0; j != n_var_dofs; j++) K_var(i,j) += penalty*phi[i]*phi[j]; } // End if request_jacobian } // End i loop } // End if pin_location return; }
void BoundaryConditions::pin_value( AssemblyContext& context, const CachedValues& /*cache*/, const bool request_jacobian, const VariableIndex var, const double pin_value, const libMesh::Point& pin_location, const double penalty ) { if (context.get_elem().contains_point(pin_location)) { libMesh::FEGenericBase<libMesh::Real>* elem_fe = NULL; context.get_element_fe( var, elem_fe ); libMesh::DenseSubVector<libMesh::Number> &F_var = context.get_elem_residual(var); // residual libMesh::DenseSubMatrix<libMesh::Number> &K_var = context.get_elem_jacobian(var,var); // jacobian // The number of local degrees of freedom in p variable. const unsigned int n_var_dofs = context.get_dof_indices(var).size(); libMesh::Number var_value = context.point_value(var, pin_location); libMesh::FEType fe_type = elem_fe->get_fe_type(); libMesh::Point point_loc_in_masterelem = libMesh::FEInterface::inverse_map(context.get_dim(), fe_type, &context.get_elem(), pin_location); std::vector<libMesh::Real> phi(n_var_dofs); for (unsigned int i=0; i != n_var_dofs; i++) { phi[i] = libMesh::FEInterface::shape( context.get_dim(), fe_type, &context.get_elem(), i, point_loc_in_masterelem ); } for (unsigned int i=0; i != n_var_dofs; i++) { F_var(i) += penalty*(var_value - pin_value)*phi[i]; /** \todo What the hell is the context.get_elem_solution_derivative() all about? */ if (request_jacobian && context.get_elem_solution_derivative()) { libmesh_assert (context.get_elem_solution_derivative() == 1.0); for (unsigned int j=0; j != n_var_dofs; j++) K_var(i,j) += penalty*phi[i]*phi[j]; } // End if request_jacobian } // End i loop } // End if pin_location return; }
void PressurePinning::pin_value( libMesh::DiffContext &context, const bool request_jacobian, const VariableIndex var, const double penalty ) { /** \todo pin_location needs to be const. Currently a libMesh restriction. */ AssemblyContext &c = libMesh::libmesh_cast_ref<AssemblyContext&>(context); if (c.get_elem().contains_point(_pin_location)) { libMesh::DenseSubVector<libMesh::Number> &F_var = c.get_elem_residual(var); // residual libMesh::DenseSubMatrix<libMesh::Number> &K_var = c.get_elem_jacobian(var, var); // jacobian // The number of local degrees of freedom in p variable. const unsigned int n_var_dofs = c.get_dof_indices(var).size(); libMesh::Number var_value = c.point_value(var, _pin_location); libMesh::FEType fe_type = c.get_element_fe(var)->get_fe_type(); libMesh::Point point_loc_in_masterelem = libMesh::FEInterface::inverse_map(c.get_dim(), fe_type, &c.get_elem(), _pin_location); std::vector<libMesh::Real> phi(n_var_dofs); for (unsigned int i=0; i != n_var_dofs; i++) phi[i] = libMesh::FEInterface::shape( c.get_dim(), fe_type, &c.get_elem(), i, point_loc_in_masterelem ); for (unsigned int i=0; i != n_var_dofs; i++) { F_var(i) += penalty*(var_value - _pin_value)*phi[i]; /** \todo What the hell is the c.get_elem_solution_derivative() all about? */ if (request_jacobian && c.get_elem_solution_derivative()) { libmesh_assert (c.get_elem_solution_derivative() == 1.0); for (unsigned int j=0; j != n_var_dofs; j++) K_var(i,j) += penalty*phi[i]*phi[j]; } // End if request_jacobian } // End i loop } // End if pin_location return; }
void ConstantSourceTerm::element_time_derivative ( bool /*compute_jacobian*/, AssemblyContext & context ) { for( std::vector<VariableIndex>::const_iterator v_it = _vars.begin(); v_it != _vars.end(); ++v_it ) { VariableIndex var = *v_it; // The number of local degrees of freedom in each variable. const unsigned int n_dofs = context.get_dof_indices(var).size(); // Element Jacobian * quadrature weights for interior integration. const std::vector<libMesh::Real> &JxW = context.get_element_fe(var)->get_JxW(); // The temperature shape functions at interior quadrature points. const std::vector<std::vector<libMesh::Real> >& phi = context.get_element_fe(var)->get_phi(); // Get residuals libMesh::DenseSubVector<libMesh::Number> &F_var = context.get_elem_residual(var); // Now we will build the element Jacobian and residual. // Constructing the residual requires the solution and its // gradient from the previous timestep. This must be // calculated at each quadrature point by summing the // solution degree-of-freedom values by the appropriate // weight functions. unsigned int n_qpoints = context.get_element_qrule().n_points(); for (unsigned int qp=0; qp != n_qpoints; qp++) { for (unsigned int i=0; i != n_dofs; i++) { F_var(i) += (this->_value)*phi[i][qp]*JxW[qp]; } } } // Variable loop return; }
void GRINS::BoundaryConditions::apply_neumann_axisymmetric( libMesh::FEMContext& context, const CachedValues& cache, const bool request_jacobian, const GRINS::VariableIndex var, const libMesh::Real sign, std::tr1::shared_ptr<GRINS::NeumannFuncObj> neumann_func ) const { // The number of local degrees of freedom const unsigned int n_var_dofs = context.dof_indices_var[var].size(); // Element Jacobian * quadrature weight for side integration. const std::vector<libMesh::Real> &JxW_side = context.side_fe_var[var]->get_JxW(); // The var shape functions at side quadrature points. const std::vector<std::vector<libMesh::Real> >& var_phi_side = context.side_fe_var[var]->get_phi(); // Physical location of the quadrature points const std::vector<libMesh::Point>& var_qpoint = context.side_fe_var[var]->get_xyz(); const std::vector<libMesh::Point> &normals = context.side_fe_var[var]->get_normals(); libMesh::DenseSubVector<libMesh::Number> &F_var = *context.elem_subresiduals[var]; // residual libMesh::DenseSubMatrix<libMesh::Number> &K_var = *context.elem_subjacobians[var][var]; // jacobian unsigned int n_qpoints = context.side_qrule->n_points(); for (unsigned int qp=0; qp != n_qpoints; qp++) { const libMesh::Point bc_value = neumann_func->value( context, cache, qp ); const libMesh::Point jac_value = neumann_func->derivative( context, cache, qp ); const libMesh::Number r = var_qpoint[qp](0); for (unsigned int i=0; i != n_var_dofs; i++) { F_var(i) += sign*r*JxW_side[qp]*bc_value*normals[qp]*var_phi_side[i][qp]; if (request_jacobian) { for (unsigned int j=0; j != n_var_dofs; j++) { K_var(i,j) += sign*r*JxW_side[qp]*jac_value*normals[qp]* var_phi_side[i][qp]*var_phi_side[j][qp]; } } } } // End quadrature loop // Now must take care of the case that the boundary condition depends on variables // other than var. std::vector<VariableIndex> other_jac_vars = neumann_func->get_other_jac_vars(); if( (other_jac_vars.size() > 0) && request_jacobian ) { for( std::vector<VariableIndex>::const_iterator var2 = other_jac_vars.begin(); var2 != other_jac_vars.end(); var2++ ) { libMesh::DenseSubMatrix<libMesh::Number> &K_var2 = *context.elem_subjacobians[var][*var2]; // jacobian const unsigned int n_var2_dofs = context.dof_indices_var[*var2].size(); const std::vector<std::vector<libMesh::Real> >& var2_phi_side = context.side_fe_var[*var2]->get_phi(); for (unsigned int qp=0; qp != n_qpoints; qp++) { const libMesh::Number r = var_qpoint[qp](0); const libMesh::Point jac_value = neumann_func->derivative( context, cache, qp, *var2 ); for (unsigned int i=0; i != n_var_dofs; i++) { for (unsigned int j=0; j != n_var2_dofs; j++) { K_var2(i,j) += sign*r*JxW_side[qp]*jac_value*normals[qp]* var_phi_side[i][qp]*var2_phi_side[j][qp]; } } } } // End loop over auxillary Jacobian variables } return; }
void BoundaryConditions::apply_neumann_normal_axisymmetric( AssemblyContext& context, const CachedValues& cache, const bool request_jacobian, const VariableIndex var, const libMesh::Real sign, const SharedPtr<NeumannFuncObj> neumann_func ) const { libMesh::FEGenericBase<libMesh::Real>* side_fe = NULL; context.get_side_fe( var, side_fe ); // The number of local degrees of freedom const unsigned int n_var_dofs = context.get_dof_indices(var).size(); // Element Jacobian * quadrature weight for side integration. const std::vector<libMesh::Real> &JxW_side = side_fe->get_JxW(); // The var shape functions at side quadrature points. const std::vector<std::vector<libMesh::Real> >& var_phi_side = side_fe->get_phi(); // Physical location of the quadrature points const std::vector<libMesh::Point>& var_qpoint = side_fe->get_xyz(); libMesh::DenseSubVector<libMesh::Number> &F_var = context.get_elem_residual(var); // residual libMesh::DenseSubMatrix<libMesh::Number> &K_var = context.get_elem_jacobian(var,var); // jacobian unsigned int n_qpoints = context.get_side_qrule().n_points(); for (unsigned int qp=0; qp != n_qpoints; qp++) { const libMesh::Real bc_value = neumann_func->normal_value( context, cache, qp ); libMesh::Real jac_value = 0.0; if(request_jacobian) { jac_value = neumann_func->normal_derivative( context, cache, qp ); } const libMesh::Number r = var_qpoint[qp](0); for (unsigned int i=0; i != n_var_dofs; i++) { F_var(i) += sign*r*bc_value*var_phi_side[i][qp]*JxW_side[qp]; if (request_jacobian) { for (unsigned int j=0; j != n_var_dofs; j++) { K_var(i,j) += sign*r*jac_value* var_phi_side[i][qp]*var_phi_side[j][qp]*JxW_side[qp]; } } } } // End quadrature loop // Now must take care of the case that the boundary condition depends on variables // other than var. std::vector<VariableIndex> other_jac_vars = neumann_func->get_other_jac_vars(); if( (other_jac_vars.size() > 0) && request_jacobian ) { for( std::vector<VariableIndex>::const_iterator var2 = other_jac_vars.begin(); var2 != other_jac_vars.end(); var2++ ) { libMesh::FEGenericBase<libMesh::Real>* side_fe2 = NULL; context.get_side_fe( *var2, side_fe2 ); libMesh::DenseSubMatrix<libMesh::Number> &K_var2 = context.get_elem_jacobian(var,*var2); // jacobian const unsigned int n_var2_dofs = context.get_dof_indices(*var2).size(); const std::vector<std::vector<libMesh::Real> >& var2_phi_side = side_fe2->get_phi(); for (unsigned int qp=0; qp != n_qpoints; qp++) { const libMesh::Real jac_value = neumann_func->normal_derivative( context, cache, qp, *var2 ); const libMesh::Number r = var_qpoint[qp](0); for (unsigned int i=0; i != n_var_dofs; i++) { for (unsigned int j=0; j != n_var2_dofs; j++) { K_var2(i,j) += sign*r*jac_value* var_phi_side[i][qp]*var2_phi_side[j][qp]*JxW_side[qp]; } } } } // End loop over auxillary Jacobian variables } return; }