https://mooseframework.inl.gov
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 
19 registerMooseObjectRenamed("StochasticToolsApp",
20  SamplerTransfer,
21  "01/01/2020 00:00",
23 registerMooseObject("StochasticToolsApp", SamplerParameterTransfer);
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 
52 void
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 
79 void
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 
93 std::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 
163 std::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 }
registerMooseObjectRenamed("StochasticToolsApp", SamplerTransfer, "01/01/2020 00:00", SamplerParameterTransfer)
bool hasLocalApp(unsigned int global_app) const
const std::vector< std::string > & _parameter_names
Storage for the list of parameters to control.
Sampler * _sampler_ptr
Pointer to the Sampler object used by the SamplerTransientMultiApp or SamplerFullSolveMultiApp.
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)
bool tokenizeAndConvert(const std::string &str, std::vector< T > &tokenized_vector, const std::string &delimiter=" \\
unsigned int numLocalApps()
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...
std::vector< Real > getNextLocalRow()
dof_id_type getLocalRowBegin() const
const std::shared_ptr< MultiApp > getToMultiApp() const
dof_id_type getNumberOfLocalRows() const
bool hasFromMultiApp() const
The class creates an additional API to allow Transfers to work when running the StochasticTools<FullS...
std::shared_ptr< MultiApp > getMultiApp(const std::string &multi_app_name) const
std::vector< std::string > split(const std::string &str, const std::string &delimiter, std::size_t max_count=std::numeric_limits< std::size_t >::max())
void suppressParameter(const std::string &name)
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.
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
dof_id_type _app_index
Index for the sub-app that the batch-mode multiapp is working on.
SamplerParameterTransfer(const InputParameters &parameters)
virtual void executeToMultiapp() override
Methods used when running in batch mode (see SamplerFullSolveMultiApp)
FEProblemBase & appProblemBase(unsigned int app)
static InputParameters validParams()
void paramError(const std::string &param, Args... args) const
dof_id_type getLocalRowEnd() const
A Control object for receiving data from a master application Sampler object.
unsigned int firstLocalApp()
Copy each row from each DenseMatrix to the sub-applications SamplerReceiver object.
registerMooseObject("StochasticToolsApp", SamplerParameterTransfer)
void mooseError(Args &&... args) const
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.
void addClassDescription(const std::string &doc_string)
std::vector< Real > _row_data
The current row of data (comes from multiapp)
uint8_t dof_id_type
virtual void execute() override
Traditional Transfer callback.
static InputParameters validParams()