https://mooseframework.inl.gov
Loading...
Searching...
No Matches
CoefficientManager.C
Go to the documentation of this file.
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#include "MooseStringUtils.h"
13#include "CoefficientManager.h"
15#include <algorithm>
16
17namespace Moose::MFEM
18{
19
20mfem::Coefficient &
21CoefficientManager::declareScalar(const std::string & name, std::shared_ptr<mfem::Coefficient> coef)
22{
23 this->_scalar_coeffs.addCoefficient(name, coef);
24 return *coef;
25}
26
27mfem::Coefficient &
28CoefficientManager::declareScalar(const std::string & name, const std::string & existing_or_literal)
29{
30 return this->declareScalar(name, this->getScalarCoefficientPtr(existing_or_literal));
31}
32
33mfem::Coefficient &
35 const std::vector<std::string> & blocks,
36 std::shared_ptr<mfem::Coefficient> coef)
37{
38 this->_scalar_coeffs.addPiecewiseBlocks(name, coef, blocks);
39 return getScalarCoefficient(name);
40}
41
42mfem::Coefficient &
44 const std::vector<std::string> & blocks,
45 const std::string & existing_or_literal)
46{
47 std::shared_ptr<mfem::Coefficient> coef = this->getScalarCoefficientPtr(existing_or_literal);
48 if (std::dynamic_pointer_cast<mfem::PWCoefficient>(coef))
49 mooseError("Properties must not be defined out of other properties or piecewise coefficients.");
50 return this->declareScalarProperty(name, blocks, coef);
51}
52
53mfem::VectorCoefficient &
54CoefficientManager::declareVector(const std::string & name,
55 std::shared_ptr<mfem::VectorCoefficient> coef)
56{
57 this->_vector_coeffs.addCoefficient(name, coef);
58 return *coef;
59}
60
61mfem::VectorCoefficient &
62CoefficientManager::declareVector(const std::string & name, const std::string & existing_or_literal)
63{
64 return this->declareVector(name, this->getVectorCoefficientPtr(existing_or_literal));
65}
66
67mfem::VectorCoefficient &
69 const std::vector<std::string> & blocks,
70 std::shared_ptr<mfem::VectorCoefficient> coef)
71{
72 this->_vector_coeffs.addPiecewiseBlocks(name, coef, blocks);
73 return getVectorCoefficient(name);
74}
75
76mfem::VectorCoefficient &
78 const std::vector<std::string> & blocks,
79 const std::string & existing_or_literal)
80{
81 std::shared_ptr<mfem::VectorCoefficient> coef =
82 this->getVectorCoefficientPtr(existing_or_literal);
83 if (std::dynamic_pointer_cast<mfem::PWVectorCoefficient>(coef))
84 mooseError("Properties must not be defined out of other properties or piecewise coefficients.");
85 return this->declareVectorProperty(name, blocks, coef);
86}
87
88mfem::MatrixCoefficient &
89CoefficientManager::declareMatrix(const std::string & name,
90 std::shared_ptr<mfem::MatrixCoefficient> coef)
91{
92 this->_matrix_coeffs.addCoefficient(name, coef);
93 return *coef;
94}
95
96mfem::MatrixCoefficient &
97CoefficientManager::declareMatrix(const std::string & name, const std::string & existing_coef)
98{
99 return this->declareMatrix(name, this->getMatrixCoefficientPtr(existing_coef));
100}
101
102mfem::MatrixCoefficient &
104 const std::vector<std::string> & blocks,
105 std::shared_ptr<mfem::MatrixCoefficient> coef)
106{
107 this->_matrix_coeffs.addPiecewiseBlocks(name, coef, blocks);
108 return getMatrixCoefficient(name);
109}
110
111mfem::MatrixCoefficient &
113 const std::vector<std::string> & blocks,
114 const std::string & existing_coef)
115{
116 std::shared_ptr<mfem::MatrixCoefficient> coef = this->getMatrixCoefficientPtr(existing_coef);
117 if (std::dynamic_pointer_cast<mfem::PWMatrixCoefficient>(coef))
118 mooseError("Properties must not be defined out of other properties or piecewise coefficients.");
119 return this->declareMatrixProperty(name, blocks, coef);
120}
121
122std::shared_ptr<mfem::Coefficient>
124{
125 if (this->_scalar_coeffs.hasCoefficient(name))
126 return this->_scalar_coeffs.getCoefficientPtr(name);
127 // If name not present, check if it can be parsed cleanly into a real number
128 std::istringstream ss(MooseUtils::trim(name));
129 mfem::real_t real_value;
130 if (ss >> real_value && ss.eof())
131 {
132 this->declareScalar<mfem::ConstantCoefficient>(name, real_value);
133 return this->_scalar_coeffs.getCoefficientPtr(name);
134 }
135 mooseError("Scalar coefficient with name '" + name + "' has not been declared.");
136}
137
138std::shared_ptr<mfem::VectorCoefficient>
140{
141 if (this->_vector_coeffs.hasCoefficient(name))
142 return this->_vector_coeffs.getCoefficientPtr(name);
143 // If name not present, check if it can be parsed cleanly into a vector of real numbers
144 std::vector<mfem::real_t> vec_values;
145 if (MooseUtils::tokenizeAndConvert(name, vec_values) && vec_values.size() > 0)
146 {
147 this->declareVector<mfem::VectorConstantCoefficient>(
148 name, mfem::Vector(vec_values.data(), vec_values.size()));
149 return this->_vector_coeffs.getCoefficientPtr(name);
150 }
151 mooseError("Vector coefficient with name '" + name + "' has not been declared.");
152}
153
154std::shared_ptr<mfem::MatrixCoefficient>
156{
157 if (this->_matrix_coeffs.hasCoefficient(name))
158 return this->_matrix_coeffs.getCoefficientPtr(name);
159 // If name not present, try to interpret it as a literal constant matrix. Rows are
160 // separated by ';' and entries within a row by whitespace. Every row must
161 // have the same number of entries; a string with no ';' is a single row.
162 std::vector<std::string> row_strs;
163 MooseUtils::tokenize(name, row_strs, 1, ";");
164 std::vector<std::vector<mfem::real_t>> rows;
165 for (const auto & row_str : row_strs)
166 {
167 std::vector<mfem::real_t> row_vals;
168 if (MooseUtils::tokenizeAndConvert(row_str, row_vals) && row_vals.size() > 0)
169 {
170 rows.push_back(row_vals);
171 if (rows.back().size() != rows.front().size())
172 mooseError("Matrix coefficient literal '" + name + "' has rows of differing length.");
173 }
174 }
175 if (rows.size() == static_cast<std::size_t>(std::count(name.begin(), name.end(), ';')) + 1)
176 {
177 const int nrows = static_cast<int>(rows.size());
178 const int ncols = static_cast<int>(rows.front().size());
179 mfem::DenseMatrix mat(nrows, ncols);
180 for (int i = 0; i < nrows; ++i)
181 for (int j = 0; j < ncols; ++j)
182 mat(i, j) = rows[i][j];
183 this->declareMatrix<mfem::MatrixConstantCoefficient>(name, mat);
184 return this->_matrix_coeffs.getCoefficientPtr(name);
185 }
186 mooseError("Matrix coefficient with name '" + name + "' has not been declared.");
187}
188
189mfem::Coefficient &
191{
192 return *this->getScalarCoefficientPtr(name);
193}
194
195mfem::VectorCoefficient &
197{
198 return *this->getVectorCoefficientPtr(name);
199}
200
201mfem::MatrixCoefficient &
203{
204 return *this->getMatrixCoefficientPtr(name);
205}
206
207bool
209 const std::string & block) const
210{
211 return this->_scalar_coeffs.propertyDefinedOnBlock(name, block);
212}
213
214bool
216 const std::string & block) const
217{
218 return this->_vector_coeffs.propertyDefinedOnBlock(name, block);
219}
220
221bool
223 const std::string & block) const
224{
225 return this->_matrix_coeffs.propertyDefinedOnBlock(name, block);
226}
227
228void
229CoefficientManager::setTime(const mfem::real_t time)
230{
231 this->_scalar_coeffs.setTime(time);
232 this->_vector_coeffs.setTime(time);
233 this->_matrix_coeffs.setTime(time);
234}
235
236void
238{
239 auto mark_solution_changed = [](auto & coef)
240 {
241 if (auto * const qf_coef = dynamic_cast<MFEMQuadratureFunctionCoefficientBase *>(&coef))
242 qf_coef->MarkSolutionChanged();
243 };
244 this->_scalar_coeffs.apply(mark_solution_changed);
245 this->_vector_coeffs.apply(mark_solution_changed);
246}
247}
248
249#endif
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
char ** blocks
Shared lazy-update state for quadrature function coefficients.
std::shared_ptr< mfem::Coefficient > getScalarCoefficientPtr(const std::string &name)
mfem::VectorCoefficient & declareVectorProperty(const std::string &name, const std::vector< std::string > &blocks, const std::string &existing_or_literal)
Use an existing vector coefficient for a property on some blocks of the mesh.
bool scalarPropertyIsDefined(const std::string &name, const std::string &block) const
std::shared_ptr< mfem::VectorCoefficient > getVectorCoefficientPtr(const std::string &name)
mfem::Coefficient & declareScalarProperty(const std::string &name, const std::vector< std::string > &blocks, const std::string &existing_or_literal)
Use an existing scalar coefficient for a property on some blocks of the mesh.
void setTime(const mfem::real_t time)
mfem::Coefficient & declareScalar(const std::string &name, const std::string &existing_or_literal)
Declare an alias to an existing scalar coefficient or, if it does not exist, try interpreting the nam...
mfem::MatrixCoefficient & declareMatrixProperty(const std::string &name, const std::vector< std::string > &blocks, const std::string &existing_coef)
Use an existing matrix coefficient for a property on some blocks of the mesh.
mfem::MatrixCoefficient & declareMatrix(const std::string &name, const std::string &existing_coef)
Declare an alias to an existing matrix coefficient.
mfem::MatrixCoefficient & getMatrixCoefficient(const std::string &name)
Return scalar coefficient with the given name.
mfem::VectorCoefficient & getVectorCoefficient(const std::string &name)
Return a vector coefficient with the given name or, if that doesn't exist, try interpreting the name ...
bool vectorPropertyIsDefined(const std::string &name, const std::string &block) const
mfem::Coefficient & getScalarCoefficient(const std::string &name)
Return a scalar coefficient with the given name or, if that doesn't exist, try interpreting the name ...
void markSolutionChanged()
Notify quadrature function coefficients that solution variables have changed, marking the stored valu...
mfem::VectorCoefficient & declareVector(const std::string &name, const std::string &existing_or_literal)
Declare an alias to an existing vector coefficientor or, if it does not exist, try interpreting the n...
std::shared_ptr< mfem::MatrixCoefficient > getMatrixCoefficientPtr(const std::string &name)
bool matrixPropertyIsDefined(const std::string &name, const std::string &block) const
bool propertyDefinedOnBlock(const std::string &name, const std::string &block) const
void addCoefficient(const std::string &name, std::shared_ptr< T > coeff)
Add a named global coefficient.
bool hasCoefficient(const std::string &name) const
void addPiecewiseBlocks(const std::string &name, std::shared_ptr< T > coeff, const std::vector< std::string > &blocks)
Add piecewise material property.
std::shared_ptr< T > getCoefficientPtr(const std::string &name)
void setTime(const mfem::real_t time)
void apply(F &&func)
Apply a function to every coefficient created by this map.
bool tokenizeAndConvert(const std::string &str, std::vector< T > &tokenized_vector, const std::string &delimiter=" \t\n\v\f\r")
tokenizeAndConvert splits a string using delimiter and then converts to type T.
void tokenize(const std::string &str, std::vector< T > &elements, unsigned int min_len=1, const std::string &delims="/")
This function will split the passed in string on a set of delimiters appending the substrings to the ...
std::string trim(const std::string &str, const std::string &white_space=" \t\n\v\f\r")
Standard scripting language trim function.
Utilities for converting between vector(s) of libMesh Points and MFEM Vector(s).