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 : #include "MooseParsedFunctionWrapper.h"
11 : #include "FEProblem.h"
12 : #include "MooseVariableScalar.h"
13 : #include "Function.h"
14 : #include "MooseUtils.h"
15 :
16 : using namespace libMesh;
17 :
18 43975 : MooseParsedFunctionWrapper::MooseParsedFunctionWrapper(FEProblemBase & feproblem,
19 : const std::string & function_str,
20 : const std::vector<std::string> & vars,
21 : const std::vector<std::string> & vals,
22 43975 : const THREAD_ID tid)
23 43975 : : _feproblem(feproblem), _function_str(function_str), _vars(vars), _vals_input(vals), _tid(tid)
24 : {
25 43975 : initialize();
26 :
27 : _function_ptr =
28 43972 : std::make_unique<ParsedFunction<Real, RealGradient>>(_function_str, &_vars, &_initial_vals);
29 :
30 46354 : for (auto & v : _vars)
31 2382 : _addr.push_back(&_function_ptr->getVarAddress(v));
32 43972 : }
33 :
34 85246 : MooseParsedFunctionWrapper::~MooseParsedFunctionWrapper() {}
35 :
36 : template <>
37 : Real
38 1877769053 : MooseParsedFunctionWrapper::evaluate(Real t, const Point & p)
39 : {
40 1877769053 : update();
41 1877769053 : updateFunctionValues(t, p);
42 1877769053 : return (*_function_ptr)(p, t);
43 : }
44 :
45 : template <>
46 : DenseVector<Real>
47 11190607 : MooseParsedFunctionWrapper::evaluate(Real t, const Point & p)
48 : {
49 11190607 : update();
50 11190607 : updateFunctionValues(t, p);
51 11190607 : DenseVector<Real> output(LIBMESH_DIM);
52 11190607 : (*_function_ptr)(p, t, output);
53 11190607 : return output;
54 0 : }
55 :
56 : template <>
57 : RealVectorValue
58 11190607 : MooseParsedFunctionWrapper::evaluate(Real t, const Point & p)
59 : {
60 11190607 : DenseVector<Real> output = evaluate<DenseVector<Real>>(t, p);
61 :
62 11190607 : return RealVectorValue(output(0)
63 : #if LIBMESH_DIM > 1
64 : ,
65 11190607 : output(1)
66 : #endif
67 : #if LIBMESH_DIM > 2
68 : ,
69 11190607 : output(2)
70 : #endif
71 22381214 : );
72 11190607 : }
73 :
74 : RealGradient
75 7398806 : MooseParsedFunctionWrapper::evaluateGradient(Real t, const Point & p)
76 : {
77 7398806 : update();
78 7398806 : updateFunctionValues(t, p);
79 7398806 : return _function_ptr->gradient(p, t);
80 : }
81 :
82 : Real
83 3904348 : MooseParsedFunctionWrapper::evaluateDot(Real t, const Point & p)
84 : {
85 3904348 : update();
86 3904348 : updateFunctionValues(t, p);
87 3904348 : return _function_ptr->dot(p, t);
88 : }
89 :
90 : void
91 43975 : MooseParsedFunctionWrapper::initialize()
92 : {
93 : // Loop through all the input values supplied by the users.
94 46357 : for (unsigned int i = 0; i < _vals_input.size(); ++i)
95 : {
96 : // Case when a Postprocessor is found by the name given in the input values
97 2385 : ReporterName r_name(_vals_input[i], "value");
98 2385 : if (_feproblem.getReporterData().hasReporterValue<PostprocessorValue>(r_name))
99 : {
100 100 : const Real & pp_val = _feproblem.getPostprocessorValueByName(_vals_input[i]);
101 100 : _initial_vals.push_back(pp_val);
102 100 : _pp_vals.push_back(&pp_val);
103 100 : _pp_index.push_back(i);
104 : }
105 :
106 : // Case when a scalar variable is found by the name given in the input values
107 2285 : else if (_feproblem.hasScalarVariable(_vals_input[i]))
108 : {
109 38 : auto & scalar_val = _feproblem.getScalarVariable(_tid, _vals_input[i]).sln()[0];
110 38 : _initial_vals.push_back(scalar_val);
111 38 : _scalar_vals.push_back(&scalar_val);
112 38 : _scalar_index.push_back(i);
113 : }
114 :
115 : // Case when a function is found by the name given in the input values
116 2247 : else if (_feproblem.hasFunction(_vals_input[i]))
117 : {
118 282 : Function & fn = _feproblem.getFunction(_vals_input[i], _tid);
119 282 : _initial_vals.push_back(0);
120 282 : _functions.push_back(&fn);
121 282 : _function_index.push_back(i);
122 : }
123 :
124 : // Case when a Real is supplied
125 : else
126 : {
127 : Real val;
128 : try
129 : {
130 1965 : val = MooseUtils::convert<Real>(_vals_input[i], true);
131 : }
132 3 : catch (const std::invalid_argument & e)
133 : {
134 3 : mooseError("'No postprocessor, scalar variable, or function with the name '",
135 3 : _vals_input[i],
136 : "' found. ",
137 3 : e.what());
138 0 : }
139 1962 : _initial_vals.push_back(val);
140 : }
141 2382 : }
142 43972 : }
143 :
144 : void
145 1900262814 : MooseParsedFunctionWrapper::update()
146 : {
147 1900292936 : for (unsigned int i = 0; i < _pp_index.size(); ++i)
148 30122 : (*_addr[_pp_index[i]]) = (*_pp_vals[i]);
149 :
150 1900268775 : for (unsigned int i = 0; i < _scalar_index.size(); ++i)
151 5961 : (*_addr[_scalar_index[i]]) = (*_scalar_vals[i]);
152 1900262814 : }
153 :
154 : void
155 1900262814 : MooseParsedFunctionWrapper::updateFunctionValues(Real t, const Point & pt)
156 : {
157 1904002038 : for (unsigned int i = 0; i < _function_index.size(); ++i)
158 3739224 : (*_addr[_function_index[i]]) = _functions[i]->value(t, pt);
159 1900262814 : }
|