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
virtual void backup()
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
void paramError(const std::string &param, Args... args) 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.
registerMooseObject("StochasticToolsApp", PODFullSolveMultiApp)
void mooseError(Args &&... args) const
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.