https://mooseframework.inl.gov
Loading...
Searching...
No Matches
SamplerParameterTransfer.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// MOOSE includes
14#include "SamplerReceiver.h"
15#include "Sampler.h"
16#include "MooseUtils.h"
17#include "pcrecpp.h"
18
19registerMooseObjectRenamed("StochasticToolsApp",
20 SamplerTransfer,
21 "01/01/2020 00:00",
24
27{
29 params.addClassDescription("Copies Sampler data to a SamplerReceiver object.");
30 params.suppressParameter<MultiMooseEnum>("direction");
31 params.suppressParameter<MultiAppName>("multi_app");
32 params.addParam<std::vector<std::string>>(
33 "parameters",
34 "A list of parameters (on the sub application) to control "
35 "with the Sampler data. The order of the parameters listed "
36 "here should match the order of the items in the Sampler.");
37 params.addDeprecatedParam<std::string>(
38 "to_control",
39 "Unused parameter.",
40 "This parameter is no longer used as the SamplerReceiver will automatically be detected.");
41 return params;
42}
43
45 : StochasticToolsTransfer(parameters),
46 _parameter_names(getParam<std::vector<std::string>>("parameters"))
47{
48 if (hasFromMultiApp())
49 paramError("from_multi_app", "From and between multiapp directions are not implemented");
50}
51
52void
54{
55 mooseAssert((_sampler_ptr->getNumberOfLocalRows() == 0) ||
56 (_sampler_ptr->getNumberOfLocalRows() == getToMultiApp()->numLocalApps()),
57 "The number of MultiApps and the number of sample rows must be the same.");
58
59 // Loop over all sub-apps
60 for (dof_id_type row_index = _sampler_ptr->getLocalRowBegin();
61 row_index < _sampler_ptr->getLocalRowEnd();
62 row_index++)
63 {
64 mooseAssert(getToMultiApp()->hasLocalApp(row_index),
65 "The current sample row index is not a valid global MultiApp index.");
66
67 // Populate the row of data to transfer
68 std::vector<Real> row = _sampler_ptr->getNextLocalRow();
69
70 // Get the command line arguments
72
73 // Get the sub-app SamplerReceiver objects and transfer param-values map
74 for (auto & ptr : getReceivers(row_index, args))
75 ptr.first->transfer(ptr.second);
76 }
77}
78
79void
81{
82 if (getToMultiApp()->isRootProcessor())
83 {
84 // Get the command line arguments
86
87 // Get the sub-app SamplerReceiver objects and transfer param-values map
88 for (auto & ptr : getReceivers(_app_index, args))
89 ptr.first->transfer(ptr.second);
90 }
91}
92
93std::map<SamplerReceiver *, std::map<std::string, std::vector<Real>>>
95 const std::vector<std::string> & args)
96{
97 // These are the receivers we are returning
98 std::map<SamplerReceiver *, std::map<std::string, std::vector<Real>>> ptrs;
99
100 // Split all the input parameters to retrieve receivers and set param-values pairs
101 // Cache the multiapp-reciever mapping
102 std::unordered_map<std::string, std::vector<SamplerReceiver *>> multiapp_receivers;
103 for (const auto & param : args)
104 {
105 // Get MultiApp Name
106 std::string multiapp_name = getToMultiApp()->name();
107 const auto pos = param.rfind(":");
108 if (pos != std::string::npos)
109 multiapp_name += ":" + param.substr(0, pos);
110 // Get parameter name
111 const auto pos2 = param.rfind("=");
112 if (pos2 == std::string::npos)
113 mooseError("Internal error: Improper command-line format\n ", param, ".");
114 const std::string param_name = param.substr(pos + 1, pos2 - pos - 1);
115
116 // Get values
117 const std::string vstr = param.substr(pos2 + 1);
118 const auto vpos1 = vstr.find("'");
119 const auto vpos2 = vstr.rfind("'");
120 std::vector<Real> value;
121 if (!MooseUtils::tokenizeAndConvert(vstr.substr(vpos1 + 1, vpos2 - vpos1 - 1), value, " "))
122 mooseError("Internal error: Improper command-line format\n ", param, ".");
123
124 // Find receivers if we haven't already found them
125 if (multiapp_receivers.find(multiapp_name) == multiapp_receivers.end())
126 {
127 auto & recvs = multiapp_receivers[multiapp_name]; // Convenience
128 // Split the <sub>:<subsub>:<subsubsub> syntax
129 const std::vector<std::string> nested_names = MooseUtils::split(multiapp_name, ":");
130 // Find all the appropriate FEProblemBases based on the parameter syntax and get a
131 // SamplerReceiver
132 for (const auto & problem : getMultiAppProblemsHelper(
133 getToMultiApp()->appProblemBase(app_index),
134 std::vector<std::string>(nested_names.begin() + 1, nested_names.end())))
135 {
136 // Loop through all the active controls and find one that is a SamplerReciever
137 SamplerReceiver * recv_ptr = nullptr;
138 for (const auto & control_ptr : problem->getControlWarehouse().getActiveObjects())
139 {
140 recv_ptr = dynamic_cast<SamplerReceiver *>(control_ptr.get());
141 if (recv_ptr)
142 break;
143 }
144 if (!recv_ptr)
145 paramError("parameters",
146 "The sub-application (",
147 multiapp_name,
148 ") does not contain a SamplerReceiver control object.");
149
150 // Insert the found receiver
151 recvs.push_back(recv_ptr);
152 }
153 }
154
155 // Add the parameter and value to the reciever map
156 for (const auto & recv_ptr : multiapp_receivers[multiapp_name])
157 ptrs[recv_ptr][param_name] = value;
158 }
159
160 return ptrs;
161}
162
163std::vector<FEProblemBase *>
165 const std::vector<std::string> & multiapp_names)
166{
167 // This is what we'll return
168 std::vector<FEProblemBase *> problems;
169
170 if (multiapp_names.empty()) // Stop recursion if no nested apps provided
171 problems.push_back(&base_problem);
172 else
173 {
174 // Get the name of highest level app provided and the index if provided
175 std::string sub_name;
176 int sub_num = -1;
177 pcrecpp::RE("(\\S*?)(\\d*)").FullMatch(multiapp_names[0], &sub_name, &sub_num);
178 MultiApp & multiapp = *base_problem.getMultiApp(sub_name);
179
180 // Get the app indices (either the requested one or all of them)
181 std::pair<unsigned int, unsigned int> app_ind;
182 if (sub_num == -1) // There was no number provided, so get all the local sub apps
183 app_ind = std::make_pair(multiapp.firstLocalApp(),
184 multiapp.firstLocalApp() + multiapp.numLocalApps());
185 else if (multiapp.hasLocalApp(sub_num)) // Number provided, get that app if owned
186 app_ind = std::make_pair(sub_num, sub_num + 1);
187 else // This processor doesn't own the app index provided
188 return {};
189
190 // Get all the nested subapps with recursion
191 std::vector<std::string> nested_names(multiapp_names.begin() + 1, multiapp_names.end());
192 for (unsigned int i = app_ind.first; i < app_ind.second; ++i)
193 for (auto & prob : getMultiAppProblemsHelper(multiapp.appProblemBase(i), nested_names))
194 problems.push_back(prob);
195 }
196
197 return problems;
198}
registerMooseObject("StochasticToolsApp", SamplerParameterTransfer)
registerMooseObjectRenamed("StochasticToolsApp", SamplerTransfer, "01/01/2020 00:00", SamplerParameterTransfer)
std::shared_ptr< MultiApp > getMultiApp(const std::string &multi_app_name) const
void suppressParameter(const std::string &name)
void addDeprecatedParam(const std::string &name, const T &value, const std::string &doc_string, const std::string &deprecation_message)
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
void mooseError(Args &&... args) const
const std::shared_ptr< MultiApp > getToMultiApp() const
bool hasFromMultiApp() const
unsigned int numLocalApps()
FEProblemBase & appProblemBase(unsigned int app)
bool hasLocalApp(unsigned int global_app) const
unsigned int firstLocalApp()
static std::vector< std::string > sampledCommandLineArgs(const std::vector< Real > &row, const std::vector< std::string > &full_args_name)
Helper for inserting row data into commandline arguments Used here and in SamplerTransientMultiApp.
Copy each row from each DenseMatrix to the sub-applications SamplerReceiver object.
static InputParameters validParams()
virtual void executeToMultiapp() override
Methods used when running in batch mode (see SamplerFullSolveMultiApp)
const std::vector< std::string > & _parameter_names
Storage for the list of parameters to control.
SamplerParameterTransfer(const InputParameters &parameters)
std::map< SamplerReceiver *, std::map< std::string, std::vector< Real > > > getReceivers(unsigned int app_index, const std::vector< std::string > &args)
Based on command line args, return a map between SamplerReceiver objects and the parameter-value pair...
virtual void execute() override
Traditional Transfer callback.
static std::vector< FEProblemBase * > getMultiAppProblemsHelper(FEProblemBase &base_problem, const std::vector< std::string > &multiapp_names)
Helper function that recursively finds feproblem pointers from nested multiapps.
A Control object for receiving data from a master application Sampler object.
std::vector< Real > getNextLocalRow()
dof_id_type getNumberOfLocalRows() const
dof_id_type getLocalRowEnd() const
dof_id_type getLocalRowBegin() const
The class creates an additional API to allow Transfers to work when running the StochasticTools<FullS...
static InputParameters validParams()
std::vector< Real > _row_data
The current row of data (comes from multiapp)
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.
bool tokenizeAndConvert(const std::string &str, std::vector< T > &tokenized_vector, const std::string &delimiter=" \t\n\v\f\r")
std::vector< std::string > split(const std::string &str, const std::string &delimiter, std::size_t max_count)