Line data Source code
1 : //* This file is part of the MOOSE framework
2 : //* https://mooseframework.inl.gov
3 : //*
4 : //* All rights reserved, see COPYRIGHT for full restrictions
5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 : //*
7 : //* Licensed under LGPL 2.1, please see LICENSE for details
8 : //* https://www.gnu.org/licenses/lgpl-2.1.html
9 :
10 : #ifdef MFEM_ENABLED
11 :
12 : #pragma once
13 : #include <map>
14 : #include <memory>
15 : #include <string>
16 : #include <tuple>
17 : #include <utility>
18 : #include <variant>
19 : #include <vector>
20 :
21 : #include "MooseException.h"
22 :
23 : #include "libmesh/ignore_warnings.h"
24 : #include <mfem.hpp>
25 : #include "libmesh/restore_warnings.h"
26 : #include "CoefficientMap.h"
27 :
28 : namespace Moose::MFEM
29 : {
30 : /**
31 : * Front-end class for creating and storing MFEM coefficients. They
32 : * can be created so they are global (defined across the entire
33 : * domain) or as piecewise material properties.
34 : */
35 : class CoefficientManager
36 : {
37 : public:
38 316 : CoefficientManager() = default;
39 :
40 : /// Declare an alias to an existing scalar coefficient or, if it
41 : /// does not exist, try interpreting the name as a number with which
42 : /// to create a new constant coefficient.
43 : mfem::Coefficient & declareScalar(const std::string & name,
44 : const std::string & existing_or_literal);
45 : /// Create a new scalar coefficient, constructed from the argument pack
46 : template <class P, class... Args>
47 522 : P & declareScalar(const std::string & name, Args &&... args)
48 : {
49 522 : auto coef = _scalar_coeffs.make<P>(args...);
50 523 : this->declareScalar(name, coef);
51 1042 : return *coef;
52 522 : }
53 :
54 : /**
55 : * Use an existing scalar coefficient for a property on some blocks
56 : * of the mesh. The property will be a piecewise coefficient and it
57 : * will have the value of `existing_coef` on these blocks. If no
58 : * such scalar coefficient exists, try interpreting the name as a
59 : * number with which to create a new constant coefficient.
60 : */
61 : mfem::Coefficient & declareScalarProperty(const std::string & name,
62 : const std::vector<std::string> & blocks,
63 : const std::string & existing_or_literal);
64 : /**
65 : * Use a new scalar coefficient, constructed from the argument pack, for a
66 : * property on some blocks of the mesh. The property will be a piecewise
67 : * coefficient and it will have the value of the new coefficient on these
68 : * blocks.
69 : */
70 : template <class P, class... Args>
71 14 : mfem::Coefficient & declareScalarProperty(const std::string & name,
72 : const std::vector<std::string> & blocks,
73 : Args &&... args)
74 : {
75 14 : return this->declareScalarProperty(name, blocks, _scalar_coeffs.make<P>(args...));
76 : }
77 :
78 : /// Declare an alias to an existing vector coefficientor or, if it
79 : /// does not exist, try interpreting the name as a vector of numbers with which
80 : /// to create a new constant vector coefficient.
81 : mfem::VectorCoefficient & declareVector(const std::string & name,
82 : const std::string & existing_or_literal);
83 : /// Create a new vector coefficient, constructed from the argument pack.
84 : template <class P, class... Args>
85 190 : P & declareVector(const std::string & name, Args &&... args)
86 : {
87 190 : auto coef = _vector_coeffs.make<P>(args...);
88 191 : this->declareVector(name, coef);
89 378 : return *coef;
90 190 : }
91 :
92 : /**
93 : * Use an existing vector coefficient for a property on some blocks
94 : * of the mesh. The property will be a piecewise coefficient and it
95 : * will have the value of `existing_coef` on these blocks. If no
96 : * such vector coefficient exists, try interpreting the name as a
97 : * vector of numbers with which to create a new constant vector
98 : * coefficient.
99 : */
100 : mfem::VectorCoefficient & declareVectorProperty(const std::string & name,
101 : const std::vector<std::string> & blocks,
102 : const std::string & existing_or_literal);
103 : /**
104 : * Use a new vector coefficient, constructed from the argument pack, for a
105 : * property on some blocks of the mesh. The property will be a piecewise
106 : * coefficient and it will have the value of the new coefficient on these
107 : * blocks.
108 : */
109 : template <class P, class... Args>
110 14 : mfem::VectorCoefficient & declareVectorProperty(const std::string & name,
111 : const std::vector<std::string> & blocks,
112 : Args &&... args)
113 : {
114 14 : return this->declareVectorProperty(name, blocks, _vector_coeffs.make<P>(args...));
115 : }
116 :
117 : /// Declare an alias to an existing matrix coefficient. Unlike for
118 : /// the scalar and vector counterparts, there is currently no way to
119 : /// try interpreting the name as numbers with which to construct a
120 : /// constant matrix coefficient.
121 : mfem::MatrixCoefficient & declareMatrix(const std::string & name,
122 : const std::string & existing_coef);
123 : /// Create a new matrix coefficient, constructed from the argument pack.
124 : template <class P, class... Args>
125 14 : P & declareMatrix(const std::string & name, Args &&... args)
126 : {
127 14 : auto coef = _matrix_coeffs.make<P>(args...);
128 15 : this->declareMatrix(name, coef);
129 26 : return *coef;
130 14 : }
131 :
132 : /**
133 : * Use an existing matrix coefficient for a property on some blocks of the
134 : * mesh. The property will be a piecewise coefficient and it will have
135 : * the value of `existing_coef` on these blocks. Unlike for
136 : * the scalar and vector counterparts, there is currently no way to
137 : * try interpreting the name as numbers with which to construct a
138 : * constant matrix coefficient.
139 : */
140 : mfem::MatrixCoefficient & declareMatrixProperty(const std::string & name,
141 : const std::vector<std::string> & blocks,
142 : const std::string & existing_coef);
143 : /**
144 : * Use a new matrix coefficient, constructed from the argument pack, for a
145 : * property on some blocks of the mesh. The property will be a piecewise
146 : * coefficient and it will have the value of the new coefficient on these
147 : * blocks.
148 : */
149 : template <class P, class... Args>
150 14 : mfem::MatrixCoefficient & declareMatrixProperty(const std::string & name,
151 : const std::vector<std::string> & blocks,
152 : Args &&... args)
153 : {
154 14 : return this->declareMatrixProperty(name, blocks, _matrix_coeffs.make<P>(args...));
155 : }
156 :
157 : /// Return a scalar coefficient with the given name or, if that
158 : /// doesn't exists, try interpreting the name as a number with which
159 : /// to build a new constant coefficient.
160 : mfem::Coefficient & getScalarCoefficient(const std::string & name);
161 :
162 : /// Return a vector coefficient with the given name or, if that
163 : /// doesn't exists, try interpreting the name as a vector of number with which
164 : /// to build a new constant vector coefficient.
165 : mfem::VectorCoefficient & getVectorCoefficient(const std::string & name);
166 :
167 : /// Return scalar coefficient with the given name. Unlike for
168 : /// the scalar and vector counterparts, there is currently no way to
169 : /// try interpreting the name as numbers with which to construct a
170 : /// constant matrix coefficient.
171 : mfem::MatrixCoefficient & getMatrixCoefficient(const std::string & name);
172 :
173 : bool scalarPropertyIsDefined(const std::string & name, const std::string & block) const;
174 : bool vectorPropertyIsDefined(const std::string & name, const std::string & block) const;
175 : bool matrixPropertyIsDefined(const std::string & name, const std::string & block) const;
176 : void setTime(const double time);
177 :
178 : private:
179 : ScalarMap _scalar_coeffs;
180 : VectorMap _vector_coeffs;
181 : MatrixMap _matrix_coeffs;
182 :
183 : mfem::Coefficient & declareScalar(const std::string & name,
184 : std::shared_ptr<mfem::Coefficient> coef);
185 : mfem::Coefficient & declareScalarProperty(const std::string & name,
186 : const std::vector<std::string> & blocks,
187 : std::shared_ptr<mfem::Coefficient> coef);
188 : mfem::VectorCoefficient & declareVector(const std::string & name,
189 : std::shared_ptr<mfem::VectorCoefficient> coef);
190 : mfem::VectorCoefficient & declareVectorProperty(const std::string & name,
191 : const std::vector<std::string> & blocks,
192 : std::shared_ptr<mfem::VectorCoefficient> coef);
193 : mfem::MatrixCoefficient & declareMatrix(const std::string & name,
194 : std::shared_ptr<mfem::MatrixCoefficient> coef);
195 : mfem::MatrixCoefficient & declareMatrixProperty(const std::string & name,
196 : const std::vector<std::string> & blocks,
197 : std::shared_ptr<mfem::MatrixCoefficient> coef);
198 : std::shared_ptr<mfem::Coefficient> getScalarCoefficientPtr(const std::string & name);
199 : std::shared_ptr<mfem::VectorCoefficient> getVectorCoefficientPtr(const std::string & name);
200 : std::shared_ptr<mfem::MatrixCoefficient> getMatrixCoefficientPtr(const std::string & name);
201 : };
202 : }
203 :
204 : #endif
|