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