libMesh
miscellaneous_ex8.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2026 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 8 - Meshfree Interpolation Utilities.</h1>
21 // \author Benjamin S. Kirk
22 // \date 2012
23 //
24 // LibMesh provides some utilities for pointcloud-type interpolation, as
25 // demonstrated in this example.
26 
27 // Example include files
28 #include "libmesh/libmesh.h"
29 #include "libmesh/meshfree_interpolation.h"
30 #include "libmesh/radial_basis_interpolation.h"
31 #include "libmesh/mesh.h"
32 #include "libmesh/mesh_refinement.h"
33 #include "libmesh/equation_systems.h"
34 #include "libmesh/numeric_vector.h"
35 #include "libmesh/tecplot_io.h"
36 #include "libmesh/threads.h"
37 #include "libmesh/node.h"
38 #include "libmesh/getpot.h"
39 #include "libmesh/meshfree_interpolation_function.h"
40 
41 // C++ includes
42 #include <cstdlib>
43 
44 
45 // Bring in everything from the libMesh namespace
46 using namespace libMesh;
47 
48 
49 void create_random_point_cloud (const unsigned int Npts,
50  std::vector<Point> & pts,
51  const Real max_range = 10)
52 {
53  libMesh::out << "Generating "<< Npts << " local point cloud...";
54  pts.resize(Npts);
55 
56  for (size_t i=0;i<Npts;i++)
57  {
58  pts[i](0) = max_range * (std::rand() % 1000) / Real(1000);
59  pts[i](1) = max_range * (std::rand() % 1000) / Real(1000);
60  pts[i](2) = max_range * (std::rand() % 1000) / Real(1000);
61  }
62  libMesh::out << "done\n";
63 }
64 
65 
66 
68 {
69  const Real
70  x = p(0),
71  y = p(1),
72  z = p(2);
73 
74  return (x*x*x +
75  y*y*y*y +
76  z*z*z*z*z);
77 }
78 
79 
80 
82 {
83  const Real
84  x = p(0),
85  y = p(1),
86  z = p(2);
87 
88  return (x*x +
89  y*y +
90  z*z*z);
91 }
92 
94  const Parameters &,
95  const std::string &,
96  const std::string &)
97 {
98  return exact_solution_v(p);
99 }
100 
101 // We now define the function which provides the
102 // initialization routines for the "Convection-Diffusion"
103 // system. This handles things like setting initial
104 // conditions and boundary conditions.
106  const std::string & system_name)
107 {
108  // Get a reference to the Convection-Diffusion system object.
109  System & system =
110  es.get_system<System>(system_name);
111 
112  system.project_solution(exact_value, nullptr, es.parameters);
113 }
114 
115 
116 
117 
118 int main(int argc, char ** argv)
119 {
120  // Skip this example if we do not meet certain requirements
121  libmesh_example_requires(3 <= LIBMESH_DIM, "3D support");
122 #ifndef LIBMESH_HAVE_EIGEN
123  libmesh_example_requires(false, "--enable-eigen");
124 #endif
125 #ifndef LIBMESH_HAVE_ZLIB_H
126  libmesh_example_requires(false, "--enable-zlib");
127 #endif
128  // Nanoflann is giving me trouble with extended Reals
129 #ifdef LIBMESH_DEFAULT_TRIPLE_PRECISION
130  libmesh_example_requires(false, "--disable-triple-precision");
131 #endif
132 #ifdef LIBMESH_DEFAULT_QUADRUPLE_PRECISION
133  libmesh_example_requires(false, "--disable-quadruple-precision");
134 #endif
135 
136  // Initialize libMesh.
137  LibMeshInit init (argc, argv);
138  {
139  GetPot input(argc, argv);
140 
141  // Demonstration case 1
142  {
143  std::vector<Point> tgt_pts;
144  std::vector<Number> tgt_data_idi, tgt_data_rbi;
145  std::vector<std::string> field_vars {"u", "v"};
146 
148  /* n_interp_pts = */ 8,
149  /* power = */ 2);
150 
151  RadialBasisInterpolation<3> rbi (init.comm());
152 
153  idi.set_field_variables (field_vars);
154  rbi.set_field_variables (field_vars);
155 
156  const int n_source_points = input("n_source_points", 100);
157 
158  // Source points are independent on each processor
159  const int my_n_source_points =
160  n_source_points / init.comm().size() +
161  (init.comm().rank() < n_source_points % init.comm().size());
162 
163  create_random_point_cloud (my_n_source_points,
164  idi.get_source_points());
165 
166 
167  // Explicitly set the data values we will interpolate from
168  {
169  const std::vector<Point> & src_pts (idi.get_source_points());
170  std::vector<Number> & src_vals (idi.get_source_vals());
171 
172  src_vals.clear(); src_vals.reserve(2*src_pts.size());
173 
174  for (std::vector<Point>::const_iterator pt_it=src_pts.begin();
175  pt_it != src_pts.end(); ++pt_it)
176  {
177  src_vals.push_back (exact_solution_u (*pt_it));
178  src_vals.push_back (exact_solution_v (*pt_it));
179  }
180  }
181 
182  // give rbi the same info as idi
183  rbi.get_source_points() = idi.get_source_points();
184  rbi.get_source_vals() = idi.get_source_vals();
185 
186  idi.prepare_for_use();
187  rbi.prepare_for_use();
188 
189  libMesh::out << idi;
190 
191  // Interpolate to some other random points, and evaluate the result
192  {
193  const int n_target_points = input("n_target_points", 100);
194 
195  create_random_point_cloud (n_target_points,
196  tgt_pts);
197 
198  //tgt_pts = rbi.get_source_points();
199 
200  idi.interpolate_field_data (field_vars,
201  tgt_pts,
202  tgt_data_idi);
203 
204  rbi.interpolate_field_data (field_vars,
205  tgt_pts,
206  tgt_data_rbi);
207 
208  std::vector<Number>::const_iterator
209  v_idi = tgt_data_idi.begin(),
210  v_rbi = tgt_data_rbi.begin();
211 
212  for (std::vector<Point>::const_iterator p_it=tgt_pts.begin();
213  p_it!=tgt_pts.end(); ++p_it)
214  {
215  libMesh::out << "\nAt target point " << *p_it
216  << "\n u_interp_idi=" << *v_idi
217  << ", u_interp_rbi=" << *v_rbi
218  << ", u_exact=" << exact_solution_u(*p_it);
219  ++v_idi;
220  ++v_rbi;
221  libMesh::out << "\n v_interp_idi=" << *v_idi
222  << ", v_interp_rbi=" << *v_rbi
223  << ", v_exact=" << exact_solution_v(*p_it)
224  << std::endl;
225  ++v_idi;
226  ++v_rbi;
227  }
228  }
229  }
230 
231 
232  // Demonstration case 2
233  {
234  Mesh mesh_a(init.comm()), mesh_b(init.comm());
235 
236  mesh_a.read("struct.ucd.gz");
237  mesh_b.read("unstruct.ucd.gz");
238 
239  // Refine the meshes if requested
240  const int n_refinements = input("n_refinements", 0);
241 
242  // Skip adaptive runs on a non-adaptive libMesh build
243 #ifndef LIBMESH_ENABLE_AMR
244  libmesh_example_requires(n_refinements==0, "--enable-amr");
245 #else
246  MeshRefinement mesh_refinement_a(mesh_a);
247  mesh_refinement_a.uniformly_refine(n_refinements);
248  MeshRefinement mesh_refinement_b(mesh_b);
249  mesh_refinement_b.uniformly_refine(n_refinements);
250 #endif
251 
252  // Create equation systems objects.
254  es_a(mesh_a), es_b(mesh_b);
255 
256  System & sys_a = es_a.add_system<System>("src_system");
257  System & sys_b = es_b.add_system<System>("dest_system");
258 
259  sys_a.add_variable ("Cp", FIRST);
260  sys_b.add_variable ("Cp", FIRST);
261 
263  es_a.init();
264 
265  // Write out the initial conditions.
266  TecplotIO(mesh_a).write_equation_systems ("src.dat",
267  es_a);
268 
270  /* n_interp_pts = */ 4,
271  /* power = */ 2);
272  RadialBasisInterpolation<3> rbi (init.comm());
273 
274  std::vector<Point> & src_pts (idi.get_source_points());
275  std::vector<Number> & src_vals (idi.get_source_vals());
276  idi.set_field_variables({"Cp"});
277 
278  // We now will loop over every node in the source mesh
279  // and add it to a source point list, along with the solution
280  for (const auto & node : mesh_a.local_node_ptr_range())
281  {
282  src_pts.push_back(*node);
283  src_vals.push_back(sys_a.current_solution(node->dof_number(0, 0, 0)));
284  }
285 
286  rbi.set_field_variables({"Cp"});
287  rbi.get_source_points() = idi.get_source_points();
288  rbi.get_source_vals() = idi.get_source_vals();
289 
290  // We have only set local values - prepare for use by gathering remote data
291  idi.prepare_for_use();
292  rbi.prepare_for_use();
293 
294  // Create a MeshfreeInterpolationFunction that uses our InverseDistanceInterpolation
295  // object. Since each MeshfreeInterpolationFunction shares the same InverseDistanceInterpolation
296  // object in a threaded environment we must also provide a locking mechanism.
297  {
298  Threads::spin_mutex mutex;
299  MeshfreeInterpolationFunction mif(idi, mutex);
300 
301  // project the solution onto system b
302  es_b.init();
303  sys_b.project_solution (&mif);
304 
305  // Write the result
306  TecplotIO(mesh_b).write_equation_systems ("dest_idi.dat",
307  es_b);
308  }
309 
310  // Create a MeshfreeInterpolationFunction that uses our RadialBasisInterpolation
311  // object. Since each MeshfreeInterpolationFunction shares the same RadialBasisInterpolation
312  // object in a threaded environment we must also provide a locking mechanism.
313  {
314  Threads::spin_mutex mutex;
315  MeshfreeInterpolationFunction mif(rbi, mutex);
316 
317  // project the solution onto system b
318  sys_b.project_solution (&mif);
319 
320  // Write the result
321  TecplotIO(mesh_b).write_equation_systems ("dest_rbi.dat",
322  es_b);
323  }
324  }
325  }
326  return 0;
327 }
This is the EquationSystems class.
Inverse distance interpolation.
Radial Basis Function interpolation.
This class provides the ability to map between arbitrary, user-defined strings and several data types...
Definition: parameters.h:74
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
Real exact_solution_v(const Point &p)
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
Definition: libmesh.h:91
The libMesh namespace provides an interface to certain functionality in the library.
const T_sys & get_system(std::string_view name) const
Number current_solution(const dof_id_type global_dof_number) const
Definition: system.C:162
void init_sys(EquationSystems &es, const std::string &system_name)
Implements (adaptive) mesh refinement algorithms for a MeshBase.
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition: system.h:98
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
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.
Real exact_solution_u(const Point &p)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void set_field_variables(std::vector< std::string > names)
Defines the field variable(s) we are responsible for, and importantly their assumed ordering...
OStreamProxy out
virtual void read(const std::string &name, void *mesh_data=nullptr, bool skip_renumber_nodes_and_elements=false, bool skip_find_neighbors=false, bool skip_detect_interior_parents=false) override
Reads the file specified by name.
Parameters parameters
Data structure holding arbitrary parameters.
This class implements writing meshes in the Tecplot format.
Definition: tecplot_io.h:43
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.
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition: mesh.h:50
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
void attach_init_function(void fptr(EquationSystems &es, const std::string &name))
Register a user function to use in initializing the system.
Definition: system.C:1928
Number exact_value(const Point &p, const Parameters &, const std::string &, const std::string &)
int main(int argc, char **argv)
void uniformly_refine(unsigned int n=1)
Uniformly refines the mesh n times.
void create_random_point_cloud(const unsigned int Npts, std::vector< Point > &pts, const Real max_range=10)