21 #include "libmesh/dof_map.h"
22 #include "libmesh/fe.h"
23 #include "libmesh/fe_interface.h"
24 #include "libmesh/elem.h"
25 #include "libmesh/remote_elem.h"
26 #include "libmesh/threads.h"
27 #include "libmesh/enum_to_string.h"
34 void lagrange_nodal_soln(
const Elem * elem,
36 const std::vector<Number> & elem_soln,
37 std::vector<Number> & nodal_soln)
39 const unsigned int n_nodes = elem->n_nodes();
42 const Order totalorder = static_cast<Order>(order+elem->p_level());
57 libmesh_assert_equal_to (elem_soln.size(), 2);
58 libmesh_assert_equal_to (nodal_soln.size(), 3);
60 nodal_soln[0] = elem_soln[0];
61 nodal_soln[1] = elem_soln[1];
62 nodal_soln[2] = .5*(elem_soln[0] + elem_soln[1]);
69 libmesh_assert_equal_to (elem_soln.size(), 2);
70 libmesh_assert_equal_to (nodal_soln.size(), 4);
72 nodal_soln[0] = elem_soln[0];
73 nodal_soln[1] = elem_soln[1];
74 nodal_soln[2] = (2.*elem_soln[0] + elem_soln[1])/3.;
75 nodal_soln[3] = (elem_soln[0] + 2.*elem_soln[1])/3.;
83 libmesh_assert_equal_to (elem_soln.size(), 3);
84 libmesh_assert_equal_to (nodal_soln.size(), 6);
86 nodal_soln[0] = elem_soln[0];
87 nodal_soln[1] = elem_soln[1];
88 nodal_soln[2] = elem_soln[2];
89 nodal_soln[3] = .5*(elem_soln[0] + elem_soln[1]);
90 nodal_soln[4] = .5*(elem_soln[1] + elem_soln[2]);
91 nodal_soln[5] = .5*(elem_soln[2] + elem_soln[0]);
100 libmesh_assert_equal_to (elem_soln.size(), 4);
103 libmesh_assert_equal_to (nodal_soln.size(), 8);
105 libmesh_assert_equal_to (nodal_soln.size(), 9);
108 nodal_soln[0] = elem_soln[0];
109 nodal_soln[1] = elem_soln[1];
110 nodal_soln[2] = elem_soln[2];
111 nodal_soln[3] = elem_soln[3];
112 nodal_soln[4] = .5*(elem_soln[0] + elem_soln[1]);
113 nodal_soln[5] = .5*(elem_soln[1] + elem_soln[2]);
114 nodal_soln[6] = .5*(elem_soln[2] + elem_soln[3]);
115 nodal_soln[7] = .5*(elem_soln[3] + elem_soln[0]);
118 nodal_soln[8] = .25*(elem_soln[0] + elem_soln[1] + elem_soln[2] + elem_soln[3]);
126 libmesh_assert_equal_to (elem_soln.size(), 4);
127 libmesh_assert_equal_to (nodal_soln.size(), 10);
129 nodal_soln[0] = elem_soln[0];
130 nodal_soln[1] = elem_soln[1];
131 nodal_soln[2] = elem_soln[2];
132 nodal_soln[3] = elem_soln[3];
133 nodal_soln[4] = .5*(elem_soln[0] + elem_soln[1]);
134 nodal_soln[5] = .5*(elem_soln[1] + elem_soln[2]);
135 nodal_soln[6] = .5*(elem_soln[2] + elem_soln[0]);
136 nodal_soln[7] = .5*(elem_soln[3] + elem_soln[0]);
137 nodal_soln[8] = .5*(elem_soln[3] + elem_soln[1]);
138 nodal_soln[9] = .5*(elem_soln[3] + elem_soln[2]);
147 libmesh_assert_equal_to (elem_soln.size(), 8);
150 libmesh_assert_equal_to (nodal_soln.size(), 20);
152 libmesh_assert_equal_to (nodal_soln.size(), 27);
154 nodal_soln[0] = elem_soln[0];
155 nodal_soln[1] = elem_soln[1];
156 nodal_soln[2] = elem_soln[2];
157 nodal_soln[3] = elem_soln[3];
158 nodal_soln[4] = elem_soln[4];
159 nodal_soln[5] = elem_soln[5];
160 nodal_soln[6] = elem_soln[6];
161 nodal_soln[7] = elem_soln[7];
162 nodal_soln[8] = .5*(elem_soln[0] + elem_soln[1]);
163 nodal_soln[9] = .5*(elem_soln[1] + elem_soln[2]);
164 nodal_soln[10] = .5*(elem_soln[2] + elem_soln[3]);
165 nodal_soln[11] = .5*(elem_soln[3] + elem_soln[0]);
166 nodal_soln[12] = .5*(elem_soln[0] + elem_soln[4]);
167 nodal_soln[13] = .5*(elem_soln[1] + elem_soln[5]);
168 nodal_soln[14] = .5*(elem_soln[2] + elem_soln[6]);
169 nodal_soln[15] = .5*(elem_soln[3] + elem_soln[7]);
170 nodal_soln[16] = .5*(elem_soln[4] + elem_soln[5]);
171 nodal_soln[17] = .5*(elem_soln[5] + elem_soln[6]);
172 nodal_soln[18] = .5*(elem_soln[6] + elem_soln[7]);
173 nodal_soln[19] = .5*(elem_soln[4] + elem_soln[7]);
177 nodal_soln[20] = .25*(elem_soln[0] + elem_soln[1] + elem_soln[2] + elem_soln[3]);
178 nodal_soln[21] = .25*(elem_soln[0] + elem_soln[1] + elem_soln[4] + elem_soln[5]);
179 nodal_soln[22] = .25*(elem_soln[1] + elem_soln[2] + elem_soln[5] + elem_soln[6]);
180 nodal_soln[23] = .25*(elem_soln[2] + elem_soln[3] + elem_soln[6] + elem_soln[7]);
181 nodal_soln[24] = .25*(elem_soln[3] + elem_soln[0] + elem_soln[7] + elem_soln[4]);
182 nodal_soln[25] = .25*(elem_soln[4] + elem_soln[5] + elem_soln[6] + elem_soln[7]);
184 nodal_soln[26] = .125*(elem_soln[0] + elem_soln[1] + elem_soln[2] + elem_soln[3] +
185 elem_soln[4] + elem_soln[5] + elem_soln[6] + elem_soln[7]);
195 libmesh_assert_equal_to (elem_soln.size(), 6);
198 libmesh_assert_equal_to (nodal_soln.size(), 15);
200 libmesh_assert_equal_to (nodal_soln.size(), 18);
202 nodal_soln[0] = elem_soln[0];
203 nodal_soln[1] = elem_soln[1];
204 nodal_soln[2] = elem_soln[2];
205 nodal_soln[3] = elem_soln[3];
206 nodal_soln[4] = elem_soln[4];
207 nodal_soln[5] = elem_soln[5];
208 nodal_soln[6] = .5*(elem_soln[0] + elem_soln[1]);
209 nodal_soln[7] = .5*(elem_soln[1] + elem_soln[2]);
210 nodal_soln[8] = .5*(elem_soln[0] + elem_soln[2]);
211 nodal_soln[9] = .5*(elem_soln[0] + elem_soln[3]);
212 nodal_soln[10] = .5*(elem_soln[1] + elem_soln[4]);
213 nodal_soln[11] = .5*(elem_soln[2] + elem_soln[5]);
214 nodal_soln[12] = .5*(elem_soln[3] + elem_soln[4]);
215 nodal_soln[13] = .5*(elem_soln[4] + elem_soln[5]);
216 nodal_soln[14] = .5*(elem_soln[3] + elem_soln[5]);
220 nodal_soln[15] = .25*(elem_soln[0] + elem_soln[1] + elem_soln[4] + elem_soln[3]);
221 nodal_soln[16] = .25*(elem_soln[1] + elem_soln[2] + elem_soln[5] + elem_soln[4]);
222 nodal_soln[17] = .25*(elem_soln[2] + elem_soln[0] + elem_soln[3] + elem_soln[5]);
230 libmesh_assert_equal_to (elem_soln.size(), 5);
231 libmesh_assert_equal_to (nodal_soln.size(), 13);
233 nodal_soln[0] = elem_soln[0];
234 nodal_soln[1] = elem_soln[1];
235 nodal_soln[2] = elem_soln[2];
236 nodal_soln[3] = elem_soln[3];
237 nodal_soln[4] = elem_soln[4];
238 nodal_soln[5] = .5*(elem_soln[0] + elem_soln[1]);
239 nodal_soln[6] = .5*(elem_soln[1] + elem_soln[2]);
240 nodal_soln[7] = .5*(elem_soln[2] + elem_soln[3]);
241 nodal_soln[8] = .5*(elem_soln[3] + elem_soln[0]);
242 nodal_soln[9] = .5*(elem_soln[0] + elem_soln[4]);
243 nodal_soln[10] = .5*(elem_soln[1] + elem_soln[4]);
244 nodal_soln[11] = .5*(elem_soln[2] + elem_soln[4]);
245 nodal_soln[12] = .5*(elem_soln[3] + elem_soln[4]);
252 libmesh_assert_equal_to (elem_soln.size(), 5);
253 libmesh_assert_equal_to (nodal_soln.size(), 14);
255 nodal_soln[0] = elem_soln[0];
256 nodal_soln[1] = elem_soln[1];
257 nodal_soln[2] = elem_soln[2];
258 nodal_soln[3] = elem_soln[3];
259 nodal_soln[4] = elem_soln[4];
260 nodal_soln[5] = .5*(elem_soln[0] + elem_soln[1]);
261 nodal_soln[6] = .5*(elem_soln[1] + elem_soln[2]);
262 nodal_soln[7] = .5*(elem_soln[2] + elem_soln[3]);
263 nodal_soln[8] = .5*(elem_soln[3] + elem_soln[0]);
264 nodal_soln[9] = .5*(elem_soln[0] + elem_soln[4]);
265 nodal_soln[10] = .5*(elem_soln[1] + elem_soln[4]);
266 nodal_soln[11] = .5*(elem_soln[2] + elem_soln[4]);
267 nodal_soln[12] = .5*(elem_soln[3] + elem_soln[4]);
268 nodal_soln[13] = .25*(elem_soln[0] + elem_soln[1] + elem_soln[2] + elem_soln[3]);
277 nodal_soln = elem_soln;
290 libmesh_assert_equal_to (elem_soln.size(), 3);
291 libmesh_assert_equal_to (nodal_soln.size(), 4);
294 nodal_soln[0] = elem_soln[0];
295 nodal_soln[1] = elem_soln[1];
296 nodal_soln[2] = (2.*elem_soln[0] - elem_soln[1] +
298 nodal_soln[3] = (-elem_soln[0] + 2.*elem_soln[1] +
307 nodal_soln = elem_soln;
321 nodal_soln = elem_soln;
330 unsigned int lagrange_n_dofs(
const ElemType t,
const Order o)
458 libmesh_error_msg(
"ERROR: Invalid Order " <<
Utility::enum_to_string(o) <<
" selected for LAGRANGE FE family!");
465 unsigned int lagrange_n_dofs_at_node(
const ElemType t,
467 const unsigned int n)
660 libmesh_error_msg(
"Unsupported order: " << o );
666 #ifdef LIBMESH_ENABLE_AMR
667 void lagrange_compute_constraints (DofConstraints & constraints,
669 const unsigned int variable_number,
680 if (elem->subactive())
683 FEType fe_type = dof_map.variable_type(variable_number);
684 fe_type.order = static_cast<Order>(fe_type.order + elem->p_level());
687 std::vector<dof_id_type> my_dof_indices, parent_dof_indices;
688 std::unique_ptr<const Elem> my_side, parent_side;
692 for (
auto s : elem->side_index_range())
693 if (elem->neighbor_ptr(s) !=
nullptr &&
695 if (elem->neighbor_ptr(s)->level() < elem->level())
699 const Elem * parent = elem->parent();
706 elem->build_side_ptr(my_side, s);
707 parent->build_side_ptr(parent_side, s);
713 my_dof_indices.reserve (my_side->n_nodes());
714 parent_dof_indices.reserve (parent_side->n_nodes());
716 dof_map.dof_indices (my_side.get(), my_dof_indices,
718 dof_map.dof_indices (parent_side.get(), parent_dof_indices,
721 const unsigned int n_side_dofs =
723 const unsigned int n_parent_side_dofs =
725 for (
unsigned int my_dof=0; my_dof != n_side_dofs; my_dof++)
727 libmesh_assert_less (my_dof, my_side->n_nodes());
730 const dof_id_type my_dof_g = my_dof_indices[my_dof];
734 bool self_constraint =
false;
735 for (
unsigned int their_dof=0;
736 their_dof != n_parent_side_dofs; their_dof++)
738 libmesh_assert_less (their_dof, parent_side->n_nodes());
742 parent_dof_indices[their_dof];
744 if (their_dof_g == my_dof_g)
746 self_constraint =
true;
762 if (dof_map.is_constrained_dof(my_dof_g))
765 constraint_row = &(constraints[my_dof_g]);
770 const Point & support_point = my_side->point(my_dof);
778 for (
unsigned int their_dof=0;
779 their_dof != n_parent_side_dofs; their_dof++)
781 libmesh_assert_less (their_dof, parent_side->n_nodes());
785 parent_dof_indices[their_dof];
795 if ((
std::abs(their_dof_value) > 1.e-5) &&
798 constraint_row->insert(std::make_pair (their_dof_g,
804 else if (their_dof_value >= .999)
805 libmesh_assert_equal_to (my_dof_g, their_dof_g);
811 #endif // #ifdef LIBMESH_ENABLE_AMR
822 const std::vector<Number> & elem_soln,
823 std::vector<Number> & nodal_soln)
824 { lagrange_nodal_soln(elem, order, elem_soln, nodal_soln); }
829 const std::vector<Number> & elem_soln,
830 std::vector<Number> & nodal_soln)
831 { lagrange_nodal_soln(elem, order, elem_soln, nodal_soln); }
836 const std::vector<Number> & elem_soln,
837 std::vector<Number> & nodal_soln)
838 { lagrange_nodal_soln(elem, order, elem_soln, nodal_soln); }
843 const std::vector<Number> & elem_soln,
844 std::vector<Number> & nodal_soln)
845 { lagrange_nodal_soln(elem, order, elem_soln, nodal_soln); }
894 #ifdef LIBMESH_ENABLE_AMR
898 const unsigned int variable_number,
900 { lagrange_compute_constraints(constraints, dof_map, variable_number, elem, 2); }
905 const unsigned int variable_number,
907 { lagrange_compute_constraints(constraints, dof_map, variable_number, elem, 3); }
908 #endif // LIBMESH_ENABLE_AMR