https://mooseframework.inl.gov
PODFullSolveMultiApp.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
11 #include "PODFullSolveMultiApp.h"
12 #include "NonlinearSystemBase.h"
13 #include "Sampler.h"
14 #include "Executioner.h"
16 #include "PODResidualTransfer.h"
17 
18 registerMooseObject("StochasticToolsApp", PODFullSolveMultiApp);
19 
22 {
24  params.addClassDescription(
25  "Creates a full-solve type sub-application for each row of a Sampler matrix. "
26  "On second call, this object creates residuals for a PODReducedBasisTrainer with given basis "
27  "functions.");
28  params.addRequiredParam<UserObjectName>(
29  "trainer_name", "Trainer object that contains the solutions for different samples.");
30 
31  return params;
32 }
33 
35  : SamplerFullSolveMultiApp(parameters),
37  _trainer(getSurrogateTrainer<PODReducedBasisTrainer>("trainer_name")),
38  _snapshot_generation(true)
39 {
40  if (getParam<unsigned int>("max_procs_per_app") != 1)
41  paramError("max_procs_per_app", " does not support more than one processors per subapp!");
42 
44  mooseError(type(),
45  " needs to be run with fewer processors (detected ",
46  n_processors(),
47  ") than samples (detected ",
49  ")!");
50 }
51 
52 void
53 PODFullSolveMultiApp::preTransfer(Real dt, Real target_time)
54 {
55  // Reinitialize the problem only if the snapshot generation part is done.
57  {
58  dof_id_type base_size = _trainer.getSumBaseSize();
59  if (base_size < 1)
60  mooseError(
61  "There are no basis vectors available for residual generation."
62  " This indicates that the bases have not been created yet."
63  " The most common cause of this error is the wrong setting"
64  " of the 'execute_on' flags in the PODFullSolveMultiApp and/or PODReducedBasisTrainer.");
65 
66  init(base_size,
69 
70  initialSetup();
71  }
73 }
74 
75 bool
76 PODFullSolveMultiApp::solveStep(Real dt, Real target_time, bool auto_advance)
77 {
78 
79  bool last_solve_converged = true;
80 
81  // If snapshot generation phase, solve the subapplications in a regular manner.
82  // Otherwise, compute the residuals only.
84  {
85  last_solve_converged = SamplerFullSolveMultiApp::solveStep(dt, target_time, auto_advance);
86  _snapshot_generation = false;
87  }
88  else
89  {
92  computeResidualBatch(target_time);
93  else
95  }
96 
97  return last_solve_converged;
98 }
99 
100 void
102 {
103  // Doing the regular computation but instead of solving the subapplication,
104  // the residuals for different tags are evaluated.
105  if (!_has_an_app)
106  return;
107 
109 
110  int rank;
111  int ierr;
112  ierr = MPI_Comm_rank(_communicator.get(), &rank);
113  mooseCheckMPIErr(ierr);
114 
115  // Getting the necessary tag names.
116  const std::vector<std::string> & trainer_tags = _trainer.getTagNames();
117 
118  // Looping over the subapplications and computing residuals.
119  for (unsigned int i = 0; i < _my_num_apps; i++)
120  {
121  // Getting the local problem
122  FEProblemBase & problem = _apps[i]->getExecutioner()->feProblem();
123 
124  // Extracting the TagIDs based on tag names from the current subapp.
125  std::set<TagID> tags_to_compute;
126  for (auto & tag_name : trainer_tags)
127  tags_to_compute.insert(problem.getVectorTagID(tag_name));
128 
129  problem.setCurrentNonlinearSystem(0);
130  problem.computeResidualTags(tags_to_compute);
131  }
132 }
133 
134 void
136 {
137  // Getting the overall base size from the trainer.
138  dof_id_type base_size = _trainer.getSumBaseSize();
139 
140  // Distributing the residual evaluation among processes.
141  dof_id_type local_base_begin;
142  dof_id_type local_base_end;
143  dof_id_type n_local_bases;
145  base_size, n_processors(), processor_id(), n_local_bases, local_base_begin, local_base_end);
146 
147  // List of active relevant Transfer objects
148  std::vector<std::shared_ptr<PODSamplerSolutionTransfer>> to_transfers =
150  std::vector<std::shared_ptr<PODResidualTransfer>> from_transfers =
152 
153  // Initialize to/from transfers
154  for (auto transfer : to_transfers)
155  transfer->initializeToMultiapp();
156 
157  for (auto transfer : from_transfers)
158  transfer->initializeFromMultiapp();
159 
161  backup();
162 
163  // Perform batch MultiApp solves
165  for (dof_id_type i = local_base_begin; i < local_base_end; ++i)
166  {
167  for (auto & transfer : to_transfers)
168  {
169  transfer->setGlobalMultiAppIndex(i);
170  transfer->executeToMultiapp();
171  }
172 
173  computeResidual();
174 
175  for (auto & transfer : from_transfers)
176  {
177  transfer->setGlobalMultiAppIndex(i);
178  transfer->executeFromMultiapp();
179  }
180 
181  if (i < _sampler.getLocalRowEnd() - 1)
182  {
184  restore();
185  else
186  {
187  // The app is being reset for the next loop, thus the batch index must be indexed as such
189  resetApp(_local_batch_app_index + i, target_time);
190  initialSetup();
191  }
192  }
193  }
194 
195  // Finalize to/from transfers
196  for (auto transfer : to_transfers)
197  transfer->finalizeToMultiapp();
198  for (auto transfer : from_transfers)
199  transfer->finalizeFromMultiapp();
200 }
201 
202 std::vector<std::shared_ptr<PODSamplerSolutionTransfer>>
204 {
205  std::vector<std::shared_ptr<PODSamplerSolutionTransfer>> output;
206  const ExecuteMooseObjectWarehouse<Transfer> & warehouse =
208  for (std::shared_ptr<Transfer> transfer : warehouse.getActiveObjects())
209  {
210  auto ptr = std::dynamic_pointer_cast<PODSamplerSolutionTransfer>(transfer);
211  if (ptr)
212  output.push_back(ptr);
213  }
214  return output;
215 }
216 
217 std::vector<std::shared_ptr<PODResidualTransfer>>
219 {
220  std::vector<std::shared_ptr<PODResidualTransfer>> output;
221  const ExecuteMooseObjectWarehouse<Transfer> & warehouse =
223  for (std::shared_ptr<Transfer> transfer : warehouse.getActiveObjects())
224  {
225  auto ptr = std::dynamic_pointer_cast<PODResidualTransfer>(transfer);
226  if (ptr)
227  output.push_back(ptr);
228  }
229  return output;
230 }
const StochasticTools::MultiAppMode _mode
The Sup-application solve mode.
virtual TagID getVectorTagID(const TagName &tag_name) const
virtual void initialSetup() override
void paramError(const std::string &param, Args... args) const
virtual void backup() override
This method is overridden so that we only store the initial state and not on any other timestep when ...
virtual bool solveStep(Real dt, Real target_time, bool auto_advance=true) override
std::vector< std::shared_ptr< PODResidualTransfer > > getActiveResidualTransfers(Transfer::DIRECTION direction)
Returning pointers to the solution transfers. Used in batch mode.
Transfer solutions from sub-applications to a container in a Trainer.
std::vector< std::shared_ptr< MooseApp > > _apps
std::vector< std::shared_ptr< PODSamplerSolutionTransfer > > getActiveSolutionTransfers(Transfer::DIRECTION direction)
Returning pointers to the solution transfers. Used in batch mode.
dof_id_type _local_batch_app_index
Counter for extracting command line arguments in batch mode.
virtual void preTransfer(Real dt, Real target_time) override
Overriding preTransfer to reinit the subappliations if the object needs to be executed twice...
const Parallel::Communicator & _communicator
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)
FEProblemBase & _fe_problem
void addRequiredParam(const std::string &name, const std::string &doc_string)
virtual void computeResidualTags(const std::set< TagID > &tags)
static InputParameters validParams()
processor_id_type n_processors() const
const std::vector< std::shared_ptr< Transfer > > & getActiveObjects(THREAD_ID tid=0) const
void setCurrentNonlinearSystem(const unsigned int nl_sys_num)
Transfers residuals for given variables and vector tags from a sub-subapplication to a PODReducedBasi...
Sampler & _sampler
Sampler to utilize for creating MultiApps.
const std::vector< std::string > & getTagNames() const
bool _snapshot_generation
Switch used to differentiate between snapshot generation and residual computation.
const std::string & type() const
const LocalRankConfig & getRankConfig(bool batch_mode) const
PODFullSolveMultiApp(const InputParameters &parameters)
virtual void resetApp(unsigned int global_app, Real time=0.0)
static InputParameters validParams()
dof_id_type getLocalRowEnd() const
unsigned int _my_num_apps
virtual bool solveStep(Real dt, Real target_time, bool auto_advance=true) override
dof_id_type getNumberOfRows() const
const ExecuteMooseObjectWarehouse< Transfer > & getMultiAppTransferWarehouse(Transfer::DIRECTION direction) const
virtual void preTransfer(Real dt, Real target_time) override
Interface for objects that need to use samplers.
virtual void restore(bool force=true) override
PODReducedBasisTrainer & _trainer
Pointer to the trainer object itself.
void mooseError(Args &&... args) const
registerMooseObject("StochasticToolsApp", PODFullSolveMultiApp)
void addClassDescription(const std::string &doc_string)
void init(unsigned int num_apps, bool batch_mode=false)
void computeResidualBatch(Real target_time)
Evaluating the residuals for every tag in the trainer in batch mode.
processor_id_type processor_id() const
MPI_Comm & _my_comm
unsigned int getSumBaseSize() const
Getting the overall base size, which is the sum of the individual bases.
uint8_t dof_id_type
void computeResidual()
Evaluating the residuals for every tag in the trainer.