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;
  }
Beispiel #2
0
  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;
  }
Beispiel #3
0
  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;
  }
Beispiel #4
0
  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;
  }
Beispiel #5
0
  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;
  }
Beispiel #8
0
  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;
  }