35#include "libmesh/mesh_tools.h"
36#include "libmesh/numeric_vector.h"
46#ifdef LIBMESH_HAVE_SYS_UTSNAME_H
47#include <sys/utsname.h>
56 params.
addParam<
bool>(
"use_displaced_mesh",
58 "Whether or not this object should use the "
59 "displaced mesh for computation. Note that "
60 "in the case this is true but no "
61 "displacements are provided in the Mesh block "
62 "the undisplaced mesh will still be used.");
64 std::ostringstream app_types_strings;
66 app_types_strings << name_bi_pair.first <<
" ";
67 MooseEnum app_types_options(app_types_strings.str(),
"",
true);
72 "The type of application to build (applications not "
73 "registered can be loaded with dynamic libraries. Parent "
74 "application type will be used if not provided.");
75 params.
addParam<std::string>(
"library_path",
77 "Path to search for dynamic libraries (please "
78 "avoid committing absolute paths in addition to "
79 "MOOSE_LIBRARY_PATH)");
83 "The file name of the library (*.la file) that will be dynamically loaded.");
84 params.
addParam<
bool>(
"library_load_dependencies",
86 "Tells MOOSE to manually load library dependencies. This should not be "
87 "necessary and is here for debugging/troubleshooting.");
92 "The positions of the App locations. Each set of 3 values will represent a "
93 "Point. This and 'positions_file' cannot be both supplied. If this and "
94 "'positions_file'/'_objects' are not supplied, a single position (0,0,0) will be used");
95 params.
addParam<std::vector<FileName>>(
"positions_file",
96 "Filename(s) that should be looked in for positions. Each"
97 " set of 3 values in that file will represent a Point. "
98 "This and 'positions(_objects)' cannot be both supplied");
99 params.
addParam<std::vector<PositionsName>>(
"positions_objects",
100 "The name of a Positions object that will contain "
101 "the locations of the sub-apps created. This and "
102 "'positions(_file)' cannot be both supplied");
104 "output_in_position",
106 "If true this will cause the output from the MultiApp to be 'moved' by its position vector");
110 "If true this will cause the mesh from the MultiApp to be 'moved' by its position vector");
114 "The input file for each App. If this parameter only contains one input file "
115 "it will be used for all of the Apps. When using 'positions_from_file' it is "
116 "also admissable to provide one input_file per file.");
117 params.
addParam<Real>(
"bounding_box_inflation",
119 "Relative amount to 'inflate' the bounding box of this MultiApp.");
120 params.
addParam<Point>(
"bounding_box_padding",
122 "Additional padding added to the dimensions of the bounding box. The "
123 "values are added to the x, y and z dimension respectively.");
130#ifdef LIBMESH_ENABLE_AMR
133 params.
setDocString(
"execute_on", exec_enum.getDocString());
136 params.
addParam<processor_id_type>(
"max_procs_per_app",
137 std::numeric_limits<processor_id_type>::max(),
138 "Maximum number of processors to give to each App in this "
139 "MultiApp. Useful for restricting small solves to just a few "
140 "procs so they don't get spread out");
141 params.
addParam<processor_id_type>(
"min_procs_per_app",
143 "Minimum number of processors to give to each App in this "
144 "MultiApp. Useful for larger, distributed mesh solves.");
146 "wait_for_first_app_init",
148 "Create the first sub-application on rank 0, then MPI_Barrier before "
149 "creating the next N-1 apps (on all ranks). "
150 "This is only needed if your sub-application needs to perform some setup "
151 "actions in quiet, without other sub-applications working at the same time.");
153 params.
addParam<Real>(
"global_time_offset",
155 "The time offset relative to the parent application for the purpose of "
156 "starting a subapp at a different time from the parent application. The "
157 "global time will be ahead by the offset specified here.");
163 "The time(s) at which to reset Apps given by the 'reset_apps' parameter. "
164 "Resetting an App means that it is destroyed and recreated, possibly "
165 "modeling the insertion of 'new' material for that app.");
166 params.
addParam<std::vector<unsigned int>>(
169 "The Apps that will be reset when 'reset_time' is hit. These are the App "
170 "'numbers' starting with 0 corresponding to the order of the App positions. "
171 "Resetting an App means that it is destroyed and recreated, possibly modeling "
172 "the insertion of 'new' material for that app.");
177 std::numeric_limits<Real>::max(),
178 "The time at which Apps designated by move_apps are moved to move_positions.");
180 params.
addParam<std::vector<unsigned int>>(
183 "Apps, designated by their 'numbers' starting with 0 corresponding to the order "
184 "of the App positions, to be moved at move_time to move_positions");
185 params.
addParam<std::vector<Point>>(
186 "move_positions", {},
"The positions corresponding to each move_app.");
188 params.
addParam<std::vector<CLIArgString>>(
191 "Additional command line arguments to pass to the sub apps. If one set is provided the "
192 "arguments are applied to all, otherwise there must be a set for each sub app.");
194 params.
addParam<std::vector<FileName>>(
196 "File names that should be looked in for additional command line arguments "
197 "to pass to the sub apps. Each line of a file is set to each sub app. If only "
198 "one line is provided, it will be applied to all sub apps.");
203 "relaxation_factor>0 & relaxation_factor<2",
204 "Fraction of newly computed value to keep."
205 "Set between 0 and 2.");
209 "Use transformed_variables.",
210 "List of subapp variables to relax during Multiapp coupling iterations");
211 params.
addParam<std::vector<std::string>>(
212 "transformed_variables",
214 "List of subapp variables to use coupling algorithm on during Multiapp coupling iterations");
215 params.
addParam<std::vector<PostprocessorName>>(
216 "transformed_postprocessors",
218 "List of subapp postprocessors to use coupling "
219 "algorithm on during Multiapp coupling iterations");
220 params.
addParam<
bool>(
"keep_solution_during_restore",
222 "This is useful when doing MultiApp coupling iterations. It takes the "
223 "final solution from the previous coupling iteration"
224 "and re-uses it as the initial guess for the next coupling iteration");
225 params.
addParam<
bool>(
"keep_aux_solution_during_restore",
227 "This is useful when doing MultiApp coupling iterations. It takes the "
228 "final auxiliary solution from the previous coupling iteration"
229 "and re-uses it as the initial guess for the next coupling iteration");
233 "True to turn off restore for this multiapp. This is useful when doing steady-state "
234 "Picard iterations where we want to use the solution of previous Picard iteration as the "
235 "initial guess of the current Picard iteration.");
237 "max_multiapp_level",
239 "Integer set by user that will stop the simulation if the multiapp level "
240 "exceeds it. Useful for preventing infinite loops with multiapp simulations");
244 "True to clone parent app mesh and use it for this MultiApp.",
245 "clone_master_mesh is deprecated, use clone_parent_mesh instead");
247 "clone_parent_mesh",
false,
"True to clone parent app mesh and use it for this MultiApp.");
249 params.
addParam<
unsigned int>(
"execution_order_group",
251 "Execution order group. If Problem/num_concurrent_multiapps>1, "
252 "multiple multiapps may be executed synchronously.");
262 "output_in_position",
263 "Positions / transformations of the MultiApp frame of reference");
267 params.
addParamNamesToGroup(
"relaxation_factor transformed_variables transformed_postprocessors "
268 "keep_solution_during_restore keep_aux_solution_during_restore "
270 "Fixed point iteration");
282 _fe_problem(*getCheckedPointerParam<
FEProblemBase *>(
"_fe_problem_base")),
283 _app_type(isParamValid(
"app_type") ?
std::string(getParam<
MooseEnum>(
"app_type"))
284 : _fe_problem.getMooseApp().type()),
285 _use_positions(getParam<bool>(
"use_positions")),
286 _input_files(getParam<
std::vector<FileName>>(
"input_files")),
287 _wait_for_first_app_init(getParam<bool>(
"wait_for_first_app_init")),
291 _orig_comm(_communicator.get()),
293 _my_comm(_my_communicator.get()),
295 _inflation(getParam<Real>(
"bounding_box_inflation")),
296 _bounding_box_padding(getParam<Point>(
"bounding_box_padding")),
297 _max_procs_per_app(getParam<processor_id_type>(
"max_procs_per_app")),
298 _min_procs_per_app(getParam<processor_id_type>(
"min_procs_per_app")),
299 _output_in_position(getParam<bool>(
"output_in_position")),
300 _global_time_offset(getParam<Real>(
"global_time_offset")),
301 _reset_times(getParam<
std::vector<Real>>(
"reset_time")),
302 _reset_apps(getParam<
std::vector<unsigned
int>>(
"reset_apps")),
303 _reset_happened(false),
304 _move_time(getParam<Real>(
"move_time")),
305 _move_apps(getParam<
std::vector<unsigned
int>>(
"move_apps")),
306 _move_positions(getParam<
std::vector<Point>>(
"move_positions")),
307 _move_happened(false),
309 _cli_args(getParam<
std::vector<CLIArgString>>(
"cli_args")),
310 _keep_solution_during_restore(getParam<bool>(
"keep_solution_during_restore")),
311 _keep_aux_solution_during_restore(getParam<bool>(
"keep_aux_solution_during_restore")),
312 _no_restore(getParam<bool>(
"no_restore")),
313 _run_in_position(getParam<bool>(
"run_in_position")),
314 _sub_app_backups(declareRestartableDataWithContext<
SubAppBackups>(
"sub_app_backups", this)),
315 _solve_step_timer(registerTimedSection(
"solveStep", 3,
"Executing MultiApps", false)),
316 _init_timer(registerTimedSection(
"init", 3,
"Initializing MultiApp")),
317 _backup_timer(registerTimedSection(
"backup", 3,
"Backing Up MultiApp")),
318 _restore_timer(registerTimedSection(
"restore", 3,
"Restoring MultiApp")),
319 _reset_timer(registerTimedSection(
"resetApp", 3,
"Resetting MultiApp"))
324 "'cli_args' and 'cli_args_files' cannot be specified simultaneously in MultiApp ");
329 "This MultiApps has been set to not use positions, "
330 "but a 'positions' parameter has been set.");
334 mooseError(
"reset_time and reset_apps may only be specified together");
338 std::sort(sorted_times.begin(), sorted_times.end());
340 paramError(
"reset_time",
"List of reset times must be sorted in increasing order");
348 init(num_apps, config);
367 "The number of items supplied must be 1 or equal to the number of sub apps.");
374 mooseError(
"The number of items supplied as command line argument to subapps must be 1 or "
375 "equal to the number of sub apps. Note: you use a multiapp that provides its own "
376 "command line parameters so the error is not in cli_args");
397 TIME_SECTION(
"createApps", 2,
"Instantiating Sub-Apps",
false);
409 getParam<std::string>(
"library_path"),
410 getParam<std::string>(
"library_name"),
411 getParam<bool>(
"library_load_dependencies"));
413 bool rank_did_quiet_init =
false;
419 rank_did_quiet_init =
true;
429 if (rank_did_quiet_init && i == local_app)
457 std::vector<FileName> cli_args_files = getParam<std::vector<FileName>>(
"cli_args_files");
458 std::vector<FileName> input_files = getParam<std::vector<FileName>>(
"input_files");
461 if (!cli_args_files.size())
462 paramError(
"cli_args_files",
"You need to provide at least one commandLine argument file ");
466 if (cli_args_files.size() != 1 && cli_args_files.size() != input_files.size())
468 "The number of commandLine argument files ",
469 cli_args_files.size(),
472 " must either be only one or match the number of input files ",
476 std::vector<std::string> cli_args;
477 for (
unsigned int p_file_it = 0; p_file_it < cli_args_files.size(); p_file_it++)
479 std::string cli_args_file = cli_args_files[p_file_it];
487 std::ifstream is(cli_args_file.c_str());
490 while (std::getline(is, line))
491 cli_args.push_back(line);
494 if (!cli_args.size())
496 "There is no commandLine argument in the commandLine argument file ",
507 if (cli_args.size() == 1)
508 for (MooseIndex(num_positions) num = 0; num < num_positions; num++)
510 else if (cli_args.size() == num_positions)
511 for (
auto && cli_arg : cli_args)
513 else if (cli_args.size() != num_positions)
515 "The number of commandLine argument strings ",
519 " must either be only one or match the number of positions ",
526 for (
auto && cli_arg : cli_args)
538 mooseError(
" The number of commandLine argument strings ",
540 " must either be only one or match the total "
541 "number of sub apps ",
545 mooseError(
"Cannot set commandLine arguments from both input_file and external files");
552 mooseError(
"The number of apps to move and the positions to move them to must be the same for "
559 mooseError(
"Only one 'positions' parameter may be specified");
563 _positions = getParam<std::vector<Point>>(
"positions");
566 mooseError(
"Not enough positions for the number of input files provided in MultiApp ",
571 std::vector<FileName> positions_files = getParam<std::vector<FileName>>(
"positions_file");
572 std::vector<FileName> input_files = getParam<std::vector<FileName>>(
"input_files");
574 if (input_files.size() != 1 && positions_files.size() != input_files.size())
575 mooseError(
"Number of input_files for MultiApp ",
577 " must either be only one or match the number of positions_file files");
580 if (input_files.size() != 1)
583 for (
unsigned int p_file_it = 0; p_file_it < positions_files.size(); p_file_it++)
585 std::string positions_file = positions_files[p_file_it];
591 for (
const auto & d : data)
597 for (
unsigned int i = 0; i < data.size(); ++i)
598 if (input_files.size() != 1)
604 const auto & positions_param_objs = getParam<std::vector<PositionsName>>(
"positions_objects");
605 const auto & input_files = getParam<std::vector<FileName>>(
"input_files");
607 if (input_files.size() != 1 && positions_param_objs.size() != input_files.size())
608 mooseError(
"Number of input_files for MultiApp ",
610 " must either be only one or match the number of positions_objects specified");
613 if (input_files.size() != 1)
617 unsigned int offset = 0;
619 for (
const auto p_obj_it : index_range(positions_param_objs))
621 const std::string & positions_name = positions_param_objs[p_obj_it];
627 for (
const auto & d : data)
635 "'" + positions_name +
"' is not of the expected type. Should be a Positions");
638 for (
unsigned int i = 0; i < data.size(); ++i)
640 if (input_files.size() != 1)
645 offset += data.size();
653 mooseError(
"Not enough positions for the number of input files provided in MultiApp ",
658 "Number of positions and input files are not the same!");
665 Real timestep_tol = 1e-13;
671 bool backup_apps =
false;
687 transfer->getAppInfo();
693 auto app_ptr =
_apps[i];
694 auto &
mesh = app_ptr->getExecutioner()->feProblem().mesh();
696 app_ptr->getExecutioner()->feProblem().coordTransform().transformMesh(
699 app_ptr->getExecutioner()->feProblem().coordTransform().transformMesh(
mesh,
704 mesh.getMesh().complete_preparation();
723 for (
unsigned int i = 0; i <
_move_apps.size(); i++)
746 for (
const auto & app_ptr :
_apps)
748 auto * executioner = app_ptr->getExecutioner();
749 mooseAssert(executioner,
"Executioner is nullptr");
752 executioner->feProblem().outputStep(
EXEC_FINAL);
759 for (
const auto & app_ptr :
_apps)
761 auto * executioner = app_ptr->getExecutioner();
762 mooseAssert(executioner,
"Executioner is nullptr");
764 executioner->postExecute();
774 _console <<
"Backed up MultiApp ... ";
804 for (
unsigned int j = 0; j <
_apps[i]->getExecutioner()->feProblem().numSolverSystems();
814 auto & sub_multiapps =
815 _apps[i]->getExecutioner()->feProblem().getMultiAppWarehouse().getObjects();
819 for (
auto & multi_app : sub_multiapps)
835 _console <<
"Restoring MultiApp ... ";
852 for (
unsigned int j = 0; j <
_apps[i]->getExecutioner()->feProblem().numSolverSystems();
855 _apps[i]->getExecutioner()->feProblem().getSolverSystem(j).solution() =
859 _apps[i]->getExecutioner()->feProblem().getSolverSystem(j).update();
870 _apps[i]->getExecutioner()->feProblem().getAuxiliarySystem().solution() =
874 _apps[i]->getExecutioner()->feProblem().getAuxiliarySystem().update();
881 for (
const auto & app_ptr :
_apps)
882 if (app_ptr->feProblem().getDisplacedProblem())
883 app_ptr->feProblem().getDisplacedProblem()->updateMesh();
887 for (
auto & app_ptr :
_apps)
888 app_ptr->getExecutioner()->fixedPointSolve().clearFixedPointStatus();
894 for (
auto & sub_app :
895 _apps[i]->getExecutioner()->feProblem().getMultiAppWarehouse().getObjects())
896 sub_app->restore(
false);
906 "This parameter should only be provided in parent app");
914 const Real min_x = box.first(0);
915 const Real max_x = box.second(0);
916 const Real min_y = box.first(1);
917 const Real max_y = box.second(1);
918 const Real min_z = box.first(2);
919 const Real max_z = box.second(2);
921 std::array<Point, 8> box_corners = {{Point(min_x, min_y, min_z),
922 Point(max_x, min_y, min_z),
923 Point(min_x, max_y, min_z),
924 Point(max_x, max_y, min_z),
925 Point(min_x, min_y, max_z),
926 Point(max_x, min_y, max_z),
927 Point(min_x, max_y, max_z),
928 Point(max_x, max_y, max_z)}};
931 for (
auto & corner : box_corners)
932 corner = transform(corner);
935 Point new_box_min = box_corners[0];
936 Point new_box_max = new_box_min;
937 for (
const auto p : make_range(1, 8))
940 const Point & pt = box_corners[p];
941 if (new_box_min(d) > pt(d))
942 new_box_min(d) = pt(d);
944 if (new_box_max(d) < pt(d))
945 new_box_max(d) = pt(d);
947 box.first = new_box_min;
948 box.second = new_box_max;
963 : fe_problem_base.
mesh();
980 Point min = bbox.min();
982 Point max = bbox.max();
985 Point inflation_amount = (max - min) *
_inflation;
987 Point inflated_min = min - inflation_amount;
988 Point inflated_max = max + inflation_amount;
990 Point shifted_min = inflated_min;
991 Point shifted_max = inflated_max;
998 shifted_min(0) = -inflated_max(0);
999 shifted_min(1) = inflated_min(1);
1000 shifted_min(2) = -inflated_max(0);
1002 shifted_max(0) = inflated_max(0);
1003 shifted_max(1) = inflated_max(1);
1004 shifted_max(2) = inflated_max(0);
1007 if (coord_transform)
1009 BoundingBox transformed_bbox(shifted_min, shifted_max);
1011 return transformed_bbox;
1021 return BoundingBox(shifted_min, shifted_max);
1033 return _apps[local_app]->getExecutioner()->feProblem();
1040 "MultiApp::appProblem() is deprecated, call MultiApp::appProblemBase() instead.\n");
1046 return dynamic_cast<FEProblem &
>(
_apps[local_app]->getExecutioner()->feProblem());
1067NumericVector<Number> &
1093 return _apps[local_app].get();
1108 std::map<std::string, unsigned int> m =
_apps[local_app]->getOutputWarehouse().getFileNumbers();
1113 _apps[local_app]->getOutputWarehouse().setFileNumbers(m);
1129 _apps[local_app]->setOutputPosition(p);
1131 paramError(
"run_in_position",
"Moving apps and running apps in position is not supported");
1140 for (
unsigned int i = 0; i <
_apps.size(); i++)
1153 std::string full_name;
1157 full_name =
_app.
name() +
"_" + multiapp_name;
1159 full_name = multiapp_name;
1167 std::vector<std::string> input_cli_args;
1173 const std::set<std::string> recover_exclude =
1175 ? std::set<std::string>{}
1176 : std::set<std::string>{
"recover",
"test_checkpoint_half_transient"};
1180 name(), multiapp_name, input_cli_args, recover_exclude);
1186 <<
" on processor " <<
processor_id() <<
" with full name " << full_name
1187 << COLOR_DEFAULT << std::endl;
1191#ifdef MOOSE_MFEM_ENABLED
1197 app_params.
set<std::shared_ptr<mfem::Device>>(
"_mfem_device") =
1200 app_params.
set<std::set<std::string>>(
"_mfem_devices") = mfem_device_set;
1204 app_params.
set<std::shared_ptr<mfem::Device>>(
"_mfem_device") =
1207 app_params.
set<std::set<std::string>>(
"_mfem_devices") = mfem_device_set;
1210 if (getParam<bool>(
"clone_master_mesh") || getParam<bool>(
"clone_parent_mesh"))
1213 _console << COLOR_CYAN <<
"Cloned parent app mesh will be used for MultiApp " <<
name()
1214 << COLOR_DEFAULT << std::endl;
1215 app_params.
set<
bool>(
"_use_master_mesh") =
true;
1226 auto parser = std::make_unique<Parser>(input_file);
1227 parser->setCommandLineParams(app_cli->buildHitParams());
1231 const auto & app_type = parser->getAppType();
1232 if (app_type.empty() &&
_app_type.empty())
1233 mooseWarning(
"The application type is not specified for ",
1235 ". Please use [Application] block to specify the application type.");
1241 "' is not a registered application. The registered application is named: '",
1243 "'. Please double check the [Application] block to make sure the correct "
1244 "application is provided. \n");
1246 if (parser->getAppType().empty())
1249 app_params.
set<std::shared_ptr<Parser>>(
"_parser") = std::move(parser);
1250 app_params.
set<std::shared_ptr<CommandLine>>(
"_command_line") = std::move(app_cli);
1252 auto & app =
_apps[i];
1254 app->setGlobalTimeOffset(start_time);
1263 "Sub-apps are already displaced, so they are already output in position");
1266 app->setupOptions();
1272 if (app->getOutputFileBase().empty())
1276 mooseError(
"Maximum multiapp level has been reached. This is likely caused by an infinite loop "
1277 "in your multiapp system. If additional multiapp levels are needed, "
1278 "max_multiapp_level can be specified in the MuliApps block.");
1281 _apps[i]->fixedPointConfig().sub_relaxation_factor = getParam<Real>(
"relaxation_factor");
1282 _apps[i]->fixedPointConfig().sub_transformed_vars =
1283 getParam<std::vector<std::string>>(
"transformed_variables");
1286 _apps[i]->fixedPointConfig().sub_transformed_vars =
1287 getParam<std::vector<std::string>>(
"relaxed_variables");
1288 _apps[i]->fixedPointConfig().sub_transformed_pps =
1289 getParam<std::vector<PostprocessorName>>(
"transformed_postprocessors");
1291 app->runInputFile();
1292 auto fixed_point_solve = &(
_apps[i]->getExecutioner()->fixedPointSolve());
1293 if (fixed_point_solve)
1294 fixed_point_solve->allocateStorage(
false);
1299 auto &
mesh = app->getExecutioner()->feProblem().mesh();
1301 app->getExecutioner()->feProblem().coordTransform().transformMesh(
1304 app->getExecutioner()->feProblem().coordTransform().transformMesh(
mesh, Point(0, 0, 0));
1308 mesh.getMesh().complete_preparation();
1312std::vector<std::string>
1317 std::string combined_args;
1320 if (cla.size() == 1)
1321 combined_args = cla[0];
1325 cli_args_param =
"cli_args_files";
1329 else if (cla.size())
1334 cli_args_param =
"cli_args_files";
1343 if (combined_args.empty())
1349 for (
const auto & arg : args)
1353 const auto error =
"An empty MultiApp command line argument was provided. Your "
1354 "combined command line string has a ';' with no argument after it.";
1367 processor_id_type nprocs,
1369 processor_id_type min_app_procs,
1370 processor_id_type max_app_procs,
1373 if (min_app_procs > nprocs)
1374 mooseError(
"minimum number of procs per app is higher than the available number of procs");
1375 else if (min_app_procs > max_app_procs)
1376 mooseError(
"minimum number of procs per app must be lower than the max procs per app");
1378 mooseAssert(rank < nprocs,
"rank must be smaller than the number of procs");
1383 const processor_id_type slot_size =
1384 std::max(std::min(cast_int<processor_id_type>(nprocs / napps), max_app_procs), min_app_procs);
1385 const processor_id_type nslots = std::min(
1387 cast_int<processor_id_type>(std::min(
1388 static_cast<dof_id_type
>(std::numeric_limits<processor_id_type>::max()), napps)));
1389 mooseAssert(nprocs >= (nslots * slot_size),
1390 "Ensure that leftover procs is represented by an unsigned type");
1391 const processor_id_type leftover_procs = nprocs - nslots * slot_size;
1392 const dof_id_type apps_per_slot = napps / nslots;
1393 const dof_id_type leftover_apps = napps % nslots;
1395 std::vector<int> slot_for_rank(nprocs);
1396 processor_id_type slot = 0;
1397 processor_id_type procs_in_slot = 0;
1398 for (processor_id_type rankiter = 0; rankiter <= rank; rankiter++)
1401 slot_for_rank[rankiter] = cast_int<int>(slot);
1403 slot_for_rank[rankiter] = -1;
1408 if (procs_in_slot == slot_size + 1 * (slot < leftover_procs && slot_size < max_app_procs))
1415 if (slot_for_rank[rank] < 0)
1417 return {0, 0, 0, 0,
false, 0};
1418 const processor_id_type slot_num = cast_int<processor_id_type>(slot_for_rank[rank]);
1420 const bool is_first_local_rank = rank == 0 || (slot_for_rank[rank - 1] != slot_for_rank[rank]);
1421 const dof_id_type n_local_apps = apps_per_slot + 1 * (slot_num < leftover_apps);
1423 processor_id_type my_first_rank = 0;
1424 for (processor_id_type rankiter = rank; rankiter > 0; rankiter--)
1425 if (slot_for_rank[rank] != slot_for_rank[rankiter])
1427 my_first_rank = cast_int<processor_id_type>(slot_for_rank[rankiter + 1]);
1431 dof_id_type app_index = 0;
1432 for (processor_id_type slot = 0; slot < slot_num; slot++)
1434 const dof_id_type num_slot_apps = apps_per_slot + 1 * (slot < leftover_apps);
1435 app_index += num_slot_apps;
1439 return {n_local_apps, app_index, 1, slot_num, is_first_local_rank, my_first_rank};
1440 return {n_local_apps, app_index, n_local_apps, app_index, is_first_local_rank, my_first_rank};
1449 mooseCheckMPIErr(ierr);
1451 mooseCheckMPIErr(ierr);
1453#ifdef LIBMESH_HAVE_SYS_UTSNAME_H
1454 struct utsname sysInfo;
1463 mooseCheckMPIErr(ierr);
1470 mooseError(
"Internal error, a processor has an undefined app.");
1476 mooseCheckMPIErr(ierr);
1491 std::stringstream ss;
1492 ss <<
"Requesting app " << global_app <<
", but processor " <<
processor_id() <<
" ";
1494 ss <<
"does not own any apps";
1500 mooseError(
"Invalid global_app!\n", ss.str());
1522std::vector<std::string>
1533 const std::string multiapp_name =
1541 std::ostringstream multiapp_name;
1542 multiapp_name << base_name << std::setw(std::ceil(std::log10(total))) << std::setprecision(0)
1543 << std::setfill(
'0') << std::right << index;
1544 return multiapp_name.str();
1562 mooseAssert(multi_app,
"Not set");
1566 dataStore(stream, cast_ref<std::vector<std::unique_ptr<Backup>> &>(backups),
nullptr);
1573 mooseAssert(multi_app,
"Not set");
1575 dataLoad(stream, cast_ref<std::vector<std::unique_ptr<Backup>> &>(backups),
nullptr);
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
const ExecFlagType EXEC_PRE_MULTIAPP_SETUP
const ExecFlagType EXEC_TIMESTEP_BEGIN
const ExecFlagType EXEC_POST_ADAPTIVITY
const ExecFlagType EXEC_INITIAL
const ExecFlagType EXEC_FINAL
LocalRankConfig rankConfig(processor_id_type rank, processor_id_type nprocs, dof_id_type napps, processor_id_type min_app_procs, processor_id_type max_app_procs, bool batch_mode)
Returns app partitioning information relevant to the given rank for a multiapp scenario with the give...
void dataStore(std::ostream &stream, SubAppBackups &backups, void *context)
void dataLoad(std::istream &stream, SubAppBackups &backups, void *context)
LocalRankConfig rankConfig(processor_id_type rank, processor_id_type nprocs, dof_id_type napps, processor_id_type min_app_procs, processor_id_type max_app_procs, bool batch_mode=false)
Returns app partitioning information relevant to the given rank for a multiapp scenario with the give...
std::shared_ptr< DisplacedProblem > displaced_problem
void ErrorVector unsigned int
bool isRegistered(const std::string &app_name) const
Returns a Boolean indicating whether an application type has been registered.
InputParameters getValidParams(const std::string &name)
Get valid parameters for the object.
const auto & registeredObjects() const
Returns a reference to the map from names to AppFactoryBuildInfo pointers.
static std::unique_ptr< MooseApp > create(const std::string &app_type, const std::vector< std::string > &cli_args={})
Create an app with no input and command line arguments.
static AppFactory & instance()
Get the instance of the AppFactory.
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
A MultiMooseEnum object to hold "execute_on" flags.
void addAvailableFlags(const ExecFlagType &flag, Args... flags)
Add additional execute_on flags to the list of possible flags.
Executioners are objects that do the actual work of solving your problem.
virtual bool lastSolveConverged() const =0
Whether or not the last solve converged.
FEProblemBase & feProblem()
Return a reference to this Executioner's FEProblemBase instance.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
bool verboseMultiApps() const
Whether or not to use verbose printing for MultiApps.
AuxiliarySystem & getAuxiliarySystem()
const PostprocessorValue & getPostprocessorValueByName(const PostprocessorName &name, std::size_t t_index=0) const
Get a read-only reference to the value associated with a Postprocessor that exists.
virtual std::shared_ptr< const DisplacedProblem > getDisplacedProblem() const
const Positions & getPositionsObject(const std::string &name) const
Get the Positions object by its name.
const ExecFlagType & getCurrentExecuteOnFlag() const
Return/set the current execution flag.
virtual MooseMesh & mesh() override
const UserObject & getUserObjectBase(const std::string &name, const THREAD_ID tid=0) const
Get the user object by its name.
virtual libMesh::System & getSystem(const std::string &var_name) override
Returns the equation system containing the variable provided.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
Base class for MOOSE-based applications.
Point getOutputPosition() const
Get the output position.
std::string getOutputFileBase(bool for_non_moose_build_output=false) const
Get the output file base name.
OutputWarehouse & getOutputWarehouse()
Get the OutputWarehouse objects.
bool isRestarting() const
Whether or not this is a "restart" calculation.
unsigned int multiAppLevel() const
The MultiApp Level.
Executioner * getExecutioner() const
Retrieve the Executioner for this App.
const std::set< std::string > & getMFEMDevices(Moose::PassKey< MultiApp >) const
Get the configured MFEM devices.
std::shared_ptr< mfem::Device > getMFEMDevice(Moose::PassKey< MultiApp >)
Get the MFEM device object.
void dynamicAppRegistration(const std::string &app_name, std::string library_path, const std::string &library_name, bool lib_load_deps)
std::shared_ptr< CommandLine > commandLine() const
Get the command line.
bool isRecovering() const
Whether or not this is a "recover" calculation.
const InputParameters & parameters() const
Get the parameters of the object.
const std::string & name() const
Get the name of the class.
void paramError(const std::string ¶m, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
const InputParameters & _pars
The object's parameters.
const std::string & _name
The name of this class.
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
MooseApp & getMooseApp() const
Get the MooseApp this class is associated with.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Every object that can be built by the factory should be derived from this class.
static InputParameters validParams()
MooseApp & _app
The MOOSE application this is associated with.
Utility class for reading delimited data (e.g., CSV data).
const std::vector< Point > getDataAsPoints() const
Get the data in Point format.
void setFormatFlag(FormatFlag value)
void read()
Perform the actual data reading.
Base class for all MultiAppTransfer objects.
A MultiApp represents one or more MOOSE applications that are running simultaneously.
std::vector< Real > _reset_times
The times at which to reset apps.
virtual void postExecute()
Method called at the end of the simulation (after finalize).
libMesh::Parallel::Communicator _my_communicator
The communicator object that holds the MPI_Comm that we're going to use.
virtual void finalize()
Method called towards the end of the simulation to execute on final.
virtual void preTransfer(Real dt, Real target_time)
Gets called just before transfers are done to the MultiApp (Which is just before the MultiApp is solv...
std::vector< std::string > _cli_args_from_file
CommandLine arguments from files.
const bool & _wait_for_first_app_init
Whether to create the first app on rank 0 while all other MPI ranks are idle.
bool usingPositions() const
Whether or not this MultiApp is using positions or its own way for constructing sub-apps.
virtual std::vector< std::string > cliArgs() const
function that provides cli_args to subapps
void buildComm()
Create an MPI communicator suitable for each app.
Real _inflation
Relative bounding box inflation.
std::vector< unsigned int > _positions_index_offsets
The offsets, in case multiple Positions objects are specified.
void keepSolutionDuringRestore(bool keep_solution_during_restore)
Preserve the solution from the previous simulation, and it is used as an initial guess for the next r...
bool _output_in_position
Whether or not to move the output of the MultiApp into position.
std::vector< bool > _has_bounding_box
Flag if this multi-app computed its bounding box (valid only for non-displaced meshes)
processor_id_type _min_procs_per_app
Minimum number of processors to give to each app.
virtual void resetApp(unsigned int global_app, Real time=0.0)
"Reset" the App corresponding to the global App number passed in.
FEProblemBase & appProblemBase(unsigned int app)
Get the FEProblemBase for the global app desired.
bool isFirstLocalRank() const
std::string _app_type
The type of application to build.
int _my_rank
The mpi "rank" of this processor in the sub communicator.
virtual void restore(bool force=true)
Restore the state of every Sub App.
virtual void moveApp(unsigned int global_app, Point p)
Move the global_app to Point p.
const Real _global_time_offset
The offset time so the MultiApp local time relative to the global time.
Real _move_time
The time at which to move apps.
bool needsRestoration()
Whether or not this MultiApp should be restored at the beginning of each Picard iteration.
const PerfID _backup_timer
void createApp(unsigned int i, Real start_time)
Helper function for creating an App instance.
MultiApp(const InputParameters ¶meters)
static std::string getMultiAppName(const std::string &base_name, dof_id_type index, dof_id_type total)
Helper for constructing the name of the multiapp.
int _orig_num_procs
The number of processors in the original comm.
std::vector< libMesh::BoundingBox > _bounding_box
This multi-app's bounding box.
std::vector< unsigned int > _npositions_inputfile
Number of positions for each input file.
std::optional< std::string > _cli_args_param
The parameter that was used to set the command line args, if any.
void setupPositions()
Called just after construction to allow derived classes to set _positions and create sub-apps accordi...
virtual void initialSetup() override
Method to be called in main-app initial setup for create sub-apps if using positions is false.
std::vector< MultiAppTransfer * > _associated_transfers
Transfers associated with this multiapp.
MPI_Comm & _my_comm
The MPI communicator this object is going to use.
bool hasLocalApp(unsigned int global_app) const
Whether or not the given global app number is on this processor.
virtual void preRunInputFile()
call back executed right before app->runInputFile()
const PerfID _restore_timer
unsigned int _first_local_app
The number of the first app on this processor.
Point _bounding_box_padding
Additional padding added to the bounding box, useful for 1D meshes.
std::vector< const Positions * > _positions_objs
The positions of all of the apps, using the Positions system.
const Point & position(unsigned int app) const
The physical position of a global App number.
bool _has_an_app
Whether or not this processor as an App at all
processor_id_type _max_procs_per_app
Maximum number of processors to give to each app.
bool _move_happened
Whether or not the move has happened.
void createApps()
Create the provided number of apps.
bool _keep_aux_solution_during_restore
Flag indicates if or not restart the auxiliary system from the latest auxiliary solution.
std::vector< std::vector< std::unique_ptr< libMesh::NumericVector< Real > > > > _end_solutions
The solution from the end of the previous solve, this is cloned from the Nonlinear solution during re...
std::vector< unsigned int > _move_apps
The apps to be moved.
int _orig_rank
The mpi "rank" of this processor in the original communicator.
FEProblem & appProblem(unsigned int app)
Get the FEProblem for the global app is part of.
virtual void backup()
Save off the state of every Sub App.
const bool _use_positions
Toggle use of "positions".
void readCommandLineArguments()
Fill command line arguments for sub apps.
void init(unsigned int num_apps, bool batch_mode=false)
Build communicators and reserve backups.
bool _keep_solution_during_restore
Flag indicates if or not restart from the latest solution.
static InputParameters validParams()
Real appPostprocessorValue(unsigned int app, const std::string &name)
Get a Postprocessor value for a specified global app.
void addAssociatedTransfer(MultiAppTransfer &transfer)
Add a transfer that is associated with this multiapp.
const MPI_Comm & _orig_comm
The original comm handle.
FEProblemBase & _fe_problem
The FEProblemBase this MultiApp is part of.
unsigned int _total_num_apps
The total number of apps to simulate.
unsigned int globalAppToLocal(unsigned int global_app)
Map a global App number to the local number.
SubAppBackups & _sub_app_backups
The cached subapp backups (passed from the parent app)
std::vector< std::shared_ptr< MooseApp > > _apps
Pointers to each of the Apps.
std::vector< bool > _reset_happened
Whether or not apps have been reset at each time.
MooseApp * localApp(unsigned int local_app)
Get the local MooseApp object.
void setAppOutputFileBase()
Sets all the app's output file bases.
virtual std::vector< std::string > getCommandLineArgs(const unsigned int local_app)
const UserObject & appUserObjectBase(unsigned int app, const std::string &name)
Get a UserObject base for a specific global app.
LocalRankConfig _rank_config
The app configuration resulting from calling init.
std::vector< std::unique_ptr< NumericVector< Real > > > _end_aux_solutions
The auxiliary solution from the end of the previous solve, this is cloned from the auxiliary solution...
virtual bool propagateRecoverToSubApps() const
Whether or not to propagate the parent's recover state (the –recover and –test-checkpoint-half-transi...
std::string _node_name
Node Name.
virtual void fillPositions()
must fill in _positions with the positions of the sub-aps
unsigned int _my_num_apps
The number of apps this object is involved in simulating.
virtual Executioner * getExecutioner(unsigned int app)
const PerfID _reset_timer
const std::vector< CLIArgString > & _cli_args
CommandLine arguments (controllable!)
std::vector< FileName > _input_files
The input file for each app's simulation.
virtual void createLocalApp(const unsigned int i)
Create the i-th local app.
std::vector< Point > _move_positions
The new positions for the apps to be moved.
std::vector< Point > _positions
The positions of all of the apps, using input constant vectors (to be deprecated)
virtual libMesh::NumericVector< libMesh::Number > & appTransferVector(unsigned int app, std::string var_name)
Get the vector to transfer to for this MultiApp.
virtual void parentOutputPositionChanged()
For apps outputting in position we need to change their output positions if their parent app moves.
const bool _run_in_position
Whether to run the child apps with their meshes transformed with the coordinate transforms.
static void transformBoundingBox(libMesh::BoundingBox &box, const MultiAppCoordTransform &transform)
Transform a bounding box according to the transformations in the provided coordinate transformation o...
virtual libMesh::BoundingBox getBoundingBox(unsigned int app, bool displaced_mesh, const MultiAppCoordTransform *coord_transform=nullptr)
Get the BoundingBox for the mesh associated with app The bounding box will be shifted to be in the co...
std::vector< unsigned int > _reset_apps
The apps to be reset.
std::map< std::string, unsigned int > getFileNumbers()
Extracts the file numbers from the output objects.
Interface for objects interacting with the PerfGraph.
const std::vector< Point > & getPositions(bool initial) const
{ Getters for the positions vector for the desired dimension 1D will be the only one guaranteed to su...
A class for creating restricted objects.
static InputParameters validParams()
void mooseWarning(Args &&... args) const
void mooseDeprecated(Args &&... args) const
Helper class for holding Sub-app backups.
Moose::CoordinateSystemType getCoordSystem(SubdomainID sid) const
NumericVector< Number > & solution()
void split(int color, int key, Communicator &target) const
void broadcast(T &data, const unsigned int root_id=0, const bool identical_sizes=false) const
Base class for transient executioners that use a FixedPointSolve solve object for multiapp-main app i...
Base class for user-specific data.
virtual std::unique_ptr< NumericVector< T > > clone() const=0
const Parallel::Communicator & _communicator
processor_id_type processor_id() const
processor_id_type n_processors() const
std::unique_ptr< NumericVector< Number > > solution
std::vector< std::string > split(const std::string &str, const std::string &delimiter, std::size_t max_count)
std::string trim(const std::string &str, const std::string &white_space=" \t\n\v\f\r")
Standard scripting language trim function.
bool checkFileReadable(const std::string &filename, bool check_line_endings, bool throw_on_unreadable, bool check_for_git_lfs_pointer)
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
std::string stringify(const T &t)
conversion to string
const unsigned int invalid_uint
Holds app partitioning information relevant to the a particular rank for a multiapp scenario.
bool is_first_local_rank
This is true if this rank is the primary/zero rank for a (sub)app slot.
dof_id_type num_local_apps
The number of (sub)apps that should/will be run locally on this rank.
dof_id_type first_local_app_index
The (global) index of the first local app for this rank.