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 42644 : 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 42644 : const THREAD_ID tid)
23 42644 : : _feproblem(feproblem), _function_str(function_str), _vars(vars), _vals_input(vals), _tid(tid)
24 : {
25 42644 : initialize();
26 :
27 : _function_ptr =
28 42640 : std::make_unique<ParsedFunction<Real, RealGradient>>(_function_str, &_vars, &_initial_vals);
29 :
30 45313 : for (auto & v : _vars)
31 2673 : _addr.push_back(&_function_ptr->getVarAddress(v));
32 42640 : }
33 :
34 82350 : MooseParsedFunctionWrapper::~MooseParsedFunctionWrapper() {}
35 :
36 : template <>
37 : Real
38 1923887307 : MooseParsedFunctionWrapper::evaluate(Real t, const Point & p)
39 : {
40 1923887307 : update();
41 1923887307 : updateFunctionValues(t, p);
42 1923887307 : return (*_function_ptr)(p, t);
43 : }
44 :
45 : template <>
46 : DenseVector<Real>
47 10405723 : MooseParsedFunctionWrapper::evaluate(Real t, const Point & p)
48 : {
49 10405723 : update();
50 10405723 : updateFunctionValues(t, p);
51 10405723 : DenseVector<Real> output(LIBMESH_DIM);
52 10405723 : (*_function_ptr)(p, t, output);
53 10405723 : return output;
54 0 : }
55 :
56 : template <>
57 : RealVectorValue
58 10405723 : MooseParsedFunctionWrapper::evaluate(Real t, const Point & p)
59 : {
60 10405723 : DenseVector<Real> output = evaluate<DenseVector<Real>>(t, p);
61 :
62 10405723 : return RealVectorValue(output(0)
63 : #if LIBMESH_DIM > 1
64 : ,
65 10405723 : output(1)
66 : #endif
67 : #if LIBMESH_DIM > 2
68 : ,
69 10405723 : output(2)
70 : #endif
71 20811446 : );
72 10405723 : }
73 :
74 : RealGradient
75 8076352 : MooseParsedFunctionWrapper::evaluateGradient(Real t, const Point & p)
76 : {
77 8076352 : update();
78 8076352 : updateFunctionValues(t, p);
79 8076352 : return _function_ptr->gradient(p, t);
80 : }
81 :
82 : Real
83 4554666 : MooseParsedFunctionWrapper::evaluateDot(Real t, const Point & p)
84 : {
85 4554666 : update();
86 4554666 : updateFunctionValues(t, p);
87 4554666 : return _function_ptr->dot(p, t);
88 : }
89 :
90 : void
91 42644 : MooseParsedFunctionWrapper::initialize()
92 : {
93 : // Loop through all the input values supplied by the users.
94 45317 : 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 2677 : ReporterName r_name(_vals_input[i], "value");
98 2677 : if (_feproblem.getReporterData().hasReporterValue<PostprocessorValue>(r_name))
99 : {
100 101 : const Real & pp_val = _feproblem.getPostprocessorValueByName(_vals_input[i]);
101 101 : _initial_vals.push_back(pp_val);
102 101 : _pp_vals.push_back(&pp_val);
103 101 : _pp_index.push_back(i);
104 : }
105 :
106 : // Case when a scalar variable is found by the name given in the input values
107 2576 : else if (_feproblem.hasScalarVariable(_vals_input[i]))
108 : {
109 39 : auto & scalar_val = _feproblem.getScalarVariable(_tid, _vals_input[i]).sln()[0];
110 39 : _initial_vals.push_back(scalar_val);
111 39 : _scalar_vals.push_back(&scalar_val);
112 39 : _scalar_index.push_back(i);
113 : }
114 :
115 : // Case when a function is found by the name given in the input values
116 2537 : else if (_feproblem.hasFunction(_vals_input[i]))
117 : {
118 133 : Function & fn = _feproblem.getFunction(_vals_input[i], _tid);
119 133 : _initial_vals.push_back(0);
120 133 : _functions.push_back(&fn);
121 133 : _function_index.push_back(i);
122 : }
123 :
124 : // Case when a Real is supplied
125 : else
126 : {
127 : Real val;
128 : try
129 : {
130 2404 : 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 2400 : _initial_vals.push_back(val);
140 : }
141 2673 : }
142 42640 : }
143 :
144 : void
145 1946924048 : MooseParsedFunctionWrapper::update()
146 : {
147 1946953208 : for (unsigned int i = 0; i < _pp_index.size(); ++i)
148 29160 : (*_addr[_pp_index[i]]) = (*_pp_vals[i]);
149 :
150 1946929895 : for (unsigned int i = 0; i < _scalar_index.size(); ++i)
151 5847 : (*_addr[_scalar_index[i]]) = (*_scalar_vals[i]);
152 1946924048 : }
153 :
154 : void
155 1946924048 : MooseParsedFunctionWrapper::updateFunctionValues(Real t, const Point & pt)
156 : {
157 1947150152 : for (unsigned int i = 0; i < _function_index.size(); ++i)
158 226104 : (*_addr[_function_index[i]]) = _functions[i]->value(t, pt);
159 1946924048 : }
|