Line data Source code
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 : #ifndef LIBMESH_LIBMESH_H
21 : #define LIBMESH_LIBMESH_H
22 :
23 :
24 : // Local includes
25 : #include "libmesh/libmesh_base.h"
26 : #include "libmesh/libmesh_common.h"
27 : #include "libmesh/libmesh_config.h"
28 :
29 : // C++ includes
30 : #include <string>
31 : #include <vector>
32 :
33 : // Forward declarations
34 : // For dealing with MPI stuff in VTK.
35 : #if defined(LIBMESH_HAVE_MPI) && defined(LIBMESH_HAVE_VTK)
36 : class vtkMPIController;
37 : #endif
38 :
39 : namespace TIMPI {
40 : class TIMPIInit;
41 : }
42 :
43 : #ifdef GETPOT_NAMESPACE
44 : namespace GETPOT_NAMESPACE {
45 : #endif
46 : class GetPot;
47 : #ifdef GETPOT_NAMESPACE
48 : }
49 : #endif
50 :
51 : /**
52 : * The \p libMesh namespace provides an interface to certain functionality
53 : * in the library. Here, it provides a LibMeshInit class which uses
54 : * the RAII (Resource Acquisition Is Initialization) idiom to ensure
55 : * initialization of any other dependent libraries (e.g. MPI or PETSC),
56 : * and to close those libraries when it goes out of scope. It also
57 : * provides a centralized place for performance logging and other
58 : * functionality.
59 : */
60 : namespace libMesh
61 : {
62 :
63 : // Forward declarations
64 : namespace Parallel {
65 : class Communicator;
66 : }
67 :
68 : class PerfLog;
69 : enum SolverPackage : int;
70 :
71 : /**
72 : * The \p LibMeshInit class, when constructed, initializes
73 : * the dependent libraries (e.g. MPI or PETSC) and does the
74 : * command line parsing needed by libMesh. The LibMeshInit
75 : * destructor closes those libraries properly.
76 : *
77 : * For most users, a single LibMeshInit object should be created at
78 : * the start of your main() function.
79 : *
80 : * All libMesh functionality should be used only when a LibMeshInit
81 : * object exists. Dependent library functionality, likewise, except
82 : * in codes which manually initialize those libraries before
83 : * LibMeshInit creation and finalize them after LibMeshInit
84 : * destruction.
85 : *
86 : * Since "it is best not to perform much more than a return rc after
87 : * calling MPI_Finalize", applications which want to do anything after
88 : * LibMeshInit destruction should manage MPI initialization and
89 : * finalization manually.
90 : */
91 : class LibMeshInit
92 : {
93 : public:
94 : #ifdef LIBMESH_HAVE_MPI
95 : /**
96 : * Initialize the library for use, with the command line options
97 : * provided. This will e.g. call MPI_Init if MPI is available and
98 : * enabled and has not already been initialized; similar
99 : * initialization may take place for Petsc, Slepc, multithreading
100 : * support, libMesh Singleton objects, the libMesh::out/err IO
101 : * streams, and any libMesh handlers for floating-point exceptions,
102 : * signals, and/or C++ aborts.
103 : *
104 : * You must create a LibMeshInit object before using any
105 : * of the library functionality. This method may take an optional
106 : * parameter to use a user-specified MPI communicator.
107 : */
108 : LibMeshInit(int argc, const char * const * argv,
109 : MPI_Comm COMM_WORLD_IN=MPI_COMM_WORLD, int n_threads=-1);
110 : #else
111 : LibMeshInit(int argc, const char * const * argv,
112 : int COMM_WORLD_IN=0, int n_threads=-1);
113 : #endif
114 :
115 : /**
116 : * Destructor. Cleans up libMesh Singleton objects, and thread
117 : * manager if threading is in use. Prints reference count and
118 : * performance logging information if enabled. Restores
119 : * pre-LibMeshInit terminate handler and floating-point-exception
120 : * handling. Finalizes any of Slepc, Petsc, and MPI which were
121 : * initialized by LibMeshInit.
122 : */
123 : virtual ~LibMeshInit();
124 :
125 : /**
126 : * Returns a Communicator created from the TIMPIInit object we hold,
127 : * which will be a compatibility shim if MPI is not enabled.
128 : */
129 : const Parallel::Communicator & comm() const { return *_comm; }
130 :
131 31508 : Parallel::Communicator & comm() { return *_comm; }
132 :
133 : private:
134 : // Should we just bite the bullet, use unique_ptr here, and bring an
135 : // #include <memory> into everything?
136 : TIMPI::TIMPIInit * _timpi_init;
137 :
138 : // Or should we keep this around so we can still inline its
139 : // accessors despite forward declaring _timpi_init?
140 : //
141 : // This is constructed from the TIMPI::Communicator, for backwards
142 : // compatibility.
143 : Parallel::Communicator * _comm;
144 :
145 : #if defined(LIBMESH_HAVE_MPI) && defined(LIBMESH_HAVE_VTK)
146 : // VTK object for dealing with MPI stuff in VTK.
147 : // This can't be a std::unique_ptr because VTK makes the destructor
148 : // protected and forces us to use a named destructor manually
149 : vtkMPIController * _vtk_mpi_controller;
150 : #endif
151 :
152 : #ifdef LIBMESH_ENABLE_EXCEPTIONS
153 : static std::terminate_handler _old_terminate_handler;
154 : #endif
155 :
156 : static PerfLog & perf_log();
157 :
158 : friend void libmesh_abort();
159 : friend void libmesh_terminate_handler();
160 : };
161 :
162 : /**
163 : * Checks that library initialization has been done. If it
164 : * hasn't an error message is printed and the code aborts.
165 : * It is useful to \p libmesh_assert(libMesh::initialized()) in library
166 : * object constructors.
167 : */
168 : bool initialized ();
169 :
170 : /**
171 : * Checks that the library has been closed. This should
172 : * always return false when called from a library object.
173 : * It is useful to \p libmesh_assert(!libMesh::closed()) in library
174 : * object destructors.
175 : */
176 : bool closed ();
177 :
178 : /**
179 : * \returns \p true if the argument \p arg was specified on the command line,
180 : * \p false otherwise.
181 : *
182 : * For backwards compatibility with past option naming conventions,
183 : * libMesh searches for the given argument first in its original form,
184 : * then with all underscores changed to dashes, then with all dashes
185 : * (except any leading dashes) changed to underscores, and returns
186 : * true if any of the above finds a match.
187 : *
188 : * This routine manipulates the command_line cursor and should not be
189 : * called concurrently with similar utilities in multiple threads.
190 : */
191 : bool on_command_line (std::string arg);
192 :
193 : /**
194 : * \returns The value associated with name on the command line if it is specified,
195 : * otherwise return the default, provided value. A second template function is provided
196 : * to support recognizing multiple variations of a given option
197 : *
198 : * This routine manipulates the command_line cursor and should not be
199 : * called concurrently with similar utilities in multiple threads.
200 : */
201 : template <typename T>
202 : T command_line_value (const std::string &, T);
203 : template <typename T>
204 : T command_line_value (const std::vector<std::string> &, T);
205 :
206 : /**
207 : * Use GetPot's search()/next() functions to get following arguments
208 : * from the command line.
209 : *
210 : * For backwards compatibility with past option naming conventions,
211 : * libMesh searches for the given argument first in its original form,
212 : * then with all underscores changed to dashes, then with all dashes
213 : * (except any leading dashes) changed to underscores, and returns
214 : * true if any of the above finds a match.
215 : *
216 : * This routine manipulates the command_line cursor and should not be
217 : * called concurrently with similar utilities in multiple threads.
218 : */
219 : template <typename T>
220 : T command_line_next (std::string name, T default_value);
221 :
222 : /**
223 : * \returns The array of values associated with name on the command line if it is specified,
224 : * otherwise return the default, provided array.
225 : *
226 : * This routine manipulates the command_line cursor and should not be
227 : * called concurrently with similar utilities in multiple threads.
228 : */
229 : template <typename T>
230 : void command_line_vector (const std::string &, std::vector<T> &);
231 :
232 : /**
233 : * \returns The set of names which this program has queried or
234 : * expected to query via the libMesh command line interface.
235 : *
236 : * This is useful for detecting any future conflicts with other
237 : * packages (such as PETSc) which manage command line values, and for
238 : * avoiding UFO warnings from such packages.
239 : */
240 : std::vector<std::string> command_line_names();
241 :
242 : /**
243 : * Add a name to the set of queried command-line names
244 : */
245 : void add_command_line_name(const std::string & name);
246 :
247 : /**
248 : * Merge a GetPot object's requested names into the set of queried
249 : * command-line names
250 : */
251 : void add_command_line_names(const GetPot & getpot);
252 :
253 :
254 : /**
255 : * The imaginary unit, \f$ \sqrt{-1} \f$.
256 : */
257 : #ifdef LIBMESH_USE_COMPLEX_NUMBERS
258 : extern const Number imaginary;
259 : #endif
260 :
261 : /**
262 : * \returns The default solver interface to use. The value depends on
263 : * which solver packages were available when the library was configured.
264 : * The command-line is also checked, allowing the user to override the
265 : * compiled default. For example, \p --use-petsc will force the use of
266 : * PETSc solvers, and \p --use-laspack will force the use of LASPACK
267 : * solvers.
268 : */
269 : SolverPackage default_solver_package ();
270 :
271 : /**
272 : * The C++ standard doesn't support literals at higher than long
273 : * double precision, so if we're in quadruple precision we need our
274 : * own user-defined literal operator.
275 : *
276 : * If we're not in quadruple precision then we just need a
277 : * zero-overhead passthrough.
278 : *
279 : * We'll use a simple _R since we're already qualified by the libMesh
280 : * namespace here.
281 : */
282 : #ifdef LIBMESH_DEFAULT_QUADRUPLE_PRECISION
283 : constexpr Real operator ""_R(const char * r) { return Real(r); }
284 : #else
285 489043 : constexpr Real operator ""_R(long double r) { return r; }
286 : constexpr Real operator ""_R(unsigned long long r) { return Real(r); }
287 : #endif
288 :
289 : /**
290 : * \f$ \pi=3.14159... \f$.
291 : */
292 : const Real pi = 3.1415926535897932384626433832795029_R;
293 :
294 : /**
295 : * \f$ zero=0. \f$.
296 : */
297 : const Number zero = 0.;
298 :
299 : /**
300 : * A number which is used quite often to represent
301 : * an invalid or uninitialized value for an unsigned integer.
302 : */
303 : const unsigned int invalid_uint = static_cast<unsigned int>(-1);
304 :
305 : /**
306 : * A number which is used quite often to represent
307 : * an invalid or uninitialized value for an integer.
308 : */
309 : const int invalid_int = std::numeric_limits<int>::max();
310 :
311 : } // namespace libMesh
312 :
313 : #endif // LIBMESH_LIBMESH_H
|