libMesh
systems_test.C
Go to the documentation of this file.
1 #include <libmesh/equation_systems.h>
2 #include <libmesh/int_range.h>
3 #include <libmesh/mesh.h>
4 #include <libmesh/node.h>
5 #include <libmesh/dof_map.h>
6 #include <libmesh/mesh_generation.h>
7 #include <libmesh/replicated_mesh.h>
8 #include <libmesh/mesh_function.h>
9 #include <libmesh/numeric_vector.h>
10 #include <libmesh/mesh_refinement.h>
11 #include <libmesh/sparse_matrix.h>
12 #include "libmesh/string_to_enum.h"
13 #include <libmesh/cell_tet4.h>
14 #include <libmesh/zero_function.h>
15 #include <libmesh/linear_implicit_system.h>
16 #include <libmesh/transient_system.h>
17 #include <libmesh/quadrature_gauss.h>
18 #include <libmesh/node_elem.h>
19 #include <libmesh/edge_edge2.h>
20 #include <libmesh/dg_fem_context.h>
21 #include <libmesh/enum_solver_type.h>
22 #include <libmesh/enum_preconditioner_type.h>
23 #include <libmesh/linear_solver.h>
24 #include <libmesh/parallel.h>
25 #include <libmesh/face_quad4.h>
26 #include <libmesh/face_quad9.h>
27 #include <libmesh/face_quad8.h>
28 #include <libmesh/face_tri3.h>
29 #include <libmesh/face_tri6.h>
30 #include <libmesh/face_tri7.h>
31 #include <libmesh/cell_hex8.h>
32 #include <libmesh/cell_hex20.h>
33 #include <libmesh/cell_hex27.h>
34 #include <libmesh/cell_tet10.h>
35 #include <libmesh/cell_tet14.h>
36 #include <libmesh/boundary_info.h>
37 
38 #include "test_comm.h"
39 #include "libmesh_cppunit.h"
40 
41 #include <string>
42 
43 using namespace libMesh;
44 
45 // Sparsity pattern augmentation class used in testDofCouplingWithVarGroups
47 {
48 private:
49 
54 
55 public:
56 
61  :
62  _mesh(mesh)
63  {}
64 
65  virtual std::unique_ptr<GhostingFunctor> clone () const override
66  {
67  return std::make_unique<AugmentSparsityOnNodes>(_mesh);
68  }
69 
73  virtual void operator() (const MeshBase::const_element_iterator & range_begin,
74  const MeshBase::const_element_iterator & range_end,
76  map_type & coupled_elements) override
77  {
78  dof_id_type node_elem_id_1 = 2;
79  dof_id_type node_elem_id_2 = 3;
80 
81  const CouplingMatrix * const null_mat = nullptr;
82 
83  for (const auto & elem : as_range(range_begin, range_end))
84  {
85  if (elem->id() == node_elem_id_1)
86  {
87  if (elem->processor_id() != p)
88  {
89  coupled_elements.emplace(elem, null_mat);
90 
91  const Elem * neighbor = _mesh.elem_ptr(node_elem_id_2);
92  if (neighbor->processor_id() != p)
93  coupled_elements.emplace(neighbor, null_mat);
94  }
95  }
96  if (elem->id() == node_elem_id_2)
97  {
98  if (elem->processor_id() != p)
99  {
100  coupled_elements.emplace(elem, null_mat);
101 
102  const Elem * neighbor = _mesh.elem_ptr(node_elem_id_1);
103  if (neighbor->processor_id() != p)
104  coupled_elements.emplace(neighbor, null_mat);
105  }
106  }
107  }
108  }
109 
114  virtual void mesh_reinit () override
115  {
116  }
117 
122  virtual void redistribute () override
123  { this->mesh_reinit(); }
124 
125 };
126 
127 // Assembly function used in testDofCouplingWithVarGroups
129  const std::string&)
130 {
131  const MeshBase& mesh = es.get_mesh();
133  const DofMap& dof_map = system.get_dof_map();
134 
137 
138  std::vector<dof_id_type> dof_indices;
139 
140  SparseMatrix<Number> & matrix = system.get_system_matrix();
141 
142  MeshBase::const_element_iterator el = mesh.active_local_elements_begin();
143  const MeshBase::const_element_iterator end_el = mesh.active_local_elements_end();
144 
145  for ( ; el != end_el; ++el)
146  {
147  const Elem* elem = *el;
148 
149  if(elem->type() == NODEELEM)
150  {
151  continue;
152  }
153 
154  dof_map.dof_indices (elem, dof_indices);
155  const unsigned int n_dofs = dof_indices.size();
156 
157  Ke.resize (n_dofs, n_dofs);
158  Fe.resize (n_dofs);
159 
160  for(unsigned int i=0; i<n_dofs; i++)
161  {
162  Ke(i,i) = 1.;
163  Fe(i) = 1.;
164  }
165 
166  matrix.add_matrix (Ke, dof_indices);
167  system.rhs->add_vector (Fe, dof_indices);
168  }
169 
170  // Add matrix for extra coupled dofs
171  {
172  const Node & node_1 = mesh.node_ref(1);
173  const Node & node_2 = mesh.node_ref(2);
174  dof_indices.resize(6);
175  dof_indices[0] =
176  node_1.dof_number(system.number(), system.variable_number("u"), 0);
177  dof_indices[1] =
178  node_1.dof_number(system.number(), system.variable_number("v"), 0);
179  dof_indices[2] =
180  node_1.dof_number(system.number(), system.variable_number("w"), 0);
181 
182  dof_indices[3] =
183  node_2.dof_number(system.number(), system.variable_number("u"), 0);
184  dof_indices[4] =
185  node_2.dof_number(system.number(), system.variable_number("v"), 0);
186  dof_indices[5] =
187  node_2.dof_number(system.number(), system.variable_number("w"), 0);
188 
189  const unsigned int n_dofs = dof_indices.size();
190  Ke.resize (n_dofs, n_dofs);
191  Fe.resize (n_dofs);
192 
193  for(unsigned int i=0; i<n_dofs; i++)
194  {
195  Ke(i,i) = 1.;
196  Fe(i) = 1.;
197  }
198 
199  matrix.add_matrix (Ke, dof_indices);
200  system.rhs->add_vector (Fe, dof_indices);
201  }
202 
203  system.rhs->close();
204  matrix.close();
205 }
206 
207 // Assembly function that uses a DGFEMContext
209  const std::string& /*system_name*/)
210 {
211  const MeshBase& mesh = es.get_mesh();
213 
216 
217  std::vector<dof_id_type> dof_indices;
218  SparseMatrix<Number> & matrix = system.get_system_matrix();
219 
220  DGFEMContext context(system);
221  {
222  // For efficiency, we should prerequest all
223  // the data we will need to build the
224  // linear system before doing an element loop.
225  FEBase* elem_fe = NULL;
226  context.get_element_fe(0, elem_fe);
227  elem_fe->get_JxW();
228  elem_fe->get_phi();
229  elem_fe->get_dphi();
230 
231  FEBase* side_fe = NULL;
232  context.get_side_fe( 0, side_fe );
233  side_fe->get_JxW();
234  side_fe->get_phi();
235 
236  FEBase* neighbor_side_fe = NULL;
237  context.get_neighbor_side_fe(0, neighbor_side_fe);
238  neighbor_side_fe->get_phi();
239  }
240 
241  for (const auto & elem : mesh.active_local_element_ptr_range())
242  {
243  context.pre_fe_reinit(system, elem);
244  context.elem_fe_reinit();
245 
246  // Element interior assembly
247  {
248  FEBase* elem_fe = NULL;
249  context.get_element_fe(0, elem_fe);
250 
251  const std::vector<Real> &JxW = elem_fe->get_JxW();
252  const std::vector<std::vector<Real> >& phi = elem_fe->get_phi();
253  const std::vector<std::vector<RealGradient> >& dphi = elem_fe->get_dphi();
254 
255  unsigned int n_dofs = context.get_dof_indices(0).size();
256  unsigned int n_qpoints = context.get_element_qrule().n_points();
257 
258  for (unsigned int qp=0; qp != n_qpoints; qp++)
259  for (unsigned int i=0; i != n_dofs; i++)
260  for (unsigned int j=0; j != n_dofs; j++)
261  context.get_elem_jacobian()(i,j) += JxW[qp] * dphi[i][qp]*dphi[j][qp];
262 
263  for (unsigned int qp=0; qp != n_qpoints; qp++)
264  for (unsigned int i=0; i != n_dofs; i++)
265  context.get_elem_residual()(i) += JxW[qp] * phi[i][qp];
266  }
267 
268  matrix.add_matrix (context.get_elem_jacobian(), context.get_dof_indices());
269  system.rhs->add_vector (context.get_elem_residual(), context.get_dof_indices());
270 
271  // Element side assembly
272  for (context.side = 0; context.side != elem->n_sides(); ++context.side)
273  {
274  // If there is a neighbor, then we proceed with assembly
275  // that involves elem and neighbor
276  const Elem* neighbor = elem->neighbor_ptr(context.get_side());
277  if(neighbor)
278  {
279  context.side_fe_reinit();
280  context.set_neighbor(*neighbor);
281 
282  // This call initializes neighbor data, and also sets
283  // context.dg_terms_are_active() to true
284  context.neighbor_side_fe_reinit();
285 
286  FEBase* side_fe = NULL;
287  context.get_side_fe(0, side_fe);
288 
289  const std::vector<Real> &JxW_face = side_fe->get_JxW();
290  const std::vector<std::vector<Real> >& phi_face = side_fe->get_phi();
291 
292  FEBase* neighbor_side_fe = NULL;
293  context.get_neighbor_side_fe(0, neighbor_side_fe);
294 
295  // These shape functions have been evaluated on the quadrature points
296  // for elem->side on the neighbor element
297  const std::vector<std::vector<Real> >& phi_neighbor_face =
298  neighbor_side_fe->get_phi();
299 
300  const unsigned int n_dofs = context.get_dof_indices(0).size();
301  const unsigned int n_neighbor_dofs = context.get_neighbor_dof_indices(0).size();
302  unsigned int n_sidepoints = context.get_side_qrule().n_points();
303 
304  for (unsigned int qp=0; qp<n_sidepoints; qp++)
305  {
306  for (unsigned int i=0; i<n_dofs; i++)
307  for (unsigned int j=0; j<n_dofs; j++)
308  {
309  context.get_elem_elem_jacobian()(i,j) +=
310  JxW_face[qp] * phi_face[i][qp] * phi_face[j][qp];
311  }
312 
313  for (unsigned int i=0; i<n_dofs; i++)
314  for (unsigned int j=0; j<n_neighbor_dofs; j++)
315  {
316  context.get_elem_neighbor_jacobian()(i,j) +=
317  JxW_face[qp] * phi_face[i][qp] * phi_neighbor_face[j][qp];
318  }
319 
320  for (unsigned int i=0; i<n_neighbor_dofs; i++)
321  for (unsigned int j=0; j<n_neighbor_dofs; j++)
322  {
323  context.get_neighbor_neighbor_jacobian()(i,j) +=
324  JxW_face[qp] * phi_neighbor_face[i][qp] * phi_neighbor_face[j][qp];
325  }
326 
327  for (unsigned int i=0; i<n_neighbor_dofs; i++)
328  for (unsigned int j=0; j<n_dofs; j++)
329  {
330  context.get_neighbor_elem_jacobian()(i,j) +=
331  JxW_face[qp] * phi_neighbor_face[i][qp] * phi_face[j][qp];
332  }
333  }
334 
335  matrix.add_matrix (context.get_elem_elem_jacobian(),
336  context.get_dof_indices(),
337  context.get_dof_indices());
338 
339  matrix.add_matrix (context.get_elem_neighbor_jacobian(),
340  context.get_dof_indices(),
341  context.get_neighbor_dof_indices());
342 
343  matrix.add_matrix (context.get_neighbor_elem_jacobian(),
344  context.get_neighbor_dof_indices(),
345  context.get_dof_indices());
346 
347  matrix.add_matrix (context.get_neighbor_neighbor_jacobian(),
348  context.get_neighbor_dof_indices(),
349  context.get_neighbor_dof_indices());
350  }
351  }
352  }
353 }
354 
355 
357  const Parameters&,
358  const std::string&,
359  const std::string&)
360 {
361  const Real & x = p(0);
362  const Real & y = LIBMESH_DIM > 1 ? p(1) : 0;
363  const Real & z = LIBMESH_DIM > 2 ? p(2) : 0;
364 
365  return x*(1-x)*(1-x) + x*x*(1-y) + x*(1-y)*(1-z) + y*(1-y)*z + z*(1-z)*(1-z);
366 }
367 
368 
370  const Parameters&,
371  const std::string&,
372  const std::string&)
373 {
374  const Real & x = p(0);
375  const Real & y = LIBMESH_DIM > 1 ? p(1) : 0;
376  const Real & z = LIBMESH_DIM > 2 ? p(2) : 0;
377 
378  return x + 2*y + 3*z - 1;
379 }
380 
381 
383  const Parameters&,
384  const std::string&,
385  const std::string&)
386 {
387  const Real & x = p(0);
388  const Real & y = LIBMESH_DIM > 1 ? p(1) : 0;
389  const Real & z = LIBMESH_DIM > 2 ? p(2) : 0;
390 
391  return (3*x < 1) + (3*y < 2) + (3*z > 2);
392 }
393 
394 
395 struct TripleFunction : public FunctionBase<Number>
396 {
397  TripleFunction(Number _offset = 0) : offset(_offset) {}
398 
399  virtual std::unique_ptr<FunctionBase<Number>> clone () const
400  { return std::make_unique<TripleFunction>(offset); }
401 
402  // We only really need the vector-valued output for projections
403  virtual Number operator() (const Point &,
404  const Real /*time*/ = 0.) override
405  { libmesh_error(); }
406 
407  virtual void operator() (const Point & p,
408  const Real,
409  DenseVector<Number> & output) override
410  {
411  libmesh_assert_greater(output.size(), 0);
412  Parameters params;
413  output(0) = cubic_test(p, params, "", "") + offset;
414  if (output.size() > 0)
415  output(1) = new_linear_test(p, params, "", "") + offset;
416  if (output.size() > 1)
417  output(2) = disc_thirds_test(p, params, "", "") + offset;
418  }
419 
420  Number component (unsigned int i,
421  const Point & p,
422  Real /* time */) override
423  {
424  Parameters params;
425  switch (i) {
426  case 0:
427  return cubic_test(p, params, "", "") + offset;
428  case 1:
429  return new_linear_test(p, params, "", "") + offset;
430  case 2:
431  return disc_thirds_test(p, params, "", "") + offset;
432  default:
433  libmesh_error();
434  }
435  return 0;
436  }
437 
439 };
440 
441 
442 class SystemsTest : public CppUnit::TestCase {
443 public:
444  LIBMESH_CPPUNIT_TEST_SUITE( SystemsTest );
445 
446  CPPUNIT_TEST( test100KVariables );
447 
448  CPPUNIT_TEST( testUninitializedInfo );
449 
450  CPPUNIT_TEST( testPostInitAddVector );
451  CPPUNIT_TEST( testAddVectorProjChange );
452  CPPUNIT_TEST( testAddVectorTypeChange );
453  CPPUNIT_TEST( testPostInitAddVectorTypeChange );
454 
455  CPPUNIT_TEST( testProjectHierarchicEdge3 );
456 #if LIBMESH_DIM > 1
457  CPPUNIT_TEST( testProjectHierarchicQuad9 );
458  CPPUNIT_TEST( testProjectHierarchicTri6 );
459  CPPUNIT_TEST( testProjectHierarchicTri7 );
460  CPPUNIT_TEST( test2DProjectVectorFETri3 );
461  CPPUNIT_TEST( test2DProjectVectorFEQuad4 );
462  CPPUNIT_TEST( test2DProjectVectorFETri6 );
463  CPPUNIT_TEST( test2DProjectVectorFETri7 );
464  CPPUNIT_TEST( test2DProjectVectorFEQuad8 );
465  CPPUNIT_TEST( test2DProjectVectorFEQuad9 );
466 #ifdef LIBMESH_HAVE_SOLVER
467  CPPUNIT_TEST( testBlockRestrictedVarNDofs );
468 #endif
469 #endif // LIBMESH_DIM > 1
470 #if LIBMESH_DIM > 2
471  CPPUNIT_TEST( testFirstScalarNumber );
472  CPPUNIT_TEST( testProjectHierarchicHex27 );
473  CPPUNIT_TEST( testProjectMeshFunctionHex27 );
474  CPPUNIT_TEST( testBoundaryProjectCube );
475  CPPUNIT_TEST( test3DProjectVectorFETet4 );
476  CPPUNIT_TEST( test3DProjectVectorFEHex8 );
477  CPPUNIT_TEST( test3DProjectVectorFETet10 );
478  CPPUNIT_TEST( test3DProjectVectorFETet14 );
479  CPPUNIT_TEST( test3DProjectVectorFEHex20 );
480  CPPUNIT_TEST( test3DProjectVectorFEHex27 );
481 #ifdef LIBMESH_HAVE_SOLVER
482  CPPUNIT_TEST( testSetSystemParameterOverEquationSystem);
483  CPPUNIT_TEST( testAssemblyWithDgFemContext );
484 #endif
485 #endif // LIBMESH_DIM > 2
486 #ifdef LIBMESH_HAVE_SOLVER
487  CPPUNIT_TEST( testDofCouplingWithVarGroups );
488 #endif
489 
490 #ifdef LIBMESH_ENABLE_AMR
491 #ifdef LIBMESH_HAVE_METAPHYSICL
492 #ifdef LIBMESH_HAVE_PETSC
493  CPPUNIT_TEST( testProjectMatrixEdge2 );
494 #if LIBMESH_DIM > 1
495  CPPUNIT_TEST( testProjectMatrixQuad4 );
496  CPPUNIT_TEST( testProjectMatrixTri3 );
497 #endif // LIBMESH_DIM > 1
498 #if LIBMESH_DIM > 2
499  CPPUNIT_TEST( testProjectMatrixHex8 );
500  CPPUNIT_TEST( testProjectMatrixTet4 );
501 #endif // LIBMESH_DIM > 2
502 #endif // LIBMESH_HAVE_PETSC
503 #endif // LIBMESH_HAVE_METAPHYSICL
504 #endif // LIBMESH_ENABLE_AMR
505 
506  CPPUNIT_TEST_SUITE_END();
507 
508 private:
509  void tripleValueTest (const Point & p,
510  const TransientExplicitSystem & sys,
511  const PointLocatorBase & locator,
512  std::set<subdomain_id_type> & u_subdomains,
513  std::set<subdomain_id_type> & v_subdomains,
514  std::set<subdomain_id_type> & w_subdomains,
515  const Parameters & param)
516  {
517  const Elem * elem = locator(p);
518  subdomain_id_type sbd_id = elem ? elem->subdomain_id() : 0;
519  TestCommWorld->max(sbd_id);
520 
521  if (u_subdomains.count(sbd_id))
522  {
523  LIBMESH_ASSERT_NUMBERS_EQUAL(cubic_test(p,param,"",""),
524  sys.point_value(0,p),
525  TOLERANCE*TOLERANCE*10);
526  LIBMESH_ASSERT_NUMBERS_EQUAL
527  (cubic_test(p,param,"","") + Number(10),
528  sys.point_value(0,p,sys.old_local_solution),
529  TOLERANCE*TOLERANCE*100);
530  LIBMESH_ASSERT_NUMBERS_EQUAL
531  (cubic_test(p,param,"","") + Number(20),
532  sys.point_value(0,p,sys.older_local_solution),
533  TOLERANCE*TOLERANCE*100);
534  }
535  if (v_subdomains.count(sbd_id))
536  {
537  LIBMESH_ASSERT_NUMBERS_EQUAL
538  (new_linear_test(p,param,"",""), sys.point_value(1,p),
539  TOLERANCE*TOLERANCE*10);
540  LIBMESH_ASSERT_NUMBERS_EQUAL
541  (new_linear_test(p,param,"","") + Number(10),
542  sys.point_value(1,p,sys.old_local_solution),
543  TOLERANCE*TOLERANCE*100);
544  LIBMESH_ASSERT_NUMBERS_EQUAL
545  (new_linear_test(p,param,"","") + Number(20),
546  sys.point_value(1,p,sys.older_local_solution),
547  TOLERANCE*TOLERANCE*100);
548  }
549  if (w_subdomains.count(sbd_id))
550  {
551  LIBMESH_ASSERT_NUMBERS_EQUAL
552  (disc_thirds_test(p,param,"",""), sys.point_value(2,p),
553  TOLERANCE*TOLERANCE*10);
554  LIBMESH_ASSERT_NUMBERS_EQUAL
555  (disc_thirds_test(p,param,"","") + Number(10),
556  sys.point_value(2,p,sys.old_local_solution),
557  TOLERANCE*TOLERANCE*100);
558  LIBMESH_ASSERT_NUMBERS_EQUAL
559  (disc_thirds_test(p,param,"","") + Number(20),
560  sys.point_value(2,p,sys.older_local_solution),
561  TOLERANCE*TOLERANCE*100);
562  }
563  }
564 
565 public:
566  void setUp()
567  {}
568 
569  void tearDown()
570  {}
571 
572 
574  EquationSystems & es)
575  {
576  ExplicitSystem &sys =
577  es.add_system<ExplicitSystem> ("Simple");
578 
579  sys.add_variable("u", FIRST);
580 
582  10,
583  0., 1.,
584  EDGE3);
585 
586  return sys;
587  }
588 
589 
591  {
593 
595  1, 1, 1,
596  0., 1., 0., 1., 0., 1.,
597  HEX8);
598 
599  EquationSystems es(mesh);
600  System &sys = es.add_system<System> ("SimpleSystem");
601 
602  const FEFamily types[3] = {MONOMIAL_VEC, LAGRANGE_VEC, NEDELEC_ONE};
603  const Order orders[3] = {CONSTANT, SECOND, FIRST};
604  const std::string names[3] = {"u", "v", "w"};
605  const unsigned int var_nums[3] =
606  {
608  sys.add_variable("v", SECOND, LAGRANGE_VEC),
609  sys.add_variable("w", FIRST, NEDELEC_ONE)
610  };
611 
612  for (unsigned int i : {0, 1, 2})
613  {
614  // We did just add these in order
615  CPPUNIT_ASSERT_EQUAL(i, var_nums[i]);
616 
617  auto & var = sys.variable(i);
618  CPPUNIT_ASSERT_EQUAL(var.system(), &sys);
619  CPPUNIT_ASSERT_EQUAL(var.name(), names[i]);
620  CPPUNIT_ASSERT_EQUAL(var.number(), i);
621  CPPUNIT_ASSERT_EQUAL(var.first_scalar_number(), i*3);
622  CPPUNIT_ASSERT_EQUAL(var.type().family, types[i]);
623  CPPUNIT_ASSERT_EQUAL(Order(var.type().order), orders[i]);
624  CPPUNIT_ASSERT_EQUAL(var.n_components(mesh), 3u);
625  }
626  }
627 
628 
630  {
632  EquationSystems es(mesh);
633  ExplicitSystem &sys =
634  es.add_system<ExplicitSystem> ("100KVars");
635 
636  dof_id_type n_dofs = 100000;
637 
638  // This takes 16 seconds in opt mode for me, 200 in dbg!?
639  /*
640  for (auto i : make_range(n_dofs))
641  sys.add_variable(std::to_string(i), FIRST);
642  */
643 
644  std::vector<std::string> var_names(n_dofs);
645  for (auto i : make_range(n_dofs))
646  var_names[i] = std::to_string(i);
647 
648  sys.add_variables(var_names, FIRST);
649 
651  4,
652  0., 1.,
653  EDGE3);
654 
655  es.init();
656 
657  CPPUNIT_ASSERT_EQUAL(sys.n_dofs(), n_dofs*5);
658  for (const Node * node : mesh.node_ptr_range())
659  CPPUNIT_ASSERT_EQUAL(dof_id_type(node->n_vars(0)), n_dofs);
660 
661  std::vector<dof_id_type> each = sys.get_dof_map().n_dofs_per_processor(888);
662  CPPUNIT_ASSERT_EQUAL(std::accumulate(each.begin(), each.end(), dof_id_type(0)), dof_id_type(5));
663  CPPUNIT_ASSERT_EQUAL(sys.get_dof_map().n_dofs(888), dof_id_type(5));
664  }
665 
667  {
669  EquationSystems es(mesh);
670  ExplicitSystem & sys = simpleSetup(mesh, es);
671 
672  auto info = sys.get_info();
673 
674  CPPUNIT_ASSERT (info.find("uninitialized") != std::string::npos);
675  }
676 
677 
679  {
681  EquationSystems es(mesh);
682  ExplicitSystem & sys = simpleSetup(mesh, es);
683  es.init();
684 
685  auto & late_vec = sys.add_vector("late");
686 
687  CPPUNIT_ASSERT_EQUAL(sys.n_dofs(), dof_id_type(11));
688 
689  // late_vec should be initialized
690  CPPUNIT_ASSERT_EQUAL(late_vec.size(), dof_id_type(11));
691  CPPUNIT_ASSERT_EQUAL(late_vec.local_size(), sys.solution->local_size());
692  }
693 
694 
696  {
698  EquationSystems es(mesh);
699  ExplicitSystem & sys = simpleSetup(mesh, es);
700 
701  sys.add_vector("late", /* projections = */ false);
702  CPPUNIT_ASSERT_EQUAL(sys.vector_preservation("late"), false);
703 
704  sys.add_vector("late");
705  CPPUNIT_ASSERT_EQUAL(sys.vector_preservation("late"), true);
706  }
707 
708 
710  {
711  // Vector types are all pretty much equivalent in serial.
712  if (TestCommWorld->size() == 1)
713  return;
714 
716  EquationSystems es(mesh);
717  ExplicitSystem & sys = simpleSetup(mesh, es);
718 
719  auto & late_vec = sys.add_vector("late");
720  CPPUNIT_ASSERT_EQUAL(late_vec.type(), PARALLEL);
721  CPPUNIT_ASSERT_EQUAL(sys.vector_preservation("late"), true);
722 
723  // We should never downgrade projection settings, so "false"
724  // should be safely ignored here
725  sys.add_vector("late", false, GHOSTED);
726  CPPUNIT_ASSERT_EQUAL(late_vec.type(), GHOSTED);
727  CPPUNIT_ASSERT_EQUAL(sys.vector_preservation("late"), true);
728 
729  // We should never downgrade storage settings, so this should be a
730  // no-op.
731  sys.add_vector("late", true, PARALLEL);
732  CPPUNIT_ASSERT_EQUAL(late_vec.type(), GHOSTED);
733  CPPUNIT_ASSERT_EQUAL(sys.vector_preservation("late"), true);
734  }
735 
736 
738  {
739  // Vector types are all pretty much equivalent in serial.
740  if (TestCommWorld->size() == 1)
741  return;
742 
744  EquationSystems es(mesh);
745  ExplicitSystem & sys = simpleSetup(mesh, es);
746 
747  auto & late_vec = sys.add_vector("late");
748  CPPUNIT_ASSERT_EQUAL(late_vec.type(), PARALLEL);
749  CPPUNIT_ASSERT_EQUAL(sys.vector_preservation("late"), true);
750 
751  es.init();
752 
753  auto & dof_map = sys.get_dof_map();
754 
755  // Set some data to make sure it's preserved
756  CPPUNIT_ASSERT_EQUAL(sys.n_dofs(), dof_id_type(11));
757  for (auto i : make_range(dof_map.first_dof(),
758  dof_map.end_dof()))
759  late_vec.set(i, 2.0*i);
760  late_vec.close();
761 
762  sys.add_vector("late", false, GHOSTED);
763  CPPUNIT_ASSERT_EQUAL(late_vec.type(), GHOSTED);
764 
765  std::vector<dof_id_type> dof_indices;
766  for (auto & elem : mesh.active_local_element_ptr_range())
767  {
768  dof_map.dof_indices (elem, dof_indices);
769 
770  for (auto d : dof_indices)
771  CPPUNIT_ASSERT_EQUAL(late_vec(d), Number(2.0*d));
772  }
773  }
774 
775 
776 
777  void testProjectLine(const ElemType elem_type)
778  {
780 
781  EquationSystems es(mesh);
783  es.add_system<TransientExplicitSystem> ("SimpleSystem");
784 
785  std::set<subdomain_id_type> u_subdomains {0, 1, 4, 5},
786  v_subdomains {1, 2, 3, 4},
787  w_subdomains {0, 1, 2, 3, 4};
788 
789  sys.add_variable("u", THIRD, HIERARCHIC, &u_subdomains);
790  sys.add_variable("v", FIRST, LAGRANGE, &v_subdomains);
791  sys.add_variable("w", CONSTANT, MONOMIAL, &w_subdomains);
792 
794  6,
795  0., 1.,
796  elem_type);
797 
798  for (auto & elem : mesh.element_ptr_range())
799  elem->subdomain_id() = elem->id();
800 
801  es.init();
802  TripleFunction tfunc;
803  sys.project_solution(&tfunc);
804  tfunc.offset = 10;
805  sys.project_vector(*sys.old_local_solution, &tfunc);
806  tfunc.offset = 20;
807  sys.project_vector(*sys.older_local_solution, &tfunc);
808 
809  std::unique_ptr<PointLocatorBase> locator = mesh.sub_point_locator();
810  locator->enable_out_of_mesh_mode();
811  for (Real x = 0.1; x < 1; x += 0.2)
812  tripleValueTest(Point(x), sys, *locator,
813  u_subdomains, v_subdomains, w_subdomains,
814  es.parameters);
815 
816 #ifdef LIBMESH_ENABLE_AMR
817  for (auto & elem : mesh.element_ptr_range())
818  if ((elem->id()/2)%2)
819  elem->set_refinement_flag(Elem::REFINE);
820  es.reinit();
821 
822  locator = mesh.sub_point_locator();
823  locator->enable_out_of_mesh_mode();
824  for (Real x = 0.1; x < 1; x += 0.2)
825  tripleValueTest(Point(x), sys, *locator,
826  u_subdomains, v_subdomains, w_subdomains,
827  es.parameters);
828 #endif
829  }
830 
831  void test2DProjectVectorFE(const ElemType elem_type)
832  {
834 
835  EquationSystems es(mesh);
837  es.add_system<TransientExplicitSystem> ("SimpleSystem");
838 
839  auto u_var = sys.add_variable("u", Elem::type_to_default_order_map[elem_type], LAGRANGE_VEC);
840 
842  1, 1,
843  0., 1., 0., 1.,
844  elem_type);
845 
846  es.init();
847 
848  // Manually set-up the solution because I'm too lazy to set-up all the generic
849  // function projection code right now
850  for (const auto & node : mesh.local_node_ptr_range())
851  {
852  for (unsigned int i : make_range(Elem::type_to_dim_map[elem_type]))
853  {
854  auto dof_index = node->dof_number(sys.number(), u_var, i);
855  sys.solution->set(dof_index, (*node)(i));
856  }
857  }
858 
859  // After setting values, we need to assemble
860  sys.solution->close();
861 
862 
863 #ifdef LIBMESH_ENABLE_AMR
864  for (auto & elem : mesh.element_ptr_range())
865  elem->set_refinement_flag(Elem::REFINE);
866  es.reinit();
867 #endif
868 
869  for (const auto & node : mesh.local_node_ptr_range())
870  {
871  // 2D element here
872  for (unsigned int i : make_range(Elem::type_to_dim_map[elem_type]))
873  {
874  auto dof_index = node->dof_number(sys.number(), u_var, i);
875  auto value = (*sys.solution)(dof_index);
876  LIBMESH_ASSERT_NUMBERS_EQUAL(value, (*node)(i), TOLERANCE*TOLERANCE);
877  }
878  }
879  }
880 
881  void test3DProjectVectorFE(const ElemType elem_type)
882  {
884 
885  EquationSystems es(mesh);
887  es.add_system<TransientExplicitSystem> ("SimpleSystem");
888 
889  auto u_var = sys.add_variable
891 
893  1, 1, 1,
894  0., 1., 0., 1., 0., 1.,
895  elem_type);
896 
897  es.init();
898 
899  // Manually set-up the solution because I'm too lazy to set-up all the generic
900  // function projection code right now
901  for (const auto & node : mesh.local_node_ptr_range())
902  {
903  for (unsigned int i : make_range(Elem::type_to_dim_map[elem_type]))
904  {
905  auto dof_index = node->dof_number(sys.number(), u_var, i);
906  sys.solution->set(dof_index, (*node)(i));
907  }
908  }
909 
910  // After setting values, we need to assemble
911  sys.solution->close();
912 
913 
914 #ifdef LIBMESH_ENABLE_AMR
915  for (auto & elem : mesh.element_ptr_range())
916  elem->set_refinement_flag(Elem::REFINE);
917  es.reinit();
918 #endif
919 
920  for (const auto & node : mesh.local_node_ptr_range())
921  {
922  for (unsigned int i : make_range(Elem::type_to_dim_map[elem_type]))
923  {
924  auto dof_index = node->dof_number(sys.number(), u_var, i);
925  auto value = (*sys.solution)(dof_index);
926  LIBMESH_ASSERT_NUMBERS_EQUAL(value, (*node)(i), TOLERANCE*TOLERANCE);
927  }
928  }
929  }
930 
931  void testProjectSquare(const ElemType elem_type)
932  {
934 
935  EquationSystems es(mesh);
937  es.add_system<TransientExplicitSystem> ("SimpleSystem");
938 
939  std::set<subdomain_id_type> u_subdomains {0, 1, 4, 5},
940  v_subdomains {1, 2, 3, 4},
941  w_subdomains {0, 1, 2, 3, 4};
942 
943  sys.add_variable("u", THIRD, HIERARCHIC, &u_subdomains);
944  sys.add_variable("v", FIRST, LAGRANGE, &v_subdomains);
945  sys.add_variable("w", CONSTANT, MONOMIAL, &w_subdomains);
946 
948  3, 3,
949  0., 1., 0., 1.,
950  elem_type);
951 
952  for (auto & elem : mesh.element_ptr_range())
953  elem->subdomain_id() = elem->id()/2;
954 
955  es.init();
956  TripleFunction tfunc;
957  sys.project_solution(&tfunc);
958  tfunc.offset = 10;
959  sys.project_vector(*sys.old_local_solution, &tfunc);
960  tfunc.offset = 20;
961  sys.project_vector(*sys.older_local_solution, &tfunc);
962 
963  std::unique_ptr<PointLocatorBase> locator = mesh.sub_point_locator();
964  locator->enable_out_of_mesh_mode();
965  for (Real x = 0.1; x < 1; x += 0.2)
966  for (Real y = 0.1; y < 1; y += 0.2)
967  tripleValueTest(Point(x,y), sys, *locator,
968  u_subdomains, v_subdomains, w_subdomains,
969  es.parameters);
970 
971 #ifdef LIBMESH_ENABLE_AMR
972  for (auto & elem : mesh.element_ptr_range())
973  if ((elem->id()/2)%2)
974  elem->set_refinement_flag(Elem::REFINE);
975  es.reinit();
976 
977  locator = mesh.sub_point_locator();
978  locator->enable_out_of_mesh_mode();
979  for (Real x = 0.1; x < 1; x += 0.2)
980  for (Real y = 0.1; y < 1; y += 0.2)
981  tripleValueTest(Point(x,y), sys, *locator,
982  u_subdomains, v_subdomains, w_subdomains,
983  es.parameters);
984 #endif
985  }
986 
987  void testProjectCube(const ElemType elem_type)
988  {
990 
991  EquationSystems es(mesh);
993  es.add_system<TransientExplicitSystem> ("SimpleSystem");
994 
995  std::set<subdomain_id_type> u_subdomains {0, 1, 4, 5},
996  v_subdomains {1, 2, 3, 4},
997  w_subdomains {0, 1, 2, 3, 4};
998 
999  sys.add_variable("u", THIRD, HIERARCHIC, &u_subdomains);
1000  sys.add_variable("v", FIRST, LAGRANGE, &v_subdomains);
1001  sys.add_variable("w", CONSTANT, MONOMIAL, &w_subdomains);
1002 
1004  3, 3, 3,
1005  0., 1., 0., 1., 0., 1.,
1006  elem_type);
1007 
1008  for (auto & elem : mesh.element_ptr_range())
1009  elem->subdomain_id() = elem->id()/6;
1010 
1011  es.init();
1012  TripleFunction tfunc;
1013  sys.project_solution(&tfunc);
1014  tfunc.offset = 10;
1015  sys.project_vector(*sys.old_local_solution, &tfunc);
1016  tfunc.offset = 20;
1017  sys.project_vector(*sys.older_local_solution, &tfunc);
1018 
1019  std::unique_ptr<PointLocatorBase> locator = mesh.sub_point_locator();
1020  locator->enable_out_of_mesh_mode();
1021  for (Real x = 0.1; x < 1; x += 0.2)
1022  for (Real y = 0.1; y < 1; y += 0.2)
1023  for (Real z = 0.1; z < 1; z += 0.2)
1024  tripleValueTest(Point(x,y,z), sys, *locator,
1025  u_subdomains, v_subdomains, w_subdomains,
1026  es.parameters);
1027 
1028  #ifdef LIBMESH_ENABLE_AMR
1029  for (auto & elem : mesh.element_ptr_range())
1030  if ((elem->id()/2)%2)
1031  elem->set_refinement_flag(Elem::REFINE);
1032  es.reinit();
1033 
1034  locator = mesh.sub_point_locator();
1035  locator->enable_out_of_mesh_mode();
1036  for (Real x = 0.1; x < 1; x += 0.2)
1037  for (Real y = 0.1; y < 1; y += 0.2)
1038  for (Real z = 0.1; z < 1; z += 0.2)
1039  tripleValueTest(Point(x,y,z), sys, *locator,
1040  u_subdomains, v_subdomains, w_subdomains,
1041  es.parameters);
1042  #endif
1043  }
1044 
1046  {
1047  // The source mesh needs to exist everywhere it's queried, so we
1048  // use a ReplicatedMesh
1050 
1051  EquationSystems es(mesh);
1052  System &sys = es.add_system<System> ("SimpleSystem");
1053  sys.add_variable("u", THIRD, MONOMIAL);
1054 
1056  3, 3, 3,
1057  0., 1., 0., 1., 0., 1.,
1058  elem_type);
1059 
1060  es.init();
1061  sys.project_solution(cubic_test, nullptr, es.parameters);
1062 
1063  std::vector<unsigned int> variables;
1064  sys.get_all_variable_numbers(variables);
1065  std::sort(variables.begin(),variables.end());
1066 
1067  std::unique_ptr< NumericVector<Number> > mesh_function_vector =
1069  mesh_function_vector->init(sys.n_dofs(), false, SERIAL);
1070  sys.solution->localize( *mesh_function_vector );
1071 
1072  MeshFunction mesh_function(es,
1073  *mesh_function_vector,
1074  sys.get_dof_map(),
1075  variables);
1076  mesh_function.init();
1077 
1078  // Make a second system and project onto it using a MeshFunction
1079  Mesh proj_mesh(*TestCommWorld);
1080  EquationSystems proj_es(proj_mesh);
1081 
1082  System &proj_sys = proj_es.add_system<System> ("ProjectionSystem");
1083 
1084  // use 3rd order again so we can expect exact results
1085  proj_sys.add_variable("u", THIRD, HIERARCHIC);
1086 
1088  5, 5, 5,
1089  0., 1., 0., 1., 0., 1.,
1090  elem_type);
1091 
1092  proj_es.init();
1093  proj_sys.project_solution(&mesh_function);
1094 
1095  for (Real x = 0.1; x < 1; x += 0.2)
1096  for (Real y = 0.1; y < 1; y += 0.2)
1097  for (Real z = 0.1; z < 1; z += 0.2)
1098  {
1099  Point p(x,y,z);
1100  LIBMESH_ASSERT_NUMBERS_EQUAL
1101  (cubic_test(p,es.parameters,"",""),
1102  proj_sys.point_value(0,p), TOLERANCE*TOLERANCE);
1103  }
1104  }
1105 
1107  {
1108  LOG_UNIT_TEST;
1109 
1111 
1112  // const boundary_id_type BOUNDARY_ID_MIN_Z = 0;
1113  const boundary_id_type BOUNDARY_ID_MIN_Y = 1;
1114  const boundary_id_type BOUNDARY_ID_MAX_X = 2;
1115  const boundary_id_type BOUNDARY_ID_MAX_Y = 3;
1116  const boundary_id_type BOUNDARY_ID_MIN_X = 4;
1117  const boundary_id_type BOUNDARY_ID_MAX_Z = 5;
1118  const boundary_id_type NODE_BOUNDARY_ID = 10;
1119  const boundary_id_type EDGE_BOUNDARY_ID = 20;
1120  const boundary_id_type SIDE_BOUNDARY_ID = BOUNDARY_ID_MIN_X;
1121 
1122  EquationSystems es(mesh);
1123  System &sys = es.add_system<System> ("SimpleSystem");
1124  unsigned int u_var = sys.add_variable("u", FIRST, LAGRANGE);
1125 
1127  3, 3, 3,
1128  0., 1., 0., 1., 0., 1.,
1129  HEX8);
1130 
1131  // Count the number of nodes on SIDE_BOUNDARY_ID
1132  std::set<dof_id_type> projected_nodes_set;
1133 
1134  for (const auto & elem : mesh.element_ptr_range())
1135  {
1136  for (auto side : elem->side_index_range())
1137  {
1138  std::vector<boundary_id_type> vec_to_fill;
1139  mesh.get_boundary_info().boundary_ids(elem, side, vec_to_fill);
1140 
1141  auto vec_it = std::find(vec_to_fill.begin(), vec_to_fill.end(), SIDE_BOUNDARY_ID);
1142  if (vec_it != vec_to_fill.end())
1143  {
1144  for (unsigned int node_index=0; node_index<elem->n_nodes(); node_index++)
1145  {
1146  if( elem->is_node_on_side(node_index, side))
1147  {
1148  projected_nodes_set.insert(elem->node_id(node_index));
1149  }
1150  }
1151  }
1152  }
1153  }
1154 
1155  // Also add some edge and node boundary IDs
1156  for (const auto & elem : mesh.element_ptr_range())
1157  {
1158  unsigned int
1159  side_max_x = 0, side_min_y = 0,
1160  side_max_y = 0, side_max_z = 0;
1161 
1162  bool
1163  found_side_max_x = false, found_side_max_y = false,
1164  found_side_min_y = false, found_side_max_z = false;
1165 
1166  for (auto side : elem->side_index_range())
1167  {
1168  if (mesh.get_boundary_info().has_boundary_id(elem, side, BOUNDARY_ID_MAX_X))
1169  {
1170  side_max_x = side;
1171  found_side_max_x = true;
1172  }
1173 
1174  if (mesh.get_boundary_info().has_boundary_id(elem, side, BOUNDARY_ID_MIN_Y))
1175  {
1176  side_min_y = side;
1177  found_side_min_y = true;
1178  }
1179 
1180  if (mesh.get_boundary_info().has_boundary_id(elem, side, BOUNDARY_ID_MAX_Y))
1181  {
1182  side_max_y = side;
1183  found_side_max_y = true;
1184  }
1185 
1186  if (mesh.get_boundary_info().has_boundary_id(elem, side, BOUNDARY_ID_MAX_Z))
1187  {
1188  side_max_z = side;
1189  found_side_max_z = true;
1190  }
1191  }
1192 
1193  // If elem has sides on boundaries
1194  // BOUNDARY_ID_MAX_X, BOUNDARY_ID_MAX_Y, BOUNDARY_ID_MAX_Z
1195  // then let's set a node boundary condition
1196  if (found_side_max_x && found_side_max_y && found_side_max_z)
1197  for (auto n : elem->node_index_range())
1198  if (elem->is_node_on_side(n, side_max_x) &&
1199  elem->is_node_on_side(n, side_max_y) &&
1200  elem->is_node_on_side(n, side_max_z))
1201  {
1202  projected_nodes_set.insert(elem->node_id(n));
1203  mesh.get_boundary_info().add_node(elem->node_ptr(n), NODE_BOUNDARY_ID);
1204  }
1205 
1206  // If elem has sides on boundaries
1207  // BOUNDARY_ID_MAX_X and BOUNDARY_ID_MIN_Y
1208  // then let's set an edge boundary condition
1209  if (found_side_max_x && found_side_min_y)
1210  for (auto e : elem->edge_index_range())
1211  if (elem->is_edge_on_side(e, side_max_x) &&
1212  elem->is_edge_on_side(e, side_min_y))
1213  {
1214  mesh.get_boundary_info().add_edge(elem, e, EDGE_BOUNDARY_ID);
1215 
1216  for (unsigned int node_index=0; node_index<elem->n_nodes(); node_index++)
1217  {
1218  if (elem->is_node_on_edge(node_index, e))
1219  {
1220  projected_nodes_set.insert(elem->node_id(node_index));
1221  }
1222  }
1223  }
1224  }
1225 
1226  es.init();
1227 
1228  sys.solution->add(1.0);
1229 
1230  std::set<boundary_id_type> boundary_ids;
1231  boundary_ids.insert(NODE_BOUNDARY_ID);
1232  boundary_ids.insert(EDGE_BOUNDARY_ID);
1233  boundary_ids.insert(SIDE_BOUNDARY_ID);
1234  std::vector<unsigned int> variables;
1235  variables.push_back(u_var);
1236  ZeroFunction<> zf;
1237  sys.boundary_project_solution(boundary_ids, variables, &zf);
1238 
1239  // On a distributed mesh we may not have every node on every
1240  // processor
1241  TestCommWorld->set_union(projected_nodes_set);
1242 
1243  // We set the solution to be 1 everywhere and then zero on specific boundary
1244  // nodes, so the final l1 norm of the solution is the difference between the
1245  // number of nodes in the mesh and the number of nodes we zero on.
1246  Real ref_l1_norm = static_cast<Real>(mesh.n_nodes()) - static_cast<Real>(projected_nodes_set.size());
1247 
1248  LIBMESH_ASSERT_FP_EQUAL(sys.solution->l1_norm(), ref_l1_norm, TOLERANCE*TOLERANCE);
1249  }
1250 
1252  {
1253  LOG_UNIT_TEST;
1254 
1256 
1258  1,
1259  0,
1260  0,
1261  0., 1.,
1262  0., 0.,
1263  0., 0.,
1264  EDGE2);
1265 
1266  Point new_point_a(2.);
1267  Point new_point_b(3.);
1268  Node* new_node_a = mesh.add_point( new_point_a );
1269  Node* new_node_b = mesh.add_point( new_point_b );
1270  auto new_edge_elem = mesh.add_elem(Elem::build(EDGE2));
1271  new_edge_elem->set_node(0, new_node_a);
1272  new_edge_elem->set_node(1, new_node_b);
1273 
1274  mesh.elem_ref(0).subdomain_id() = 10;
1275  mesh.elem_ref(1).subdomain_id() = 10;
1276 
1277  // Add NodeElems for coupling purposes
1278  auto node_elem_1 = mesh.add_elem(Elem::build(NODEELEM));
1279  node_elem_1->set_node(0, mesh.elem_ref(0).node_ptr(1));
1280  auto node_elem_2 = mesh.add_elem(Elem::build(NODEELEM));
1281  node_elem_2->set_node(0, new_node_a);
1282 
1284 
1285  // Create an equation systems object.
1286  EquationSystems equation_systems (mesh);
1287  LinearImplicitSystem & system =
1288  equation_systems.add_system<LinearImplicitSystem> ("test");
1289 
1290  system.add_variable ("u", libMesh::FIRST);
1291  system.add_variable ("v", libMesh::FIRST);
1292  system.add_variable ("w", libMesh::FIRST);
1293 
1294  std::set<subdomain_id_type> theta_subdomains;
1295  theta_subdomains.insert(10);
1296  system.add_variable ("theta_x", libMesh::FIRST, &theta_subdomains);
1297  system.add_variable ("theta_y", libMesh::FIRST, &theta_subdomains);
1298  system.add_variable ("theta_z", libMesh::FIRST, &theta_subdomains);
1299 
1301 
1302  AugmentSparsityOnNodes augment_sparsity(mesh);
1303  system.get_dof_map().add_coupling_functor(augment_sparsity);
1304 
1305  // LASPACK GMRES + ILU defaults don't like this problem, but it's
1306  // small enough to just use a simpler iteration.
1309 
1310  equation_systems.init ();
1311 
1312  system.solve();
1313 
1314  // We set the solution to be 1 everywhere, so the final l1 norm of the
1315  // solution is the product of the number of variables and number of nodes.
1316  Real ref_l1_norm = static_cast<Real>(mesh.n_nodes() * system.n_vars());
1317 
1318  LIBMESH_ASSERT_FP_EQUAL(system.solution->l1_norm(), ref_l1_norm, TOLERANCE*TOLERANCE);
1319  }
1320 
1321 
1323  {
1324  LOG_UNIT_TEST;
1325 
1327 
1329  1,
1330  0,
1331  0,
1332  0., 1.,
1333  0., 0.,
1334  0., 0.,
1335  EDGE2);
1336 
1337  Point new_point_a(2.);
1338  Point new_point_b(3.);
1339  Node* new_node_a = mesh.add_point( new_point_a );
1340  Node* new_node_b = mesh.add_point( new_point_b );
1341  auto new_edge_elem = mesh.add_elem(Elem::build(EDGE2));
1342  new_edge_elem->set_node(0, new_node_a);
1343  new_edge_elem->set_node(1, new_node_b);
1344 
1345  mesh.elem_ref(0).subdomain_id() = 10;
1346  mesh.elem_ref(1).subdomain_id() = 10;
1347 
1349 
1350  // Create an equation systems object.
1351  EquationSystems equation_systems (mesh);
1352 
1353  // Set some parameters to the equation system that would cause a failed test
1354  equation_systems.parameters.set<unsigned int>("linear solver maximum iterations") = 0;
1355 
1356  // Setup Linear Implicit system
1357  LinearImplicitSystem & li_system =
1358  equation_systems.add_system<LinearImplicitSystem> ("test");
1359 
1360  // We must use a discontinuous variable type in this test or
1361  // else the sparsity pattern will not be correct
1362  li_system.add_variable("u", FIRST, L2_LAGRANGE);
1363 
1365  5, 5, 5,
1366  0., 1., 0., 1., 0., 1.,
1367  HEX8);
1368 
1369  li_system.attach_assemble_function (assembly_with_dg_fem_context);
1370  li_system.get_linear_solver()->set_solver_type(GMRES);
1371  // Need 5 iterations, dont overdo the preconditioning
1372  li_system.get_linear_solver()->set_preconditioner_type(IDENTITY_PRECOND);
1373 
1374  // Set some parameters to the system that work for the solve
1375  li_system.parameters.set<unsigned int>("linear solver maximum iterations") = 5;
1376  li_system.parameters.set<Real>("linear solver tolerance") = 1e-100;
1377 
1378  // Need to init before we can access the system matrix
1379  equation_systems.init ();
1380 
1381  // See the solve pass, indicating system parameters are used over equation system parameters
1382  li_system.solve();
1383 
1384  // Check that the number of iterations from the systems got obeyed
1385  CPPUNIT_ASSERT_EQUAL(li_system.n_linear_iterations(), 5u);
1386 }
1387 
1389  {
1390  LOG_UNIT_TEST;
1391 
1393 
1394  EquationSystems es(mesh);
1395  System &sys = es.add_system<LinearImplicitSystem> ("test");
1396 
1397  // We must use a discontinuous variable type in this test or
1398  // else the sparsity pattern will not be correct
1399  sys.add_variable("u", FIRST, L2_LAGRANGE);
1400 
1402  5, 5, 5,
1403  0., 1., 0., 1., 0., 1.,
1404  HEX8);
1405 
1406  es.init();
1408  sys.solve();
1409 
1410  // We don't actually assert anything in this test. We just want to check that
1411  // the assembly and solve do not encounter any errors.
1412  }
1413 
1415  {
1416  LOG_UNIT_TEST;
1417 
1419 
1421  4,
1422  4,
1423  0,
1424  0., 1.,
1425  0., 1.,
1426  0., 0.,
1427  QUAD4);
1428 
1429  for (const auto & elem : mesh.element_ptr_range())
1430  {
1431  Point c = elem->vertex_average();
1432  if (c(0) <= 0.5 && c(1) <= 0.5)
1433  elem->subdomain_id() = 0;
1434  else
1435  elem->subdomain_id() = 1;
1436  }
1437 
1439 
1440  // Create an equation systems object.
1441  EquationSystems equation_systems (mesh);
1442  ExplicitSystem& system =
1443  equation_systems.add_system<LinearImplicitSystem> ("test");
1444 
1445  std::set<subdomain_id_type> block0;
1446  std::set<subdomain_id_type> block1;
1447  block0.insert(0);
1448  block1.insert(1);
1449  auto u0 = system.add_variable ("u0", libMesh::FIRST, &block0);
1450  auto u1 = system.add_variable ("u1", libMesh::FIRST, &block1);
1451  equation_systems.init();
1452 
1453  std::vector<dof_id_type> u0_dofs;
1454  system.get_dof_map().local_variable_indices(u0_dofs, mesh, u0);
1455  std::vector<dof_id_type> u1_dofs;
1456  system.get_dof_map().local_variable_indices(u1_dofs, mesh, u1);
1457 
1458  std::set<dof_id_type> sys_u0_dofs;
1459  system.local_dof_indices(u0, sys_u0_dofs);
1460  std::set<dof_id_type> sys_u1_dofs;
1461  system.local_dof_indices(u1, sys_u1_dofs);
1462 
1463  // Get local indices from other processors too
1464  mesh.comm().allgather(u0_dofs);
1465  mesh.comm().allgather(u1_dofs);
1466  mesh.comm().set_union(sys_u0_dofs);
1467  mesh.comm().set_union(sys_u1_dofs);
1468 
1469  const std::size_t c9 = 9;
1470  const std::size_t c21 = 21;
1471  CPPUNIT_ASSERT_EQUAL(c9, u0_dofs.size());
1472  CPPUNIT_ASSERT_EQUAL(c21, u1_dofs.size());
1473  CPPUNIT_ASSERT_EQUAL(c9, sys_u0_dofs.size());
1474  CPPUNIT_ASSERT_EQUAL(c21, sys_u1_dofs.size());
1475  }
1476 
1477 #ifdef LIBMESH_ENABLE_AMR
1478 #ifdef LIBMESH_HAVE_METAPHYSICL
1479 #ifdef LIBMESH_HAVE_PETSC
1480  void testProjectMatrix1D(const ElemType elem_type)
1481  {
1482  // Use ReplicatedMesh to get consistent child element node
1483  // numbering during refinement
1485 
1486  // fix the node numbering to resolve dof_id numbering issues in parallel tests
1487  mesh.allow_renumbering(false);
1488 
1489  // init a simple 1d system
1490  EquationSystems es(mesh);
1491  System &sys = es.add_system<System> ("SimpleSystem");
1492  sys.add_variable("u", FIRST, LAGRANGE);
1493 
1495  4, 0., 1.,
1496  elem_type);
1497 
1498  es.init();
1499 
1500  // static set of coarse nodes / order of fine grid nodes from x=0 to x=1 going left to right
1501  std::set<dof_id_type> coarse_nodes({0,1,2,3,4});
1502  std::vector<dof_id_type> node_order_f({0,5,1,6,2,7,3,8,4});
1503 
1504  // stash number of dofs on coarse grid for projection sizing
1505  int n_old_dofs = sys.n_dofs();
1506 
1507  // save old coarse dof_ids in order of coarse nodes
1508  std::map <dof_id_type, dof_id_type> node2dof_c;
1509  for ( const auto & node : mesh.node_ptr_range() )
1510  {
1511  dof_id_type cdof_id = node->dof_number(0,0,0);
1512  node2dof_c.insert( std::pair<dof_id_type,dof_id_type>( node->id() , cdof_id) );
1513  }
1514 
1515  // refine the mesh so we can utilize old_dof_indices for projection_matrix
1516  MeshRefinement mr(mesh);
1517  mr.uniformly_refine(1);
1519 
1520  // fine node to dof map
1521  std::map <dof_id_type, dof_id_type> node2dof_f;
1522  for ( const auto & node : mesh.local_node_ptr_range() )
1523  {
1524  dof_id_type fdof_id = node->dof_number(0,0,0);
1525  node2dof_f.insert( std::pair<dof_id_type,dof_id_type>(node->id() , fdof_id) );
1526  }
1527 
1528  // local and global projection_matrix sizes infos
1529  int n_new_dofs = sys.n_dofs();
1530  int n_new_dofs_local = sys.get_dof_map().n_local_dofs();
1531  int ndofs_old_first = sys.get_dof_map().first_old_dof();
1532  int ndofs_old_end = sys.get_dof_map().end_old_dof();
1533  int n_old_dofs_local = ndofs_old_end - ndofs_old_first;
1534 
1535  // init and compute the projection matrix using GenericProjector
1536  std::unique_ptr<SparseMatrix<Number> > proj_mat_ptr =
1538  SparseMatrix<Number> & proj_mat = *proj_mat_ptr;
1539  proj_mat.init(n_new_dofs, n_old_dofs, n_new_dofs_local, n_old_dofs_local);
1540  sys.projection_matrix(proj_mat);
1541  proj_mat.close();
1542 
1543  // init the gold standard projection matrix
1544  std::unique_ptr<SparseMatrix<Number> > gold_mat_ptr =
1546  SparseMatrix<Number> & gold_mat = *gold_mat_ptr;
1547  gold_mat.init(n_new_dofs, n_old_dofs, n_new_dofs_local, n_old_dofs_local);
1548 
1549  // construct the gold projection matrix using static node numbering as reference info
1550  for ( const auto & node : mesh.local_node_ptr_range() )
1551  {
1552  dof_id_type node_id = node->id();
1553  dof_id_type fdof_id = (node2dof_f.find(node_id))->second;
1554 
1555  if (coarse_nodes.find(node_id) != coarse_nodes.end() )
1556  { //direct inject coarse nodes
1557  if (fdof_id >= gold_mat.row_start() && fdof_id < gold_mat.row_stop())
1558  {
1559  auto cdof_id = node2dof_c.find(node_id);
1560  gold_mat.set(fdof_id, cdof_id->second, 1.0);
1561  }
1562  }
1563  else
1564  { // new nodes with old_dof neighbor contributions
1565  if (fdof_id >= gold_mat.row_start() && fdof_id < gold_mat.row_stop())
1566  {
1567  auto node_loc = std::find(node_order_f.begin(), node_order_f.end(), node_id);
1568  auto node_n = *std::next(node_loc, 1);
1569  auto node_p = *std::prev(node_loc, 1);
1570  auto dof_p = node2dof_c.find(node_p);
1571  auto dof_n = node2dof_c.find(node_n);
1572 
1573  gold_mat.set(fdof_id, dof_p->second, 0.5);
1574  gold_mat.set(fdof_id, dof_n->second, 0.5);
1575  }
1576  }
1577  } // end gold mat build
1578  gold_mat.close();
1579 
1580  // calculate relative difference norm between the two projection matrices
1581  Real gold_norm = gold_mat.linfty_norm();
1582  gold_mat.add(-1.0, proj_mat);
1583  Real diff_norm = gold_mat.linfty_norm();
1584  CPPUNIT_ASSERT(diff_norm/gold_norm < TOLERANCE*TOLERANCE);
1585  }
1586 
1587  void testProjectMatrix2D(const ElemType elem_type)
1588  {
1589  // Use ReplicatedMesh to get consistent child element node
1590  // numbering during refinement
1592 
1593  // fix the node numbering to resolve dof_id numbering issues in parallel tests
1594  mesh.allow_renumbering(false);
1595 
1596  // init a simple 1d system
1597  EquationSystems es(mesh);
1598  System &sys = es.add_system<System> ("SimpleSystem");
1599  sys.add_variable("u", FIRST, LAGRANGE);
1600 
1601  if (elem_type == Utility::string_to_enum<ElemType>("QUAD4"))
1603  2, 2,
1604  0., 1., 0., 1.,
1605  elem_type);
1606  else if (elem_type == Utility::string_to_enum<ElemType>("TRI3"))
1608  1, 1,
1609  0., 1., 0., 1.,
1610  elem_type);
1611 
1612  es.init();
1613 
1614  // static sets of nodes and their neighbors
1615  std::set<dof_id_type> coarse_nodes;
1616  std::map<dof_id_type, std::vector<dof_id_type>> side_nbr_nodes;
1617  std::map<dof_id_type, std::vector<dof_id_type>> int_nbr_nodes;
1618 
1619  // fill neighbor maps based on static node numbering
1620  if (elem_type == Utility::string_to_enum<ElemType>("QUAD4"))
1621  {
1622  coarse_nodes.insert({0,1,2,3,4,5,6,7,8});
1623 
1624  side_nbr_nodes.insert({9, {0,1}});
1625  side_nbr_nodes.insert({14, {1,2}});
1626  side_nbr_nodes.insert({11, {0,3}});
1627  side_nbr_nodes.insert({12, {1,4}});
1628  side_nbr_nodes.insert({16, {2,5}});
1629  side_nbr_nodes.insert({13, {3,4}});
1630  side_nbr_nodes.insert({17, {4,5}});
1631  side_nbr_nodes.insert({19, {3,6}});
1632  side_nbr_nodes.insert({20, {4,7}});
1633  side_nbr_nodes.insert({23, {5,8}});
1634  side_nbr_nodes.insert({21, {6,7}});
1635  side_nbr_nodes.insert({24, {7,8}});
1636 
1637  int_nbr_nodes.insert({10, {0,1,3,4}});
1638  int_nbr_nodes.insert({15, {1,2,4,5}});
1639  int_nbr_nodes.insert({18, {3,4,6,7}});
1640  int_nbr_nodes.insert({22, {4,5,7,8}});
1641  }
1642  else if (elem_type == Utility::string_to_enum<ElemType>("TRI3"))
1643  {
1644  coarse_nodes.insert({0,1,2,3});
1645 
1646  side_nbr_nodes.insert({4, {0,1}});
1647  side_nbr_nodes.insert({5, {0,3}});
1648  side_nbr_nodes.insert({6, {1,3}});
1649  side_nbr_nodes.insert({7, {0,2}});
1650  side_nbr_nodes.insert({8, {2,3}});
1651  }
1652 
1653  // stash number of dofs on coarse grid for projection sizing
1654  int n_old_dofs = sys.n_dofs();
1655 
1656  // save old coarse dof_ids in order of coarse nodes
1657  std::map <dof_id_type, dof_id_type> node2dof_c;
1658  for ( const auto & node : mesh.node_ptr_range() )
1659  {
1660  dof_id_type cdof_id = node->dof_number(0,0,0);
1661  node2dof_c.insert( std::pair<dof_id_type,dof_id_type>( node->id() , cdof_id) );
1662  }
1663 
1664  // refine the mesh so we can utilize old_dof_indices for projection_matrix
1665  MeshRefinement mr(mesh);
1666  mr.uniformly_refine(1);
1668 
1669  // fine node to dof map
1670  std::map <dof_id_type, dof_id_type> node2dof_f;
1671  for ( const auto & node : mesh.local_node_ptr_range() )
1672  {
1673  dof_id_type fdof_id = node->dof_number(0,0,0);
1674  node2dof_f.insert( std::pair<dof_id_type,dof_id_type>(node->id() , fdof_id) );
1675  }
1676 
1677  // local and global projection_matrix sizes infos
1678  int n_new_dofs = sys.n_dofs();
1679  int n_new_dofs_local = sys.get_dof_map().n_local_dofs();
1680  int ndofs_old_first = sys.get_dof_map().first_old_dof();
1681  int ndofs_old_end = sys.get_dof_map().end_old_dof();
1682  int n_old_dofs_local = ndofs_old_end - ndofs_old_first;
1683 
1684  // init and compute the projection matrix using GenericProjector
1685  std::unique_ptr<SparseMatrix<Number> > proj_mat_ptr =
1687  SparseMatrix<Number> & proj_mat = *proj_mat_ptr;
1688  proj_mat.init(n_new_dofs, n_old_dofs, n_new_dofs_local, n_old_dofs_local);
1689  sys.projection_matrix(proj_mat);
1690  proj_mat.close();
1691 
1692  // init the gold standard projection matrix
1693  std::unique_ptr<SparseMatrix<Number> > gold_mat_ptr =
1695  SparseMatrix<Number> & gold_mat = *gold_mat_ptr;
1696  gold_mat.init(n_new_dofs, n_old_dofs, n_new_dofs_local, n_old_dofs_local);
1697 
1698  // construct the gold projection matrix using static node numbering as reference info
1699  for ( const auto & node : mesh.local_node_ptr_range() )
1700  {
1701  dof_id_type node_id = node->id();
1702  dof_id_type fdof_id = (node2dof_f.find(node_id))->second;
1703 
1704  if (coarse_nodes.find(node_id) != coarse_nodes.end() )
1705  { // direct inject coarse nodes
1706  if (fdof_id >= gold_mat.row_start() && fdof_id < gold_mat.row_stop())
1707  {
1708  auto cdof_id = node2dof_c.find(node_id);
1709  gold_mat.set(fdof_id, cdof_id->second, 1.0);
1710  }
1711  }
1712  else if ( side_nbr_nodes.find(node_id) != side_nbr_nodes.end() )
1713  { // new side nodes with old_dof neighbor contributions
1714  if (fdof_id >= gold_mat.row_start() && fdof_id < gold_mat.row_stop())
1715  {
1716  auto node_nbrs = side_nbr_nodes.find(node_id);
1717  for (auto nbr : node_nbrs->second)
1718  {
1719  auto nbr_dof = node2dof_c.find(nbr);
1720  gold_mat.set(fdof_id, nbr_dof->second, 0.5);
1721  }
1722  }
1723  }
1724  else
1725  { // new interior nodes with old_dof neighbor contributions
1726  if (fdof_id >= gold_mat.row_start() && fdof_id < gold_mat.row_stop())
1727  {
1728  auto node_nbrs = int_nbr_nodes.find(node_id);
1729  for (auto nbr : node_nbrs->second)
1730  {
1731  auto nbr_dof = node2dof_c.find(nbr);
1732  gold_mat.set(fdof_id, nbr_dof->second, 0.25);
1733  }
1734  }
1735  }
1736  } // end gold mat build
1737  gold_mat.close();
1738 
1739  // calculate relative difference norm between the two projection matrices
1740  Real gold_norm = gold_mat.linfty_norm();
1741  proj_mat.add(-1.0, gold_mat);
1742  Real diff_norm = proj_mat.linfty_norm();
1743  CPPUNIT_ASSERT(diff_norm/gold_norm < TOLERANCE*TOLERANCE);
1744  }
1745 
1746  void testProjectMatrix3D(const ElemType elem_type)
1747  {
1748  // Use ReplicatedMesh to get consistent child element node
1749  // numbering during refinement
1751 
1752  // fix the node numbering to resolve dof_id numbering issues in parallel tests
1753  mesh.allow_renumbering(false);
1754 
1755  // init a simple 1d system
1756  EquationSystems es(mesh);
1757  System &sys = es.add_system<System> ("SimpleSystem");
1758  sys.add_variable("u", FIRST, LAGRANGE);
1759 
1760  if (elem_type == Utility::string_to_enum<ElemType>("HEX8"))
1762  1, 1, 1,
1763  0., 1., 0., 1., 0., 1.,
1764  elem_type);
1765  else if (elem_type == Utility::string_to_enum<ElemType>("TET4"))
1766  {
1767  // manually build a Tet4 element
1768  mesh.add_point( Point(0,0,0), 0 );
1769  mesh.add_point( Point(1,0,0), 1 );
1770  mesh.add_point( Point(0,1,0), 2 );
1771  mesh.add_point( Point(1./3.,1./3.,1), 3 );
1772 
1773  Elem * elem = mesh.add_elem(Elem::build_with_id(TET4, 0));
1774  elem->set_node(0, mesh.node_ptr(0));
1775  elem->set_node(1, mesh.node_ptr(1));
1776  elem->set_node(2, mesh.node_ptr(2));
1777  elem->set_node(3, mesh.node_ptr(3));
1778 
1780  }
1781  es.init();
1782 
1783  // static sets of nodes and their neighbors
1784  std::set<dof_id_type> coarse_nodes;
1785  std::map<dof_id_type, std::vector<dof_id_type>> side_nbr_nodes;
1786  std::map<dof_id_type, std::vector<dof_id_type>> face_nbr_nodes;
1787  std::map<dof_id_type, std::vector<dof_id_type>> int_nbr_nodes;
1788 
1789  if (elem_type == Utility::string_to_enum<ElemType>("HEX8"))
1790  {
1791  coarse_nodes.insert({0,1,2,3,4,5,6,7});
1792 
1793  // fill neighbor maps based on static node numbering
1794  side_nbr_nodes.insert({8, {0,1}});
1795  side_nbr_nodes.insert({10, {0,2}});
1796  side_nbr_nodes.insert({15, {1,3}});
1797  side_nbr_nodes.insert({18, {2,3}});
1798  side_nbr_nodes.insert({11, {0,4}});
1799  side_nbr_nodes.insert({16, {1,5}});
1800  side_nbr_nodes.insert({21, {3,7}});
1801  side_nbr_nodes.insert({20, {2,6}});
1802  side_nbr_nodes.insert({22, {4,5}});
1803  side_nbr_nodes.insert({24, {4,6}});
1804  side_nbr_nodes.insert({25, {5,7}});
1805  side_nbr_nodes.insert({26, {6,7}});
1806 
1807  face_nbr_nodes.insert({12, {0,1,4,5}});
1808  face_nbr_nodes.insert({9 , {0,1,2,3}});
1809  face_nbr_nodes.insert({14, {0,2,4,6}});
1810  face_nbr_nodes.insert({17, {1,3,5,7}});
1811  face_nbr_nodes.insert({19, {2,3,6,7}});
1812  face_nbr_nodes.insert({23, {4,5,6,7}});
1813 
1814  int_nbr_nodes.insert({13, {0,1,2,3,4,5,6,7}});
1815  }
1816  else if (elem_type == Utility::string_to_enum<ElemType>("TET4"))
1817  {
1818  coarse_nodes.insert({0,1,2,3});
1819 
1820  // fill neighbor maps based on static node numbering
1821  side_nbr_nodes.insert({4, {0,1}});
1822  side_nbr_nodes.insert({5, {0,2}});
1823  side_nbr_nodes.insert({6, {0,3}});
1824  side_nbr_nodes.insert({7, {1,2}});
1825  side_nbr_nodes.insert({8, {1,3}});
1826  side_nbr_nodes.insert({9, {2,3}});
1827  }
1828 
1829  // stash number of dofs on coarse grid for projection sizing
1830  int n_old_dofs = sys.n_dofs();
1831 
1832  // save old coarse dof_ids in order of coarse nodes
1833  std::map <dof_id_type, dof_id_type> node2dof_c;
1834  for ( const auto & node : mesh.node_ptr_range() )
1835  {
1836  dof_id_type cdof_id = node->dof_number(0,0,0);
1837  node2dof_c.insert( std::pair<dof_id_type,dof_id_type>( node->id() , cdof_id) );
1838  }
1839 
1840  // refine the mesh so we can utilize old_dof_indices for projection_matrix
1841  MeshRefinement mr(mesh);
1842  mr.uniformly_refine(1);
1844 
1845  // fine node to dof map
1846  std::map <dof_id_type, dof_id_type> node2dof_f;
1847  for ( const auto & node : mesh.local_node_ptr_range() )
1848  {
1849  dof_id_type fdof_id = node->dof_number(0,0,0);
1850  node2dof_f.insert( std::pair<dof_id_type,dof_id_type>(node->id() , fdof_id) );
1851  }
1852 
1853  // local and global projection_matrix sizes infos
1854  int n_new_dofs = sys.n_dofs();
1855  int n_new_dofs_local = sys.get_dof_map().n_dofs_on_processor(sys.processor_id());
1856  int ndofs_old_first = sys.get_dof_map().first_old_dof(sys.processor_id());
1857  int ndofs_old_end = sys.get_dof_map().end_old_dof(sys.processor_id());
1858  int n_old_dofs_local = ndofs_old_end - ndofs_old_first;
1859 
1860  // init and compute the projection matrix using GenericProjector
1861  std::unique_ptr<SparseMatrix<Number> > proj_mat_ptr =
1863  SparseMatrix<Number> & proj_mat = *proj_mat_ptr;
1864  proj_mat.init(n_new_dofs, n_old_dofs, n_new_dofs_local, n_old_dofs_local);
1865  sys.projection_matrix(proj_mat);
1866  proj_mat.close();
1867 
1868  // init the gold standard projection matrix
1869  std::unique_ptr<SparseMatrix<Number> > gold_mat_ptr =
1871  SparseMatrix<Number> & gold_mat = *gold_mat_ptr;
1872  gold_mat.init(n_new_dofs, n_old_dofs, n_new_dofs_local, n_old_dofs_local);
1873 
1874  // construct the gold projection matrix using static node numbering as reference info
1875  for ( const auto & node : mesh.local_node_ptr_range() )
1876  {
1877  dof_id_type node_id = node->id();
1878  dof_id_type fdof_id = (node2dof_f.find(node_id))->second;
1879 
1880  if (coarse_nodes.find(node_id) != coarse_nodes.end() )
1881  { // direct inject coarse nodes
1882  if (fdof_id >= gold_mat.row_start() && fdof_id < gold_mat.row_stop())
1883  {
1884  auto cdof_id = node2dof_c.find(node_id);
1885  gold_mat.set(fdof_id, cdof_id->second, 1.0);
1886  }
1887  }
1888  else if ( side_nbr_nodes.find(node_id) != side_nbr_nodes.end() )
1889  { // new side nodes with old_dof neighbor contributions
1890  if (fdof_id >= gold_mat.row_start() && fdof_id < gold_mat.row_stop())
1891  {
1892  auto node_nbrs = side_nbr_nodes.find(node_id);
1893  for (auto nbr : node_nbrs->second)
1894  {
1895  auto nbr_dof = node2dof_c.find(nbr);
1896  gold_mat.set(fdof_id, nbr_dof->second, 0.5);
1897  }
1898  }
1899  }
1900  else if ( face_nbr_nodes.find(node_id) != face_nbr_nodes.end() )
1901  { // new face nodes with old_dof neighbor contributions
1902  if (fdof_id >= gold_mat.row_start() && fdof_id < gold_mat.row_stop())
1903  {
1904  auto node_nbrs = face_nbr_nodes.find(node_id);
1905  for (auto nbr : node_nbrs->second)
1906  {
1907  auto nbr_dof = node2dof_c.find(nbr);
1908  gold_mat.set(fdof_id, nbr_dof->second, 0.25);
1909  }
1910  }
1911  }
1912  else
1913  { // new interior nodes with old_dof neighbor contributions
1914  if (fdof_id >= gold_mat.row_start() && fdof_id < gold_mat.row_stop())
1915  {
1916  auto node_nbrs = int_nbr_nodes.find(node_id);
1917  for (auto nbr : node_nbrs->second)
1918  {
1919  auto nbr_dof = node2dof_c.find(nbr);
1920  gold_mat.set(fdof_id, nbr_dof->second, 0.125);
1921  }
1922  }
1923  }
1924  } // end gold mat build
1925  gold_mat.close();
1926 
1927  // calculate relative difference norm between the two projection matrices
1928  Real gold_norm = gold_mat.linfty_norm();
1929  proj_mat.add(-1.0, gold_mat);
1930  Real diff_norm = proj_mat.linfty_norm();
1931  CPPUNIT_ASSERT(diff_norm/gold_norm < TOLERANCE*TOLERANCE);
1932  }
1933 #endif // LIBMESH_HAVE_PETSC
1934 #endif // LIBMESH_HAVE_METAPHYSICL
1935 #endif // LIBMESH_ENABLE_AMR
1936 
1937 
1938  void testProjectHierarchicEdge3() { LOG_UNIT_TEST; testProjectLine(EDGE3); }
1939  void testProjectHierarchicQuad9() { LOG_UNIT_TEST; testProjectSquare(QUAD9); }
1940  void testProjectHierarchicTri6() { LOG_UNIT_TEST; testProjectSquare(TRI6); }
1941  void testProjectHierarchicTri7() { LOG_UNIT_TEST; testProjectSquare(TRI7); }
1942  void testProjectHierarchicHex27() { LOG_UNIT_TEST; testProjectCube(HEX27); }
1943  void testProjectMeshFunctionHex27() { LOG_UNIT_TEST; testProjectCubeWithMeshFunction(HEX27); }
1944  void test2DProjectVectorFETri3() { LOG_UNIT_TEST; test2DProjectVectorFE(TRI3); }
1945  void test2DProjectVectorFEQuad4() { LOG_UNIT_TEST; test2DProjectVectorFE(QUAD4); }
1946  void test2DProjectVectorFETri6() { LOG_UNIT_TEST; test2DProjectVectorFE(TRI6); }
1947  void test2DProjectVectorFETri7() { LOG_UNIT_TEST; test2DProjectVectorFE(TRI7); }
1948  void test2DProjectVectorFEQuad8() { LOG_UNIT_TEST; test2DProjectVectorFE(QUAD8); }
1949  void test2DProjectVectorFEQuad9() { LOG_UNIT_TEST; test2DProjectVectorFE(QUAD9); }
1950  void test3DProjectVectorFETet4() { LOG_UNIT_TEST; test3DProjectVectorFE(TET4); }
1951  void test3DProjectVectorFEHex8() { LOG_UNIT_TEST; test3DProjectVectorFE(HEX8); }
1952  void test3DProjectVectorFETet10() { LOG_UNIT_TEST; test3DProjectVectorFE(TET10); }
1953  void test3DProjectVectorFETet14() { LOG_UNIT_TEST; test3DProjectVectorFE(TET14); }
1954  void test3DProjectVectorFEHex20() { LOG_UNIT_TEST; test3DProjectVectorFE(HEX20); }
1955  void test3DProjectVectorFEHex27() { LOG_UNIT_TEST; test3DProjectVectorFE(HEX27); }
1956 
1957 #ifdef LIBMESH_ENABLE_AMR
1958 #ifdef LIBMESH_HAVE_METAPHYSICL
1959 #ifdef LIBMESH_HAVE_PETSC
1960  // projection matrix tests
1961  void testProjectMatrixEdge2() { LOG_UNIT_TEST; testProjectMatrix1D(EDGE2); }
1962  void testProjectMatrixQuad4() { LOG_UNIT_TEST; testProjectMatrix2D(QUAD4); }
1963  void testProjectMatrixTri3() { LOG_UNIT_TEST; testProjectMatrix2D(TRI3); }
1964  void testProjectMatrixHex8() { LOG_UNIT_TEST; testProjectMatrix3D(HEX8); }
1965  void testProjectMatrixTet4() { LOG_UNIT_TEST; testProjectMatrix3D(TET4); }
1966 #endif // LIBMESH_HAVE_PETSC
1967 #endif // LIBMESH_HAVE_METAPHYSICL
1968 #endif // LIBMESH_ENABLE_AMR
1969 
1970 };
1971 
unsigned int add_variables(const std::vector< std::string > &vars, const FEType &type, const std::set< subdomain_id_type > *const active_subdomains=nullptr)
Adds the variables vars to the list of variables for this system.
Definition: system.C:1366
void test3DProjectVectorFETet14()
void test2DProjectVectorFETri7()
static const Order type_to_default_order_map[INVALID_ELEM]
This array maps the integer representation of the ElemType enum to the default approximation order of...
Definition: elem.h:990
Number cubic_test(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition: systems_test.C:356
void local_dof_indices(const unsigned int var, std::set< dof_id_type > &var_indices) const
Fills the std::set with the degrees of freedom on the local processor corresponding the the variable ...
Definition: system.C:1409
void testAddVectorTypeChange()
Definition: systems_test.C:709
ElemType
Defines an enum for geometric element types.
void testProjectMatrixQuad4()
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
This is the EquationSystems class.
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
Definition: dof_object.h:1008
The ReplicatedMesh class is derived from the MeshBase class, and is used to store identical copies of...
const DenseMatrix< Number > & get_elem_jacobian() const
Const accessor for element Jacobian.
Definition: diff_context.h:274
Order
defines an enum for polynomial orders.
Definition: enum_order.h:40
virtual Node *& set_node(const unsigned int i)
Definition: elem.h:2564
A Node is like a Point, but with more information.
Definition: node.h:52
This abstract base class defines the interface by which library code and user code can report associa...
const Variable & variable(unsigned int var) const
Return a constant reference to Variable var.
Definition: system.C:2704
void tripleValueTest(const Point &p, const TransientExplicitSystem &sys, const PointLocatorBase &locator, std::set< subdomain_id_type > &u_subdomains, std::set< subdomain_id_type > &v_subdomains, std::set< subdomain_id_type > &w_subdomains, const Parameters &param)
Definition: systems_test.C:509
void get_side_fe(unsigned int var, FEGenericBase< OutputShape > *&fe) const
Accessor for edge/face (2D/3D) finite element object for variable var for the largest dimension in th...
Definition: fem_context.h:317
virtual void pre_fe_reinit(const System &, const Elem *e)
Reinitializes local data vectors/matrices on the current geometric element.
Definition: fem_context.C:1683
bool has_boundary_id(const Node *const node, const boundary_id_type id) const
std::unique_ptr< PointLocatorBase > sub_point_locator() const
Definition: mesh_base.C:1826
void testProjectHierarchicTri6()
ConstFunction that simply returns 0.
Definition: zero_function.h:38
This class provides the ability to map between arbitrary, user-defined strings and several data types...
Definition: parameters.h:74
MPI_Info info
void allow_renumbering(bool allow)
If false is passed in then this mesh will no longer be renumbered when being prepared for use...
Definition: mesh_base.h:1345
void testUninitializedInfo()
Definition: systems_test.C:666
void neighbor_side_fe_reinit()
Initialize neighbor side data needed to assemble DG terms.
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:218
void test3DProjectVectorFE(const ElemType elem_type)
Definition: systems_test.C:881
The definition of the const_element_iterator struct.
Definition: mesh_base.h:2521
std::size_t distribute_dofs(MeshBase &)
Distribute dofs on the current mesh.
Definition: dof_map.C:949
static constexpr Real TOLERANCE
void local_variable_indices(T &idx, const MeshBase &mesh, unsigned int var_num) const
If T == dof_id_type, counts, if T == std::vector<dof_id_type>, fills an array of, those dof indices w...
Definition: dof_map.C:1122
dof_id_type end_old_dof(const processor_id_type proc) const
Definition: dof_map_base.h:210
void setUp()
Definition: systems_test.C:566
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and linear solvers ...
void testProjectMatrixHex8()
virtual void side_fe_reinit() override
Override side_fe_reinit to set a boolean flag so that by default DG terms are assumed to be inactive...
void resize(const unsigned int n)
Resize the vector.
Definition: dense_vector.h:396
virtual void add_vector(const T *v, const std::vector< numeric_index_type > &dof_indices)
Computes , where v is a pointer and each dof_indices[i] specifies where to add value v[i]...
const std::vector< dof_id_type > & get_neighbor_dof_indices() const
Accessor for neighbor dof indices.
void prepare_for_use(const bool skip_renumber_nodes_and_elements, const bool skip_find_neighbors)
Prepare a newly created (or read) mesh for use.
Definition: mesh_base.C:824
virtual void mesh_reinit() override
Rebuild the cached _lower_to_upper map whenever our Mesh has changed.
Definition: systems_test.C:114
static const unsigned int type_to_dim_map[INVALID_ELEM]
This array maps the integer representation of the ElemType enum to the geometric dimension of the ele...
Definition: elem.h:628
void testAddVectorProjChange()
Definition: systems_test.C:695
void projection_matrix(SparseMatrix< Number > &proj_mat) const
This method creates a projection matrix which corresponds to the operation of project_vector between ...
TripleFunction(Number _offset=0)
Definition: systems_test.C:397
static const unsigned int prev[3]
A lookup table for the decrement modulo 3 operation, for iterating through the three nodes per elemen...
virtual std::unique_ptr< FunctionBase< Number > > clone() const
Definition: systems_test.C:399
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
MeshBase & mesh
Number point_value(unsigned int var, const Point &p, const bool insist_on_success=true, const NumericVector< Number > *sol=nullptr) const
Definition: system.C:2219
NumericVector< Number > * rhs
The system matrix.
void testSetSystemParameterOverEquationSystem()
const Parallel::Communicator & comm() const
Manages storage and variables for transient systems.
NumericVector< Number > & add_vector(std::string_view vec_name, const bool projections=true, const ParallelType type=PARALLEL)
Adds the additional vector vec_name to this system.
Definition: system.C:756
void get_all_variable_numbers(std::vector< unsigned int > &all_variable_numbers) const
Fills all_variable_numbers with all the variable numbers for the variables that have been added to th...
Definition: system.C:1403
Number disc_thirds_test(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition: systems_test.C:382
void build_square(UnstructuredMesh &mesh, const unsigned int nx, const unsigned int ny, const Real xmin=0., const Real xmax=1., const Real ymin=0., const Real ymax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
A specialized build_cube() for 2D meshes.
void boundary_ids(const Node *node, std::vector< boundary_id_type > &vec_to_fill) const
Fills a user-provided std::vector with the boundary ids associated with Node node.
std::map< const Elem *, const CouplingMatrix *, CompareDofObjectsByPIDAndThenID > map_type
What elements do we care about and what variables do we care about on each element?
dof_id_type n_dofs(const unsigned int vn) const
Definition: dof_map.h:776
void test2DProjectVectorFEQuad8()
virtual LinearSolver< Number > * get_linear_solver() const override
const DenseMatrix< Number > & get_neighbor_neighbor_jacobian() const
Const accessor for element-neighbor Jacobian.
The libMesh namespace provides an interface to certain functionality in the library.
void test2DProjectVectorFEQuad9()
dof_id_type n_local_dofs(const unsigned int vn) const
Definition: dof_map.h:794
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
Definition: mesh_base.h:170
void test2DProjectVectorFEQuad4()
virtual void solve() override
Assembles & solves the linear system A*x=b.
const T_sys & get_system(std::string_view name) const
void test3DProjectVectorFETet10()
CPPUNIT_TEST_SUITE_REGISTRATION(SystemsTest)
unsigned char get_side() const
Accessor for current side of Elem object.
Definition: fem_context.h:922
void test100KVariables()
Definition: systems_test.C:629
void testProjectMatrix3D(const ElemType elem_type)
void add_coupling_functor(GhostingFunctor &coupling_functor, bool to_mesh=true)
Adds a functor which can specify coupling requirements for creation of sparse matrices.
Definition: dof_map.C:2005
virtual Node * add_point(const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id)=0
Add a new Node at Point p to the end of the vertex array, with processor_id procid.
static std::unique_ptr< SparseMatrix< T > > build(const Parallel::Communicator &comm, const SolverPackage solver_package=libMesh::default_solver_package(), const MatrixBuildType matrix_build_type=MatrixBuildType::AUTOMATIC)
Builds a SparseMatrix<T> using the linear solver package specified by solver_package.
void testPostInitAddVectorTypeChange()
Definition: systems_test.C:737
NumericVector< Number > * old_local_solution
All the values I need to compute my contribution to the simulation at hand.
dof_id_type n_dofs() const
Definition: system.C:118
void test2DProjectVectorFETri3()
This is the MeshBase class.
Definition: mesh_base.h:80
virtual numeric_index_type row_stop() const =0
void assemble_matrix_and_rhs(EquationSystems &es, const std::string &)
Definition: systems_test.C:128
virtual void set(const numeric_index_type i, const numeric_index_type j, const T value)=0
Set the element (i,j) to value.
virtual void elem_fe_reinit(const std::vector< Point > *const pts=nullptr)
Reinitializes interior FE objects on the current geometric element.
Definition: fem_context.C:1476
unsigned int variable_number(std::string_view var) const
Definition: system.C:1398
virtual void add(const numeric_index_type i, const numeric_index_type j, const T value)=0
Add value to the element (i,j).
This class handles the numbering of degrees of freedom on a mesh.
Definition: dof_map.h:179
NumericVector< Number > * older_local_solution
All the values I need to compute my contribution to the simulation at hand.
processor_id_type size() const
void tearDown()
Definition: systems_test.C:569
const std::vector< std::vector< OutputGradient > > & get_dphi() const
Definition: fe_base.h:230
uint8_t processor_id_type
void add_node(const Node *node, const boundary_id_type id)
Add Node node with boundary id id to the boundary information data structures.
unsigned int number() const
Definition: system.h:2393
virtual void add_matrix(const DenseMatrix< T > &dm, const std::vector< numeric_index_type > &rows, const std::vector< numeric_index_type > &cols)=0
Add the full matrix dm to the SparseMatrix.
void testBlockRestrictedVarNDofs()
void get_neighbor_side_fe(unsigned int var, FEGenericBase< OutputShape > *&fe) const
Accessor for neighbor edge/face (2D/3D) finite element object for variable var.
Implements (adaptive) mesh refinement algorithms for a MeshBase.
void set_neighbor(const Elem &neighbor)
Set the neighbor element which we will use to assemble DG terms.
int8_t boundary_id_type
Definition: id_types.h:51
The UnstructuredMesh class is derived from the MeshBase class.
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition: system.h:98
virtual Elem * add_elem(Elem *e)=0
Add elem e to the end of the element array.
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
Definition: elem.C:442
void testProjectMatrixTri3()
virtual void reinit()
Handle any mesh changes and reinitialize all the systems on the updated mesh.
void test3DProjectVectorFEHex20()
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
Definition: simple_range.h:57
void test2DProjectVectorFETri6()
Number new_linear_test(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition: systems_test.C:369
void testProjectHierarchicEdge3()
void set_preconditioner_type(const PreconditionerType pct)
Sets the type of preconditioner to use.
std::string get_info() const
Definition: system.C:1827
AugmentSparsityOnNodes(MeshBase &mesh)
Constructor.
Definition: systems_test.C:60
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition: system.h:1655
This class extends FEMContext in order to provide extra data required to perform local element residu...
virtual void init() override
Override the FunctionBase::init() member function.
virtual_for_inffe const std::vector< Real > & get_JxW() const
Definition: fe_abstract.h:303
const std::vector< dof_id_type > & get_dof_indices() const
Accessor for element dof indices.
Definition: diff_context.h:363
unsigned int add_variable(std::string_view var, const FEType &type, const std::set< subdomain_id_type > *const active_subdomains=nullptr)
Adds the variable var to the list of variables for this system.
Definition: system.C:1344
void testProjectSquare(const ElemType elem_type)
Definition: systems_test.C:931
unsigned int n_points() const
Definition: quadrature.h:131
void testProjectMatrixTet4()
This is the base class for point locators.
void set_solver_type(const SolverType st)
Sets the type of solver to use.
void attach_assemble_function(void fptr(EquationSystems &es, const std::string &name))
Register a user function to use in assembling the system matrix and RHS.
Definition: system.C:1959
dof_id_type n_dofs_on_processor(const processor_id_type proc) const
Definition: dof_map_base.h:197
void project_solution(FunctionBase< Number > *f, FunctionBase< Gradient > *g=nullptr, std::optional< ConstElemRange > active_local_range=std::nullopt, std::optional< std::vector< unsigned int >> variable_numbers=std::nullopt) const
Projects arbitrary functions onto the current solution.
void testProjectMatrix1D(const ElemType elem_type)
const DenseMatrix< Number > & get_elem_neighbor_jacobian() const
Const accessor for element-neighbor Jacobian.
void test2DProjectVectorFE(const ElemType elem_type)
Definition: systems_test.C:831
virtual void solve()
Solves the system.
Definition: system.h:349
virtual void close()=0
Calls the NumericVector&#39;s internal assembly routines, ensuring that the values are consistent across ...
void boundary_project_solution(const std::set< boundary_id_type > &b, const std::vector< unsigned int > &variables, FunctionBase< Number > *f, FunctionBase< Gradient > *g=nullptr, std::optional< ConstElemRange > active_local_range=std::nullopt)
Projects arbitrary boundary functions onto a vector of degree of freedom values for the current syste...
void testProjectCube(const ElemType elem_type)
Definition: systems_test.C:987
virtual void redistribute() override
Update the cached _lower_to_upper map whenever our Mesh has been redistributed.
Definition: systems_test.C:122
void testBoundaryProjectCube()
virtual const Elem * elem_ptr(const dof_id_type i) const =0
void test3DProjectVectorFEHex8()
const DenseMatrix< Number > & get_neighbor_elem_jacobian() const
Const accessor for element-neighbor Jacobian.
const Elem * neighbor_ptr(unsigned int i) const
Definition: elem.h:2612
static const unsigned int next[3]
A lookup table for the increment modulo 3 operation, for iterating through the three nodes per elemen...
const DenseVector< Number > & get_elem_residual() const
Const accessor for element residual.
Definition: diff_context.h:242
virtual void close()=0
Calls the SparseMatrix&#39;s internal assembly routines, ensuring that the values are consistent across p...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
subdomain_id_type subdomain_id() const
Definition: elem.h:2588
void testFirstScalarNumber()
Definition: systems_test.C:590
MeshBase & _mesh
The Mesh we&#39;re calculating on.
Definition: systems_test.C:53
unsigned char side
Current side for side_* to examine.
Definition: fem_context.h:1013
void max(const T &r, T &o, Request &req) const
virtual numeric_index_type row_start() const =0
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:2513
void testDofCouplingWithVarGroups()
T & set(const std::string &)
Definition: parameters.h:494
static std::unique_ptr< Elem > build_with_id(const ElemType type, dof_id_type id)
Calls the build() method above with a nullptr parent, and additionally sets the newly-created Elem&#39;s ...
Definition: elem.C:556
const MeshBase & get_mesh() const
static const bool value
Definition: xdr_io.C:55
virtual const Elem & elem_ref(const dof_id_type i) const
Definition: mesh_base.h:778
void resize(const unsigned int new_m, const unsigned int new_n)
Resizes the matrix to the specified size and calls zero().
Definition: dense_matrix.h:895
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 test3DProjectVectorFEHex27()
ExplicitSystem & simpleSetup(UnstructuredMesh &mesh, EquationSystems &es)
Definition: systems_test.C:573
static std::unique_ptr< NumericVector< T > > build(const Parallel::Communicator &comm, SolverPackage solver_package=libMesh::default_solver_package(), ParallelType parallel_type=AUTOMATIC)
Builds a NumericVector on the processors in communicator comm using the linear solver package specifi...
Parameters parameters
Data structure holding arbitrary parameters.
virtual unsigned int size() const override final
Definition: dense_vector.h:104
void build_line(UnstructuredMesh &mesh, const unsigned int nx, const Real xmin=0., const Real xmax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
A specialized build_cube() for 1D meshes.
void get_element_fe(unsigned int var, FEGenericBase< OutputShape > *&fe) const
Accessor for interior finite element object for variable var for the largest dimension in the mesh...
Definition: fem_context.h:277
virtual Real linfty_norm() const =0
virtual const Node & node_ref(const dof_id_type i) const
Definition: mesh_base.h:735
void testProjectHierarchicTri7()
const DenseMatrix< Number > & get_elem_elem_jacobian() const
Const accessor for element-element Jacobian.
virtual std::unique_ptr< GhostingFunctor > clone() const override
A clone() is needed because GhostingFunctor can not be shared between different meshes.
Definition: systems_test.C:65
virtual void init()
Initialize all the systems.
dof_id_type first_old_dof(const processor_id_type proc) const
Definition: dof_map_base.h:204
This class provides function-like objects for data distributed over a mesh.
Definition: mesh_function.h:54
void testAssemblyWithDgFemContext()
FEFamily
defines an enum for finite element families.
void testProjectMatrix2D(const ElemType elem_type)
unsigned int n_vars() const
Definition: system.C:2674
void testProjectMeshFunctionHex27()
virtual System & add_system(std::string_view system_type, std::string_view name)
Add the system of type system_type named name to the systems array.
virtual const Node * node_ptr(const dof_id_type i) const =0
void testProjectMatrixEdge2()
Base class for functors that can be evaluated at a point and (optionally) time.
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition: mesh.h:50
processor_id_type processor_id() const
void testProjectHierarchicHex27()
bool vector_preservation(std::string_view vec_name) const
Definition: system.C:1135
void testProjectLine(const ElemType elem_type)
Definition: systems_test.C:777
const DofMap & get_dof_map() const
Definition: system.h:2417
processor_id_type processor_id() const
Definition: dof_object.h:881
virtual ElemType type() const =0
Number component(unsigned int i, const Point &p, Real) override
Definition: systems_test.C:420
void assembly_with_dg_fem_context(EquationSystems &es, const std::string &)
Definition: systems_test.C:208
void testProjectCubeWithMeshFunction(const ElemType elem_type)
void testPostInitAddVector()
Definition: systems_test.C:678
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
void test3DProjectVectorFETet4()
const SparseMatrix< Number > & get_system_matrix() const
std::vector< dof_id_type > n_dofs_per_processor(const unsigned int vn) const
Definition: dof_map.h:805
void build_cube(UnstructuredMesh &mesh, const unsigned int nx=0, const unsigned int ny=0, const unsigned int nz=0, const Real xmin=0., const Real xmax=1., const Real ymin=0., const Real ymax=1., const Real zmin=0., const Real zmax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
Builds a (elements) cube.
virtual dof_id_type n_nodes() const =0
This class forms the foundation from which generic finite elements may be derived.
const QBase & get_element_qrule() const
Accessor for element interior quadrature rule for the dimension of the current _elem.
Definition: fem_context.h:802
Manages consistently variables, degrees of freedom, and coefficient vectors for explicit systems...
const QBase & get_side_qrule() const
Accessor for element side quadrature rule for the dimension of the current _elem. ...
Definition: fem_context.h:809
uint8_t dof_id_type
Definition: id_types.h:67
void testProjectHierarchicQuad9()
void add_edge(const dof_id_type elem, const unsigned short int edge, const boundary_id_type id)
Add edge edge of element number elem with boundary id id to the boundary information data structure...
const std::vector< std::vector< OutputShape > > & get_phi() const
Definition: fe_base.h:207
virtual void init(const numeric_index_type m, const numeric_index_type n, const numeric_index_type m_l, const numeric_index_type n_l, const numeric_index_type nnz=30, const numeric_index_type noz=10, const numeric_index_type blocksize=1)=0
Initialize SparseMatrix with the specified sizes.
void uniformly_refine(unsigned int n=1)
Uniformly refines the mesh n times.
This class defines a coupling matrix.
void set_union(T &data, const unsigned int root_id) const