libMesh
write_vec_and_scalar.C
Go to the documentation of this file.
1 // Basic include files
2 #include "libmesh/equation_systems.h"
3 #include "libmesh/exodusII_io.h"
4 #include "libmesh/mesh.h"
5 #include "libmesh/mesh_generation.h"
6 #include "libmesh/node.h"
7 #include "libmesh/string_to_enum.h"
8 #include "libmesh/exodusII_io.h"
9 #include "libmesh/explicit_system.h"
10 #include "libmesh/numeric_vector.h"
11 
12 #include "test_comm.h"
13 #include "libmesh_cppunit.h"
14 
15 
16 // Bring in everything from the libMesh namespace
17 using namespace libMesh;
18 
19 class WriteVecAndScalar : public CppUnit::TestCase
20 {
24 public:
25  CPPUNIT_TEST_SUITE(WriteVecAndScalar);
26 
27 #if LIBMESH_DIM > 1
28  CPPUNIT_TEST(testWrite);
29 #endif
30 
31  CPPUNIT_TEST_SUITE_END();
32 
33  void testWrite()
34  {
36 
37  // We set our initial conditions based on build_square node ids
38  mesh.allow_renumbering(false);
39 
41  1, 1,
42  -1., 1.,
43  -1., 1.,
44  Utility::string_to_enum<ElemType>("TRI6"));
45 
46  // Create an equation systems object.
47  EquationSystems equation_systems(mesh);
48 
49  ExplicitSystem & system = equation_systems.add_system<ExplicitSystem>("Tester");
50  system.add_variable("u", FIRST, NEDELEC_ONE);
51  system.add_variable("v", FIRST, LAGRANGE);
52 
53  // Initialize the system
54  equation_systems.init();
55 
56  // Mimic the initial conditions of u(i)=2*i in the serial case,
57  // but indexed by node id rather than dof id.
58  std::vector<Real> initial_vector({10, 0, 12, 8, 4, 2, 16, 6, 14});
59 
60  NumericVector<Number> & sys_solution = *(system.solution);
61  for (const auto & node : mesh.node_ptr_range())
62  {
63  dof_id_type dof_id;
64  if (node->n_comp(0,0))
65  {
66  dof_id = node->dof_number(0,0,0);
67  }
68  else
69  {
70  CPPUNIT_ASSERT(node->n_comp(0,1));
71  dof_id = node->dof_number(0,1,0);
72  }
73  if (dof_id >= sys_solution.first_local_index() &&
74  dof_id < sys_solution.last_local_index())
75  sys_solution.set(dof_id, initial_vector[node->id()]);
76  if (mesh.n_processors() == 1)
77  CPPUNIT_ASSERT_EQUAL(initial_vector[node->id()], dof_id*Real(2));
78  }
79  sys_solution.close();
80 
81 #ifdef LIBMESH_HAVE_EXODUS_API
82 
83  // We write the file in the ExodusII format.
84  ExodusII_IO(mesh).write_equation_systems("out.e", equation_systems);
85 
86  // Make sure that the writing is done before the reading starts.
87  TestCommWorld->barrier();
88 
89  // Now read it back in
90  Mesh read_mesh(*TestCommWorld);
91  ExodusII_IO exio(read_mesh);
92  exio.read("out.e");
93 
94  read_mesh.prepare_for_use();
95  EquationSystems es2(read_mesh);
96  ExplicitSystem & sys2 = es2.add_system<ExplicitSystem>("Test");
97 
98  const std::vector<std::string> & nodal_vars(exio.get_nodal_var_names());
99 
100  for (const auto & var_name : nodal_vars)
101  sys2.add_variable(var_name, SECOND, LAGRANGE);
102 
103  es2.init();
104 
105  for (const auto & var_name : nodal_vars)
106  exio.copy_nodal_solution(sys2, var_name, var_name, 1);
107 
108  // VariableGroup optimization means that DoFs iterate over each of
109  // the 3 variables on each node before proceeding to the next
110  // node.
111  // u_x, u_y, v
112  const std::vector<Real> gold_vector = {-1, 3, 10,
113  0, 1, 12,
114  2, 0, 14,
115  0, 1.5, 11,
116  0.5, 1, 13,
117  0.5, 1.5, 12,
118  3, 4, 16,
119  3, 1.5, 15,
120  0.5, 4, 13};
121 
122  // Translation from node id to dof indexing order as gets done in
123  // serial
124  const std::vector<dof_id_type>
125  node_reordering({0, 3, 1, 8, 5, 4, 6, 7, 2});
126 
127  Real tol = 1e-12;
128  NumericVector<Number> & sys2_soln(*sys2.solution);
129  for (const auto & node : read_mesh.node_ptr_range())
130  {
131  if (node->processor_id() != mesh.processor_id())
132  continue;
133 
134  // We write out real, imaginary, and magnitude for complex
135  // numbers
136 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
137  const unsigned int v2 = 3;
138 #else
139  const unsigned int v2 = 1;
140 #endif
141  CPPUNIT_ASSERT_EQUAL(node->n_vars(0), 3*v2);
142 
143  const dof_id_type gold_i_ux = node_reordering[node->id()] * 3;
144  const dof_id_type gold_i_uy = gold_i_ux + 1;
145  const dof_id_type gold_i_v = gold_i_uy + 1;
146 
147  LIBMESH_ASSERT_FP_EQUAL(libmesh_real(sys2_soln(node->dof_number(0,0,0))),
148  gold_vector[gold_i_ux], tol);
149  LIBMESH_ASSERT_FP_EQUAL(libmesh_real(sys2_soln(node->dof_number(0,v2,0))),
150  gold_vector[gold_i_uy], tol);
151  LIBMESH_ASSERT_FP_EQUAL(libmesh_real(sys2_soln(node->dof_number(0,2*v2,0))),
152  gold_vector[gold_i_v], tol);
153 
154  // Let's check imaginary parts and magnitude for good measure
155 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
156  LIBMESH_ASSERT_FP_EQUAL(libmesh_real(sys2_soln(node->dof_number(0,1,0))),
157  0.0, tol);
158  LIBMESH_ASSERT_FP_EQUAL(libmesh_real(sys2_soln(node->dof_number(0,2,0))),
159  std::abs(gold_vector[gold_i_ux]), tol);
160  LIBMESH_ASSERT_FP_EQUAL(libmesh_real(sys2_soln(node->dof_number(0,4,0))),
161  0.0, tol);
162  LIBMESH_ASSERT_FP_EQUAL(libmesh_real(sys2_soln(node->dof_number(0,5,0))),
163  std::abs(gold_vector[gold_i_uy]), tol);
164  LIBMESH_ASSERT_FP_EQUAL(libmesh_real(sys2_soln(node->dof_number(0,7,0))),
165  0.0, tol);
166  LIBMESH_ASSERT_FP_EQUAL(libmesh_real(sys2_soln(node->dof_number(0,8,0))),
167  std::abs(gold_vector[gold_i_v]), tol);
168 #endif
169  }
170 #endif // #ifdef LIBMESH_HAVE_EXODUS_API
171  }
172 };
173 
CPPUNIT_TEST_SUITE_REGISTRATION
CPPUNIT_TEST_SUITE_REGISTRATION(WriteVecAndScalar)
libMesh::dof_id_type
uint8_t dof_id_type
Definition: id_types.h:67
libMesh::Mesh
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition: mesh.h:50
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
WriteVecAndScalar
Definition: write_vec_and_scalar.C:19
libMesh::libmesh_real
T libmesh_real(T a)
Definition: libmesh_common.h:166
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
Definition: factoryfunction.C:55
mesh
MeshBase & mesh
Definition: mesh_communication.C:1257
libMesh::DistributedMesh::node_ptr_range
virtual SimpleRange< node_iterator > node_ptr_range() override
Definition: distributed_mesh.h:501
libMesh::ExodusII_IO
The ExodusII_IO class implements reading meshes in the ExodusII file format from Sandia National Labs...
Definition: exodusII_io.h:51
libMesh::SECOND
Definition: enum_order.h:43
libMesh::NumericVector< Number >
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::ExodusII_IO::copy_nodal_solution
void copy_nodal_solution(System &system, std::string var_name, unsigned int timestep=1)
Backward compatibility version of function that takes a single variable name.
Definition: exodusII_io.C:82
std::abs
MetaPhysicL::DualNumber< T, D > abs(const MetaPhysicL::DualNumber< T, D > &in)
libMesh::ParallelObject::n_processors
processor_id_type n_processors() const
Definition: parallel_object.h:100
libMesh::MeshBase::node_ptr_range
virtual SimpleRange< node_iterator > node_ptr_range()=0
libMesh::ParallelObject::processor_id
processor_id_type processor_id() const
Definition: parallel_object.h:106
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
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::ExodusII_IO::get_nodal_var_names
const std::vector< std::string > & get_nodal_var_names()
Return list of the nodal variable names.
Definition: exodusII_io.C:1481
libMesh::EquationSystems
This is the EquationSystems class.
Definition: equation_systems.h:74
libMesh::MeshOutput::write_equation_systems
virtual void write_equation_systems(const std::string &, const EquationSystems &, const std::set< std::string > *system_names=nullptr)
This method implements writing a mesh with data to a specified file where the data is taken from the ...
Definition: mesh_output.C:31
libMesh::ExplicitSystem
Manages consistently variables, degrees of freedom, and coefficient vectors for explicit systems.
Definition: explicit_system.h:48
libMesh::System::solution
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition: system.h:1539
libMesh::NumericVector::set
virtual void set(const numeric_index_type i, const T value)=0
Sets v(i) = value.
libmesh_cppunit.h
libMesh::NEDELEC_ONE
Definition: enum_fe_family.h:61
WriteVecAndScalar::testWrite
void testWrite()
Definition: write_vec_and_scalar.C:33
libMesh::LAGRANGE
Definition: enum_fe_family.h:36
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::ExodusII_IO::read
virtual void read(const std::string &name) override
This method implements reading a mesh from a specified file.
Definition: exodusII_io.C:143
libMesh::FIRST
Definition: enum_order.h:42