Loading [MathJax]/extensions/tex2jax.js
libMesh
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
miscellaneous_ex8.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2025 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:67
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:90
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 project_solution(FunctionBase< Number > *f, FunctionBase< Gradient > *g=nullptr) const
Projects arbitrary functions onto the current solution.
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:96
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:1335
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
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 void read(const std::string &name, void *mesh_data=nullptr, bool skip_renumber_nodes_and_elements=false, bool skip_find_neighbors=false) override
Reads the file specified by name.
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:2108
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)