https://mooseframework.inl.gov
Loading...
Searching...
No Matches
MultiAppPostprocessorInterpolationTransfer.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
11
12// MOOSE includes
13#include "FEProblem.h"
14#include "MooseMesh.h"
15#include "MooseTypes.h"
16#include "MultiApp.h"
18
19#include "libmesh/meshfree_interpolation.h"
20#include "libmesh/numeric_vector.h"
21#include "libmesh/system.h"
22#include "libmesh/radial_basis_interpolation.h"
23
25
28{
30 params.addClassDescription("Transfer postprocessor data from sub-application into field data on "
31 "the parent application.");
32 params.addRequiredParam<AuxVariableName>(
33 "variable", "The auxiliary variable to store the transferred values in.");
34 params.addRequiredParam<PostprocessorName>("postprocessor", "The Postprocessor to interpolate.");
35 params.addParam<unsigned int>(
36 "num_points", 3, "The number of nearest points to use for interpolation.");
37 params.addParam<Real>(
38 "power", 2, "The polynomial power to use for calculation of the decay in the interpolation.");
39
40 MooseEnum interp_type("inverse_distance radial_basis", "inverse_distance");
41
42 params.addParam<MooseEnum>("interp_type", interp_type, "The algorithm to use for interpolation.");
43
44 params.addParam<Real>("radius",
45 -1,
46 "Radius to use for radial_basis interpolation. If negative "
47 "then the radius is taken as the max distance between "
48 "points.");
49 return params;
50}
51
53 const InputParameters & parameters)
54 : MultiAppTransfer(parameters),
55 _postprocessor(getParam<PostprocessorName>("postprocessor")),
56 _to_var_name(getParam<AuxVariableName>("variable")),
57 _num_points(getParam<unsigned int>("num_points")),
58 _power(getParam<Real>("power")),
59 _interp_type(getParam<MooseEnum>("interp_type")),
60 _radius(getParam<Real>("radius")),
61 _nodal(false)
62{
63 if (isParamValid("to_multi_app"))
64 paramError("to_multi_app", "Unused parameter; only from-MultiApp transfers are implemented");
65
66 auto & to_fe_type =
67 getFromMultiApp()->problemBase().getStandardVariable(0, _to_var_name).feType();
68 if ((to_fe_type.order != CONSTANT || to_fe_type.family != MONOMIAL) &&
69 (to_fe_type.order != FIRST || to_fe_type.family != LAGRANGE))
70 paramError("variable", "Must be either CONSTANT MONOMIAL or FIRST LAGRANGE");
71
72 _nodal = to_fe_type.family == LAGRANGE;
73}
74
75void
77{
78 TIME_SECTION("MultiAppPostprocessorInterpolationTransfer::execute()",
79 5,
80 "Transferring/interpolating postprocessors");
81
82 switch (_current_direction)
83 {
84 case TO_MULTIAPP:
85 {
86 mooseError("Interpolation from a variable to a MultiApp postprocessors has not been "
87 "implemented. Use MultiAppVariableValueSamplePostprocessorTransfer!");
88 break;
89 }
90 case FROM_MULTIAPP:
91 {
93 std::unique_ptr<libMesh::InverseDistanceInterpolation<LIBMESH_DIM>> idi;
94
95 switch (_interp_type)
96 {
97 case 0:
98 idi = std::make_unique<libMesh::InverseDistanceInterpolation<LIBMESH_DIM>>(
100 break;
101 case 1:
102 idi = std::make_unique<libMesh::RadialBasisInterpolation<LIBMESH_DIM>>(_communicator,
103 _radius);
104 break;
105 default:
106 mooseError("Unknown interpolation type!");
107 }
108
109 std::vector<Point> & src_pts(idi->get_source_points());
110 std::vector<Number> & src_vals(idi->get_source_vals());
111
112 std::vector<std::string> field_vars;
113 field_vars.push_back(_to_var_name);
114 idi->set_field_variables(field_vars);
115
116 {
117 mooseAssert(_to_transforms.size() == 1, "There should only be one transform here");
118 const auto & to_coord_transform = *_to_transforms[0];
119 for (unsigned int i = 0; i < getFromMultiApp()->numGlobalApps(); i++)
120 {
121 if (getFromMultiApp()->hasLocalApp(i) && getFromMultiApp()->isRootProcessor())
122 {
123 // Evaluation of the _from_transform at the origin yields the transformed position of
124 // the from multi-app
125 if (!getFromMultiApp()->runningInPosition())
126 src_pts.push_back(to_coord_transform.mapBack((*_from_transforms[i])(Point(0))));
127 else
128 // if running in position, the subapp mesh has been transformed so the translation
129 // is no longer applied by the transform
130 src_pts.push_back(to_coord_transform.mapBack(
131 (*_from_transforms[i])(getFromMultiApp()->position(i))));
132 src_vals.push_back(getFromMultiApp()->appPostprocessorValue(i, _postprocessor));
133 }
134 }
135 }
136
137 // We have only set local values - prepare for use by gathering remote data
138 idi->prepare_for_use();
139
140 // Loop over the parent app nodes and set the value of the variable
141 {
142 System * to_sys = find_sys(getFromMultiApp()->problemBase().es(), _to_var_name);
143
144 unsigned int sys_num = to_sys->number();
145 unsigned int var_num = to_sys->variable_number(_to_var_name);
146
147 NumericVector<Real> & solution = *to_sys->solution;
148
149 MooseMesh & mesh = getFromMultiApp()->problemBase().mesh();
150
151 std::vector<std::string> vars;
152
153 vars.push_back(_to_var_name);
154
155 if (_nodal)
156 {
157 // handle linear lagrange shape functions
158 for (const auto & node : as_range(mesh.localNodesBegin(), mesh.localNodesEnd()))
159 {
160 if (node->n_dofs(sys_num, var_num) > 0) // If this variable has dofs at this node
161 {
162 std::vector<Point> pts;
163 std::vector<Number> vals;
164
165 pts.push_back(*node);
166 vals.resize(1);
167
168 idi->interpolate_field_data(vars, pts, vals);
169
170 Real value = vals.front();
171
172 // The zero only works for LAGRANGE!
173 dof_id_type dof = node->dof_number(sys_num, var_num, 0);
174
175 solution.set(dof, value);
176 }
177 }
178 }
179 else
180 {
181 // handle constant monomial shape functions
182 for (const auto & elem :
183 as_range(mesh.getMesh().local_elements_begin(), mesh.getMesh().local_elements_end()))
184 {
185 // Exclude the elements without dofs
186 if (elem->n_dofs(sys_num, var_num) > 0)
187 {
188 std::vector<Point> pts;
189 std::vector<Number> vals;
190
191 pts.push_back(elem->vertex_average());
192 vals.resize(1);
193
194 idi->interpolate_field_data(vars, pts, vals);
195
196 Real value = vals.front();
197
198 dof_id_type dof = elem->dof_number(sys_num, var_num, 0);
199 solution.set(dof, value);
200 }
201 }
202 }
203
204 solution.close();
205 }
206
207 getFromMultiApp()->problemBase().es().update();
208
209 break;
210 }
211 }
212}
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
registerMooseObject("MooseApp", MultiAppPostprocessorInterpolationTransfer)
char ** vars
void ErrorVector unsigned int
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object.
void addRequiredParam(const std::string &name, const std::string &doc_string)
This method adds a parameter and documentation string to the InputParameters object that will be extr...
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump.
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
Definition MooseBase.h:457
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition MooseBase.h:199
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition MooseEnum.h:55
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Definition MooseMesh.h:95
Transfers from postprocessors in child apps of a MultiApp in different locations in parent app mesh,...
unsigned int _num_points
Number of points to consider for the interpolation.
PostprocessorName _postprocessor
Postprocessor in the child apps to transfer the data from.
AuxVariableName _to_var_name
Variable in the main application to fill with the interpolation of the postprocessors.
Real _radius
Radius to consider for inverse interpolation.
bool _nodal
Whether the target variable is nodal or elemental.
Real _power
Exponent for power-law decrease of the interpolation coefficients.
Base class for all MultiAppTransfer objects.
void errorIfObjectExecutesOnTransferInSourceApp(const std::string &object_name) const
Error if executing this MooseObject on EXEC_TRANSFER in a source multiapp (from_multiapp,...
std::vector< std::unique_ptr< MultiAppCoordTransform > > _from_transforms
static InputParameters validParams()
const std::shared_ptr< MultiApp > getFromMultiApp() const
Get the MultiApp to transfer data from.
std::vector< std::unique_ptr< MultiAppCoordTransform > > _to_transforms
@ FROM_MULTIAPP
Definition Transfer.h:71
@ TO_MULTIAPP
Definition Transfer.h:70
MooseEnum _current_direction
Definition Transfer.h:109
static libMesh::System * find_sys(libMesh::EquationSystems &es, const std::string &var_name)
Small helper function for finding the system containing the variable.
Definition Transfer.C:99
const Parallel::Communicator & _communicator
MeshBase & mesh