libMesh
systems_test.C
Go to the documentation of this file.
1 #include <libmesh/equation_systems.h>
2 #include <libmesh/mesh.h>
3 #include <libmesh/node.h>
4 #include <libmesh/dof_map.h>
5 #include <libmesh/mesh_generation.h>
6 #include <libmesh/replicated_mesh.h>
7 #include <libmesh/mesh_function.h>
8 #include <libmesh/numeric_vector.h>
9 #include <libmesh/mesh_refinement.h>
10 #include <libmesh/sparse_matrix.h>
11 #include "libmesh/string_to_enum.h"
12 #include <libmesh/cell_tet4.h>
13 #include <libmesh/zero_function.h>
14 #include <libmesh/linear_implicit_system.h>
15 #include <libmesh/transient_system.h>
16 #include <libmesh/quadrature_gauss.h>
17 #include <libmesh/node_elem.h>
18 #include <libmesh/edge_edge2.h>
19 #include <libmesh/dg_fem_context.h>
20 #include <libmesh/enum_solver_type.h>
21 #include <libmesh/enum_preconditioner_type.h>
22 #include <libmesh/linear_solver.h>
23 #include <libmesh/parallel.h>
24 
25 #include "test_comm.h"
26 #include "libmesh_cppunit.h"
27 
28 
29 using namespace libMesh;
30 
31 // Sparsity pattern augmentation class used in testDofCouplingWithVarGroups
33 {
34 private:
35 
40 
41 public:
42 
47  :
48  _mesh(mesh)
49  {}
50 
54  virtual void operator() (const MeshBase::const_element_iterator & range_begin,
55  const MeshBase::const_element_iterator & range_end,
57  map_type & coupled_elements) override
58  {
59  dof_id_type node_elem_id_1 = 2;
60  dof_id_type node_elem_id_2 = 3;
61 
62  const CouplingMatrix * const null_mat = nullptr;
63 
64  for (const auto & elem : as_range(range_begin, range_end))
65  {
66  if (elem->id() == node_elem_id_1)
67  {
68  if (elem->processor_id() != p)
69  {
70  coupled_elements.insert (std::make_pair(elem, null_mat));
71 
72  const Elem * neighbor = _mesh.elem_ptr(node_elem_id_2);
73  if (neighbor->processor_id() != p)
74  coupled_elements.insert (std::make_pair(neighbor, null_mat));
75  }
76  }
77  if (elem->id() == node_elem_id_2)
78  {
79  if (elem->processor_id() != p)
80  {
81  coupled_elements.insert (std::make_pair(elem, null_mat));
82 
83  const Elem * neighbor = _mesh.elem_ptr(node_elem_id_1);
84  if (neighbor->processor_id() != p)
85  coupled_elements.insert (std::make_pair(neighbor, null_mat));
86  }
87  }
88  }
89  }
90 
95  virtual void mesh_reinit () override
96  {
97  }
98 
103  virtual void redistribute () override
104  { this->mesh_reinit(); }
105 
106 };
107 
108 // Assembly function used in testDofCouplingWithVarGroups
110  const std::string& system_name)
111 {
112  const MeshBase& mesh = es.get_mesh();
114  const DofMap& dof_map = system.get_dof_map();
115 
118 
119  std::vector<dof_id_type> dof_indices;
120 
123 
124  for ( ; el != end_el; ++el)
125  {
126  const Elem* elem = *el;
127 
128  if(elem->type() == NODEELEM)
129  {
130  continue;
131  }
132 
133  dof_map.dof_indices (elem, dof_indices);
134  const unsigned int n_dofs = dof_indices.size();
135 
136  Ke.resize (n_dofs, n_dofs);
137  Fe.resize (n_dofs);
138 
139  for(unsigned int i=0; i<n_dofs; i++)
140  {
141  Ke(i,i) = 1.;
142  Fe(i) = 1.;
143  }
144 
145  system.matrix->add_matrix (Ke, dof_indices);
146  system.rhs->add_vector (Fe, dof_indices);
147  }
148 
149  // Add matrix for extra coupled dofs
150  {
151  const Node & node_1 = mesh.node_ref(1);
152  const Node & node_2 = mesh.node_ref(2);
153  dof_indices.resize(6);
154  dof_indices[0] =
155  node_1.dof_number(system.number(), system.variable_number("u"), 0);
156  dof_indices[1] =
157  node_1.dof_number(system.number(), system.variable_number("v"), 0);
158  dof_indices[2] =
159  node_1.dof_number(system.number(), system.variable_number("w"), 0);
160 
161  dof_indices[3] =
162  node_2.dof_number(system.number(), system.variable_number("u"), 0);
163  dof_indices[4] =
164  node_2.dof_number(system.number(), system.variable_number("v"), 0);
165  dof_indices[5] =
166  node_2.dof_number(system.number(), system.variable_number("w"), 0);
167 
168  const unsigned int n_dofs = dof_indices.size();
169  Ke.resize (n_dofs, n_dofs);
170  Fe.resize (n_dofs);
171 
172  for(unsigned int i=0; i<n_dofs; i++)
173  {
174  Ke(i,i) = 1.;
175  Fe(i) = 1.;
176  }
177 
178  system.matrix->add_matrix (Ke, dof_indices);
179  system.rhs->add_vector (Fe, dof_indices);
180  }
181 
182  system.rhs->close();
183  system.matrix->close();
184 }
185 
186 // Assembly function that uses a DGFEMContext
188  const std::string& /*system_name*/)
189 {
190  const MeshBase& mesh = es.get_mesh();
192 
195 
196  std::vector<dof_id_type> dof_indices;
197 
198  DGFEMContext context(system);
199  {
200  // For efficiency, we should prerequest all
201  // the data we will need to build the
202  // linear system before doing an element loop.
203  FEBase* elem_fe = NULL;
204  context.get_element_fe(0, elem_fe);
205  elem_fe->get_JxW();
206  elem_fe->get_phi();
207  elem_fe->get_dphi();
208 
209  FEBase* side_fe = NULL;
210  context.get_side_fe( 0, side_fe );
211  side_fe->get_JxW();
212  side_fe->get_phi();
213  }
214 
215  for (const auto & elem : mesh.active_local_element_ptr_range())
216  {
217  context.pre_fe_reinit(system, elem);
218  context.elem_fe_reinit();
219 
220  // Element interior assembly
221  {
222  FEBase* elem_fe = NULL;
223  context.get_element_fe(0, elem_fe);
224 
225  const std::vector<Real> &JxW = elem_fe->get_JxW();
226  const std::vector<std::vector<Real> >& phi = elem_fe->get_phi();
227  const std::vector<std::vector<RealGradient> >& dphi = elem_fe->get_dphi();
228 
229  unsigned int n_dofs = context.get_dof_indices(0).size();
230  unsigned int n_qpoints = context.get_element_qrule().n_points();
231 
232  for (unsigned int qp=0; qp != n_qpoints; qp++)
233  for (unsigned int i=0; i != n_dofs; i++)
234  for (unsigned int j=0; j != n_dofs; j++)
235  context.get_elem_jacobian()(i,j) += JxW[qp] * dphi[i][qp]*dphi[j][qp];
236 
237  for (unsigned int qp=0; qp != n_qpoints; qp++)
238  for (unsigned int i=0; i != n_dofs; i++)
239  context.get_elem_residual()(i) += JxW[qp] * phi[i][qp];
240  }
241 
242  system.matrix->add_matrix (context.get_elem_jacobian(), context.get_dof_indices());
243  system.rhs->add_vector (context.get_elem_residual(), context.get_dof_indices());
244 
245  // Element side assembly
246  for (context.side = 0; context.side != elem->n_sides(); ++context.side)
247  {
248  // If there is a neighbor, then we proceed with assembly
249  // that involves elem and neighbor
250  const Elem* neighbor = elem->neighbor_ptr(context.get_side());
251  if(neighbor)
252  {
253  context.side_fe_reinit();
254  context.set_neighbor(*neighbor);
255 
256  // This call initializes neighbor data, and also sets
257  // context.dg_terms_are_active() to true
258  context.neighbor_side_fe_reinit();
259 
260  FEBase* side_fe = NULL;
261  context.get_side_fe(0, side_fe);
262 
263  const std::vector<Real> &JxW_face = side_fe->get_JxW();
264  const std::vector<std::vector<Real> >& phi_face = side_fe->get_phi();
265 
266  FEBase* neighbor_side_fe = NULL;
267  context.get_neighbor_side_fe(0, neighbor_side_fe);
268 
269  // These shape functions have been evaluated on the quadrature points
270  // for elem->side on the neighbor element
271  const std::vector<std::vector<Real> >& phi_neighbor_face =
272  neighbor_side_fe->get_phi();
273 
274  const unsigned int n_dofs = context.get_dof_indices(0).size();
275  const unsigned int n_neighbor_dofs = context.get_neighbor_dof_indices(0).size();
276  unsigned int n_sidepoints = context.get_side_qrule().n_points();
277 
278  for (unsigned int qp=0; qp<n_sidepoints; qp++)
279  {
280  for (unsigned int i=0; i<n_dofs; i++)
281  for (unsigned int j=0; j<n_dofs; j++)
282  {
283  context.get_elem_elem_jacobian()(i,j) +=
284  JxW_face[qp] * phi_face[i][qp] * phi_face[j][qp];
285  }
286 
287  for (unsigned int i=0; i<n_dofs; i++)
288  for (unsigned int j=0; j<n_neighbor_dofs; j++)
289  {
290  context.get_elem_neighbor_jacobian()(i,j) +=
291  JxW_face[qp] * phi_face[i][qp] * phi_neighbor_face[j][qp];
292  }
293 
294  for (unsigned int i=0; i<n_neighbor_dofs; i++)
295  for (unsigned int j=0; j<n_neighbor_dofs; j++)
296  {
297  context.get_neighbor_neighbor_jacobian()(i,j) +=
298  JxW_face[qp] * phi_neighbor_face[i][qp] * phi_neighbor_face[j][qp];
299  }
300 
301  for (unsigned int i=0; i<n_neighbor_dofs; i++)
302  for (unsigned int j=0; j<n_dofs; j++)
303  {
304  context.get_neighbor_elem_jacobian()(i,j) +=
305  JxW_face[qp] * phi_neighbor_face[i][qp] * phi_face[j][qp];
306  }
307  }
308 
309  system.matrix->add_matrix (context.get_elem_elem_jacobian(),
310  context.get_dof_indices(),
311  context.get_dof_indices());
312 
313  system.matrix->add_matrix (context.get_elem_neighbor_jacobian(),
314  context.get_dof_indices(),
315  context.get_neighbor_dof_indices());
316 
317  system.matrix->add_matrix (context.get_neighbor_elem_jacobian(),
318  context.get_neighbor_dof_indices(),
319  context.get_dof_indices());
320 
322  context.get_neighbor_dof_indices(),
323  context.get_neighbor_dof_indices());
324  }
325  }
326  }
327 }
328 
329 
331  const Parameters&,
332  const std::string&,
333  const std::string&)
334 {
335  const Real & x = p(0);
336  const Real & y = LIBMESH_DIM > 1 ? p(1) : 0;
337  const Real & z = LIBMESH_DIM > 2 ? p(2) : 0;
338 
339  return x*(1-x)*(1-x) + x*x*(1-y) + x*(1-y)*(1-z) + y*(1-y)*z + z*(1-z)*(1-z);
340 }
341 
342 
344  const Parameters&,
345  const std::string&,
346  const std::string&)
347 {
348  const Real & x = p(0);
349  const Real & y = LIBMESH_DIM > 1 ? p(1) : 0;
350  const Real & z = LIBMESH_DIM > 2 ? p(2) : 0;
351 
352  return x + 2*y + 3*z - 1;
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 (3*x < 1) + (3*y < 2) + (3*z > 2);
366 }
367 
368 
369 struct TripleFunction : public FunctionBase<Number>
370 {
371  TripleFunction(Number _offset = 0) : offset(_offset) {}
372 
373  virtual std::unique_ptr<FunctionBase<Number>> clone () const
374  { return libmesh_make_unique<TripleFunction>(offset); }
375 
376  // We only really need the vector-valued output for projections
377  virtual Number operator() (const Point &,
378  const Real /*time*/ = 0.) override
379  { libmesh_error(); }
380 
381  virtual void operator() (const Point & p,
382  const Real time,
383  DenseVector<Number> & output) override
384  {
385  libmesh_assert_greater(output.size(), 0);
386  Parameters params;
387  output(0) = cubic_test(p, params, "", "") + offset;
388  if (output.size() > 0)
389  output(1) = new_linear_test(p, params, "", "") + offset;
390  if (output.size() > 1)
391  output(2) = disc_thirds_test(p, params, "", "") + offset;
392  }
393 
394  Number component (unsigned int i,
395  const Point & p,
396  Real /* time */) override
397  {
398  Parameters params;
399  switch (i) {
400  case 0:
401  return cubic_test(p, params, "", "") + offset;
402  case 1:
403  return new_linear_test(p, params, "", "") + offset;
404  case 2:
405  return disc_thirds_test(p, params, "", "") + offset;
406  default:
407  libmesh_error();
408  }
409  return 0;
410  }
411 
413 };
414 
415 
416 class SystemsTest : public CppUnit::TestCase {
417 public:
418  CPPUNIT_TEST_SUITE( SystemsTest );
419 
420  CPPUNIT_TEST( testProjectHierarchicEdge3 );
421 #if LIBMESH_DIM > 1
422  CPPUNIT_TEST( testProjectHierarchicQuad9 );
423  CPPUNIT_TEST( testProjectHierarchicTri6 );
424 #ifdef LIBMESH_HAVE_SOLVER
425  CPPUNIT_TEST( testBlockRestrictedVarNDofs );
426 #endif
427 #endif // LIBMESH_DIM > 1
428 #if LIBMESH_DIM > 2
429  CPPUNIT_TEST( testProjectHierarchicHex27 );
430  CPPUNIT_TEST( testProjectMeshFunctionHex27 );
431  CPPUNIT_TEST( testBoundaryProjectCube );
432 #ifdef LIBMESH_HAVE_SOLVER
433  CPPUNIT_TEST( testAssemblyWithDgFemContext );
434 #endif
435 #endif // LIBMESH_DIM > 2
436 #ifdef LIBMESH_HAVE_SOLVER
437  CPPUNIT_TEST( testDofCouplingWithVarGroups );
438 #endif
439 
440 #ifdef LIBMESH_ENABLE_AMR
441 #ifdef LIBMESH_HAVE_METAPHYSICL
442 #ifdef LIBMESH_HAVE_PETSC
443  CPPUNIT_TEST( testProjectMatrixEdge2 );
444 #if LIBMESH_DIM > 1
445  CPPUNIT_TEST( testProjectMatrixQuad4 );
446  CPPUNIT_TEST( testProjectMatrixTri3 );
447 #endif // LIBMESH_DIM > 1
448 #if LIBMESH_DIM > 2
449  CPPUNIT_TEST( testProjectMatrixHex8 );
450  CPPUNIT_TEST( testProjectMatrixTet4 );
451 #endif // LIBMESH_DIM > 2
452 #endif // LIBMESH_HAVE_PETSC
453 #endif // LIBMESH_HAVE_METAPHYSICL
454 #endif // LIBMESH_ENABLE_AMR
455 
456  CPPUNIT_TEST_SUITE_END();
457 
458 private:
459  void tripleValueTest (const Point & p,
460  const TransientExplicitSystem & sys,
461  const PointLocatorBase & locator,
462  std::set<subdomain_id_type> & u_subdomains,
463  std::set<subdomain_id_type> & v_subdomains,
464  std::set<subdomain_id_type> & w_subdomains,
465  const Parameters & param)
466  {
467  const Elem * elem = locator(p);
468  subdomain_id_type sbd_id = elem ? elem->subdomain_id() : 0;
469  TestCommWorld->max(sbd_id);
470 
471  if (u_subdomains.count(sbd_id))
472  {
473  LIBMESH_ASSERT_FP_EQUAL(libmesh_real(sys.point_value(0,p)),
474  libmesh_real(cubic_test(p,param,"","")),
475  TOLERANCE*TOLERANCE*10);
476  LIBMESH_ASSERT_FP_EQUAL(libmesh_real(sys.point_value(0,p,sys.old_local_solution.get())),
477  libmesh_real(cubic_test(p,param,"","") + Number(10)),
478  TOLERANCE*TOLERANCE*100);
479  LIBMESH_ASSERT_FP_EQUAL(libmesh_real(sys.point_value(0,p,sys.older_local_solution.get())),
480  libmesh_real(cubic_test(p,param,"","") + Number(20)),
481  TOLERANCE*TOLERANCE*100);
482  }
483  if (v_subdomains.count(sbd_id))
484  {
485  LIBMESH_ASSERT_FP_EQUAL(libmesh_real(sys.point_value(1,p)),
486  libmesh_real(new_linear_test(p,param,"","")),
487  TOLERANCE*TOLERANCE*10);
488  LIBMESH_ASSERT_FP_EQUAL(libmesh_real(sys.point_value(1,p,sys.old_local_solution.get())),
489  libmesh_real(new_linear_test(p,param,"","") + Number(10)),
490  TOLERANCE*TOLERANCE*100);
491  LIBMESH_ASSERT_FP_EQUAL(libmesh_real(sys.point_value(1,p,sys.older_local_solution.get())),
492  libmesh_real(new_linear_test(p,param,"","") + Number(20)),
493  TOLERANCE*TOLERANCE*100);
494  }
495  if (w_subdomains.count(sbd_id))
496  {
497  LIBMESH_ASSERT_FP_EQUAL(libmesh_real(sys.point_value(2,p)),
498  libmesh_real(disc_thirds_test(p,param,"","")),
499  TOLERANCE*TOLERANCE*10);
500  LIBMESH_ASSERT_FP_EQUAL(libmesh_real(sys.point_value(2,p,sys.old_local_solution.get())),
501  libmesh_real(disc_thirds_test(p,param,"","") + Number(10)),
502  TOLERANCE*TOLERANCE*100);
503  LIBMESH_ASSERT_FP_EQUAL(libmesh_real(sys.point_value(2,p,sys.older_local_solution.get())),
504  libmesh_real(disc_thirds_test(p,param,"","") + Number(20)),
505  TOLERANCE*TOLERANCE*100);
506  }
507  }
508 
509 public:
510  void setUp()
511  {}
512 
513  void tearDown()
514  {}
515 
516  void testProjectLine(const ElemType elem_type)
517  {
519 
520  EquationSystems es(mesh);
522  es.add_system<TransientExplicitSystem> ("SimpleSystem");
523 
524  std::set<subdomain_id_type> u_subdomains {0, 1, 4, 5},
525  v_subdomains {1, 2, 3, 4},
526  w_subdomains {0, 1, 2, 3, 4};
527 
528  sys.add_variable("u", THIRD, HIERARCHIC, &u_subdomains);
529  sys.add_variable("v", FIRST, LAGRANGE, &v_subdomains);
530  sys.add_variable("w", CONSTANT, MONOMIAL, &w_subdomains);
531 
533  6,
534  0., 1.,
535  elem_type);
536 
537  for (auto & elem : mesh.element_ptr_range())
538  elem->subdomain_id() = elem->id();
539 
540  es.init();
541  TripleFunction tfunc;
542  sys.project_solution(&tfunc);
543  tfunc.offset = 10;
544  sys.project_vector(*sys.old_local_solution, &tfunc);
545  tfunc.offset = 20;
546  sys.project_vector(*sys.older_local_solution, &tfunc);
547 
548  std::unique_ptr<PointLocatorBase> locator = mesh.sub_point_locator();
549  locator->enable_out_of_mesh_mode();
550  for (Real x = 0.1; x < 1; x += 0.2)
551  tripleValueTest(Point(x), sys, *locator,
552  u_subdomains, v_subdomains, w_subdomains,
553  es.parameters);
554 
555 #ifdef LIBMESH_ENABLE_AMR
556  for (auto & elem : mesh.element_ptr_range())
557  if ((elem->id()/2)%2)
558  elem->set_refinement_flag(Elem::REFINE);
559  es.reinit();
560 
561  locator = mesh.sub_point_locator();
562  locator->enable_out_of_mesh_mode();
563  for (Real x = 0.1; x < 1; x += 0.2)
564  tripleValueTest(Point(x), sys, *locator,
565  u_subdomains, v_subdomains, w_subdomains,
566  es.parameters);
567 #endif
568  }
569 
570  void testProjectSquare(const ElemType elem_type)
571  {
573 
574  EquationSystems es(mesh);
576  es.add_system<TransientExplicitSystem> ("SimpleSystem");
577 
578  std::set<subdomain_id_type> u_subdomains {0, 1, 4, 5},
579  v_subdomains {1, 2, 3, 4},
580  w_subdomains {0, 1, 2, 3, 4};
581 
582  sys.add_variable("u", THIRD, HIERARCHIC, &u_subdomains);
583  sys.add_variable("v", FIRST, LAGRANGE, &v_subdomains);
584  sys.add_variable("w", CONSTANT, MONOMIAL, &w_subdomains);
585 
587  3, 3,
588  0., 1., 0., 1.,
589  elem_type);
590 
591  for (auto & elem : mesh.element_ptr_range())
592  elem->subdomain_id() = elem->id()/2;
593 
594  es.init();
595  TripleFunction tfunc;
596  sys.project_solution(&tfunc);
597  tfunc.offset = 10;
598  sys.project_vector(*sys.old_local_solution, &tfunc);
599  tfunc.offset = 20;
600  sys.project_vector(*sys.older_local_solution, &tfunc);
601 
602  std::unique_ptr<PointLocatorBase> locator = mesh.sub_point_locator();
603  locator->enable_out_of_mesh_mode();
604  for (Real x = 0.1; x < 1; x += 0.2)
605  for (Real y = 0.1; y < 1; y += 0.2)
606  tripleValueTest(Point(x,y), sys, *locator,
607  u_subdomains, v_subdomains, w_subdomains,
608  es.parameters);
609 
610 #ifdef LIBMESH_ENABLE_AMR
611  for (auto & elem : mesh.element_ptr_range())
612  if ((elem->id()/2)%2)
613  elem->set_refinement_flag(Elem::REFINE);
614  es.reinit();
615 
616  locator = mesh.sub_point_locator();
617  locator->enable_out_of_mesh_mode();
618  for (Real x = 0.1; x < 1; x += 0.2)
619  for (Real y = 0.1; y < 1; y += 0.2)
620  tripleValueTest(Point(x,y), sys, *locator,
621  u_subdomains, v_subdomains, w_subdomains,
622  es.parameters);
623 #endif
624  }
625 
626  void testProjectCube(const ElemType elem_type)
627  {
629 
630  EquationSystems es(mesh);
632  es.add_system<TransientExplicitSystem> ("SimpleSystem");
633 
634  std::set<subdomain_id_type> u_subdomains {0, 1, 4, 5},
635  v_subdomains {1, 2, 3, 4},
636  w_subdomains {0, 1, 2, 3, 4};
637 
638  sys.add_variable("u", THIRD, HIERARCHIC, &u_subdomains);
639  sys.add_variable("v", FIRST, LAGRANGE, &v_subdomains);
640  sys.add_variable("w", CONSTANT, MONOMIAL, &w_subdomains);
641 
643  3, 3, 3,
644  0., 1., 0., 1., 0., 1.,
645  elem_type);
646 
647  for (auto & elem : mesh.element_ptr_range())
648  elem->subdomain_id() = elem->id()/6;
649 
650  es.init();
651  TripleFunction tfunc;
652  sys.project_solution(&tfunc);
653  tfunc.offset = 10;
654  sys.project_vector(*sys.old_local_solution, &tfunc);
655  tfunc.offset = 20;
656  sys.project_vector(*sys.older_local_solution, &tfunc);
657 
658  std::unique_ptr<PointLocatorBase> locator = mesh.sub_point_locator();
659  locator->enable_out_of_mesh_mode();
660  for (Real x = 0.1; x < 1; x += 0.2)
661  for (Real y = 0.1; y < 1; y += 0.2)
662  for (Real z = 0.1; z < 1; z += 0.2)
663  tripleValueTest(Point(x,y,z), sys, *locator,
664  u_subdomains, v_subdomains, w_subdomains,
665  es.parameters);
666 
667  #ifdef LIBMESH_ENABLE_AMR
668  for (auto & elem : mesh.element_ptr_range())
669  if ((elem->id()/2)%2)
670  elem->set_refinement_flag(Elem::REFINE);
671  es.reinit();
672 
673  locator = mesh.sub_point_locator();
674  locator->enable_out_of_mesh_mode();
675  for (Real x = 0.1; x < 1; x += 0.2)
676  for (Real y = 0.1; y < 1; y += 0.2)
677  for (Real z = 0.1; z < 1; z += 0.2)
678  tripleValueTest(Point(x,y,z), sys, *locator,
679  u_subdomains, v_subdomains, w_subdomains,
680  es.parameters);
681  #endif
682  }
683 
685  {
686  // The source mesh needs to exist everywhere it's queried, so we
687  // use a ReplicatedMesh
689 
690  EquationSystems es(mesh);
691  System &sys = es.add_system<System> ("SimpleSystem");
692  sys.add_variable("u", THIRD, MONOMIAL);
693 
695  3, 3, 3,
696  0., 1., 0., 1., 0., 1.,
697  elem_type);
698 
699  es.init();
700  sys.project_solution(cubic_test, nullptr, es.parameters);
701 
702  std::vector<unsigned int> variables;
703  sys.get_all_variable_numbers(variables);
704  std::sort(variables.begin(),variables.end());
705 
706  std::unique_ptr< NumericVector<Number> > mesh_function_vector =
708  mesh_function_vector->init(sys.n_dofs(), false, SERIAL);
709  sys.solution->localize( *mesh_function_vector );
710 
711  MeshFunction mesh_function(es,
712  *mesh_function_vector,
713  sys.get_dof_map(),
714  variables);
715  mesh_function.init();
716 
717  // Make a second system and project onto it using a MeshFunction
718  Mesh proj_mesh(*TestCommWorld);
719  EquationSystems proj_es(proj_mesh);
720 
721  System &proj_sys = proj_es.add_system<System> ("ProjectionSystem");
722 
723  // use 3rd order again so we can expect exact results
724  proj_sys.add_variable("u", THIRD, HIERARCHIC);
725 
727  5, 5, 5,
728  0., 1., 0., 1., 0., 1.,
729  elem_type);
730 
731  proj_es.init();
732  proj_sys.project_solution(&mesh_function);
733 
734  for (Real x = 0.1; x < 1; x += 0.2)
735  for (Real y = 0.1; y < 1; y += 0.2)
736  for (Real z = 0.1; z < 1; z += 0.2)
737  {
738  Point p(x,y,z);
739  LIBMESH_ASSERT_FP_EQUAL(libmesh_real(proj_sys.point_value(0,p)),
740  libmesh_real(cubic_test(p,es.parameters,"","")),
742  }
743  }
744 
746  {
748 
749  // const boundary_id_type BOUNDARY_ID_MIN_Z = 0;
750  const boundary_id_type BOUNDARY_ID_MIN_Y = 1;
751  const boundary_id_type BOUNDARY_ID_MAX_X = 2;
752  const boundary_id_type BOUNDARY_ID_MAX_Y = 3;
753  const boundary_id_type BOUNDARY_ID_MIN_X = 4;
754  const boundary_id_type BOUNDARY_ID_MAX_Z = 5;
755  const boundary_id_type NODE_BOUNDARY_ID = 10;
756  const boundary_id_type EDGE_BOUNDARY_ID = 20;
757  const boundary_id_type SIDE_BOUNDARY_ID = BOUNDARY_ID_MIN_X;
758 
759  EquationSystems es(mesh);
760  System &sys = es.add_system<System> ("SimpleSystem");
761  unsigned int u_var = sys.add_variable("u", FIRST, LAGRANGE);
762 
764  3, 3, 3,
765  0., 1., 0., 1., 0., 1.,
766  HEX8);
767 
768  // Count the number of nodes on SIDE_BOUNDARY_ID
769  std::set<dof_id_type> projected_nodes_set;
770 
771  for (const auto & elem : mesh.element_ptr_range())
772  {
773  for (auto side : elem->side_index_range())
774  {
775  std::vector<boundary_id_type> vec_to_fill;
776  mesh.get_boundary_info().boundary_ids(elem, side, vec_to_fill);
777 
778  auto vec_it = std::find(vec_to_fill.begin(), vec_to_fill.end(), SIDE_BOUNDARY_ID);
779  if (vec_it != vec_to_fill.end())
780  {
781  for (unsigned int node_index=0; node_index<elem->n_nodes(); node_index++)
782  {
783  if( elem->is_node_on_side(node_index, side))
784  {
785  projected_nodes_set.insert(elem->node_id(node_index));
786  }
787  }
788  }
789  }
790  }
791 
792  // Also add some edge and node boundary IDs
793  for (const auto & elem : mesh.element_ptr_range())
794  {
795  unsigned int
796  side_max_x = 0, side_min_y = 0,
797  side_max_y = 0, side_max_z = 0;
798 
799  bool
800  found_side_max_x = false, found_side_max_y = false,
801  found_side_min_y = false, found_side_max_z = false;
802 
803  for (auto side : elem->side_index_range())
804  {
805  if (mesh.get_boundary_info().has_boundary_id(elem, side, BOUNDARY_ID_MAX_X))
806  {
807  side_max_x = side;
808  found_side_max_x = true;
809  }
810 
811  if (mesh.get_boundary_info().has_boundary_id(elem, side, BOUNDARY_ID_MIN_Y))
812  {
813  side_min_y = side;
814  found_side_min_y = true;
815  }
816 
817  if (mesh.get_boundary_info().has_boundary_id(elem, side, BOUNDARY_ID_MAX_Y))
818  {
819  side_max_y = side;
820  found_side_max_y = true;
821  }
822 
823  if (mesh.get_boundary_info().has_boundary_id(elem, side, BOUNDARY_ID_MAX_Z))
824  {
825  side_max_z = side;
826  found_side_max_z = true;
827  }
828  }
829 
830  // If elem has sides on boundaries
831  // BOUNDARY_ID_MAX_X, BOUNDARY_ID_MAX_Y, BOUNDARY_ID_MAX_Z
832  // then let's set a node boundary condition
833  if (found_side_max_x && found_side_max_y && found_side_max_z)
834  for (auto n : elem->node_index_range())
835  if (elem->is_node_on_side(n, side_max_x) &&
836  elem->is_node_on_side(n, side_max_y) &&
837  elem->is_node_on_side(n, side_max_z))
838  {
839  projected_nodes_set.insert(elem->node_id(n));
840  mesh.get_boundary_info().add_node(elem->node_ptr(n), NODE_BOUNDARY_ID);
841  }
842 
843  // If elem has sides on boundaries
844  // BOUNDARY_ID_MAX_X and BOUNDARY_ID_MIN_Y
845  // then let's set an edge boundary condition
846  if (found_side_max_x && found_side_min_y)
847  for (auto e : elem->edge_index_range())
848  if (elem->is_edge_on_side(e, side_max_x) &&
849  elem->is_edge_on_side(e, side_min_y))
850  {
851  mesh.get_boundary_info().add_edge(elem, e, EDGE_BOUNDARY_ID);
852 
853  for (unsigned int node_index=0; node_index<elem->n_nodes(); node_index++)
854  {
855  if (elem->is_node_on_edge(node_index, e))
856  {
857  projected_nodes_set.insert(elem->node_id(node_index));
858  }
859  }
860  }
861  }
862 
863  es.init();
864 
865  sys.solution->add(1.0);
866 
867  std::set<boundary_id_type> boundary_ids;
868  boundary_ids.insert(NODE_BOUNDARY_ID);
869  boundary_ids.insert(EDGE_BOUNDARY_ID);
870  boundary_ids.insert(SIDE_BOUNDARY_ID);
871  std::vector<unsigned int> variables;
872  variables.push_back(u_var);
873  ZeroFunction<> zf;
874  sys.boundary_project_solution(boundary_ids, variables, &zf);
875 
876  // On a distributed mesh we may not have every node on every
877  // processor
878  TestCommWorld->set_union(projected_nodes_set);
879 
880  // We set the solution to be 1 everywhere and then zero on specific boundary
881  // nodes, so the final l1 norm of the solution is the difference between the
882  // number of nodes in the mesh and the number of nodes we zero on.
883  Real ref_l1_norm = static_cast<Real>(mesh.n_nodes()) - static_cast<Real>(projected_nodes_set.size());
884 
885  LIBMESH_ASSERT_FP_EQUAL(sys.solution->l1_norm(), ref_l1_norm, TOLERANCE*TOLERANCE);
886  }
887 
889  {
891 
893  1,
894  0,
895  0,
896  0., 1.,
897  0., 0.,
898  0., 0.,
899  EDGE2);
900 
901  Point new_point_a(2.);
902  Point new_point_b(3.);
903  Node* new_node_a = mesh.add_point( new_point_a );
904  Node* new_node_b = mesh.add_point( new_point_b );
905  Elem* new_edge_elem = mesh.add_elem (new Edge2);
906  new_edge_elem->set_node(0) = new_node_a;
907  new_edge_elem->set_node(1) = new_node_b;
908 
909  mesh.elem_ref(0).subdomain_id() = 10;
910  mesh.elem_ref(1).subdomain_id() = 10;
911 
912  // Add NodeElems for coupling purposes
913  Elem* node_elem_1 = mesh.add_elem (new NodeElem);
914  node_elem_1->set_node(0) = mesh.elem_ref(0).node_ptr(1);
915  Elem* node_elem_2 = mesh.add_elem (new NodeElem);
916  node_elem_2->set_node(0) = new_node_a;
917 
919 
920  // Create an equation systems object.
921  EquationSystems equation_systems (mesh);
922  LinearImplicitSystem & system =
923  equation_systems.add_system<LinearImplicitSystem> ("test");
924 
925  system.add_variable ("u", libMesh::FIRST);
926  system.add_variable ("v", libMesh::FIRST);
927  system.add_variable ("w", libMesh::FIRST);
928 
929  std::set<subdomain_id_type> theta_subdomains;
930  theta_subdomains.insert(10);
931  system.add_variable ("theta_x", libMesh::FIRST, &theta_subdomains);
932  system.add_variable ("theta_y", libMesh::FIRST, &theta_subdomains);
933  system.add_variable ("theta_z", libMesh::FIRST, &theta_subdomains);
934 
936 
937  AugmentSparsityOnNodes augment_sparsity(mesh);
938  system.get_dof_map().add_coupling_functor(augment_sparsity);
939 
940  // LASPACK GMRES + ILU defaults don't like this problem, but it's
941  // small enough to just use a simpler iteration.
944 
945  equation_systems.init ();
946 
947  system.solve();
948 
949  // We set the solution to be 1 everywhere, so the final l1 norm of the
950  // solution is the product of the number of variables and number of nodes.
951  Real ref_l1_norm = static_cast<Real>(mesh.n_nodes() * system.n_vars());
952 
953  LIBMESH_ASSERT_FP_EQUAL(system.solution->l1_norm(), ref_l1_norm, TOLERANCE*TOLERANCE);
954  }
955 
957  {
959 
960  EquationSystems es(mesh);
961  System &sys = es.add_system<LinearImplicitSystem> ("test");
962 
963  // We must use a discontinuous variable type in this test or
964  // else the sparsity pattern will not be correct
965  sys.add_variable("u", FIRST, L2_LAGRANGE);
966 
968  5, 5, 5,
969  0., 1., 0., 1., 0., 1.,
970  HEX8);
971 
972  es.init();
974  sys.solve();
975 
976  // We don't actually assert anything in this test. We just want to check that
977  // the assembly and solve do not encounter any errors.
978  }
979 
981  {
983 
985  4,
986  4,
987  0,
988  0., 1.,
989  0., 1.,
990  0., 0.,
991  QUAD4);
992 
993  auto el_beg = mesh.elements_begin();
994  auto el_end = mesh.elements_end();
995  auto el = mesh.elements_begin();
996  for (; el != el_end; ++el)
997  if ((*el)->centroid()(0) <= 0.5 && (*el)->centroid()(1) <= 0.5)
998  (*el)->subdomain_id() = 0;
999  else
1000  (*el)->subdomain_id() = 1;
1001 
1003 
1004  // Create an equation systems object.
1005  EquationSystems equation_systems (mesh);
1006  ExplicitSystem& system =
1007  equation_systems.add_system<LinearImplicitSystem> ("test");
1008 
1009  std::set<subdomain_id_type> block0;
1010  std::set<subdomain_id_type> block1;
1011  block0.insert(0);
1012  block1.insert(1);
1013  auto u0 = system.add_variable ("u0", libMesh::FIRST, &block0);
1014  auto u1 = system.add_variable ("u1", libMesh::FIRST, &block1);
1015  equation_systems.init();
1016 
1017  std::vector<dof_id_type> u0_dofs;
1018  system.get_dof_map().local_variable_indices(u0_dofs, mesh, u0);
1019  std::vector<dof_id_type> u1_dofs;
1020  system.get_dof_map().local_variable_indices(u1_dofs, mesh, u1);
1021 
1022  std::set<dof_id_type> sys_u0_dofs;
1023  system.local_dof_indices(u0, sys_u0_dofs);
1024  std::set<dof_id_type> sys_u1_dofs;
1025  system.local_dof_indices(u1, sys_u1_dofs);
1026 
1027  // Get local indices from other processors too
1028  mesh.comm().allgather(u0_dofs);
1029  mesh.comm().allgather(u1_dofs);
1030  mesh.comm().set_union(sys_u0_dofs);
1031  mesh.comm().set_union(sys_u1_dofs);
1032 
1033  const std::size_t c9 = 9;
1034  const std::size_t c21 = 21;
1035  CPPUNIT_ASSERT_EQUAL(c9, u0_dofs.size());
1036  CPPUNIT_ASSERT_EQUAL(c21, u1_dofs.size());
1037  CPPUNIT_ASSERT_EQUAL(c9, sys_u0_dofs.size());
1038  CPPUNIT_ASSERT_EQUAL(c21, sys_u1_dofs.size());
1039  }
1040 
1041 #ifdef LIBMESH_ENABLE_AMR
1042 #ifdef LIBMESH_HAVE_METAPHYSICL
1043 #ifdef LIBMESH_HAVE_PETSC
1044  void testProjectMatrix1D(const ElemType elem_type)
1045  {
1046  // Use ReplicatedMesh to get consistent child element node
1047  // numbering during refinement
1049 
1050  // fix the node numbering to resolve dof_id numbering issues in parallel tests
1051  mesh.allow_renumbering(false);
1052 
1053  // init a simple 1d system
1054  EquationSystems es(mesh);
1055  System &sys = es.add_system<System> ("SimpleSystem");
1056  sys.add_variable("u", FIRST, LAGRANGE);
1057 
1059  4, 0., 1.,
1060  elem_type);
1061 
1062  es.init();
1063 
1064  // static set of coarse nodes / order of fine grid nodes from x=0 to x=1 going left to right
1065  std::set<dof_id_type> coarse_nodes({0,1,2,3,4});
1066  std::vector<dof_id_type> node_order_f({0,5,1,6,2,7,3,8,4});
1067 
1068  // stash number of dofs on coarse grid for projection sizing
1069  int n_old_dofs = sys.n_dofs();
1070 
1071  // save old coarse dof_ids in order of coarse nodes
1072  std::map <dof_id_type, dof_id_type> node2dof_c;
1073  for ( const auto & node : mesh.node_ptr_range() )
1074  {
1075  dof_id_type cdof_id = node->dof_number(0,0,0);
1076  node2dof_c.insert( std::pair<dof_id_type,dof_id_type>( node->id() , cdof_id) );
1077  }
1078 
1079  // refine the mesh so we can utilize old_dof_indices for projection_matrix
1080  MeshRefinement mr(mesh);
1081  mr.uniformly_refine(1);
1083 
1084  // fine node to dof map
1085  std::map <dof_id_type, dof_id_type> node2dof_f;
1086  for ( const auto & node : mesh.local_node_ptr_range() )
1087  {
1088  dof_id_type fdof_id = node->dof_number(0,0,0);
1089  node2dof_f.insert( std::pair<dof_id_type,dof_id_type>(node->id() , fdof_id) );
1090  }
1091 
1092  // local and global projection_matrix sizes infos
1093  int n_new_dofs = sys.n_dofs();
1094  int n_new_dofs_local = sys.get_dof_map().n_dofs_on_processor(sys.processor_id());
1095  int ndofs_old_first = sys.get_dof_map().first_old_dof(sys.processor_id());
1096  int ndofs_old_end = sys.get_dof_map().end_old_dof(sys.processor_id());
1097  int n_old_dofs_local = ndofs_old_end - ndofs_old_first;
1098 
1099  // init and compute the projection matrix using GenericProjector
1100  std::unique_ptr<SparseMatrix<Number> > proj_mat_ptr =
1102  SparseMatrix<Number> & proj_mat = *proj_mat_ptr;
1103  proj_mat.init(n_new_dofs, n_old_dofs, n_new_dofs_local, n_old_dofs_local);
1104  sys.projection_matrix(proj_mat);
1105  proj_mat.close();
1106 
1107  // init the gold standard projection matrix
1108  std::unique_ptr<SparseMatrix<Number> > gold_mat_ptr =
1110  SparseMatrix<Number> & gold_mat = *gold_mat_ptr;
1111  gold_mat.init(n_new_dofs, n_old_dofs, n_new_dofs_local, n_old_dofs_local);
1112 
1113  // construct the gold projection matrix using static node numbering as reference info
1114  for ( const auto & node : mesh.local_node_ptr_range() )
1115  {
1116  dof_id_type node_id = node->id();
1117  dof_id_type fdof_id = (node2dof_f.find(node_id))->second;
1118 
1119  if (coarse_nodes.find(node_id) != coarse_nodes.end() )
1120  { //direct inject coarse nodes
1121  if (fdof_id >= gold_mat.row_start() && fdof_id < gold_mat.row_stop())
1122  {
1123  auto cdof_id = node2dof_c.find(node_id);
1124  gold_mat.set(fdof_id, cdof_id->second, 1.0);
1125  }
1126  }
1127  else
1128  { // new nodes with old_dof neighbor contributions
1129  if (fdof_id >= gold_mat.row_start() && fdof_id < gold_mat.row_stop())
1130  {
1131  auto node_loc = std::find(node_order_f.begin(), node_order_f.end(), node_id);
1132  auto node_n = *std::next(node_loc, 1);
1133  auto node_p = *std::prev(node_loc, 1);
1134  auto dof_p = node2dof_c.find(node_p);
1135  auto dof_n = node2dof_c.find(node_n);
1136 
1137  gold_mat.set(fdof_id, dof_p->second, 0.5);
1138  gold_mat.set(fdof_id, dof_n->second, 0.5);
1139  }
1140  }
1141  } // end gold mat build
1142  gold_mat.close();
1143 
1144  // calculate relative difference norm between the two projection matrices
1145  Real gold_norm = gold_mat.linfty_norm();
1146  gold_mat.add(-1.0, proj_mat);
1147  Real diff_norm = gold_mat.linfty_norm();
1148  CPPUNIT_ASSERT(diff_norm/gold_norm < TOLERANCE*TOLERANCE);
1149  }
1150 
1151  void testProjectMatrix2D(const ElemType elem_type)
1152  {
1153  // Use ReplicatedMesh to get consistent child element node
1154  // numbering during refinement
1156 
1157  // fix the node numbering to resolve dof_id numbering issues in parallel tests
1158  mesh.allow_renumbering(false);
1159 
1160  // init a simple 1d system
1161  EquationSystems es(mesh);
1162  System &sys = es.add_system<System> ("SimpleSystem");
1163  sys.add_variable("u", FIRST, LAGRANGE);
1164 
1165  if (elem_type == Utility::string_to_enum<ElemType>("QUAD4"))
1167  2, 2,
1168  0., 1., 0., 1.,
1169  elem_type);
1170  else if (elem_type == Utility::string_to_enum<ElemType>("TRI3"))
1172  1, 1,
1173  0., 1., 0., 1.,
1174  elem_type);
1175 
1176  es.init();
1177 
1178  // static sets of nodes and their neighbors
1179  std::set<dof_id_type> coarse_nodes;
1180  std::map<dof_id_type, std::vector<dof_id_type>> side_nbr_nodes;
1181  std::map<dof_id_type, std::vector<dof_id_type>> int_nbr_nodes;
1182 
1183  // fill neighbor maps based on static node numbering
1184  if (elem_type == Utility::string_to_enum<ElemType>("QUAD4"))
1185  {
1186  coarse_nodes.insert({0,1,2,3,4,5,6,7,8});
1187 
1188  side_nbr_nodes.insert({9, {0,1}});
1189  side_nbr_nodes.insert({14, {1,2}});
1190  side_nbr_nodes.insert({11, {0,3}});
1191  side_nbr_nodes.insert({12, {1,4}});
1192  side_nbr_nodes.insert({16, {2,5}});
1193  side_nbr_nodes.insert({13, {3,4}});
1194  side_nbr_nodes.insert({17, {4,5}});
1195  side_nbr_nodes.insert({19, {3,6}});
1196  side_nbr_nodes.insert({20, {4,7}});
1197  side_nbr_nodes.insert({23, {5,8}});
1198  side_nbr_nodes.insert({21, {6,7}});
1199  side_nbr_nodes.insert({24, {7,8}});
1200 
1201  int_nbr_nodes.insert({10, {0,1,3,4}});
1202  int_nbr_nodes.insert({15, {1,2,4,5}});
1203  int_nbr_nodes.insert({18, {3,4,6,7}});
1204  int_nbr_nodes.insert({22, {4,5,7,8}});
1205  }
1206  else if (elem_type == Utility::string_to_enum<ElemType>("TRI3"))
1207  {
1208  coarse_nodes.insert({0,1,2,3});
1209 
1210  side_nbr_nodes.insert({4, {0,1}});
1211  side_nbr_nodes.insert({5, {0,3}});
1212  side_nbr_nodes.insert({6, {1,3}});
1213  side_nbr_nodes.insert({7, {0,2}});
1214  side_nbr_nodes.insert({8, {2,3}});
1215  }
1216 
1217  // stash number of dofs on coarse grid for projection sizing
1218  int n_old_dofs = sys.n_dofs();
1219 
1220  // save old coarse dof_ids in order of coarse nodes
1221  std::map <dof_id_type, dof_id_type> node2dof_c;
1222  for ( const auto & node : mesh.node_ptr_range() )
1223  {
1224  dof_id_type cdof_id = node->dof_number(0,0,0);
1225  node2dof_c.insert( std::pair<dof_id_type,dof_id_type>( node->id() , cdof_id) );
1226  }
1227 
1228  // refine the mesh so we can utilize old_dof_indices for projection_matrix
1229  MeshRefinement mr(mesh);
1230  mr.uniformly_refine(1);
1232 
1233  // fine node to dof map
1234  std::map <dof_id_type, dof_id_type> node2dof_f;
1235  for ( const auto & node : mesh.local_node_ptr_range() )
1236  {
1237  dof_id_type fdof_id = node->dof_number(0,0,0);
1238  node2dof_f.insert( std::pair<dof_id_type,dof_id_type>(node->id() , fdof_id) );
1239  }
1240 
1241  // local and global projection_matrix sizes infos
1242  int n_new_dofs = sys.n_dofs();
1243  int n_new_dofs_local = sys.get_dof_map().n_dofs_on_processor(sys.processor_id());
1244  int ndofs_old_first = sys.get_dof_map().first_old_dof(sys.processor_id());
1245  int ndofs_old_end = sys.get_dof_map().end_old_dof(sys.processor_id());
1246  int n_old_dofs_local = ndofs_old_end - ndofs_old_first;
1247 
1248  // init and compute the projection matrix using GenericProjector
1249  std::unique_ptr<SparseMatrix<Number> > proj_mat_ptr =
1251  SparseMatrix<Number> & proj_mat = *proj_mat_ptr;
1252  proj_mat.init(n_new_dofs, n_old_dofs, n_new_dofs_local, n_old_dofs_local);
1253  sys.projection_matrix(proj_mat);
1254  proj_mat.close();
1255 
1256  // init the gold standard projection matrix
1257  std::unique_ptr<SparseMatrix<Number> > gold_mat_ptr =
1259  SparseMatrix<Number> & gold_mat = *gold_mat_ptr;
1260  gold_mat.init(n_new_dofs, n_old_dofs, n_new_dofs_local, n_old_dofs_local);
1261 
1262  // construct the gold projection matrix using static node numbering as reference info
1263  for ( const auto & node : mesh.local_node_ptr_range() )
1264  {
1265  dof_id_type node_id = node->id();
1266  dof_id_type fdof_id = (node2dof_f.find(node_id))->second;
1267 
1268  if (coarse_nodes.find(node_id) != coarse_nodes.end() )
1269  { // direct inject coarse nodes
1270  if (fdof_id >= gold_mat.row_start() && fdof_id < gold_mat.row_stop())
1271  {
1272  auto cdof_id = node2dof_c.find(node_id);
1273  gold_mat.set(fdof_id, cdof_id->second, 1.0);
1274  }
1275  }
1276  else if ( side_nbr_nodes.find(node_id) != side_nbr_nodes.end() )
1277  { // new side nodes with old_dof neighbor contributions
1278  if (fdof_id >= gold_mat.row_start() && fdof_id < gold_mat.row_stop())
1279  {
1280  auto node_nbrs = side_nbr_nodes.find(node_id);
1281  for (auto nbr : node_nbrs->second)
1282  {
1283  auto nbr_dof = node2dof_c.find(nbr);
1284  gold_mat.set(fdof_id, nbr_dof->second, 0.5);
1285  }
1286  }
1287  }
1288  else
1289  { // new interior nodes with old_dof neighbor contributions
1290  if (fdof_id >= gold_mat.row_start() && fdof_id < gold_mat.row_stop())
1291  {
1292  auto node_nbrs = int_nbr_nodes.find(node_id);
1293  for (auto nbr : node_nbrs->second)
1294  {
1295  auto nbr_dof = node2dof_c.find(nbr);
1296  gold_mat.set(fdof_id, nbr_dof->second, 0.25);
1297  }
1298  }
1299  }
1300  } // end gold mat build
1301  gold_mat.close();
1302 
1303  // calculate relative difference norm between the two projection matrices
1304  Real gold_norm = gold_mat.linfty_norm();
1305  proj_mat.add(-1.0, gold_mat);
1306  Real diff_norm = proj_mat.linfty_norm();
1307  CPPUNIT_ASSERT(diff_norm/gold_norm < TOLERANCE*TOLERANCE);
1308  }
1309 
1310  void testProjectMatrix3D(const ElemType elem_type)
1311  {
1312  // Use ReplicatedMesh to get consistent child element node
1313  // numbering during refinement
1315 
1316  // fix the node numbering to resolve dof_id numbering issues in parallel tests
1317  mesh.allow_renumbering(false);
1318 
1319  // init a simple 1d system
1320  EquationSystems es(mesh);
1321  System &sys = es.add_system<System> ("SimpleSystem");
1322  sys.add_variable("u", FIRST, LAGRANGE);
1323 
1324  if (elem_type == Utility::string_to_enum<ElemType>("HEX8"))
1326  1, 1, 1,
1327  0., 1., 0., 1., 0., 1.,
1328  elem_type);
1329  else if (elem_type == Utility::string_to_enum<ElemType>("TET4"))
1330  {
1331  // manually build a Tet4 element
1332  mesh.add_point( Point(0,0,0), 0 );
1333  mesh.add_point( Point(1,0,0), 1 );
1334  mesh.add_point( Point(0,1,0), 2 );
1335  mesh.add_point( Point(1./3.,1./3.,1), 3 );
1336 
1337  Elem * elem = new Tet4();
1338  elem->set_id(0);
1339  elem = mesh.add_elem(elem);
1340  elem->set_node(0) = mesh.node_ptr(0);
1341  elem->set_node(1) = mesh.node_ptr(1);
1342  elem->set_node(2) = mesh.node_ptr(2);
1343  elem->set_node(3) = mesh.node_ptr(3);
1344 
1346  }
1347  es.init();
1348 
1349  // static sets of nodes and their neighbors
1350  std::set<dof_id_type> coarse_nodes;
1351  std::map<dof_id_type, std::vector<dof_id_type>> side_nbr_nodes;
1352  std::map<dof_id_type, std::vector<dof_id_type>> face_nbr_nodes;
1353  std::map<dof_id_type, std::vector<dof_id_type>> int_nbr_nodes;
1354 
1355  if (elem_type == Utility::string_to_enum<ElemType>("HEX8"))
1356  {
1357  coarse_nodes.insert({0,1,2,3,4,5,6,7});
1358 
1359  // fill neighbor maps based on static node numbering
1360  side_nbr_nodes.insert({8, {0,1}});
1361  side_nbr_nodes.insert({10, {0,2}});
1362  side_nbr_nodes.insert({15, {1,3}});
1363  side_nbr_nodes.insert({18, {2,3}});
1364  side_nbr_nodes.insert({11, {0,4}});
1365  side_nbr_nodes.insert({16, {1,5}});
1366  side_nbr_nodes.insert({21, {3,7}});
1367  side_nbr_nodes.insert({20, {2,6}});
1368  side_nbr_nodes.insert({22, {4,5}});
1369  side_nbr_nodes.insert({24, {4,6}});
1370  side_nbr_nodes.insert({25, {5,7}});
1371  side_nbr_nodes.insert({26, {6,7}});
1372 
1373  face_nbr_nodes.insert({12, {0,1,4,5}});
1374  face_nbr_nodes.insert({9 , {0,1,2,3}});
1375  face_nbr_nodes.insert({14, {0,2,4,6}});
1376  face_nbr_nodes.insert({17, {1,3,5,7}});
1377  face_nbr_nodes.insert({19, {2,3,6,7}});
1378  face_nbr_nodes.insert({23, {4,5,6,7}});
1379 
1380  int_nbr_nodes.insert({13, {0,1,2,3,4,5,6,7}});
1381  }
1382  else if (elem_type == Utility::string_to_enum<ElemType>("TET4"))
1383  {
1384  coarse_nodes.insert({0,1,2,3});
1385 
1386  // fill neighbor maps based on static node numbering
1387  side_nbr_nodes.insert({4, {0,1}});
1388  side_nbr_nodes.insert({5, {0,2}});
1389  side_nbr_nodes.insert({6, {0,3}});
1390  side_nbr_nodes.insert({7, {1,2}});
1391  side_nbr_nodes.insert({8, {1,3}});
1392  side_nbr_nodes.insert({9, {2,3}});
1393  }
1394 
1395  // stash number of dofs on coarse grid for projection sizing
1396  int n_old_dofs = sys.n_dofs();
1397 
1398  // save old coarse dof_ids in order of coarse nodes
1399  std::map <dof_id_type, dof_id_type> node2dof_c;
1400  for ( const auto & node : mesh.node_ptr_range() )
1401  {
1402  dof_id_type cdof_id = node->dof_number(0,0,0);
1403  node2dof_c.insert( std::pair<dof_id_type,dof_id_type>( node->id() , cdof_id) );
1404  }
1405 
1406  // refine the mesh so we can utilize old_dof_indices for projection_matrix
1407  MeshRefinement mr(mesh);
1408  mr.uniformly_refine(1);
1410 
1411  // fine node to dof map
1412  std::map <dof_id_type, dof_id_type> node2dof_f;
1413  for ( const auto & node : mesh.local_node_ptr_range() )
1414  {
1415  dof_id_type fdof_id = node->dof_number(0,0,0);
1416  node2dof_f.insert( std::pair<dof_id_type,dof_id_type>(node->id() , fdof_id) );
1417  }
1418 
1419  // local and global projection_matrix sizes infos
1420  int n_new_dofs = sys.n_dofs();
1421  int n_new_dofs_local = sys.get_dof_map().n_dofs_on_processor(sys.processor_id());
1422  int ndofs_old_first = sys.get_dof_map().first_old_dof(sys.processor_id());
1423  int ndofs_old_end = sys.get_dof_map().end_old_dof(sys.processor_id());
1424  int n_old_dofs_local = ndofs_old_end - ndofs_old_first;
1425 
1426  // init and compute the projection matrix using GenericProjector
1427  std::unique_ptr<SparseMatrix<Number> > proj_mat_ptr =
1429  SparseMatrix<Number> & proj_mat = *proj_mat_ptr;
1430  proj_mat.init(n_new_dofs, n_old_dofs, n_new_dofs_local, n_old_dofs_local);
1431  sys.projection_matrix(proj_mat);
1432  proj_mat.close();
1433 
1434  // init the gold standard projection matrix
1435  std::unique_ptr<SparseMatrix<Number> > gold_mat_ptr =
1437  SparseMatrix<Number> & gold_mat = *gold_mat_ptr;
1438  gold_mat.init(n_new_dofs, n_old_dofs, n_new_dofs_local, n_old_dofs_local);
1439 
1440  // construct the gold projection matrix using static node numbering as reference info
1441  for ( const auto & node : mesh.local_node_ptr_range() )
1442  {
1443  dof_id_type node_id = node->id();
1444  dof_id_type fdof_id = (node2dof_f.find(node_id))->second;
1445 
1446  if (coarse_nodes.find(node_id) != coarse_nodes.end() )
1447  { // direct inject coarse nodes
1448  if (fdof_id >= gold_mat.row_start() && fdof_id < gold_mat.row_stop())
1449  {
1450  auto cdof_id = node2dof_c.find(node_id);
1451  gold_mat.set(fdof_id, cdof_id->second, 1.0);
1452  }
1453  }
1454  else if ( side_nbr_nodes.find(node_id) != side_nbr_nodes.end() )
1455  { // new side nodes with old_dof neighbor contributions
1456  if (fdof_id >= gold_mat.row_start() && fdof_id < gold_mat.row_stop())
1457  {
1458  auto node_nbrs = side_nbr_nodes.find(node_id);
1459  for (auto nbr : node_nbrs->second)
1460  {
1461  auto nbr_dof = node2dof_c.find(nbr);
1462  gold_mat.set(fdof_id, nbr_dof->second, 0.5);
1463  }
1464  }
1465  }
1466  else if ( face_nbr_nodes.find(node_id) != face_nbr_nodes.end() )
1467  { // new face nodes with old_dof neighbor contributions
1468  if (fdof_id >= gold_mat.row_start() && fdof_id < gold_mat.row_stop())
1469  {
1470  auto node_nbrs = face_nbr_nodes.find(node_id);
1471  for (auto nbr : node_nbrs->second)
1472  {
1473  auto nbr_dof = node2dof_c.find(nbr);
1474  gold_mat.set(fdof_id, nbr_dof->second, 0.25);
1475  }
1476  }
1477  }
1478  else
1479  { // new interior nodes with old_dof neighbor contributions
1480  if (fdof_id >= gold_mat.row_start() && fdof_id < gold_mat.row_stop())
1481  {
1482  auto node_nbrs = int_nbr_nodes.find(node_id);
1483  for (auto nbr : node_nbrs->second)
1484  {
1485  auto nbr_dof = node2dof_c.find(nbr);
1486  gold_mat.set(fdof_id, nbr_dof->second, 0.125);
1487  }
1488  }
1489  }
1490  } // end gold mat build
1491  gold_mat.close();
1492 
1493  // calculate relative difference norm between the two projection matrices
1494  Real gold_norm = gold_mat.linfty_norm();
1495  proj_mat.add(-1.0, gold_mat);
1496  Real diff_norm = proj_mat.linfty_norm();
1497  CPPUNIT_ASSERT(diff_norm/gold_norm < TOLERANCE*TOLERANCE);
1498  }
1499 #endif // LIBMESH_HAVE_PETSC
1500 #endif // LIBMESH_HAVE_METAPHYSICL
1501 #endif // LIBMESH_ENABLE_AMR
1502 
1503 
1504  void testProjectHierarchicEdge3() { testProjectLine(EDGE3); }
1505  void testProjectHierarchicQuad9() { testProjectSquare(QUAD9); }
1506  void testProjectHierarchicTri6() { testProjectSquare(TRI6); }
1507  void testProjectHierarchicHex27() { testProjectCube(HEX27); }
1508  void testProjectMeshFunctionHex27() { testProjectCubeWithMeshFunction(HEX27); }
1509 
1510 #ifdef LIBMESH_ENABLE_AMR
1511 #ifdef LIBMESH_HAVE_METAPHYSICL
1512 #ifdef LIBMESH_HAVE_PETSC
1513  // projection matrix tests
1514  void testProjectMatrixEdge2() { testProjectMatrix1D(EDGE2); }
1515  void testProjectMatrixQuad4() { testProjectMatrix2D(QUAD4); }
1516  void testProjectMatrixTri3() { testProjectMatrix2D(TRI3); }
1517  void testProjectMatrixHex8() { testProjectMatrix3D(HEX8); }
1518  void testProjectMatrixTet4() { testProjectMatrix3D(TET4); }
1519 #endif // LIBMESH_HAVE_PETSC
1520 #endif // LIBMESH_HAVE_METAPHYSICL
1521 #endif // LIBMESH_ENABLE_AMR
1522 
1523 };
1524 
libMesh::SparseMatrix::close
virtual void close()=0
Calls the SparseMatrix's internal assembly routines, ensuring that the values are consistent across p...
SystemsTest
Definition: systems_test.C:416
libMesh::System
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition: system.h:100
SystemsTest::setUp
void setUp()
Definition: systems_test.C:510
SystemsTest::testAssemblyWithDgFemContext
void testAssemblyWithDgFemContext()
Definition: systems_test.C:956
SystemsTest::testProjectHierarchicQuad9
void testProjectHierarchicQuad9()
Definition: systems_test.C:1505
libMesh::Number
Real Number
Definition: libmesh_common.h:195
libMesh::dof_id_type
uint8_t dof_id_type
Definition: id_types.h:67
libMesh::DiffContext::get_elem_residual
const DenseVector< Number > & get_elem_residual() const
Const accessor for element residual.
Definition: diff_context.h:249
libMesh::System::boundary_project_solution
void boundary_project_solution(const std::set< boundary_id_type > &b, const std::vector< unsigned int > &variables, FunctionBase< Number > *f, FunctionBase< Gradient > *g=nullptr)
Projects arbitrary boundary functions onto a vector of degree of freedom values for the current syste...
Definition: system_projection.C:1126
libMesh::System::n_vars
unsigned int n_vars() const
Definition: system.h:2155
libMesh::FEMContext::get_element_qrule
const QBase & get_element_qrule() const
Accessor for element interior quadrature rule for the dimension of the current _elem.
Definition: fem_context.h:790
libMesh::BoundaryInfo::boundary_ids
std::vector< boundary_id_type > boundary_ids(const Node *node) const
Definition: boundary_info.C:985
libMesh::FunctionBase
Base class for functors that can be evaluated at a point and (optionally) time.
Definition: dirichlet_boundaries.h:44
libMesh::DGFEMContext::neighbor_side_fe_reinit
void neighbor_side_fe_reinit()
Initialize neighbor side data needed to assemble DG terms.
Definition: dg_fem_context.C:86
libMesh::FEMContext::side
unsigned char side
Current side for side_* to examine.
Definition: fem_context.h:1010
SystemsTest::testProjectMatrixEdge2
void testProjectMatrixEdge2()
Definition: systems_test.C:1514
libMesh::MeshTools::Subdivision::next
static const unsigned int next[3]
A lookup table for the increment modulo 3 operation, for iterating through the three nodes per elemen...
Definition: mesh_subdivision_support.h:102
SystemsTest::testProjectMeshFunctionHex27
void testProjectMeshFunctionHex27()
Definition: systems_test.C:1508
libMesh::Mesh
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition: mesh.h:50
cubic_test
Number cubic_test(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition: systems_test.C:330
libMesh::EquationSystems::add_system
virtual System & add_system(const std::string &system_type, const std::string &name)
Add the system of type system_type named name to the systems array.
Definition: equation_systems.C:345
libMesh::EquationSystems::get_mesh
const MeshBase & get_mesh() const
Definition: equation_systems.h:637
libMesh::DGFEMContext::get_neighbor_side_fe
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.
Definition: dg_fem_context.h:301
AugmentSparsityOnNodes::AugmentSparsityOnNodes
AugmentSparsityOnNodes(MeshBase &mesh)
Constructor.
Definition: systems_test.C:46
libMesh::DGFEMContext::get_neighbor_dof_indices
const std::vector< dof_id_type > & get_neighbor_dof_indices() const
Accessor for neighbor dof indices.
Definition: dg_fem_context.h:71
libMesh::TransientSystem
Manages storage and variables for transient systems.
Definition: transient_system.h:57
libMesh::MeshBase::get_boundary_info
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
Definition: mesh_base.h:132
libMesh::ExplicitSystem::rhs
NumericVector< Number > * rhs
The system matrix.
Definition: explicit_system.h:114
libMesh::DiffContext::get_dof_indices
const std::vector< dof_id_type > & get_dof_indices() const
Accessor for element dof indices.
Definition: diff_context.h:367
libMesh::DGFEMContext::side_fe_reinit
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.
Definition: dg_fem_context.C:77
libMesh::MeshFunction::init
virtual void init() override
Override the FunctionBase::init() member function by calling our own and specifying the Trees::NODES ...
Definition: mesh_function.h:110
libMesh::HEX8
Definition: enum_elem_type.h:47
TripleFunction::component
Number component(unsigned int i, const Point &p, Real) override
Definition: systems_test.C:394
libMesh::BoundaryInfo::add_node
void add_node(const Node *node, const boundary_id_type id)
Add Node node with boundary id id to the boundary information data structures.
Definition: boundary_info.C:636
libMesh::SparseMatrix::init
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.
libMesh::libmesh_real
T libmesh_real(T a)
Definition: libmesh_common.h:166
SystemsTest::testProjectHierarchicTri6
void testProjectHierarchicTri6()
Definition: systems_test.C:1506
libMesh::MeshBase::active_local_element_ptr_range
virtual SimpleRange< element_iterator > active_local_element_ptr_range()=0
libMesh::MeshBase::active_local_elements_begin
virtual element_iterator active_local_elements_begin()=0
libMesh::MeshFunction
This class provides function-like objects for data distributed over a mesh.
Definition: mesh_function.h:53
libMesh::JACOBI
Definition: enum_solver_type.h:46
libMesh::DGFEMContext
This class extends FEMContext in order to provide extra data required to perform local element residu...
Definition: dg_fem_context.h:39
libMesh::QBase::n_points
unsigned int n_points() const
Definition: quadrature.h:126
libMesh::DofObject::set_id
dof_id_type & set_id()
Definition: dof_object.h:776
libMesh::MeshBase::elem_ref
virtual const Elem & elem_ref(const dof_id_type i) const
Definition: mesh_base.h:521
libMesh::IDENTITY_PRECOND
Definition: enum_preconditioner_type.h:34
SystemsTest::testProjectMatrix3D
void testProjectMatrix3D(const ElemType elem_type)
Definition: systems_test.C:1310
libMesh::SERIAL
Definition: enum_parallel_type.h:35
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
Definition: factoryfunction.C:55
SystemsTest::testProjectMatrixQuad4
void testProjectMatrixQuad4()
Definition: systems_test.C:1515
assemble_matrix_and_rhs
void assemble_matrix_and_rhs(EquationSystems &es, const std::string &system_name)
Definition: systems_test.C:109
libMesh::FEMContext::get_side
unsigned char get_side() const
Accessor for current side of Elem object.
Definition: fem_context.h:910
libMesh::FEMContext::pre_fe_reinit
virtual void pre_fe_reinit(const System &, const Elem *e)
Reinitializes local data vectors/matrices on the current geometric element.
Definition: fem_context.C:1642
AugmentSparsityOnNodes::redistribute
virtual void redistribute() override
Update the cached _lower_to_upper map whenever our Mesh has been redistributed.
Definition: systems_test.C:103
libMesh::NumericVector::close
virtual void close()=0
Calls the NumericVector's internal assembly routines, ensuring that the values are consistent across ...
libMesh::FEGenericBase
This class forms the foundation from which generic finite elements may be derived.
Definition: exact_error_estimator.h:39
libMesh::DGFEMContext::get_neighbor_elem_jacobian
const DenseMatrix< Number > & get_neighbor_elem_jacobian() const
Const accessor for element-neighbor Jacobian.
Definition: dg_fem_context.h:162
libMesh::EquationSystems::get_system
const T_sys & get_system(const std::string &name) const
Definition: equation_systems.h:757
libMesh::FEAbstract::get_JxW
const std::vector< Real > & get_JxW() const
Definition: fe_abstract.h:244
libMesh::MeshTools::Generation::build_cube
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.
Definition: mesh_generation.C:298
libMesh::DGFEMContext::get_elem_elem_jacobian
const DenseMatrix< Number > & get_elem_elem_jacobian() const
Const accessor for element-element Jacobian.
Definition: dg_fem_context.h:110
libMesh::TOLERANCE
static const Real TOLERANCE
Definition: libmesh_common.h:128
libMesh::ParallelObject::comm
const Parallel::Communicator & comm() const
Definition: parallel_object.h:94
libMesh::DenseMatrix< Number >
libMesh::SparseMatrix::linfty_norm
virtual Real linfty_norm() const =0
SystemsTest::testProjectMatrixHex8
void testProjectMatrixHex8()
Definition: systems_test.C:1517
libMesh::GhostingFunctor::map_type
std::unordered_map< const Elem *, const CouplingMatrix * > map_type
What elements do we care about and what variables do we care about on each element?
Definition: ghosting_functor.h:171
libMesh::LinearImplicitSystem::solve
virtual void solve() override
Assembles & solves the linear system A*x=b.
Definition: linear_implicit_system.C:108
libMesh::System::number
unsigned int number() const
Definition: system.h:2075
mesh
MeshBase & mesh
Definition: mesh_communication.C:1257
libMesh::DofMap::end_old_dof
dof_id_type end_old_dof(const processor_id_type proc) const
Definition: dof_map.h:715
libMesh::MeshBase::node_ptr
virtual const Node * node_ptr(const dof_id_type i) const =0
AugmentSparsityOnNodes::_mesh
MeshBase & _mesh
The Mesh we're calculating on.
Definition: systems_test.C:39
libMesh::FEGenericBase::get_dphi
const std::vector< std::vector< OutputGradient > > & get_dphi() const
Definition: fe_base.h:214
CPPUNIT_TEST_SUITE_REGISTRATION
CPPUNIT_TEST_SUITE_REGISTRATION(SystemsTest)
disc_thirds_test
Number disc_thirds_test(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition: systems_test.C:356
TripleFunction::clone
virtual std::unique_ptr< FunctionBase< Number > > clone() const
Definition: systems_test.C:373
libMesh::boundary_id_type
int8_t boundary_id_type
Definition: id_types.h:51
libMesh::System::local_dof_indices
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:1259
libMesh::DofObject::processor_id
processor_id_type processor_id() const
Definition: dof_object.h:829
libMesh::MeshBase::elem_ptr
virtual const Elem * elem_ptr(const dof_id_type i) const =0
libMesh::MeshBase::elements_begin
virtual element_iterator elements_begin()=0
Iterate over all the elements in the Mesh.
libMesh::SparseMatrix< Number >
libMesh::NumericVector::build
static std::unique_ptr< NumericVector< T > > build(const Parallel::Communicator &comm, const SolverPackage solver_package=libMesh::default_solver_package())
Builds a NumericVector on the processors in communicator comm using the linear solver package specifi...
Definition: numeric_vector.C:49
libMesh::DenseMatrix::resize
void resize(const unsigned int new_m, const unsigned int new_n)
Resize the matrix.
Definition: dense_matrix.h:822
TripleFunction::offset
Number offset
Definition: systems_test.C:412
libMesh::TET4
Definition: enum_elem_type.h:45
libMesh::ReplicatedMesh
The ReplicatedMesh class is derived from the MeshBase class, and is used to store identical copies of...
Definition: replicated_mesh.h:47
TripleFunction
Definition: systems_test.C:369
libMesh::MeshBase::element_ptr_range
virtual SimpleRange< element_iterator > element_ptr_range()=0
libMesh::MeshRefinement
Implements (adaptive) mesh refinement algorithms for a MeshBase.
Definition: mesh_refinement.h:61
libMesh::DofObject::dof_number
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
Definition: dof_object.h:956
libMesh::MeshTools::Generation::build_square
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.
Definition: mesh_generation.C:1501
libMesh::System::attach_assemble_function
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:1755
libMesh::NumericVector::add_vector
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].
Definition: numeric_vector.C:363
libMesh::DofMap::distribute_dofs
void distribute_dofs(MeshBase &)
Distribute dofs on the current mesh.
Definition: dof_map.C:910
libMesh::MeshBase
This is the MeshBase class.
Definition: mesh_base.h:78
libMesh::HEX27
Definition: enum_elem_type.h:49
libMesh::DofMap::local_variable_indices
void local_variable_indices(std::vector< dof_id_type > &idx, const MeshBase &mesh, unsigned int var_num) const
Fills an array of those dof indices which belong to the given variable number and live on the current...
Definition: dof_map.C:1084
libMesh::LinearSolver::set_solver_type
void set_solver_type(const SolverType st)
Sets the type of solver to use.
Definition: linear_solver.h:126
libMesh::LinearImplicitSystem::get_linear_solver
virtual LinearSolver< Number > * get_linear_solver() const override
Definition: linear_implicit_system.C:353
libMesh::MeshBase::node_ptr_range
virtual SimpleRange< node_iterator > node_ptr_range()=0
SystemsTest::tearDown
void tearDown()
Definition: systems_test.C:513
libMesh::GhostingFunctor
This abstract base class defines the interface by which library code and user code can report associa...
Definition: ghosting_functor.h:153
new_linear_test
Number new_linear_test(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition: systems_test.C:343
SystemsTest::testProjectHierarchicEdge3
void testProjectHierarchicEdge3()
Definition: systems_test.C:1504
libMesh::ParallelObject::processor_id
processor_id_type processor_id() const
Definition: parallel_object.h:106
libMesh::TransientSystem::older_local_solution
std::unique_ptr< NumericVector< Number > > older_local_solution
All the values I need to compute my contribution to the simulation at hand.
Definition: transient_system.h:127
libMesh::System::add_variable
unsigned int add_variable(const std::string &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:1069
libMesh::MeshBase::local_node_ptr_range
virtual SimpleRange< node_iterator > local_node_ptr_range()=0
libMesh::MeshTools::Generation::build_line
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.
Definition: mesh_generation.C:1480
libMesh::QUAD4
Definition: enum_elem_type.h:41
TestCommWorld
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:111
libMesh::EquationSystems::init
virtual void init()
Initialize all the systems.
Definition: equation_systems.C:96
libMesh::Point
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:38
libMesh::processor_id_type
uint8_t processor_id_type
Definition: id_types.h:104
libMesh::MeshBase::active_local_elements_end
virtual element_iterator active_local_elements_end()=0
libMesh::NodeElem
The NodeElem is a point element, generally used as a side of a 1D element.
Definition: node_elem.h:37
libMesh::TRI3
Definition: enum_elem_type.h:39
libMesh::ImplicitSystem::matrix
SparseMatrix< Number > * matrix
The system matrix.
Definition: implicit_system.h:393
libMesh::Node
A Node is like a Point, but with more information.
Definition: node.h:52
libMesh::CONSTANT
Definition: enum_order.h:41
SystemsTest::testProjectMatrixTri3
void testProjectMatrixTri3()
Definition: systems_test.C:1516
libMesh::Tet4
The Tet4 is an element in 3D composed of 4 nodes.
Definition: cell_tet4.h:53
libMesh::as_range
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
libMesh::Elem::REFINE
Definition: elem.h:1171
SystemsTest::testBlockRestrictedVarNDofs
void testBlockRestrictedVarNDofs()
Definition: systems_test.C:980
libMesh::DenseVector::size
virtual unsigned int size() const override
Definition: dense_vector.h:92
libMesh::ZeroFunction
ConstFunction that simply returns 0.
Definition: zero_function.h:36
libMesh::DGFEMContext::get_elem_neighbor_jacobian
const DenseMatrix< Number > & get_elem_neighbor_jacobian() const
Const accessor for element-neighbor Jacobian.
Definition: dg_fem_context.h:136
libMesh::MeshBase::const_element_iterator
The definition of the const_element_iterator struct.
Definition: mesh_base.h:1891
SystemsTest::testBoundaryProjectCube
void testBoundaryProjectCube()
Definition: systems_test.C:745
libMesh::SparseMatrix::add
virtual void add(const numeric_index_type i, const numeric_index_type j, const T value)=0
Add value to the element (i,j).
SystemsTest::testProjectSquare
void testProjectSquare(const ElemType elem_type)
Definition: systems_test.C:570
libMesh::HIERARCHIC
Definition: enum_fe_family.h:37
libMesh::MONOMIAL
Definition: enum_fe_family.h:39
libMesh::EquationSystems
This is the EquationSystems class.
Definition: equation_systems.h:74
libMesh::Elem::set_node
virtual Node *& set_node(const unsigned int i)
Definition: elem.h:2059
SystemsTest::testProjectMatrixTet4
void testProjectMatrixTet4()
Definition: systems_test.C:1518
libMesh::MeshBase::node_ref
virtual const Node & node_ref(const dof_id_type i) const
Definition: mesh_base.h:451
libMesh::DofMap::n_dofs_on_processor
dof_id_type n_dofs_on_processor(const processor_id_type proc) const
Definition: dof_map.h:641
libMesh::MeshBase::n_nodes
virtual dof_id_type n_nodes() const =0
libMesh::TRI6
Definition: enum_elem_type.h:40
libMesh::ExplicitSystem
Manages consistently variables, degrees of freedom, and coefficient vectors for explicit systems.
Definition: explicit_system.h:48
libMesh::DenseVector::resize
void resize(const unsigned int n)
Resize the vector.
Definition: dense_vector.h:355
libMesh::EquationSystems::reinit
virtual void reinit()
Handle any mesh changes and reinitialize all the systems on the updated mesh.
Definition: equation_systems.C:121
libMesh::FEMContext::elem_fe_reinit
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:1436
SystemsTest::testProjectMatrix1D
void testProjectMatrix1D(const ElemType elem_type)
Definition: systems_test.C:1044
libMesh::MeshBase::sub_point_locator
std::unique_ptr< PointLocatorBase > sub_point_locator() const
Definition: mesh_base.C:672
libMesh::FEMContext::get_element_fe
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:275
libMesh::System::solution
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition: system.h:1539
libMesh::SparseMatrix::add_matrix
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.
AugmentSparsityOnNodes
Definition: systems_test.C:32
SystemsTest::testProjectCube
void testProjectCube(const ElemType elem_type)
Definition: systems_test.C:626
libMesh::SparseMatrix::build
static std::unique_ptr< SparseMatrix< T > > build(const Parallel::Communicator &comm, const SolverPackage solver_package=libMesh::default_solver_package())
Builds a SparseMatrix<T> using the linear solver package specified by solver_package.
Definition: sparse_matrix.C:130
libMesh::System::point_value
Number point_value(unsigned int var, const Point &p, const bool insist_on_success=true, const NumericVector< Number > *sol=nullptr) const
Definition: system.C:1971
libMesh::SparseMatrix::row_stop
virtual numeric_index_type row_stop() const =0
SystemsTest::testProjectMatrix2D
void testProjectMatrix2D(const ElemType elem_type)
Definition: systems_test.C:1151
libMesh::MeshBase::add_elem
virtual Elem * add_elem(Elem *e)=0
Add elem e to the end of the element array.
libMesh::DofMap
This class handles the numbering of degrees of freedom on a mesh.
Definition: dof_map.h:176
libmesh_cppunit.h
libMesh::Elem::subdomain_id
subdomain_id_type subdomain_id() const
Definition: elem.h:2069
libMesh::BoundaryInfo::add_edge
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.
Definition: boundary_info.C:707
AugmentSparsityOnNodes::mesh_reinit
virtual void mesh_reinit() override
Rebuild the cached _lower_to_upper map whenever our Mesh has changed.
Definition: systems_test.C:95
libMesh::System::projection_matrix
void projection_matrix(SparseMatrix< Number > &proj_mat) const
This method creates a projection matrix which corresponds to the operation of project_vector between ...
Definition: system_projection.C:870
libMesh::MeshBase::elements_end
virtual element_iterator elements_end()=0
libMesh::DiffContext::get_elem_jacobian
const DenseMatrix< Number > & get_elem_jacobian() const
Const accessor for element Jacobian.
Definition: diff_context.h:283
libMesh::EDGE3
Definition: enum_elem_type.h:36
libMesh::Edge2
The Edge2 is an element in 1D composed of 2 nodes.
Definition: edge_edge2.h:43
libMesh::DGFEMContext::get_neighbor_neighbor_jacobian
const DenseMatrix< Number > & get_neighbor_neighbor_jacobian() const
Const accessor for element-neighbor Jacobian.
Definition: dg_fem_context.h:188
libMesh::Elem
This is the base class from which all geometric element types are derived.
Definition: elem.h:100
libMesh::System::variable_number
unsigned short int variable_number(const std::string &var) const
Definition: system.C:1232
libMesh::LinearSolver::set_preconditioner_type
void set_preconditioner_type(const PreconditionerType pct)
Sets the type of preconditioner to use.
Definition: linear_solver.C:108
libMesh::FEMContext::get_side_qrule
const QBase & get_side_qrule() const
Accessor for element side quadrature rule for the dimension of the current _elem.
Definition: fem_context.h:797
libMesh::NODEELEM
Definition: enum_elem_type.h:66
libMesh::L2_LAGRANGE
Definition: enum_fe_family.h:41
libMesh::FEMContext::get_side_fe
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:312
libMesh::THIRD
Definition: enum_order.h:44
libMesh::DGFEMContext::set_neighbor
void set_neighbor(const Elem &neighbor)
Set the neighbor element which we will use to assemble DG terms.
Definition: dg_fem_context.h:220
libMesh::MeshTools::Subdivision::prev
static const unsigned int prev[3]
A lookup table for the decrement modulo 3 operation, for iterating through the three nodes per elemen...
Definition: mesh_subdivision_support.h:108
libMesh::QUAD9
Definition: enum_elem_type.h:43
libMesh::System::get_dof_map
const DofMap & get_dof_map() const
Definition: system.h:2099
libMesh::System::n_dofs
dof_id_type n_dofs() const
Definition: system.C:150
libMesh::MeshBase::add_point
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.
libMesh::SparseMatrix::set
virtual void set(const numeric_index_type i, const numeric_index_type j, const T value)=0
Set the element (i,j) to value.
libMesh::LAGRANGE
Definition: enum_fe_family.h:36
SystemsTest::testProjectHierarchicHex27
void testProjectHierarchicHex27()
Definition: systems_test.C:1507
libMesh::CouplingMatrix
This class defines a coupling matrix.
Definition: coupling_matrix.h:54
libMesh::Elem::neighbor_ptr
const Elem * neighbor_ptr(unsigned int i) const
Definition: elem.h:2085
libMesh::FEGenericBase::get_phi
const std::vector< std::vector< OutputShape > > & get_phi() const
Definition: fe_base.h:206
SystemsTest::testProjectLine
void testProjectLine(const ElemType elem_type)
Definition: systems_test.C:516
libMesh::TestClass
Definition: id_types.h:33
libMesh::MeshBase::allow_renumbering
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:1025
libMesh::Real
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Definition: libmesh_common.h:121
test_comm.h
libMesh::MeshBase::prepare_for_use
void prepare_for_use(const bool skip_renumber_nodes_and_elements=false, const bool skip_find_neighbors=false)
Prepare a newly ecreated (or read) mesh for use.
Definition: mesh_base.C:318
libMesh::TransientSystem::old_local_solution
std::unique_ptr< NumericVector< Number > > old_local_solution
All the values I need to compute my contribution to the simulation at hand.
Definition: transient_system.h:119
libMesh::LinearImplicitSystem
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and linear solvers ...
Definition: linear_implicit_system.h:55
libMesh::System::get_all_variable_numbers
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:1240
libMesh::System::project_solution
void project_solution(FunctionBase< Number > *f, FunctionBase< Gradient > *g=nullptr) const
Projects arbitrary functions onto the current solution.
Definition: system_projection.C:950
libMesh::BoundaryInfo::has_boundary_id
bool has_boundary_id(const Node *const node, const boundary_id_type id) const
Definition: boundary_info.C:972
SystemsTest::testDofCouplingWithVarGroups
void testDofCouplingWithVarGroups()
Definition: systems_test.C:888
TripleFunction::TripleFunction
TripleFunction(Number _offset=0)
Definition: systems_test.C:371
libMesh::Elem::node_ptr
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:2009
libMesh::MeshRefinement::uniformly_refine
void uniformly_refine(unsigned int n=1)
Uniformly refines the mesh n times.
Definition: mesh_refinement.C:1678
libMesh::DofMap::first_old_dof
dof_id_type first_old_dof(const processor_id_type proc) const
Definition: dof_map.h:660
libMesh::PointLocatorBase
This is the base class for point locators.
Definition: point_locator_base.h:62
libMesh::System::solve
virtual void solve()
Solves the system.
Definition: system.h:334
SystemsTest::tripleValueTest
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:459
libMesh::Elem::type
virtual ElemType type() const =0
libMesh::FIRST
Definition: enum_order.h:42
assembly_with_dg_fem_context
void assembly_with_dg_fem_context(EquationSystems &es, const std::string &)
Definition: systems_test.C:187
libMesh::Parameters
This class provides the ability to map between arbitrary, user-defined strings and several data types...
Definition: parameters.h:59
libMesh::DenseVector< Number >
libMesh::EDGE2
Definition: enum_elem_type.h:35
SystemsTest::testProjectCubeWithMeshFunction
void testProjectCubeWithMeshFunction(const ElemType elem_type)
Definition: systems_test.C:684
libMesh::ElemType
ElemType
Defines an enum for geometric element types.
Definition: enum_elem_type.h:33
libMesh::SparseMatrix::row_start
virtual numeric_index_type row_start() const =0
libMesh::DofMap::add_coupling_functor
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:1838
libMesh::EquationSystems::parameters
Parameters parameters
Data structure holding arbitrary parameters.
Definition: equation_systems.h:557