https://mooseframework.inl.gov
Loading...
Searching...
No Matches
SerializedSolutionTransfer.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
10// StochasticTools includes
12#include "NonlinearSystemBase.h"
13#include "Sampler.h"
14
16
19{
22 "Serializes and transfers solution vectors for given variables from sub-applications.");
23 params.addRequiredParam<std::string>("parallel_storage",
24 "The name of the parallel storage reporter.");
25 params.addRequiredParam<std::string>("solution_container",
26 "The name of the solution container on the subapp.");
27 params.addRequiredParam<std::vector<VariableName>>(
28 "variables",
29 "The names of the variables which should be serialized and transferred to this application.");
30 params.addParam<bool>("serialize_on_root",
31 false,
32 "If we want to gather the solution fields only on the root processors of "
33 "the subapps before transfering to the main app.");
34 return params;
35}
36
38 : StochasticToolsTransfer(parameters),
39 _variable_names(getParam<std::vector<VariableName>>("variables")),
40 _serialize_on_root(getParam<bool>("serialize_on_root"))
41{
42 if (hasToMultiApp())
43 paramError("to_multi_app", "To and between multiapp directions are not implemented");
44}
45
46void
48{
49 // Check if we have the storage space to receive the serialized solution fields
51 getParam<std::string>("parallel_storage"));
52}
53
54void
56{
57 _solution_container.clear();
58 const auto n = getFromMultiApp()->numGlobalApps();
59 const auto & serialized_solution_reporter = getParam<std::string>("solution_container");
60
61 for (MooseIndex(n) i = 0; i < n; i++)
62 if (getFromMultiApp()->hasLocalApp(i))
63 {
64 FEProblemBase & app_problem = getFromMultiApp()->appProblemBase(i);
65 _solution_container.push_back(
66 &app_problem.getUserObject<SolutionContainer>(serialized_solution_reporter));
67 }
68}
69
70void
72{
73 // First we fetch the solution containers from the subapps. This function is used
74 // in batch mode only so we will have one solution container on each rank
75 _solution_container.clear();
76
77 FEProblemBase & app_problem = getFromMultiApp()->appProblemBase(_app_index);
78
79 _solution_container.push_back(
80 &app_problem.getUserObject<SolutionContainer>(getParam<std::string>("solution_container")));
81}
82
83void
85{
87
88 const auto n = getFromMultiApp()->numGlobalApps();
89
90 for (MooseIndex(n) i = 0; i < n; i++)
91 {
92 if (getFromMultiApp()->hasLocalApp(i))
93 {
94 FEProblemBase & app_problem = getFromMultiApp()->appProblemBase(i);
95
96 // Converting the local indexing to global sample indices
97 const unsigned int local_i = i - _sampler_ptr->getLocalRowBegin();
98
99 // Here we have to branch out based on if only the root processors
100 // need to participate in the transfer or if we would like to distribute the
101 // data among every processor of the subapplication
103 transferToSubAppRoot(app_problem, *_solution_container[local_i], i);
104 else
105 transferInParallel(app_problem, *_solution_container[local_i], i);
106 }
107 }
108}
109
110void
112{
114
115 if (getFromMultiApp()->hasLocalApp(_app_index))
116 {
117 FEProblemBase & app_problem = getFromMultiApp()->appProblemBase(_app_index);
118
119 // Here we have to branch out based on if only the root processors
120 // need to participate in the transfer or if we would like to distribute the
121 // data among every processor of the subapplication
124 else
126 }
127}
128
129void
131 SolutionContainer & solution_container,
132 const dof_id_type global_i)
133{
134 unsigned int local_app_index = global_i - _sampler_ptr->getLocalRowBegin();
135
136 // Looping over the variables to extract the corresponding solution values
137 // and copy them into the container.
138 for (unsigned int var_i = 0; var_i < _variable_names.size(); ++var_i)
139 {
140 SystemBase & system = getSystem(app_problem, _variable_names[var_i]);
141
142 // We need to go through this communicator because the multiapp's
143 // communicator is not necessarily the communicator of the underlying MooseObject.
144 const auto & comm = system.comm();
145 dof_id_type num_entries = _sampler_ptr->getNumberOfLocalRows();
146 comm.sum(num_entries);
147
148 // We shall distribute the samples on the given application between its processors.
149 // Only using a linear partitioning here for the sake of simplicity.
150 dof_id_type new_local_entries_begin;
151 dof_id_type new_local_entries_end;
152 dof_id_type num_new_local_entries;
153
155 comm.size(),
156 comm.rank(),
157 num_new_local_entries,
158 new_local_entries_begin,
159 new_local_entries_end);
160
161 // Getting the corresponding DoF indices for the variable.
163
164 for (const auto & snapshot : solution_container.getSnapshots())
165 {
166 DenseVector<Real> serialized_solution;
167
168 // Localize the solution and add it to the local container on the rank
169 // which is supposed to own it
170 snapshot.localize(
171 serialized_solution.get_values(),
172 (local_app_index >= new_local_entries_begin && local_app_index < new_local_entries_end)
173 ? system.getVariableGlobalDoFs()
174 : std::vector<dof_id_type>());
175
176 if (local_app_index >= new_local_entries_begin && local_app_index < new_local_entries_end)
177 _parallel_storage->addEntry(_variable_names[var_i], global_i, serialized_solution);
178 }
179 }
180}
181
182void
184 SolutionContainer & solution_container,
185 const dof_id_type global_i)
186{
187 // Looping over the variables to extract the corresponding solution values
188 for (unsigned int var_i = 0; var_i < _variable_names.size(); ++var_i)
189 {
190 SystemBase & system = getSystem(app_problem, _variable_names[var_i]);
191
192 // Getting the corresponding DoF indices for the variable.
194
195 for (const auto & snapshot : solution_container.getSnapshots())
196 {
197 DenseVector<Real> serialized_solution;
198
199 // In this case we always serialize on the root processor of the application.
200 snapshot.localize(serialized_solution.get_values(),
201 getFromMultiApp()->isRootProcessor() ? system.getVariableGlobalDoFs()
202 : std::vector<dof_id_type>());
203
204 if (getFromMultiApp()->isRootProcessor())
205 _parallel_storage->addEntry(_variable_names[var_i], global_i, serialized_solution);
206 }
207 }
208}
209
211SerializedSolutionTransfer::getSystem(FEProblemBase & app_problem, const VariableName & vname)
212{
213 auto & variable = app_problem.getVariable(_tid, vname);
214 return variable.sys();
215}
registerMooseObject("StochasticToolsApp", SerializedSolutionTransfer)
T & getUserObject(const std::string &name, unsigned int tid=0) const
virtual const MooseVariableFieldBase & getVariable(const THREAD_ID tid, const std::string &var_name, Moose::VarKindType expected_var_type=Moose::VarKindType::VAR_ANY, Moose::VarFieldType expected_var_field_type=Moose::VarFieldType::VAR_FIELD_ANY) const override
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
void paramError(const std::string &param, Args... args) const
SystemBase & sys()
bool hasToMultiApp() const
const std::shared_ptr< MultiApp > getFromMultiApp() const
A Reporter which stores serialized solution fields for given variables in a distributed fashion.
void addEntry(const VariableName &vname, unsigned int global_i, const DenseVector< Real > &solution)
Add a new solution entry to the container.
dof_id_type getNumberOfLocalRows() const
dof_id_type getLocalRowBegin() const
This class is responsible for serializing solutions coming from subapps on specific processors.
SerializedSolutionTransfer(const InputParameters &parameters)
std::vector< SolutionContainer * > _solution_container
Link to the storage spaces on the subapplications (will only hold one in batch mode)
SystemBase & getSystem(FEProblemBase &app_problem, const VariableName &vname)
Return the system which contains the given variable.
void transferToSubAppRoot(FEProblemBase &app_problem, SolutionContainer &solution_container, const dof_id_type global_i)
Serialize on the root processor of the subapplication and transfer the result to the main application...
const bool _serialize_on_root
User-selected switch that determines if we want to serialize on the root of the subapp only or distri...
std::vector< VariableName > _variable_names
The names of the variables which should be extracted from the solution vector.
void transferInParallel(FEProblemBase &app_problem, SolutionContainer &solution_container, const dof_id_type global_i)
Serialize on methodically determined rank of the subapp and transfer to the main application.
static InputParameters validParams()
void initializeInBatchMode()
This routine queries the solution container addresses from the subapps.
ParallelSolutionStorage * _parallel_storage
The storage on the main application where the serialized solutions should be transferred.
void initializeInNormalMode()
Initializes the solution container if the multiapp is run in normal mode.
const Snapshots & getSnapshots() const
Return the whole snapshot container.
This class is responsible for collecting solution vectors in one place.
The class creates an additional API to allow Transfers to work when running the StochasticTools<FullS...
dof_id_type _global_index
Index for tracking the row index when using batch mode operation.
static InputParameters validParams()
dof_id_type _app_index
Index for the sub-app that the batch-mode multiapp is working on.
Sampler * _sampler_ptr
Pointer to the Sampler object used by the SamplerTransientMultiApp or SamplerFullSolveMultiApp.
const std::vector< dof_id_type > & getVariableGlobalDoFs()
void setVariableGlobalDoFs(const std::string &var_name)
processor_id_type size() const
processor_id_type rank() const
FEProblemBase & _fe_problem
const Parallel::Communicator & comm() const
void linearPartitionItems(dof_id_type num_items, dof_id_type num_chunks, dof_id_type chunk_id, dof_id_type &num_local_items, dof_id_type &local_items_begin, dof_id_type &local_items_end)