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 44107 : 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 44107 : const THREAD_ID tid)
23 44107 : : _feproblem(feproblem), _function_str(function_str), _vars(vars), _vals_input(vals), _tid(tid)
24 : {
25 44107 : initialize();
26 :
27 : _function_ptr =
28 44104 : std::make_unique<ParsedFunction<Real, RealGradient>>(_function_str, &_vars, &_initial_vals);
29 :
30 46516 : for (auto & v : _vars)
31 2412 : _addr.push_back(&_function_ptr->getVarAddress(v));
32 44104 : }
33 :
34 85506 : MooseParsedFunctionWrapper::~MooseParsedFunctionWrapper() {}
35 :
36 : template <>
37 : Real
38 1877944537 : MooseParsedFunctionWrapper::evaluate(Real t, const Point & p)
39 : {
40 1877944537 : update();
41 1877944537 : updateFunctionValues(t, p);
42 1877944537 : return (*_function_ptr)(p, t);
43 : }
44 :
45 : template <>
46 : DenseVector<Real>
47 11346839 : MooseParsedFunctionWrapper::evaluate(Real t, const Point & p)
48 : {
49 11346839 : update();
50 11346839 : updateFunctionValues(t, p);
51 11346839 : DenseVector<Real> output(LIBMESH_DIM);
52 11346839 : (*_function_ptr)(p, t, output);
53 11346839 : return output;
54 0 : }
55 :
56 : template <>
57 : RealVectorValue
58 11346839 : MooseParsedFunctionWrapper::evaluate(Real t, const Point & p)
59 : {
60 11346839 : DenseVector<Real> output = evaluate<DenseVector<Real>>(t, p);
61 :
62 11346839 : return RealVectorValue(output(0)
63 : #if LIBMESH_DIM > 1
64 : ,
65 11346839 : output(1)
66 : #endif
67 : #if LIBMESH_DIM > 2
68 : ,
69 11346839 : output(2)
70 : #endif
71 22693678 : );
72 11346839 : }
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 44107 : MooseParsedFunctionWrapper::initialize()
92 : {
93 : // Loop through all the input values supplied by the users.
94 46519 : 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 2415 : ReporterName r_name(_vals_input[i], "value");
98 2415 : 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 2315 : 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 2277 : 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 1995 : 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 1992 : _initial_vals.push_back(val);
140 : }
141 2412 : }
142 44104 : }
143 :
144 : void
145 1900594530 : MooseParsedFunctionWrapper::update()
146 : {
147 1900624652 : for (unsigned int i = 0; i < _pp_index.size(); ++i)
148 30122 : (*_addr[_pp_index[i]]) = (*_pp_vals[i]);
149 :
150 1900600491 : for (unsigned int i = 0; i < _scalar_index.size(); ++i)
151 5961 : (*_addr[_scalar_index[i]]) = (*_scalar_vals[i]);
152 1900594530 : }
153 :
154 : void
155 1900594530 : MooseParsedFunctionWrapper::updateFunctionValues(Real t, const Point & pt)
156 : {
157 1904333754 : for (unsigned int i = 0; i < _function_index.size(); ++i)
158 3739224 : (*_addr[_function_index[i]]) = _functions[i]->value(t, pt);
159 1900594530 : }
|