libMesh
Loading...
Searching...
No Matches
projection.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// Open the input mesh and corresponding solution file named in command line
20// arguments, open the output mesh, project that solution onto the
21// output mesh, and write a corresponding output solution file.
22
23// C++ includes
24#include <map>
25#include <string>
26
27// libMesh includes
28#include "libmesh/libmesh.h"
29#include "libmesh/dof_map.h"
30#include "libmesh/equation_systems.h"
31#include "libmesh/getpot.h"
32#include "libmesh/mesh.h"
33#include "libmesh/mesh_function.h"
34#include "libmesh/numeric_vector.h"
35#include "libmesh/point.h"
36#include "libmesh/replicated_mesh.h"
37#include "libmesh/enum_xdr_mode.h"
38#include "libmesh/utility.h"
39
40
41using namespace libMesh;
42
43
44// If there's a missing input argument, then print a help message
45void usage_error(const char * progname)
46{
47 libMesh::out << "Options: " << progname << '\n'
48 << " --dim d mesh dimension [default: autodetect]\n"
49 << " --inmesh filename input mesh file\n"
50 << " --insoln filename input solution file\n"
51 << " --outmesh filename output mesh file [default: out_<inmesh>]\n"
52 << " --outsoln filename output solution file [default: out_<insoln>]\n"
53 << std::endl;
54
55 exit(1);
56}
57
58// Get an input argument, or print a help message if it's missing
59template <typename T>
60T assert_argument (GetPot & cl,
61 const std::string & argname,
62 const char * progname,
63 const T & defaultarg)
64{
65 if (!cl.search(argname))
66 {
67 libMesh::err << ("No " + argname + " argument found!") << std::endl;
68 usage_error(progname);
69 }
70 return cl.next(defaultarg);
71}
72
73// Global collections of MeshFunctions are necessary to work with
74// global functions fptr and gptr.
75// TODO: libMesh needs functor-based alternatives to these types of
76// function arguments
77std::string current_sys_name;
78std::map<std::string, std::unique_ptr<MeshFunction>> mesh_functions;
79
80// Return the function value on the old mesh and solution
81Number fptr(const Point & p,
82 const Parameters &,
83 const std::string & libmesh_dbg_var(sys_name),
84 const std::string & unknown_name)
85{
86 libmesh_assert_equal_to (sys_name, current_sys_name);
87 libmesh_assert(mesh_functions.count(unknown_name));
88 libmesh_assert(mesh_functions[unknown_name]);
89
90 MeshFunction & meshfunc = *mesh_functions[unknown_name];
91
92 return meshfunc(p);
93}
94
95// Return the function gradient on the old mesh and solution
97 const Parameters &,
98 const std::string & libmesh_dbg_var(sys_name),
99 const std::string & unknown_name)
100{
101 libmesh_assert_equal_to (sys_name, current_sys_name);
102 libmesh_assert(mesh_functions.count(unknown_name));
103 libmesh_assert(mesh_functions[unknown_name]);
104
105 MeshFunction & meshfunc = *mesh_functions[unknown_name];
106
107 return meshfunc.gradient(p);
108}
109
110
111int main(int argc, char ** argv)
112{
113 LibMeshInit init(argc, argv);
114
115 GetPot cl(argc, argv);
116
117 // In case the mesh file doesn't let us auto-infer dimension, we let
118 // the user specify it on the command line
119 const unsigned char requested_dim =
120 cast_int<unsigned char>(cl.follow(3, "--dim"));
121
122 // Load the old mesh from --inmesh filename.
123 // Keep it serialized; we don't want elements on the new mesh to be
124 // looking for data on old mesh elements that live off-processor.
125 ReplicatedMesh old_mesh(init.comm(), requested_dim);
126
127 const std::string meshname =
128 assert_argument(cl, "--inmesh", argv[0], std::string("mesh.xda"));
129
130 old_mesh.read(meshname);
131 std::cout << "Old Mesh:" << std::endl;
132 old_mesh.print_info();
133
134 // Load the new mesh from --outmesh filename
135 Mesh new_mesh(init.comm(), requested_dim);
136
137 const std::string outmeshname = cl.follow(std::string("out_"+meshname), "--outmesh");
138
139 new_mesh.read(outmeshname);
140 std::cout << "New Mesh:" << std::endl;
141 new_mesh.print_info();
142
143 // Load the old solution from --insoln filename
144 // Construct the new solution from the old solution's headers, so
145 // that we get the system names and types, variable names and types,
146 // etc.
147 const std::string solnname =
148 assert_argument(cl, "--insoln", argv[0], std::string("soln.xda"));
149
150 EquationSystems old_es(old_mesh);
151 EquationSystems new_es(new_mesh);
152
153 XdrMODE read_mode;
154
155 if (Utility::contains(solnname, ".xdr"))
156 read_mode = DECODE;
157 else if (Utility::contains(solnname, ".xda"))
158 read_mode = READ;
159 else
160 libmesh_error_msg("Unrecognized file extension on " << solnname);
161
162 old_es.read(solnname, read_mode,
167
168 new_es.read(solnname, read_mode,
171
172 old_es.print_info();
173
174 unsigned int n_systems = old_es.n_systems();
175 libmesh_assert_equal_to (new_es.n_systems(), n_systems);
176
177 // For each system, serialize the solution so we can project it onto
178 // a potentially-very-different partitioning
179 for (unsigned int i = 0; i != n_systems; ++i)
180 {
181 System & old_sys = old_es.get_system(i);
182 current_sys_name = old_sys.name();
183
184 libMesh::out << "Projecting system " << current_sys_name << std::endl;
185
187
188 System & new_sys = new_es.get_system(current_sys_name);
189 unsigned int n_vars = old_sys.n_vars();
190 libmesh_assert_equal_to (new_sys.n_vars(), n_vars);
191
192 std::unique_ptr<NumericVector<Number>> comparison_soln =
194 std::vector<Number> global_soln;
195 old_sys.update_global_solution(global_soln);
196 comparison_soln->init(old_sys.solution->size(), true, SERIAL);
197 (*comparison_soln) = global_soln;
198
199 // For each variable, construct a MeshFunction returning that
200 // variable's value
201 for (unsigned int j = 0; j != n_vars; ++j)
202 {
203 libMesh::out << " with variable " << old_sys.variable_name(j) << std::endl;
204
205 auto mesh_func =
206 std::make_unique<MeshFunction>(old_es, *comparison_soln,
207 old_sys.get_dof_map(), j);
208 mesh_func->init();
209 mesh_functions[old_sys.variable_name(j)] = std::move(mesh_func);
210 }
211
212 // Project all variables to the new system
213 new_sys.project_solution(fptr, gptr, old_es.parameters);
214 }
215
216 // Write out the new solution file
217 const std::string outsolnname = cl.follow(std::string("out_"+solnname), "--outsoln");
218
219 new_es.write(outsolnname.c_str(),
222 libMesh::out << "Wrote solution " << outsolnname << std::endl;
223
224 return 0;
225}
unsigned int n_vars
This is the EquationSystems class.
void print_info(std::ostream &os=libMesh::out) const
Prints information about the equation systems, by default to libMesh::out.
void write(std::string_view name, const XdrMODE, const unsigned int write_flags=(WRITE_DATA), bool partition_agnostic=true) const
Write the systems to disk using the XDR data format.
unsigned int n_systems() const
void read(std::string_view name, const XdrMODE, const unsigned int read_flags=(READ_HEADER|READ_DATA), bool partition_agnostic=true)
Read & initialize the systems from disk using the XDR data format.
Parameters parameters
Data structure holding arbitrary parameters.
bool has_system(std::string_view name) const
const T_sys & get_system(std::string_view name) const
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
Definition libmesh.h:92
void print_info(std::ostream &os=libMesh::out, const unsigned int verbosity=0, const bool global=true) const
Prints relevant information about the mesh.
Definition mesh_base.C:1755
This class provides function-like objects for data distributed over a mesh.
Gradient gradient(const Point &p, const Real time=0.)
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition mesh.h:51
static std::unique_ptr< NumericVector< T > > build(const Parallel::Communicator &comm, SolverPackage solver_package=libMesh::default_solver_package(), ParallelType parallel_type=AUTOMATIC)
Builds a NumericVector on the processors in communicator comm using the linear solver package specifi...
const Parallel::Communicator & comm() const
This class provides the ability to map between arbitrary, user-defined strings and several data types...
Definition parameters.h:75
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition point.h:40
The ReplicatedMesh class is derived from the MeshBase class, and is used to store identical copies of...
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition system.h:100
const std::string & name() const
Definition system.h:2385
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.
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition system.h:1655
const std::string & variable_name(const unsigned int i) const
Definition system.C:2679
void update_global_solution(std::vector< Number > &global_soln) const
Fill the input vector global_soln so that it contains the global solution on all processors.
Definition system.C:733
unsigned int n_vars() const
Definition system.C:2674
const DofMap & get_dof_map() const
Definition system.h:2417
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.
This class defines a vector in LIBMESH_DIM dimensional Real or Complex space.
bool contains(std::string_view superstring, std::string_view substring)
Look for a substring within a string.
Definition utility.C:205
The libMesh namespace provides an interface to certain functionality in the library.
OStreamProxy err
libmesh_assert(ctx)
OStreamProxy out
XdrMODE
Defines an enum for read/write mode in Xdr format.
Gradient gptr(const Point &p, const Parameters &, const std::string &libmesh_dbg_var(sys_name), const std::string &unknown_name)
Definition projection.C:96
std::map< std::string, std::unique_ptr< MeshFunction > > mesh_functions
Definition projection.C:78
void usage_error(const char *progname)
Definition projection.C:45
std::string current_sys_name
Definition projection.C:77
Number fptr(const Point &p, const Parameters &, const std::string &libmesh_dbg_var(sys_name), const std::string &unknown_name)
Definition projection.C:81
T assert_argument(GetPot &cl, const std::string &argname, const char *progname, const T &defaultarg)
Definition projection.C:60
int main()