libMesh
miscellaneous_ex10.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2019 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 
20 // <h1>Miscellaneous Example 10 - Stitching meshes </h1>
21 // \author Dana Christen
22 // \date 2014
23 //
24 // This example shows how to generate a domain by stitching 8 cubic meshes
25 // together. Then a Poisson problem is solved on the stitched domain,
26 // and compared to the Poisson problem on a reference (unstitched) mesh
27 // to verify that the results match.
28 
29 
30 // C++ include files that we need
31 #include <iostream>
32 #include <algorithm>
33 #include <math.h>
34 #include <set>
35 #include <sstream>
36 #include <fstream>
37 
38 // libMesh includes
39 #include "libmesh/libmesh.h"
40 #include "libmesh/replicated_mesh.h"
41 #include "libmesh/mesh_generation.h"
42 #include "libmesh/linear_implicit_system.h"
43 #include "libmesh/equation_systems.h"
44 #include "libmesh/exact_solution.h"
45 #include "libmesh/exodusII_io.h"
46 #include "libmesh/fe.h"
47 #include "libmesh/quadrature_gauss.h"
48 #include "libmesh/dof_map.h"
49 #include "libmesh/sparse_matrix.h"
50 #include "libmesh/numeric_vector.h"
51 #include "libmesh/dense_matrix.h"
52 #include "libmesh/dense_vector.h"
53 #include "libmesh/elem.h"
54 #include "libmesh/dirichlet_boundaries.h"
55 #include "libmesh/zero_function.h"
56 #include "libmesh/libmesh_logging.h"
57 #include "libmesh/getpot.h"
58 #include "libmesh/error_vector.h"
59 #include "libmesh/kelly_error_estimator.h"
60 #include "libmesh/mesh_refinement.h"
61 #include "libmesh/enum_solver_package.h"
62 
63 using namespace libMesh;
64 
65 bool compare_elements(const ReplicatedMesh & mesh1,
66  const ReplicatedMesh & mesh2);
68  const std::string & system_name);
70  EquationSystems &);
71 
72 int main (int argc, char ** argv)
73 {
74  START_LOG("Initialize and create cubes", "main");
75  LibMeshInit init (argc, argv);
76 
77  // This example requires a linear solver package.
78  libmesh_example_requires(libMesh::default_solver_package() != INVALID_SOLVER_PACKAGE,
79  "--enable-petsc, --enable-trilinos, or --enable-eigen");
80 
81  // Create a GetPot object to parse the command line
82  GetPot command_line (argc, argv);
83 
84  // Check for proper calling arguments.
85  if (argc < 3)
86  libmesh_error_msg("Usage:\n" << "\t " << argv[0] << " -n 15");
87 
88  // Brief message to the user regarding the program name
89  // and command line arguments.
90  else
91  {
92  libMesh::out << "Running " << argv[0];
93 
94  for (int i=1; i<argc; i++)
95  libMesh::out << " " << argv[i];
96 
97  libMesh::out << std::endl << std::endl;
98  }
99 
100  // This is 3D-only problem
101  const unsigned int dim = 3;
102 
103  // Skip higher-dimensional examples on a lower-dimensional libMesh build
104  libmesh_example_requires(dim <= LIBMESH_DIM, "3D support");
105 
106  // We use Dirichlet boundary conditions here
107 #ifndef LIBMESH_ENABLE_DIRICHLET
108  libmesh_example_requires(false, "--enable-dirichlet");
109 #endif
110 
111  // Read number of elements used in each cube from command line
112  int ps = 10;
113  if (command_line.search(1, "-n"))
114  ps = command_line.next(ps);
115 
116  // Generate eight meshes that will be stitched
117  ReplicatedMesh mesh (init.comm());
118  ReplicatedMesh mesh1(init.comm());
119  ReplicatedMesh mesh2(init.comm());
120  ReplicatedMesh mesh3(init.comm());
121  ReplicatedMesh mesh4(init.comm());
122  ReplicatedMesh mesh5(init.comm());
123  ReplicatedMesh mesh6(init.comm());
124  ReplicatedMesh mesh7(init.comm());
125  MeshTools::Generation::build_cube (mesh, ps, ps, ps, -1, 0, 0, 1, 0, 1, HEX8);
126  MeshTools::Generation::build_cube (mesh1, ps, ps, ps, 0, 1, 0, 1, 0, 1, HEX8);
127  MeshTools::Generation::build_cube (mesh2, ps, ps, ps, -1, 0, -1, 0, 0, 1, HEX8);
128  MeshTools::Generation::build_cube (mesh3, ps, ps, ps, 0, 1, -1, 0, 0, 1, HEX8);
129  MeshTools::Generation::build_cube (mesh4, ps, ps, ps, -1, 0, 0, 1, -1, 0, HEX8);
130  MeshTools::Generation::build_cube (mesh5, ps, ps, ps, 0, 1, 0, 1, -1, 0, HEX8);
131  MeshTools::Generation::build_cube (mesh6, ps, ps, ps, -1, 0, -1, 0, -1, 0, HEX8);
132  MeshTools::Generation::build_cube (mesh7, ps, ps, ps, 0, 1, -1, 0, -1, 0, HEX8);
133 
134  // Generate a single unstitched reference mesh
135  ReplicatedMesh nostitch_mesh(init.comm());
136  MeshTools::Generation::build_cube (nostitch_mesh, ps*2, ps*2, ps*2, -1, 1, -1, 1, -1, 1, HEX8);
137  STOP_LOG("Initialize and create cubes", "main");
138 
139  START_LOG("Stitching", "main");
140  // We stitch the meshes in a hierarchical way.
141  mesh.stitch_meshes(mesh1, 2, 4, TOLERANCE, true, true, false, false);
142  mesh2.stitch_meshes(mesh3, 2, 4, TOLERANCE, true, true, false, false);
143  mesh.stitch_meshes(mesh2, 1, 3, TOLERANCE, true, true, false, false);
144  mesh4.stitch_meshes(mesh5, 2, 4, TOLERANCE, true, true, false, false);
145  mesh6.stitch_meshes(mesh7, 2, 4, TOLERANCE, true, true, false, false);
146  mesh4.stitch_meshes(mesh6, 1, 3, TOLERANCE, true, true, false, false);
147  mesh.stitch_meshes(mesh4, 0, 5, TOLERANCE, true, true, false, false);
148  STOP_LOG("Stitching", "main");
149 
150  START_LOG("Initialize and solve systems", "main");
151  EquationSystems equation_systems_stitch (mesh);
152  assemble_and_solve(mesh, equation_systems_stitch);
153 
154  EquationSystems equation_systems_nostitch (nostitch_mesh);
155  assemble_and_solve(nostitch_mesh, equation_systems_nostitch);
156  STOP_LOG("Initialize and solve systems", "main");
157 
158  START_LOG("Result comparison", "main");
159  ExactSolution comparison(equation_systems_stitch);
160  comparison.attach_reference_solution(&equation_systems_nostitch);
161  comparison.compute_error("Poisson", "u");
162  Real error = comparison.l2_error("Poisson", "u");
163  libmesh_assert_less(error, TOLERANCE*sqrt(TOLERANCE));
164  libMesh::out << "L2 error between stitched and non-stitched cases: " << error << std::endl;
165  STOP_LOG("Result comparison", "main");
166 
167  START_LOG("Output", "main");
168 #ifdef LIBMESH_HAVE_EXODUS_API
169  ExodusII_IO(mesh).write_equation_systems("solution_stitch.exo",
170  equation_systems_stitch);
171  ExodusII_IO(nostitch_mesh).write_equation_systems("solution_nostitch.exo",
172  equation_systems_nostitch);
173 #endif // #ifdef LIBMESH_HAVE_EXODUS_API
174  STOP_LOG("Output", "main");
175 
176  return 0;
177 }
178 
180  EquationSystems & equation_systems)
181 {
182  mesh.print_info();
183 
184  LinearImplicitSystem & system =
185  equation_systems.add_system<LinearImplicitSystem> ("Poisson");
186 
187 #ifdef LIBMESH_ENABLE_DIRICHLET
188  unsigned int u_var = system.add_variable("u", FIRST, LAGRANGE);
189 
191 
192  // the cube has boundaries IDs 0, 1, 2, 3, 4 and 5
193  std::set<boundary_id_type> boundary_ids;
194  for (int j = 0; j<6; ++j)
195  boundary_ids.insert(j);
196 
197  // Create a vector storing the variable numbers which the BC applies to
198  std::vector<unsigned int> variables(1);
199  variables[0] = u_var;
200 
201  ZeroFunction<> zf;
202 
203  // Most DirichletBoundary users will want to supply a "locally
204  // indexed" functor
205  DirichletBoundary dirichlet_bc(boundary_ids, variables, zf,
207  system.get_dof_map().add_dirichlet_boundary(dirichlet_bc);
208 #endif // LIBMESH_ENABLE_DIRICHLET
209 
210  equation_systems.init();
211  equation_systems.print_info();
212 
213 #ifdef LIBMESH_ENABLE_AMR
214  MeshRefinement mesh_refinement(mesh);
215 
216  mesh_refinement.refine_fraction() = 0.7;
217  mesh_refinement.coarsen_fraction() = 0.3;
218  mesh_refinement.max_h_level() = 5;
219 
220  const unsigned int max_r_steps = 2;
221 
222  for (unsigned int r_step=0; r_step<=max_r_steps; r_step++)
223  {
224  system.solve();
225  if (r_step != max_r_steps)
226  {
227  ErrorVector error;
228  KellyErrorEstimator error_estimator;
229 
230  error_estimator.estimate_error(system, error);
231 
232  libMesh::out << "Error estimate\nl2 norm = "
233  << error.l2_norm()
234  << "\nmaximum = "
235  << error.maximum()
236  << std::endl;
237 
238  mesh_refinement.flag_elements_by_error_fraction (error);
239 
240  mesh_refinement.refine_and_coarsen_elements();
241 
242  equation_systems.reinit();
243  }
244  }
245 #else
246  system.solve();
247 #endif
248 }
249 
251  const std::string & libmesh_dbg_var(system_name))
252 {
253  libmesh_assert_equal_to (system_name, "Poisson");
254 
255  const MeshBase & mesh = es.get_mesh();
256  const unsigned int dim = mesh.mesh_dimension();
257  LinearImplicitSystem & system = es.get_system<LinearImplicitSystem>("Poisson");
258 
259  const DofMap & dof_map = system.get_dof_map();
260 
261  FEType fe_type = dof_map.variable_type(0);
262  std::unique_ptr<FEBase> fe (FEBase::build(dim, fe_type));
263  QGauss qrule (dim, FIFTH);
264  fe->attach_quadrature_rule (&qrule);
265  std::unique_ptr<FEBase> fe_face (FEBase::build(dim, fe_type));
266  QGauss qface(dim-1, FIFTH);
267  fe_face->attach_quadrature_rule (&qface);
268 
269  const std::vector<Real> & JxW = fe->get_JxW();
270  const std::vector<std::vector<Real>> & phi = fe->get_phi();
271  const std::vector<std::vector<RealGradient>> & dphi = fe->get_dphi();
272 
275 
276  std::vector<dof_id_type> dof_indices;
277 
278  for (const auto & elem : mesh.active_local_element_ptr_range())
279  {
280  dof_map.dof_indices (elem, dof_indices);
281 
282  fe->reinit (elem);
283 
284  Ke.resize (dof_indices.size(),
285  dof_indices.size());
286 
287  Fe.resize (dof_indices.size());
288 
289  for (unsigned int qp=0; qp<qrule.n_points(); qp++)
290  {
291  for (std::size_t i=0; i<phi.size(); i++)
292  {
293  Fe(i) += JxW[qp]*phi[i][qp];
294  for (std::size_t j=0; j<phi.size(); j++)
295  Ke(i,j) += JxW[qp]*(dphi[i][qp]*dphi[j][qp]);
296  }
297  }
298 
299  dof_map.constrain_element_matrix_and_vector (Ke, Fe, dof_indices);
300 
301  system.matrix->add_matrix (Ke, dof_indices);
302  system.rhs->add_vector (Fe, dof_indices);
303  }
304 }
compare_elements
bool compare_elements(const ReplicatedMesh &mesh1, const ReplicatedMesh &mesh2)
libMesh::ExactSolution
This class handles the computation of the L2 and/or H1 error for the Systems in the EquationSystems o...
Definition: exact_solution.h:73
libMesh::MeshRefinement::refine_and_coarsen_elements
bool refine_and_coarsen_elements()
Refines and coarsens user-requested elements.
Definition: mesh_refinement.C:476
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::ExplicitSystem::rhs
NumericVector< Number > * rhs
The system matrix.
Definition: explicit_system.h:114
libMesh::QGauss
This class implements specific orders of Gauss quadrature.
Definition: quadrature_gauss.h:39
libMesh::DofMap::add_dirichlet_boundary
void add_dirichlet_boundary(const DirichletBoundary &dirichlet_boundary)
Adds a copy of the specified Dirichlet boundary to the system.
Definition: dof_map_constraints.C:4390
libMesh::HEX8
Definition: enum_elem_type.h:47
libMesh::JumpErrorEstimator::estimate_error
virtual void estimate_error(const System &system, ErrorVector &error_per_cell, const NumericVector< Number > *solution_vector=nullptr, bool estimate_parent_error=false) override
This function uses the derived class's jump error estimate formula to estimate the error on each cell...
Definition: jump_error_estimator.C:53
libMesh::StatisticsVector::l2_norm
virtual Real l2_norm() const
Definition: statistics.C:37
libMesh::MeshBase::active_local_element_ptr_range
virtual SimpleRange< element_iterator > active_local_element_ptr_range()=0
libMesh::QBase::n_points
unsigned int n_points() const
Definition: quadrature.h:126
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
Definition: factoryfunction.C:55
assemble_and_solve
void assemble_and_solve(MeshBase &, EquationSystems &)
Definition: miscellaneous_ex10.C:179
libMesh::EquationSystems::get_system
const T_sys & get_system(const std::string &name) const
Definition: equation_systems.h:757
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
std::sqrt
MetaPhysicL::DualNumber< T, D > sqrt(const MetaPhysicL::DualNumber< T, D > &in)
libMesh::TOLERANCE
static const Real TOLERANCE
Definition: libmesh_common.h:128
libMesh::DenseMatrix< Number >
libMesh::LinearImplicitSystem::solve
virtual void solve() override
Assembles & solves the linear system A*x=b.
Definition: linear_implicit_system.C:108
libMesh::default_solver_package
SolverPackage default_solver_package()
Definition: libmesh.C:993
mesh
MeshBase & mesh
Definition: mesh_communication.C:1257
libMesh::MeshBase::mesh_dimension
unsigned int mesh_dimension() const
Definition: mesh_base.C:135
libMesh::FIFTH
Definition: enum_order.h:46
libMesh::ExodusII_IO
The ExodusII_IO class implements reading meshes in the ExodusII file format from Sandia National Labs...
Definition: exodusII_io.h:51
dim
unsigned int dim
Definition: adaptivity_ex3.C:113
libMesh::DenseMatrix::resize
void resize(const unsigned int new_m, const unsigned int new_n)
Resize the matrix.
Definition: dense_matrix.h:822
libMesh::ReplicatedMesh
The ReplicatedMesh class is derived from the MeshBase class, and is used to store identical copies of...
Definition: replicated_mesh.h:47
libMesh::TriangleWrapper::init
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
libMesh::MeshRefinement
Implements (adaptive) mesh refinement algorithms for a MeshBase.
Definition: mesh_refinement.h:61
libMesh::LOCAL_VARIABLE_ORDER
Definition: dirichlet_boundaries.h:62
libMesh::KellyErrorEstimator
This class implements the Kelly error indicator which is based on the flux jumps between elements.
Definition: kelly_error_estimator.h:59
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
assemble_poisson
void assemble_poisson(EquationSystems &es, const std::string &system_name)
libMesh::MeshBase
This is the MeshBase class.
Definition: mesh_base.h:78
libMesh::ExactSolution::attach_reference_solution
void attach_reference_solution(const EquationSystems *es_fine)
Attach function similar to system.h which allows the user to attach a second EquationSystems object w...
Definition: exact_solution.C:81
libMesh::INVALID_SOLVER_PACKAGE
Definition: enum_solver_package.h:43
libMesh::FEGenericBase::build
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
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::EquationSystems::init
virtual void init()
Initialize all the systems.
Definition: equation_systems.C:96
libMesh::ImplicitSystem::matrix
SparseMatrix< Number > * matrix
The system matrix.
Definition: implicit_system.h:393
main
int main(int argc, char **argv)
Definition: miscellaneous_ex10.C:72
libMesh::ErrorVector
The ErrorVector is a specialization of the StatisticsVector for error data computed on a finite eleme...
Definition: error_vector.h:50
libMesh::LibMeshInit
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
Definition: libmesh.h:83
libMesh::ZeroFunction
ConstFunction that simply returns 0.
Definition: zero_function.h:36
libMesh::ExactSolution::l2_error
Real l2_error(const std::string &sys_name, const std::string &unknown_name)
Definition: exact_solution.C:333
libMesh::MeshRefinement::max_h_level
unsigned int & max_h_level()
The max_h_level is the greatest refinement level an element should reach.
Definition: mesh_refinement.h:891
libMesh::ExactSolution::compute_error
void compute_error(const std::string &sys_name, const std::string &unknown_name)
Computes and stores the error in the solution value e = u-u_h, the gradient grad(e) = grad(u) - grad(...
Definition: exact_solution.C:227
libMesh::EquationSystems::print_info
void print_info(std::ostream &os=libMesh::out) const
Prints information about the equation systems, by default to libMesh::out.
Definition: equation_systems.C:1314
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::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::MeshRefinement::coarsen_fraction
Real & coarsen_fraction()
The coarsen_fraction sets either a desired target or a desired maximum number of elements to flag for...
Definition: mesh_refinement.h:885
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.
libMesh::MeshRefinement::refine_fraction
Real & refine_fraction()
The refine_fraction sets either a desired target or a desired maximum number of elements to flag for ...
Definition: mesh_refinement.h:879
libMesh::FEType
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition: fe_type.h:178
libMesh::DofMap
This class handles the numbering of degrees of freedom on a mesh.
Definition: dof_map.h:176
libMesh::MeshBase::print_info
void print_info(std::ostream &os=libMesh::out) const
Prints relevant information about the mesh.
Definition: mesh_base.C:585
libMesh::DirichletBoundary
This class allows one to associate Dirichlet boundary values with a given set of mesh boundary ids an...
Definition: dirichlet_boundaries.h:88
libMesh::System::get_dof_map
const DofMap & get_dof_map() const
Definition: system.h:2099
libMesh::LAGRANGE
Definition: enum_fe_family.h:36
libMesh::Real
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Definition: libmesh_common.h:121
libMesh::LinearImplicitSystem
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and linear solvers ...
Definition: linear_implicit_system.h:55
libMesh::MeshRefinement::flag_elements_by_error_fraction
void flag_elements_by_error_fraction(const ErrorVector &error_per_cell, const Real refine_fraction=0.3, const Real coarsen_fraction=0.0, const unsigned int max_level=libMesh::invalid_uint)
Flags elements for coarsening and refinement based on the computed error passed in error_per_cell.
Definition: mesh_refinement_flagging.C:44
libMesh::out
OStreamProxy out
libMesh::FIRST
Definition: enum_order.h:42
libMesh::DenseVector< Number >
libMesh::StatisticsVector::maximum
virtual T maximum() const
Definition: statistics.C:62