libMesh
Loading...
Searching...
No Matches
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)
 
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 307 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 308 of file generic_projector.h.

◆ 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 310 of file generic_projector.h.

310: 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 3003 of file generic_projector.h.

3009{
3010 const auto & JxW = fe.get_JxW();
3011 const auto & phi = fe.get_phi();
3012 const std::vector<std::vector<typename FEGenericBase<typename FFunctor::RealType>::OutputGradient>> * dphi = nullptr;
3013 const std::vector<Point> & xyz_values = fe.get_xyz();
3014 const FEContinuity cont = fe.get_continuity();
3015 const std::unordered_map<dof_id_type, typename FFunctor::ValuePushType> & ids_to_save =
3016 this->projector.ids_to_save;
3017
3018 if (cont == C_ONE)
3019 dphi = &(fe.get_dphi());
3020
3021 const unsigned int n_involved_dofs =
3022 cast_int<unsigned int>(involved_dofs.size());
3023
3024 std::vector<dof_id_type> free_dof_ids;
3025 DenseVector<typename FFunctor::ValuePushType> Uinvolved(n_involved_dofs);
3026 std::vector<char> dof_is_fixed(n_involved_dofs, false); // bools
3027
3028 for (auto i : make_range(n_involved_dofs))
3029 {
3030 const dof_id_type id = dof_indices_var[involved_dofs[i]];
3031 auto iter = ids_to_save.find(id);
3032 if (iter == ids_to_save.end())
3033 free_dof_ids.push_back(id);
3034 else
3035 {
3036 dof_is_fixed[i] = true;
3037 Uinvolved(i) = iter->second;
3038 }
3039 }
3040
3041 const unsigned int free_dofs = free_dof_ids.size();
3042
3043 // There may be nothing to project
3044 if (!free_dofs)
3045 return;
3046
3047 // The element matrix and RHS for projections.
3048 // Note that Ke is always real-valued, whereas
3049 // Fe may be complex valued if complex number
3050 // support is enabled
3051 DenseMatrix<Real> Ke(free_dofs, free_dofs);
3052 DenseVector<typename FFunctor::ValuePushType> Fe(free_dofs);
3053 // The new degree of freedom coefficients to solve for
3054 DenseVector<typename FFunctor::ValuePushType> Ufree(free_dofs);
3055
3056 const unsigned int n_qp =
3057 cast_int<unsigned int>(xyz_values.size());
3058
3059 // Loop over the quadrature points
3060 for (unsigned int qp=0; qp<n_qp; qp++)
3061 {
3062 // solution at the quadrature point
3063 FValue fineval = f.eval_at_point(context,
3064 var_component,
3065 xyz_values[qp],
3066 system.time,
3067 false);
3068 // solution grad at the quadrature point
3069 typename GFunctor::FunctorValue finegrad;
3070 if (cont == C_ONE)
3071 finegrad = g->eval_at_point(context,
3072 var_component,
3073 xyz_values[qp],
3074 system.time,
3075 false);
3076
3077 // Form edge projection matrix
3078 for (unsigned int sidei=0, freei=0;
3079 sidei != n_involved_dofs; ++sidei)
3080 {
3081 unsigned int i = involved_dofs[sidei];
3082 // fixed DoFs aren't test functions
3083 if (dof_is_fixed[sidei])
3084 continue;
3085 for (unsigned int sidej=0, freej=0;
3086 sidej != n_involved_dofs; ++sidej)
3087 {
3088 unsigned int j = involved_dofs[sidej];
3089 if (dof_is_fixed[sidej])
3090 Fe(freei) -= phi[i][qp] * phi[j][qp] *
3091 JxW[qp] * Uinvolved(sidej);
3092 else
3093 Ke(freei,freej) += phi[i][qp] *
3094 phi[j][qp] * JxW[qp];
3095 if (cont == C_ONE)
3096 {
3097 if (dof_is_fixed[sidej])
3098 Fe(freei) -= ( TensorTools::inner_product((*dphi)[i][qp],
3099 (*dphi)[j][qp]) ) *
3100 JxW[qp] * Uinvolved(sidej);
3101 else
3102 Ke(freei,freej) += ( TensorTools::inner_product((*dphi)[i][qp],
3103 (*dphi)[j][qp]) )
3104 * JxW[qp];
3105 }
3106 if (!dof_is_fixed[sidej])
3107 freej++;
3108 }
3109 Fe(freei) += phi[i][qp] * fineval * JxW[qp];
3110 if (cont == C_ONE)
3111 Fe(freei) += (TensorTools::inner_product(finegrad,
3112 (*dphi)[i][qp]) ) *
3113 JxW[qp];
3114 freei++;
3115 }
3116 }
3117
3118 Ke.cholesky_solve(Fe, Ufree);
3119
3120 // Transfer new edge solutions to element
3121 const processor_id_type pid = node ?
3122 node->processor_id() : DofObject::invalid_processor_id;
3123 insert_ids(free_dof_ids, Ufree.get_values(), pid);
3124}
static constexpr 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:484
std::unordered_map< dof_id_type, typename FFunctor::ValuePushType > ids_to_save
Real time
For time-dependent problems, this is the time t at the beginning of the current timestep.
Definition system.h:1677
std::enable_if< ScalarTraits< T >::value &&ScalarTraits< T2 >::value, typenameCompareTypes< T, T2 >::supertype >::type inner_product(const T &a, const T2 &b)
template class LIBMESH_EXPORT DenseMatrix< Real >
uint8_t dof_id_type
Definition id_types.h:67
uint8_t processor_id_type
Definition id_types.h:104
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:176
void insert_ids(const std::vector< dof_id_type > &ids, const std::vector< InsertInput > &vals, processor_id_type pid)

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.

◆ 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 2844 of file generic_projector.h.

2846{
2847 libmesh_assert (&node == elem.node_ptr(node_num));
2848
2849 // Any ghosted node in our range might have an owner who needs our
2850 // data
2851 const processor_id_type owner = node.processor_id();
2852 if (owner != system.processor_id())
2853 {
2854 const MeshBase & mesh = system.get_mesh();
2855 const DofMap & dof_map = system.get_dof_map();
2856
2857 // But let's check and see if we can be certain the owner can
2858 // compute any or all of its own dof coefficients on that node.
2859 std::vector<dof_id_type> node_dof_ids, patch_dof_ids;
2860 for (const auto & var : vars)
2861 {
2862 const Variable & variable = system.variable(var);
2863
2864 if (!variable.active_on_subdomain(elem.subdomain_id()))
2865 continue;
2866
2867 dof_map.dof_indices(elem, node_num, node_dof_ids, var);
2868 }
2869 libmesh_assert(std::is_sorted(node_dof_ids.begin(),
2870 node_dof_ids.end()));
2871 const std::vector<dof_id_type> & patch =
2872 (*this->projector.nodes_to_elem)[node.id()];
2873 for (const auto & elem_id : patch)
2874 {
2875 const Elem & patch_elem = mesh.elem_ref(elem_id);
2876 if (!patch_elem.active() || owner != patch_elem.processor_id())
2877 continue;
2878 dof_map.dof_indices(&patch_elem, patch_dof_ids);
2879 std::sort(patch_dof_ids.begin(), patch_dof_ids.end());
2880
2881 // Remove any node_dof_ids that we see can be calculated on
2882 // this element
2883 std::vector<dof_id_type> diff_ids(node_dof_ids.size());
2884 auto it = std::set_difference(node_dof_ids.begin(), node_dof_ids.end(),
2885 patch_dof_ids.begin(), patch_dof_ids.end(), diff_ids.begin());
2886 diff_ids.resize(it-diff_ids.begin());
2887 node_dof_ids.swap(diff_ids);
2888 if (node_dof_ids.empty())
2889 break;
2890 }
2891
2892 // Give ids_to_push default invalid pid: not yet computed
2893 for (auto id : node_dof_ids)
2894 new_ids_to_push[id].second = DofObject::invalid_processor_id;
2895 }
2896}
processor_id_type processor_id() const
const Variable & variable(unsigned int var) const
Return a constant reference to Variable var.
Definition system.C:2704
const DofMap & get_dof_map() const
Definition system.h:2417
const MeshBase & get_mesh() const
Definition system.h:2401
MeshBase & mesh
libmesh_assert(ctx)
std::unordered_map< dof_id_type, std::pair< typename FFunctor::ValuePushType, processor_id_type > > new_ids_to_push

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::libmesh_assert(), mesh, libMesh::Elem::node_ptr(), libMesh::DofObject::processor_id(), libMesh::ParallelObject::processor_id(), libMesh::Elem::subdomain_id(), libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::system, and libMesh::System::variable().

◆ insert_id() [1/2]

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 ( dof_id_type  id,
const InsertInput &  val,
processor_id_type  pid 
)

Definition at line 262 of file generic_projector.h.

1380{
1381 libmesh_error_msg("ID insertion should only occur when the provided input matches that "
1382 "expected by the ProjectionAction");
1383}

◆ insert_id() [2/2]

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 ( dof_id_type  id,
const InsertInput &  val,
processor_id_type  pid 
)

◆ insert_ids() [1/2]

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 ( const std::vector< dof_id_type > &  ids,
const std::vector< InsertInput > &  vals,
processor_id_type  pid 
)

Definition at line 263 of file generic_projector.h.

1424{
1425 libmesh_error_msg("ID insertion should only occur when the provided input matches that "
1426 "expected by the ProjectionAction");
1427}

◆ insert_ids() [2/2]

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 ( const std::vector< dof_id_type > &  ids,
const std::vector< InsertInput > &  vals,
processor_id_type  pid 
)

◆ 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 1470 of file generic_projector.h.

1472{
1473 new_ids_to_push.insert(other.new_ids_to_push.begin(), other.new_ids_to_push.end());
1474 new_ids_to_save.insert(other.new_ids_to_save.begin(), other.new_ids_to_save.end());
1475}
std::unordered_map< dof_id_type, typename FFunctor::ValuePushType > new_ids_to_save

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().

◆ 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 2024 of file generic_projector.h.

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

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(), 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::FEType::p_refinement, 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().

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 256 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 259 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 260 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 257 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 240 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 267 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

◆ system

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

Definition at line 258 of file generic_projector.h.


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