libMesh
Public Member Functions | Public Attributes | Protected Member Functions | List of all members
libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::ProjectVertices Struct Reference

#include <generic_projector.h>

Inheritance diagram for libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::ProjectVertices:
[legend]

Public Member Functions

 ProjectVertices (GenericProjector &p)
 
 ProjectVertices (ProjectVertices &p_v, Threads::split)
 
void operator() (const node_range &range)
 
template<typename InsertInput , typename std::enable_if< std::is_same< typename ProjectionAction::InsertInput, InsertInput >::value, int >::type = 0>
void insert_id (dof_id_type id, const InsertInput &val, processor_id_type pid)
 
template<typename InsertInput , typename std::enable_if< !std::is_same< typename ProjectionAction::InsertInput, InsertInput >::value, int >::type = 0>
void insert_id (dof_id_type id, const InsertInput &val, processor_id_type pid)
 
template<typename InsertInput , typename std::enable_if< std::is_same< typename ProjectionAction::InsertInput, InsertInput >::value, int >::type = 0>
void insert_ids (const std::vector< dof_id_type > &ids, const std::vector< InsertInput > &vals, processor_id_type pid)
 
template<typename InsertInput , typename std::enable_if< !std::is_same< typename ProjectionAction::InsertInput, InsertInput >::value, int >::type = 0>
void insert_ids (const std::vector< dof_id_type > &ids, const std::vector< InsertInput > &vals, processor_id_type pid)
 
template<typename InsertInput , typename std::enable_if< std::is_same< typename ProjectionAction::InsertInput, InsertInput >::value, int >::type = 0>
void insert_id (dof_id_type id, const InsertInput &val, processor_id_type pid)
 
template<typename InsertInput , typename std::enable_if< std::is_same< typename ProjectionAction::InsertInput, InsertInput >::value, int >::type = 0>
void insert_ids (const std::vector< dof_id_type > &ids, const std::vector< InsertInput > &vals, processor_id_type pid)
 
void find_dofs_to_send (const Node &node, const Elem &elem, unsigned short node_num, const var_set &vars)
 
void join (const SubFunctor &other)
 

Public Attributes

ProjectionAction action
 
FFunctor f
 
std::unique_ptr< GFunctor > g
 
const Systemsystem
 
FEMContext context
 
std::vector< FEContinuityconts
 
std::vector< FEFieldTypefield_types
 
GenericProjectorprojector
 
std::unordered_map< dof_id_type, std::pair< typename FFunctor::ValuePushType, processor_id_type > > new_ids_to_push
 
std::unordered_map< dof_id_type, typename FFunctor::ValuePushType > new_ids_to_save
 

Protected Member Functions

void construct_projection (const std::vector< dof_id_type > &dof_indices_var, const std::vector< unsigned int > &involved_dofs, unsigned int var_component, const Node *node, const FEGenericBase< typename FFunctor::RealType > &fe)
 

Detailed Description

template<typename FFunctor, typename GFunctor, typename FValue, typename ProjectionAction>
struct libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::ProjectVertices

Definition at line 294 of file generic_projector.h.

Constructor & Destructor Documentation

◆ ProjectVertices() [1/2]

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::ProjectVertices::ProjectVertices ( GenericProjector p)
inline

Definition at line 295 of file generic_projector.h.

295 : SubProjector(p) {}

◆ ProjectVertices() [2/2]

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::ProjectVertices::ProjectVertices ( ProjectVertices p_v,
Threads::split   
)
inline

Definition at line 297 of file generic_projector.h.

297 : SubProjector(p_v.projector) {}

Member Function Documentation

◆ construct_projection()

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
void libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubProjector::construct_projection ( const std::vector< dof_id_type > &  dof_indices_var,
const std::vector< unsigned int > &  involved_dofs,
unsigned int  var_component,
const Node node,
const FEGenericBase< typename FFunctor::RealType > &  fe 
)
protectedinherited

Definition at line 2988 of file generic_projector.h.

References libMesh::C_ONE, libMesh::DenseMatrix< T >::cholesky_solve(), libMesh::FEAbstract::get_continuity(), libMesh::FEGenericBase< OutputType >::get_dphi(), libMesh::FEAbstract::get_JxW(), libMesh::FEGenericBase< OutputType >::get_phi(), libMesh::DenseVector< T >::get_values(), libMesh::FEAbstract::get_xyz(), libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::ids_to_save, libMesh::TensorTools::inner_product(), libMesh::DofObject::invalid_processor_id, libMesh::make_range(), libMesh::DofObject::processor_id(), libMesh::DenseVector< T >::size(), libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::system, and libMesh::System::time.

2993 {
2994  const auto & JxW = fe.get_JxW();
2995  const auto & phi = fe.get_phi();
2996  const std::vector<std::vector<typename FEGenericBase<typename FFunctor::RealType>::OutputGradient>> * dphi = nullptr;
2997  const std::vector<Point> & xyz_values = fe.get_xyz();
2998  const FEContinuity cont = fe.get_continuity();
2999  const std::unordered_map<dof_id_type, typename FFunctor::ValuePushType> & ids_to_save =
3000  this->projector.ids_to_save;
3001 
3002  if (cont == C_ONE)
3003  dphi = &(fe.get_dphi());
3004 
3005  const unsigned int n_involved_dofs =
3006  cast_int<unsigned int>(involved_dofs.size());
3007 
3008  std::vector<dof_id_type> free_dof_ids;
3009  DenseVector<typename FFunctor::ValuePushType> Uinvolved(n_involved_dofs);
3010  std::vector<char> dof_is_fixed(n_involved_dofs, false); // bools
3011 
3012  for (auto i : make_range(n_involved_dofs))
3013  {
3014  const dof_id_type id = dof_indices_var[involved_dofs[i]];
3015  auto iter = ids_to_save.find(id);
3016  if (iter == ids_to_save.end())
3017  free_dof_ids.push_back(id);
3018  else
3019  {
3020  dof_is_fixed[i] = true;
3021  Uinvolved(i) = iter->second;
3022  }
3023  }
3024 
3025  const unsigned int free_dofs = free_dof_ids.size();
3026 
3027  // There may be nothing to project
3028  if (!free_dofs)
3029  return;
3030 
3031  // The element matrix and RHS for projections.
3032  // Note that Ke is always real-valued, whereas
3033  // Fe may be complex valued if complex number
3034  // support is enabled
3035  DenseMatrix<Real> Ke(free_dofs, free_dofs);
3036  DenseVector<typename FFunctor::ValuePushType> Fe(free_dofs);
3037  // The new degree of freedom coefficients to solve for
3038  DenseVector<typename FFunctor::ValuePushType> Ufree(free_dofs);
3039 
3040  const unsigned int n_qp =
3041  cast_int<unsigned int>(xyz_values.size());
3042 
3043  // Loop over the quadrature points
3044  for (unsigned int qp=0; qp<n_qp; qp++)
3045  {
3046  // solution at the quadrature point
3047  FValue fineval = f.eval_at_point(context,
3048  var_component,
3049  xyz_values[qp],
3050  system.time,
3051  false);
3052  // solution grad at the quadrature point
3053  typename GFunctor::FunctorValue finegrad;
3054  if (cont == C_ONE)
3055  finegrad = g->eval_at_point(context,
3056  var_component,
3057  xyz_values[qp],
3058  system.time,
3059  false);
3060 
3061  // Form edge projection matrix
3062  for (unsigned int sidei=0, freei=0;
3063  sidei != n_involved_dofs; ++sidei)
3064  {
3065  unsigned int i = involved_dofs[sidei];
3066  // fixed DoFs aren't test functions
3067  if (dof_is_fixed[sidei])
3068  continue;
3069  for (unsigned int sidej=0, freej=0;
3070  sidej != n_involved_dofs; ++sidej)
3071  {
3072  unsigned int j = involved_dofs[sidej];
3073  if (dof_is_fixed[sidej])
3074  Fe(freei) -= phi[i][qp] * phi[j][qp] *
3075  JxW[qp] * Uinvolved(sidej);
3076  else
3077  Ke(freei,freej) += phi[i][qp] *
3078  phi[j][qp] * JxW[qp];
3079  if (cont == C_ONE)
3080  {
3081  if (dof_is_fixed[sidej])
3082  Fe(freei) -= ( TensorTools::inner_product((*dphi)[i][qp],
3083  (*dphi)[j][qp]) ) *
3084  JxW[qp] * Uinvolved(sidej);
3085  else
3086  Ke(freei,freej) += ( TensorTools::inner_product((*dphi)[i][qp],
3087  (*dphi)[j][qp]) )
3088  * JxW[qp];
3089  }
3090  if (!dof_is_fixed[sidej])
3091  freej++;
3092  }
3093  Fe(freei) += phi[i][qp] * fineval * JxW[qp];
3094  if (cont == C_ONE)
3095  Fe(freei) += (TensorTools::inner_product(finegrad,
3096  (*dphi)[i][qp]) ) *
3097  JxW[qp];
3098  freei++;
3099  }
3100  }
3101 
3102  Ke.cholesky_solve(Fe, Ufree);
3103 
3104  // Transfer new edge solutions to element
3105  const processor_id_type pid = node ?
3106  node->processor_id() : DofObject::invalid_processor_id;
3107  insert_ids(free_dof_ids, Ufree.get_values(), pid);
3108 }
Real time
For time-dependent problems, this is the time t at the beginning of the current timestep.
Definition: system.h:1595
uint8_t processor_id_type
std::unordered_map< dof_id_type, typename FFunctor::ValuePushType > ids_to_save
void insert_ids(const std::vector< dof_id_type > &ids, const std::vector< InsertInput > &vals, processor_id_type pid)
static const processor_id_type invalid_processor_id
An invalid processor_id to distinguish DoFs that have not been assigned to a processor.
Definition: dof_object.h:488
template class LIBMESH_EXPORT DenseMatrix< Real >
Definition: dense_matrix.C:35
FEContinuity
defines an enum for finite element types to libmesh_assert a certain level (or type? Hcurl?) of continuity.
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition: int_range.h:134
boostcopy::enable_if_c< ScalarTraits< T >::value &&ScalarTraits< T2 >::value, typename CompareTypes< T, T2 >::supertype >::type inner_product(const T &a, const T2 &b)
Definition: tensor_tools.h:51
uint8_t dof_id_type
Definition: id_types.h:67

◆ find_dofs_to_send()

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
void libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::find_dofs_to_send ( const Node node,
const Elem elem,
unsigned short  node_num,
const var_set vars 
)
inherited

Definition at line 2829 of file generic_projector.h.

References libMesh::Elem::active(), libMesh::Variable::active_on_subdomain(), libMesh::DofMap::dof_indices(), libMesh::System::get_dof_map(), libMesh::System::get_mesh(), libMesh::DofObject::id(), libMesh::DofObject::invalid_processor_id, libMesh::Parallel::Utils::is_sorted(), libMesh::libmesh_assert(), mesh, libMesh::Elem::node_ptr(), libMesh::ParallelObject::processor_id(), libMesh::DofObject::processor_id(), libMesh::Elem::subdomain_id(), libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::system, and libMesh::System::variable().

2830 {
2831  libmesh_assert (&node == elem.node_ptr(node_num));
2832 
2833  // Any ghosted node in our range might have an owner who needs our
2834  // data
2835  const processor_id_type owner = node.processor_id();
2836  if (owner != system.processor_id())
2837  {
2838  const MeshBase & mesh = system.get_mesh();
2839  const DofMap & dof_map = system.get_dof_map();
2840 
2841  // But let's check and see if we can be certain the owner can
2842  // compute any or all of its own dof coefficients on that node.
2843  std::vector<dof_id_type> node_dof_ids, patch_dof_ids;
2844  for (const auto & var : vars)
2845  {
2846  const Variable & variable = system.variable(var);
2847 
2848  if (!variable.active_on_subdomain(elem.subdomain_id()))
2849  continue;
2850 
2851  dof_map.dof_indices(elem, node_num, node_dof_ids, var);
2852  }
2853  libmesh_assert(std::is_sorted(node_dof_ids.begin(),
2854  node_dof_ids.end()));
2855  const std::vector<dof_id_type> & patch =
2856  (*this->projector.nodes_to_elem)[node.id()];
2857  for (const auto & elem_id : patch)
2858  {
2859  const Elem & patch_elem = mesh.elem_ref(elem_id);
2860  if (!patch_elem.active() || owner != patch_elem.processor_id())
2861  continue;
2862  dof_map.dof_indices(&patch_elem, patch_dof_ids);
2863  std::sort(patch_dof_ids.begin(), patch_dof_ids.end());
2864 
2865  // Remove any node_dof_ids that we see can be calculated on
2866  // this element
2867  std::vector<dof_id_type> diff_ids(node_dof_ids.size());
2868  auto it = std::set_difference(node_dof_ids.begin(), node_dof_ids.end(),
2869  patch_dof_ids.begin(), patch_dof_ids.end(), diff_ids.begin());
2870  diff_ids.resize(it-diff_ids.begin());
2871  node_dof_ids.swap(diff_ids);
2872  if (node_dof_ids.empty())
2873  break;
2874  }
2875 
2876  // Give ids_to_push default invalid pid: not yet computed
2877  for (auto id : node_dof_ids)
2879  }
2880 }
std::unordered_map< dof_id_type, std::pair< typename FFunctor::ValuePushType, processor_id_type > > new_ids_to_push
const Variable & variable(unsigned int var) const
Return a constant reference to Variable var.
Definition: system.h:2377
MeshBase & mesh
const MeshBase & get_mesh() const
Definition: system.h:2277
uint8_t processor_id_type
bool is_sorted(const std::vector< KeyType > &v)
static const processor_id_type invalid_processor_id
An invalid processor_id to distinguish DoFs that have not been assigned to a processor.
Definition: dof_object.h:488
libmesh_assert(ctx)
std::unordered_map< dof_id_type, std::vector< dof_id_type > > * nodes_to_elem
processor_id_type processor_id() const
const DofMap & get_dof_map() const
Definition: system.h:2293

◆ insert_id() [1/3]

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
template<typename InsertInput , typename std::enable_if< std::is_same< typename ProjectionAction::InsertInput, InsertInput >::value, int >::type >
void libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::insert_id ( dof_id_type  id,
const InsertInput &  val,
processor_id_type  pid 
)
inherited

Definition at line 1365 of file generic_projector.h.

1367 {
1368  libmesh_error_msg("ID insertion should only occur when the provided input matches that "
1369  "expected by the ProjectionAction");
1370 }

◆ insert_id() [2/3]

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
template<typename InsertInput , typename std::enable_if< !std::is_same< typename ProjectionAction::InsertInput, InsertInput >::value, int >::type = 0>
void libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::insert_id ( typename InsertInput  ,
typename std::enable_if< !std::is_same< typename ProjectionAction::InsertInput, InsertInput >::value, int >::type  = 0 
)

◆ insert_id() [3/3]

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
template<typename InsertInput , typename std::enable_if< std::is_same< typename ProjectionAction::InsertInput, InsertInput >::value, int >::type = 0>
void libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::insert_id ( typename InsertInput  ,
typename std::enable_if< std::is_same< typename ProjectionAction::InsertInput, InsertInput >::value, int >::type  = 0 
)

Definition at line 1365 of file generic_projector.h.

1367 {
1368  libmesh_error_msg("ID insertion should only occur when the provided input matches that "
1369  "expected by the ProjectionAction");
1370 }

◆ insert_ids() [1/3]

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
template<typename InsertInput , typename std::enable_if< std::is_same< typename ProjectionAction::InsertInput, InsertInput >::value, int >::type >
void libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::insert_ids ( const std::vector< dof_id_type > &  ids,
const std::vector< InsertInput > &  vals,
processor_id_type  pid 
)
inherited

Definition at line 1407 of file generic_projector.h.

1411 {
1412  libmesh_error_msg("ID insertion should only occur when the provided input matches that "
1413  "expected by the ProjectionAction");
1414 }

◆ insert_ids() [2/3]

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
template<typename InsertInput , typename std::enable_if< !std::is_same< typename ProjectionAction::InsertInput, InsertInput >::value, int >::type = 0>
void libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::insert_ids ( typename InsertInput  ,
typename std::enable_if< !std::is_same< typename ProjectionAction::InsertInput, InsertInput >::value, int >::type  = 0 
)

◆ insert_ids() [3/3]

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
template<typename InsertInput , typename std::enable_if< std::is_same< typename ProjectionAction::InsertInput, InsertInput >::value, int >::type = 0>
void libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::insert_ids ( typename InsertInput  ,
typename std::enable_if< std::is_same< typename ProjectionAction::InsertInput, InsertInput >::value, int >::type  = 0 
)

Definition at line 1407 of file generic_projector.h.

1411 {
1412  libmesh_error_msg("ID insertion should only occur when the provided input matches that "
1413  "expected by the ProjectionAction");
1414 }

◆ join()

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
void libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::join ( const SubFunctor other)
inherited

Definition at line 1458 of file generic_projector.h.

References libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::new_ids_to_push, and libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::new_ids_to_save.

Referenced by libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SortAndCopy::join().

1459 {
1460  new_ids_to_push.insert(other.new_ids_to_push.begin(), other.new_ids_to_push.end());
1461  new_ids_to_save.insert(other.new_ids_to_save.begin(), other.new_ids_to_save.end());
1462 }
std::unordered_map< dof_id_type, std::pair< typename FFunctor::ValuePushType, processor_id_type > > new_ids_to_push
std::unordered_map< dof_id_type, typename FFunctor::ValuePushType > new_ids_to_save

◆ operator()()

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
void libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::ProjectVertices::operator() ( const node_range range)

Definition at line 2002 of file generic_projector.h.

References libMesh::C_ONE, libMesh::C_ZERO, dim, libMesh::Elem::dim(), libMesh::DISCONTINUOUS, libMesh::DofObject::dof_number(), libMesh::MeshBase::elem_ref(), libMesh::FEInterface::extra_hanging_dofs(), libMesh::FEType::family, libMesh::System::get_mesh(), libMesh::Elem::get_node_index(), libMesh::HERMITE, libMesh::Elem::hmin(), libMesh::DofObject::id(), libMesh::index_range(), int, libMesh::Elem::is_vertex_on_parent(), libMesh::Elem::JUST_REFINED, libMesh::libmesh_assert(), libMesh::make_range(), libMesh::DofObject::n_comp(), libMesh::FEInterface::n_dofs_at_node(), libMesh::System::number(), libMesh::Elem::parent(), libMesh::Elem::point(), libMesh::DofObject::processor_id(), libMesh::Real, libMesh::Elem::refinement_flag(), libMesh::SCALAR, libMesh::SIDE_DISCONTINUOUS, libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::system, libMesh::System::time, libMesh::TOLERANCE, libMesh::Variable::type(), libMesh::TYPE_VECTOR, libMesh::System::variable(), libMesh::System::variable_scalar_number(), and libMesh::Elem::which_child_am_i().

2003 {
2004  LOG_SCOPE ("project_vertices","GenericProjector");
2005 
2006  const unsigned int sys_num = system.number();
2007 
2008  // Variables with extra hanging dofs can't safely use eval_at_node
2009  // in as many places as variables without can.
2010  std::vector<unsigned short> extra_hanging_dofs;
2011  for (auto v_num : this->projector.variables)
2012  {
2013  if (extra_hanging_dofs.size() <= v_num)
2014  extra_hanging_dofs.resize(v_num+1, false);
2015  extra_hanging_dofs[v_num] =
2017  }
2018 
2019  for (const auto & v_pair : range)
2020  {
2021  const Node & vertex = *v_pair.first;
2022  const Elem & elem = *std::get<0>(v_pair.second);
2023  const unsigned int n = std::get<1>(v_pair.second);
2024  const var_set & vertex_vars = std::get<2>(v_pair.second);
2025 
2026  context.pre_fe_reinit(system, &elem);
2027 
2028  this->find_dofs_to_send(vertex, elem, n, vertex_vars);
2029 
2030  // Look at all the variables we're supposed to interpolate from
2031  // this element on this vertex
2032  for (const auto & var : vertex_vars)
2033  {
2034  const Variable & variable = system.variable(var);
2035  const FEType & base_fe_type = variable.type();
2036  const unsigned int var_component =
2038 
2039  if (base_fe_type.family == SCALAR)
2040  continue;
2041 
2042  const FEContinuity cont = this->conts[var];
2043  const FEFieldType field_type = this->field_types[var];
2044 
2045  if (cont == DISCONTINUOUS)
2046  {
2047  libmesh_assert_equal_to(vertex.n_comp(sys_num, var), 0);
2048  }
2049  else if (cont == C_ZERO ||
2050  cont == SIDE_DISCONTINUOUS)
2051  {
2052  if (cont == SIDE_DISCONTINUOUS &&
2053  elem.dim() != 1)
2054  {
2055  libmesh_assert_equal_to(vertex.n_comp(sys_num, var), 0);
2056  continue;
2057  }
2058 
2059  const FValue val = f.eval_at_node
2060  (context, var_component, /*dim=*/ 0, // Don't care w/C0
2061  vertex, extra_hanging_dofs[var], system.time);
2062 
2063  if (field_type == TYPE_VECTOR)
2064  {
2065  libmesh_assert_equal_to(vertex.n_comp(sys_num, var), elem.dim());
2066 
2067  // We will have a number of nodal value DoFs equal to the elem dim
2068  for (auto i : make_range(elem.dim()))
2069  {
2070  const dof_id_type id = vertex.dof_number(sys_num, var, i);
2071 
2072  // Need this conversion so that this method
2073  // will compile for TYPE_SCALAR instantiations
2074  const auto insert_val =
2075  raw_value<typename ProjectionAction::InsertInput>(val, i);
2076 
2077  insert_id(id, insert_val, vertex.processor_id());
2078  }
2079  }
2080  else
2081  {
2082  // C_ZERO elements have a single nodal value DoF at
2083  // vertices. We can't assert n_comp==1 here,
2084  // because if this is a hanging node then it may have
2085  // more face/edge DoFs, but we don't need to deal with
2086  // those here.
2087 
2088  const dof_id_type id = vertex.dof_number(sys_num, var, 0);
2089  insert_id(id, val, vertex.processor_id());
2090  }
2091  }
2092  else if (cont == C_ONE)
2093  {
2094  libmesh_assert(vertex.n_comp(sys_num, var));
2095  const dof_id_type first_id = vertex.dof_number(sys_num, var, 0);
2096 
2097  // C_ONE elements have a single nodal value and dim
2098  // gradient values at vertices, as well as cross
2099  // gradients for HERMITE. We need to have an element in
2100  // hand to figure out dim and to have in case this
2101  // vertex is a new vertex.
2102  const int dim = elem.dim();
2103 #ifndef NDEBUG
2104  // For now all C1 elements at a vertex had better have
2105  // the same dimension. If anyone hits these asserts let
2106  // me know; we could probably support a mixed-dimension
2107  // mesh IFF the 2D elements were all parallel to xy and
2108  // the 1D elements all parallel to x.
2109  for (const auto e_id : (*this->projector.nodes_to_elem)[vertex.id()])
2110  {
2111  const Elem & e = system.get_mesh().elem_ref(e_id);
2112  libmesh_assert_equal_to(dim, e.dim());
2113  }
2114 #endif
2115 #ifdef LIBMESH_ENABLE_AMR
2116  bool is_old_vertex = true;
2117  if (elem.refinement_flag() == Elem::JUST_REFINED)
2118  {
2119  const int i_am_child =
2120  elem.parent()->which_child_am_i(&elem);
2121  is_old_vertex =
2122  elem.parent()->is_vertex_on_parent(i_am_child, n);
2123  }
2124 #else
2125  const bool is_old_vertex = false;
2126 #endif
2127 
2128  // The hermite element vertex shape functions are weird
2129  if (base_fe_type.family == HERMITE)
2130  {
2131  const FValue val =
2132  f.eval_at_node(context,
2133  var_component,
2134  dim,
2135  vertex,
2136  extra_hanging_dofs[var],
2137  system.time);
2138  insert_id(first_id, val, vertex.processor_id());
2139 
2140  typename GFunctor::FunctorValue grad =
2141  is_old_vertex ?
2142  g->eval_at_node(context,
2143  var_component,
2144  dim,
2145  vertex,
2146  extra_hanging_dofs[var],
2147  system.time) :
2148  g->eval_at_point(context,
2149  var_component,
2150  vertex,
2151  system.time,
2152  false);
2153  // x derivative. Use slice because grad may be a tensor type
2154  insert_id(first_id+1, grad.slice(0),
2155  vertex.processor_id());
2156 #if LIBMESH_DIM > 1
2157  if (dim > 1 && is_old_vertex && f.is_grid_projection())
2158  {
2159  for (int i = 1; i < dim; ++i)
2160  insert_id(first_id+i+1, grad.slice(i),
2161  vertex.processor_id());
2162 
2163  // We can directly copy everything else too
2164  std::vector<FValue> derivs;
2165  f.eval_mixed_derivatives
2166  (context, var_component, dim, vertex, derivs);
2167  for (auto i : index_range(derivs))
2168  insert_id(first_id+dim+1+i, derivs[i],
2169  vertex.processor_id());
2170  }
2171  else if (dim > 1)
2172  {
2173  // We'll finite difference mixed derivatives.
2174  // This delta_x used to be TOLERANCE*hmin, but
2175  // the factor of 10 improved the accuracy in
2176  // some unit test projections
2177  Real delta_x = TOLERANCE * 10 * elem.hmin();
2178 
2179  Point nxminus = elem.point(n),
2180  nxplus = elem.point(n);
2181  nxminus(0) -= delta_x;
2182  nxplus(0) += delta_x;
2183  typename GFunctor::FunctorValue gxminus =
2184  g->eval_at_point(context,
2185  var_component,
2186  nxminus,
2187  system.time,
2188  true);
2189  typename GFunctor::FunctorValue gxplus =
2190  g->eval_at_point(context,
2191  var_component,
2192  nxplus,
2193  system.time,
2194  true);
2195  // y derivative
2196  insert_id(first_id+2, grad.slice(1),
2197  vertex.processor_id());
2198  // xy derivative
2199  insert_id(first_id+3,
2200  (grad_component(gxplus, 1) - grad_component(gxminus, 1)) / 2. / delta_x,
2201  vertex.processor_id());
2202 
2203 #if LIBMESH_DIM > 2
2204  if (dim > 2)
2205  {
2206  // z derivative
2207  insert_id(first_id+4, grad.slice(2),
2208  vertex.processor_id());
2209  // xz derivative
2210  insert_id(first_id+5,
2211  (grad_component(gxplus, 2) - grad_component(gxminus, 2)) / 2. / delta_x,
2212  vertex.processor_id());
2213 
2214  // We need new points for yz
2215  Point nyminus = elem.point(n),
2216  nyplus = elem.point(n);
2217  nyminus(1) -= delta_x;
2218  nyplus(1) += delta_x;
2219  typename GFunctor::FunctorValue gyminus =
2220  g->eval_at_point(context,
2221  var_component,
2222  nyminus,
2223  system.time,
2224  true);
2225  typename GFunctor::FunctorValue gyplus =
2226  g->eval_at_point(context,
2227  var_component,
2228  nyplus,
2229  system.time,
2230  true);
2231  // yz derivative
2232  insert_id(first_id+6,
2233  (grad_component(gyplus, 2) - grad_component(gyminus, 2)) / 2. / delta_x,
2234  vertex.processor_id());
2235  // Getting a 2nd order xyz is more tedious
2236  Point nxmym = elem.point(n),
2237  nxmyp = elem.point(n),
2238  nxpym = elem.point(n),
2239  nxpyp = elem.point(n);
2240  nxmym(0) -= delta_x;
2241  nxmym(1) -= delta_x;
2242  nxmyp(0) -= delta_x;
2243  nxmyp(1) += delta_x;
2244  nxpym(0) += delta_x;
2245  nxpym(1) -= delta_x;
2246  nxpyp(0) += delta_x;
2247  nxpyp(1) += delta_x;
2248  typename GFunctor::FunctorValue gxmym =
2249  g->eval_at_point(context,
2250  var_component,
2251  nxmym,
2252  system.time,
2253  true);
2254  typename GFunctor::FunctorValue gxmyp =
2255  g->eval_at_point(context,
2256  var_component,
2257  nxmyp,
2258  system.time,
2259  true);
2260  typename GFunctor::FunctorValue gxpym =
2261  g->eval_at_point(context,
2262  var_component,
2263  nxpym,
2264  system.time,
2265  true);
2266  typename GFunctor::FunctorValue gxpyp =
2267  g->eval_at_point(context,
2268  var_component,
2269  nxpyp,
2270  system.time,
2271  true);
2272  FValue gxzplus = (grad_component(gxpyp, 2) - grad_component(gxmyp, 2))
2273  / 2. / delta_x;
2274  FValue gxzminus = (grad_component(gxpym, 2) - grad_component(gxmym, 2))
2275  / 2. / delta_x;
2276  // xyz derivative
2277  insert_id(first_id+7,
2278  (gxzplus - gxzminus) / 2. / delta_x,
2279  vertex.processor_id());
2280  }
2281 #endif // LIBMESH_DIM > 2
2282  }
2283 #endif // LIBMESH_DIM > 1
2284  }
2285  else
2286  {
2287  // Currently other C_ONE elements have a single nodal
2288  // value shape function and nodal gradient component
2289  // shape functions
2290  libmesh_assert_equal_to(
2292  base_fe_type,
2293  &elem,
2294  elem.get_node_index(&vertex),
2297  (unsigned int)(1 + dim));
2298 
2299  const FValue val =
2300  f.eval_at_node(context, var_component, dim,
2301  vertex, extra_hanging_dofs[var],
2302  system.time);
2303  insert_id(first_id, val, vertex.processor_id());
2304  typename GFunctor::FunctorValue grad =
2305  is_old_vertex ?
2306  g->eval_at_node(context, var_component, dim,
2307  vertex, extra_hanging_dofs[var],
2308  system.time) :
2309  g->eval_at_point(context, var_component, vertex,
2310  system.time, false);
2311  for (int i=0; i!= dim; ++i)
2312  insert_id(first_id + i + 1, grad.slice(i),
2313  vertex.processor_id());
2314  }
2315  }
2316  else
2317  libmesh_error_msg("Unknown continuity " << cont);
2318  }
2319  }
2320 }
Real time
For time-dependent problems, this is the time t at the beginning of the current timestep.
Definition: system.h:1595
const Elem * parent() const
Definition: elem.h:2867
unsigned int variable_scalar_number(std::string_view var, unsigned int component) const
Definition: system.h:2408
const Variable & variable(unsigned int var) const
Return a constant reference to Variable var.
Definition: system.h:2377
virtual void pre_fe_reinit(const System &, const Elem *e)
Reinitializes local data vectors/matrices on the current geometric element.
Definition: fem_context.C:1675
static constexpr Real TOLERANCE
unsigned int dim
void should_p_refine(unsigned int g, bool p_refine)
Describe whether the given variable group should be p-refined.
Definition: dof_map.h:2322
const MeshBase & get_mesh() const
Definition: system.h:2277
void insert_id(dof_id_type id, const InsertInput &val, processor_id_type pid)
unsigned int var_group_from_var_number(unsigned int var_num) const
Definition: dof_map.h:2350
unsigned int number() const
Definition: system.h:2269
static bool extra_hanging_dofs(const FEType &fe_t)
libmesh_assert(ctx)
std::vector< FEFieldType > field_types
const std::vector< unsigned int > & variables
unsigned int which_child_am_i(const Elem *e) const
Definition: elem.h:3029
static unsigned int n_dofs_at_node(const unsigned int dim, const FEType &fe_t, const ElemType t, const unsigned int n)
Definition: fe_interface.C:679
void find_dofs_to_send(const Node &node, const Elem &elem, unsigned short node_num, const var_set &vars)
std::unordered_map< dof_id_type, std::vector< dof_id_type > > * nodes_to_elem
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
FEContinuity
defines an enum for finite element types to libmesh_assert a certain level (or type? Hcurl?) of continuity.
virtual const Elem & elem_ref(const dof_id_type i) const
Definition: mesh_base.h:618
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition: int_range.h:134
std::set< unsigned int > var_set
const DofMap & get_dof_map() const
Definition: system.h:2293
void ErrorVector unsigned int
Definition: adjoints_ex3.C:360
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:111
std::vector< FEContinuity > conts
uint8_t dof_id_type
Definition: id_types.h:67
const FEType & type() const
Definition: variable.h:140
FEFieldType
defines an enum for finite element field types - i.e.

Member Data Documentation

◆ action

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
ProjectionAction libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::action

Definition at line 218 of file generic_projector.h.

◆ context

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
FEMContext libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::context

Definition at line 223 of file generic_projector.h.

◆ conts

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
std::vector<FEContinuity> libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::conts

Definition at line 226 of file generic_projector.h.

◆ f

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
FFunctor libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::f

Definition at line 219 of file generic_projector.h.

◆ field_types

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
std::vector<FEFieldType> libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::field_types

Definition at line 227 of file generic_projector.h.

◆ g

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
std::unique_ptr<GFunctor> libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubProjector::g

Definition at line 254 of file generic_projector.h.

◆ new_ids_to_push

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
std::unordered_map<dof_id_type, std::pair<typename FFunctor::ValuePushType, processor_id_type> > libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::new_ids_to_push
inherited

◆ new_ids_to_save

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
std::unordered_map<dof_id_type, typename FFunctor::ValuePushType> libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::new_ids_to_save
inherited

◆ projector

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
GenericProjector& libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::projector
inherited

Definition at line 157 of file generic_projector.h.

◆ system

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
const System& libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::system

Definition at line 229 of file generic_projector.h.


The documentation for this struct was generated from the following file: