38 void lagrange_nodal_soln(
const Elem * elem,
40 const std::vector<Number> & elem_soln,
41 std::vector<Number> & nodal_soln)
43 const unsigned int n_nodes = elem->n_nodes();
46 const Order totalorder =
static_cast<Order>(order+elem->p_level());
61 libmesh_assert_equal_to (elem_soln.size(), 2);
62 libmesh_assert_equal_to (nodal_soln.size(), 3);
64 nodal_soln[0] = elem_soln[0];
65 nodal_soln[1] = elem_soln[1];
66 nodal_soln[2] = .5*(elem_soln[0] + elem_soln[1]);
73 libmesh_assert_equal_to (elem_soln.size(), 2);
74 libmesh_assert_equal_to (nodal_soln.size(), 4);
76 nodal_soln[0] = elem_soln[0];
77 nodal_soln[1] = elem_soln[1];
78 nodal_soln[2] = (2.*elem_soln[0] + elem_soln[1])/3.;
79 nodal_soln[3] = (elem_soln[0] + 2.*elem_soln[1])/3.;
87 libmesh_assert_equal_to (elem_soln.size(), 3);
88 libmesh_assert_equal_to (nodal_soln.size(), 6);
90 nodal_soln[0] = elem_soln[0];
91 nodal_soln[1] = elem_soln[1];
92 nodal_soln[2] = elem_soln[2];
93 nodal_soln[3] = .5*(elem_soln[0] + elem_soln[1]);
94 nodal_soln[4] = .5*(elem_soln[1] + elem_soln[2]);
95 nodal_soln[5] = .5*(elem_soln[2] + elem_soln[0]);
104 libmesh_assert_equal_to (elem_soln.size(), 4);
107 libmesh_assert_equal_to (nodal_soln.size(), 8);
109 libmesh_assert_equal_to (nodal_soln.size(), 9);
112 nodal_soln[0] = elem_soln[0];
113 nodal_soln[1] = elem_soln[1];
114 nodal_soln[2] = elem_soln[2];
115 nodal_soln[3] = elem_soln[3];
116 nodal_soln[4] = .5*(elem_soln[0] + elem_soln[1]);
117 nodal_soln[5] = .5*(elem_soln[1] + elem_soln[2]);
118 nodal_soln[6] = .5*(elem_soln[2] + elem_soln[3]);
119 nodal_soln[7] = .5*(elem_soln[3] + elem_soln[0]);
122 nodal_soln[8] = .25*(elem_soln[0] + elem_soln[1] + elem_soln[2] + elem_soln[3]);
130 libmesh_assert_equal_to (elem_soln.size(), 4);
131 libmesh_assert_equal_to (nodal_soln.size(), 10);
133 nodal_soln[0] = elem_soln[0];
134 nodal_soln[1] = elem_soln[1];
135 nodal_soln[2] = elem_soln[2];
136 nodal_soln[3] = elem_soln[3];
137 nodal_soln[4] = .5*(elem_soln[0] + elem_soln[1]);
138 nodal_soln[5] = .5*(elem_soln[1] + elem_soln[2]);
139 nodal_soln[6] = .5*(elem_soln[2] + elem_soln[0]);
140 nodal_soln[7] = .5*(elem_soln[3] + elem_soln[0]);
141 nodal_soln[8] = .5*(elem_soln[3] + elem_soln[1]);
142 nodal_soln[9] = .5*(elem_soln[3] + elem_soln[2]);
151 libmesh_assert_equal_to (elem_soln.size(), 8);
154 libmesh_assert_equal_to (nodal_soln.size(), 20);
156 libmesh_assert_equal_to (nodal_soln.size(), 27);
158 nodal_soln[0] = elem_soln[0];
159 nodal_soln[1] = elem_soln[1];
160 nodal_soln[2] = elem_soln[2];
161 nodal_soln[3] = elem_soln[3];
162 nodal_soln[4] = elem_soln[4];
163 nodal_soln[5] = elem_soln[5];
164 nodal_soln[6] = elem_soln[6];
165 nodal_soln[7] = elem_soln[7];
166 nodal_soln[8] = .5*(elem_soln[0] + elem_soln[1]);
167 nodal_soln[9] = .5*(elem_soln[1] + elem_soln[2]);
168 nodal_soln[10] = .5*(elem_soln[2] + elem_soln[3]);
169 nodal_soln[11] = .5*(elem_soln[3] + elem_soln[0]);
170 nodal_soln[12] = .5*(elem_soln[0] + elem_soln[4]);
171 nodal_soln[13] = .5*(elem_soln[1] + elem_soln[5]);
172 nodal_soln[14] = .5*(elem_soln[2] + elem_soln[6]);
173 nodal_soln[15] = .5*(elem_soln[3] + elem_soln[7]);
174 nodal_soln[16] = .5*(elem_soln[4] + elem_soln[5]);
175 nodal_soln[17] = .5*(elem_soln[5] + elem_soln[6]);
176 nodal_soln[18] = .5*(elem_soln[6] + elem_soln[7]);
177 nodal_soln[19] = .5*(elem_soln[4] + elem_soln[7]);
181 nodal_soln[20] = .25*(elem_soln[0] + elem_soln[1] + elem_soln[2] + elem_soln[3]);
182 nodal_soln[21] = .25*(elem_soln[0] + elem_soln[1] + elem_soln[4] + elem_soln[5]);
183 nodal_soln[22] = .25*(elem_soln[1] + elem_soln[2] + elem_soln[5] + elem_soln[6]);
184 nodal_soln[23] = .25*(elem_soln[2] + elem_soln[3] + elem_soln[6] + elem_soln[7]);
185 nodal_soln[24] = .25*(elem_soln[3] + elem_soln[0] + elem_soln[7] + elem_soln[4]);
186 nodal_soln[25] = .25*(elem_soln[4] + elem_soln[5] + elem_soln[6] + elem_soln[7]);
188 nodal_soln[26] = .125*(elem_soln[0] + elem_soln[1] + elem_soln[2] + elem_soln[3] +
189 elem_soln[4] + elem_soln[5] + elem_soln[6] + elem_soln[7]);
199 libmesh_assert_equal_to (elem_soln.size(), 6);
202 libmesh_assert_equal_to (nodal_soln.size(), 15);
204 libmesh_assert_equal_to (nodal_soln.size(), 18);
206 nodal_soln[0] = elem_soln[0];
207 nodal_soln[1] = elem_soln[1];
208 nodal_soln[2] = elem_soln[2];
209 nodal_soln[3] = elem_soln[3];
210 nodal_soln[4] = elem_soln[4];
211 nodal_soln[5] = elem_soln[5];
212 nodal_soln[6] = .5*(elem_soln[0] + elem_soln[1]);
213 nodal_soln[7] = .5*(elem_soln[1] + elem_soln[2]);
214 nodal_soln[8] = .5*(elem_soln[0] + elem_soln[2]);
215 nodal_soln[9] = .5*(elem_soln[0] + elem_soln[3]);
216 nodal_soln[10] = .5*(elem_soln[1] + elem_soln[4]);
217 nodal_soln[11] = .5*(elem_soln[2] + elem_soln[5]);
218 nodal_soln[12] = .5*(elem_soln[3] + elem_soln[4]);
219 nodal_soln[13] = .5*(elem_soln[4] + elem_soln[5]);
220 nodal_soln[14] = .5*(elem_soln[3] + elem_soln[5]);
224 nodal_soln[15] = .25*(elem_soln[0] + elem_soln[1] + elem_soln[4] + elem_soln[3]);
225 nodal_soln[16] = .25*(elem_soln[1] + elem_soln[2] + elem_soln[5] + elem_soln[4]);
226 nodal_soln[17] = .25*(elem_soln[2] + elem_soln[0] + elem_soln[3] + elem_soln[5]);
234 libmesh_assert_equal_to (elem_soln.size(), 5);
235 libmesh_assert_equal_to (nodal_soln.size(), 13);
237 nodal_soln[0] = elem_soln[0];
238 nodal_soln[1] = elem_soln[1];
239 nodal_soln[2] = elem_soln[2];
240 nodal_soln[3] = elem_soln[3];
241 nodal_soln[4] = elem_soln[4];
242 nodal_soln[5] = .5*(elem_soln[0] + elem_soln[1]);
243 nodal_soln[6] = .5*(elem_soln[1] + elem_soln[2]);
244 nodal_soln[7] = .5*(elem_soln[2] + elem_soln[3]);
245 nodal_soln[8] = .5*(elem_soln[3] + elem_soln[0]);
246 nodal_soln[9] = .5*(elem_soln[0] + elem_soln[4]);
247 nodal_soln[10] = .5*(elem_soln[1] + elem_soln[4]);
248 nodal_soln[11] = .5*(elem_soln[2] + elem_soln[4]);
249 nodal_soln[12] = .5*(elem_soln[3] + elem_soln[4]);
256 libmesh_assert_equal_to (elem_soln.size(), 5);
257 libmesh_assert_equal_to (nodal_soln.size(), 14);
259 nodal_soln[0] = elem_soln[0];
260 nodal_soln[1] = elem_soln[1];
261 nodal_soln[2] = elem_soln[2];
262 nodal_soln[3] = elem_soln[3];
263 nodal_soln[4] = elem_soln[4];
264 nodal_soln[5] = .5*(elem_soln[0] + elem_soln[1]);
265 nodal_soln[6] = .5*(elem_soln[1] + elem_soln[2]);
266 nodal_soln[7] = .5*(elem_soln[2] + elem_soln[3]);
267 nodal_soln[8] = .5*(elem_soln[3] + elem_soln[0]);
268 nodal_soln[9] = .5*(elem_soln[0] + elem_soln[4]);
269 nodal_soln[10] = .5*(elem_soln[1] + elem_soln[4]);
270 nodal_soln[11] = .5*(elem_soln[2] + elem_soln[4]);
271 nodal_soln[12] = .5*(elem_soln[3] + elem_soln[4]);
272 nodal_soln[13] = .25*(elem_soln[0] + elem_soln[1] + elem_soln[2] + elem_soln[3]);
281 nodal_soln = elem_soln;
294 libmesh_assert_equal_to (elem_soln.size(), 3);
295 libmesh_assert_equal_to (nodal_soln.size(), 4);
298 nodal_soln[0] = elem_soln[0];
299 nodal_soln[1] = elem_soln[1];
300 nodal_soln[2] = (2.*elem_soln[0] - elem_soln[1] +
302 nodal_soln[3] = (-elem_soln[0] + 2.*elem_soln[1] +
311 nodal_soln = elem_soln;
325 nodal_soln = elem_soln;
334 unsigned int lagrange_n_dofs(
const ElemType t,
const Order o)
462 libmesh_error_msg(
"ERROR: Invalid Order " <<
Utility::enum_to_string(o) <<
" selected for LAGRANGE FE family!");
469 unsigned int lagrange_n_dofs_at_node(
const ElemType t,
471 const unsigned int n)
664 libmesh_error_msg(
"Unsupported order: " << o );
670 #ifdef LIBMESH_ENABLE_AMR 671 void lagrange_compute_constraints (DofConstraints & constraints,
673 const unsigned int variable_number,
681 libmesh_assert(elem);
684 if (elem->subactive())
687 FEType fe_type = dof_map.variable_type(variable_number);
688 fe_type.order =
static_cast<Order>(fe_type.order + elem->p_level());
691 std::vector<dof_id_type> my_dof_indices, parent_dof_indices;
692 std::unique_ptr<const Elem> my_side, parent_side;
696 for (
auto s : elem->side_index_range())
697 if (elem->neighbor_ptr(s) !=
nullptr &&
699 if (elem->neighbor_ptr(s)->level() < elem->level())
703 const Elem * parent = elem->parent();
708 libmesh_assert(parent);
710 elem->build_side_ptr(my_side, s);
711 parent->build_side_ptr(parent_side, s);
717 my_dof_indices.reserve (my_side->n_nodes());
718 parent_dof_indices.reserve (parent_side->n_nodes());
720 dof_map.dof_indices (my_side.get(), my_dof_indices,
722 dof_map.dof_indices (parent_side.get(), parent_dof_indices,
725 const unsigned int n_side_dofs =
727 const unsigned int n_parent_side_dofs =
729 for (
unsigned int my_dof=0; my_dof != n_side_dofs; my_dof++)
731 libmesh_assert_less (my_dof, my_side->n_nodes());
734 const dof_id_type my_dof_g = my_dof_indices[my_dof];
738 bool self_constraint =
false;
739 for (
unsigned int their_dof=0;
740 their_dof != n_parent_side_dofs; their_dof++)
742 libmesh_assert_less (their_dof, parent_side->n_nodes());
746 parent_dof_indices[their_dof];
748 if (their_dof_g == my_dof_g)
750 self_constraint =
true;
766 if (dof_map.is_constrained_dof(my_dof_g))
769 constraint_row = &(constraints[my_dof_g]);
770 libmesh_assert(constraint_row->empty());
774 const Point & support_point = my_side->point(my_dof);
782 for (
unsigned int their_dof=0;
783 their_dof != n_parent_side_dofs; their_dof++)
785 libmesh_assert_less (their_dof, parent_side->n_nodes());
789 parent_dof_indices[their_dof];
799 if ((
std::abs(their_dof_value) > 1.e-5) &&
802 constraint_row->insert(std::make_pair (their_dof_g,
808 else if (their_dof_value >= .999)
809 libmesh_assert_equal_to (my_dof_g, their_dof_g);
815 #endif // #ifdef LIBMESH_ENABLE_AMR 826 const std::vector<Number> & elem_soln,
827 std::vector<Number> & nodal_soln)
828 { lagrange_nodal_soln(elem, order, elem_soln, nodal_soln); }
833 const std::vector<Number> & elem_soln,
834 std::vector<Number> & nodal_soln)
835 { lagrange_nodal_soln(elem, order, elem_soln, nodal_soln); }
840 const std::vector<Number> & elem_soln,
841 std::vector<Number> & nodal_soln)
842 { lagrange_nodal_soln(elem, order, elem_soln, nodal_soln); }
847 const std::vector<Number> & elem_soln,
848 std::vector<Number> & nodal_soln)
849 { lagrange_nodal_soln(elem, order, elem_soln, nodal_soln); }
898 #ifdef LIBMESH_ENABLE_AMR 902 const unsigned int variable_number,
904 { lagrange_compute_constraints(constraints, dof_map, variable_number, elem, 2); }
909 const unsigned int variable_number,
911 { lagrange_compute_constraints(constraints, dof_map, variable_number, elem, 3); }
912 #endif // LIBMESH_ENABLE_AMR static unsigned int n_dofs(const ElemType t, const Order o)
static unsigned int n_dofs(const unsigned int dim, const FEType &fe_t, const ElemType t)
The base class for all geometric element types.
static unsigned int n_dofs_at_node(const ElemType t, const Order o, const unsigned int n)
virtual bool shapes_need_reinit() const override
virtual bool is_hierarchic() const override
Manages the degrees of freedom (DOFs) in a simulation.
const dof_id_type n_nodes
static Real shape(const unsigned int dim, const FEType &fe_t, const ElemType t, const unsigned int i, const Point &p)
static Point inverse_map(const unsigned int dim, const FEType &fe_t, const Elem *elem, const Point &p, const Real tolerance=TOLERANCE, const bool secure=true)
static unsigned int n_dofs_per_elem(const ElemType t, const Order o)
virtual FEContinuity get_continuity() const override
std::string enum_to_string(const T e)
static void compute_constraints(DofConstraints &constraints, DofMap &dof_map, const unsigned int variable_number, const Elem *elem)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
static void nodal_soln(const Elem *elem, const Order o, const std::vector< Number > &elem_soln, std::vector< Number > &nodal_soln)
std::map< dof_id_type, Real, std::less< dof_id_type >, Threads::scalable_allocator< std::pair< const dof_id_type, Real > > > DofConstraintRow
const RemoteElem * remote_elem