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 45653 : 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 45653 : const THREAD_ID tid)
23 45653 : : _feproblem(feproblem), _function_str(function_str), _vars(vars), _vals_input(vals), _tid(tid)
24 : {
25 45653 : initialize();
26 :
27 : _function_ptr =
28 45649 : std::make_unique<ParsedFunction<Real, RealGradient>>(_function_str, &_vars, &_initial_vals);
29 :
30 48645 : for (auto & v : _vars)
31 2996 : _addr.push_back(&_function_ptr->getVarAddress(v));
32 45649 : }
33 :
34 88348 : MooseParsedFunctionWrapper::~MooseParsedFunctionWrapper() {}
35 :
36 : template <>
37 : Real
38 2138646444 : MooseParsedFunctionWrapper::evaluate(Real t, const Point & p)
39 : {
40 2138646444 : update();
41 2138646444 : updateFunctionValues(t, p);
42 2138646444 : return (*_function_ptr)(p, t);
43 : }
44 :
45 : template <>
46 : DenseVector<Real>
47 12391776 : MooseParsedFunctionWrapper::evaluate(Real t, const Point & p)
48 : {
49 12391776 : update();
50 12391776 : updateFunctionValues(t, p);
51 12391776 : DenseVector<Real> output(LIBMESH_DIM);
52 12391776 : (*_function_ptr)(p, t, output);
53 12391776 : return output;
54 0 : }
55 :
56 : template <>
57 : RealVectorValue
58 12391776 : MooseParsedFunctionWrapper::evaluate(Real t, const Point & p)
59 : {
60 12391776 : DenseVector<Real> output = evaluate<DenseVector<Real>>(t, p);
61 :
62 12391776 : return RealVectorValue(output(0)
63 : #if LIBMESH_DIM > 1
64 : ,
65 12391776 : output(1)
66 : #endif
67 : #if LIBMESH_DIM > 2
68 : ,
69 12391776 : output(2)
70 : #endif
71 24783552 : );
72 12391776 : }
73 :
74 : RealGradient
75 8403754 : MooseParsedFunctionWrapper::evaluateGradient(Real t, const Point & p)
76 : {
77 8403754 : update();
78 8403754 : updateFunctionValues(t, p);
79 8403754 : return _function_ptr->gradient(p, t);
80 : }
81 :
82 : Real
83 4554970 : MooseParsedFunctionWrapper::evaluateDot(Real t, const Point & p)
84 : {
85 4554970 : update();
86 4554970 : updateFunctionValues(t, p);
87 4554970 : return _function_ptr->dot(p, t);
88 : }
89 :
90 : void
91 45653 : MooseParsedFunctionWrapper::initialize()
92 : {
93 : // Loop through all the input values supplied by the users.
94 48649 : 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 3000 : ReporterName r_name(_vals_input[i], "value");
98 3000 : if (_feproblem.getReporterData().hasReporterValue<PostprocessorValue>(r_name))
99 : {
100 109 : const Real & pp_val = _feproblem.getPostprocessorValueByName(_vals_input[i]);
101 109 : _initial_vals.push_back(pp_val);
102 109 : _pp_vals.push_back(&pp_val);
103 109 : _pp_index.push_back(i);
104 : }
105 :
106 : // Case when a scalar variable is found by the name given in the input values
107 2891 : else if (_feproblem.hasScalarVariable(_vals_input[i]))
108 : {
109 41 : auto & scalar_val = _feproblem.getScalarVariable(_tid, _vals_input[i]).sln()[0];
110 41 : _initial_vals.push_back(scalar_val);
111 41 : _scalar_vals.push_back(&scalar_val);
112 41 : _scalar_index.push_back(i);
113 : }
114 :
115 : // Case when a function is found by the name given in the input values
116 2850 : else if (_feproblem.hasFunction(_vals_input[i]))
117 : {
118 264 : Function & fn = _feproblem.getFunction(_vals_input[i], _tid);
119 264 : _initial_vals.push_back(0);
120 264 : _functions.push_back(&fn);
121 264 : _function_index.push_back(i);
122 : }
123 :
124 : // Case when a Real is supplied
125 : else
126 : {
127 : Real val;
128 : try
129 : {
130 2586 : val = MooseUtils::convert<Real>(_vals_input[i], true);
131 : }
132 4 : catch (const std::invalid_argument & e)
133 : {
134 4 : mooseError("'No postprocessor, scalar variable, or function with the name '",
135 4 : _vals_input[i],
136 : "' found. ",
137 4 : e.what());
138 0 : }
139 2582 : _initial_vals.push_back(val);
140 : }
141 2996 : }
142 45649 : }
143 :
144 : void
145 2163996944 : MooseParsedFunctionWrapper::update()
146 : {
147 2164030712 : for (unsigned int i = 0; i < _pp_index.size(); ++i)
148 33768 : (*_addr[_pp_index[i]]) = (*_pp_vals[i]);
149 :
150 2164003604 : for (unsigned int i = 0; i < _scalar_index.size(); ++i)
151 6660 : (*_addr[_scalar_index[i]]) = (*_scalar_vals[i]);
152 2163996944 : }
153 :
154 : void
155 2163996944 : MooseParsedFunctionWrapper::updateFunctionValues(Real t, const Point & pt)
156 : {
157 2164453379 : for (unsigned int i = 0; i < _function_index.size(); ++i)
158 456435 : (*_addr[_function_index[i]]) = _functions[i]->value(t, pt);
159 2163996944 : }
|