libMesh
project_solution_test.C
Go to the documentation of this file.
1 #include <libmesh/equation_systems.h>
2 #include <libmesh/replicated_mesh.h>
3 #include <libmesh/mesh_generation.h>
4 #include <libmesh/dof_map.h>
5 #include <libmesh/system.h>
6 #include <libmesh/elem.h>
7 #include <libmesh/numeric_vector.h>
8 
9 #include "test_comm.h"
10 #include "libmesh_cppunit.h"
11 
12 #include <cmath>
13 #include <vector>
14 
15 #include <libmesh/exodusII_io.h>
16 
17 using namespace libMesh;
18 
19 namespace
20 {
21 
22  Number baseline_linear_function(const Point &p,
23  const Parameters &,
24  const std::string &,
25  const std::string &)
26  {
27  return 0.5 * p(0) + 0.25 * p(1);
28  }
29 
30  Number circle_projection_function(const Point &p,
31  const Parameters &,
32  const std::string &,
33  const std::string &)
34  {
35  return std::cos(0.5 * libMesh::pi * p(0)) *
36  std::sin(0.5 * libMesh::pi * p(1)) *
37  std::cos(0.5 * libMesh::pi * p(2));
38  }
39 
40 }
41 
42 class ProjectSolutionTest : public CppUnit::TestCase
43 {
44 public:
45  LIBMESH_CPPUNIT_TEST_SUITE(ProjectSolutionTest);
46  CPPUNIT_TEST(test_partial_project_solution);
47  CPPUNIT_TEST_SUITE_END();
48 
49 private:
51  {
52  LOG_UNIT_TEST;
53 
54 #if LIBMESH_DIM < 2
55  return;
56 #else
57  ReplicatedMesh mesh(*TestCommWorld, /*dim=*/2);
58 
60  /*nx=*/5, /*ny=*/5,
61  /*xmin=*/-1., /*xmax=*/1.,
62  /*ymin=*/-1., /*ymax=*/1.,
63  QUAD4);
64 
66  System &sys = es.add_system<System>("ProjSys");
67 
68  // two dofs per element
69  const unsigned int u_var = sys.add_variable("u", CONSTANT, MONOMIAL);
70  const unsigned int v_var = sys.add_variable("v", CONSTANT, MONOMIAL);
71 
72  es.init();
73 
74  // baseline
75  sys.project_solution(baseline_linear_function, /*gptr=*/nullptr, es.parameters);
76  // ExodusII_IO(mesh).write_equation_systems("before_project.e", es);
77 
78  const DofMap &dof_map = sys.get_dof_map();
79 
80  // collect elements whose vertex_average lies inside the circle
81  const Real r2 = 0.5 * 0.5;
82 
83  std::vector<const Elem *> selected_elems;
84  for (const auto &e : mesh.active_local_element_ptr_range())
85  {
86  const Point c = e->vertex_average();
87  if (c(0) * c(0) + c(1) * c(1) <= r2)
88  selected_elems.push_back(e);
89  }
90 
91  // ConstElemRange expects mesh element iterators OR a vec_type*
92  // Here we use the vector-backed constructor.
93  ConstElemRange circle_range(&selected_elems);
94 
95  // project only on selected elements and only on u variable
96  std::vector<unsigned int> vars_to_project = {u_var};
97  sys.project_solution(circle_projection_function, /*gptr=*/nullptr, es.parameters, circle_range, vars_to_project);
98  // ExodusII_IO(mesh).write_equation_systems("after_project.e", es);
99 
100  // Check that restricted projection only overwrites elements inside the circle.
101  // Outside elements must keep the baseline projection.
102  const Real tol = 1e-3;
103 
104  for (const auto &e : mesh.active_local_element_ptr_range())
105  {
106  const Point c = e->vertex_average();
107  const bool inside = (c(0) * c(0) + c(1) * c(1) <= r2);
108 
109  std::vector<dof_id_type> u_indices, v_indices;
110  dof_map.dof_indices(e, u_indices, u_var);
111  dof_map.dof_indices(e, v_indices, v_var);
112 
113  const Number u_val = (*sys.solution)(u_indices[0]);
114  const Number v_val = (*sys.solution)(v_indices[0]);
115 
116  const Number val_baseline = baseline_linear_function(c, es.parameters, "", "");
117  const Number val_projected = circle_projection_function(c, es.parameters, "", "");
118  if (inside)
119  // Inside the circle, values should be equal to the projected value.
120  LIBMESH_ASSERT_NUMBERS_EQUAL(u_val, val_projected, tol);
121  else
122  // Outside the circle, values must remain unchanged.
123  LIBMESH_ASSERT_NUMBERS_EQUAL(u_val, val_baseline, tol);
124 
125  // v variable was never projected, should always equal baseline
126  LIBMESH_ASSERT_NUMBERS_EQUAL(v_val, val_baseline, tol);
127  }
128 #endif
129  }
130 };
131 
This is the EquationSystems class.
The ReplicatedMesh class is derived from the MeshBase class, and is used to store identical copies of...
This class provides the ability to map between arbitrary, user-defined strings and several data types...
Definition: parameters.h:74
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Definition: dof_map.C:2201
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:218
MeshBase & mesh
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.
The StoredRange class defines a contiguous, divisible set of objects.
Definition: stored_range.h:54
The libMesh namespace provides an interface to certain functionality in the library.
This class handles the numbering of degrees of freedom on a mesh.
Definition: dof_map.h:179
CPPUNIT_TEST_SUITE_REGISTRATION(ProjectSolutionTest)
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition: system.h:98
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition: system.h:1655
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 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.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Parameters parameters
Data structure holding arbitrary parameters.
virtual void init()
Initialize all the systems.
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.
const DofMap & get_dof_map() const
Definition: system.h:2417
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
const Real pi
.
Definition: libmesh.h:292