35 #include "libmesh/mesh_tools.h" 36 #include "libmesh/numeric_vector.h" 45 #ifdef LIBMESH_HAVE_SYS_UTSNAME_H 46 #include <sys/utsname.h> 55 params.
addParam<
bool>(
"use_displaced_mesh",
57 "Whether or not this object should use the " 58 "displaced mesh for computation. Note that " 59 "in the case this is true but no " 60 "displacements are provided in the Mesh block " 61 "the undisplaced mesh will still be used.");
63 std::ostringstream app_types_strings;
65 app_types_strings << name_bi_pair.first <<
" ";
66 MooseEnum app_types_options(app_types_strings.str(),
"",
true);
71 "The type of application to build (applications not " 72 "registered can be loaded with dynamic libraries. Parent " 73 "application type will be used if not provided.");
74 params.
addParam<std::string>(
"library_path",
76 "Path to search for dynamic libraries (please " 77 "avoid committing absolute paths in addition to " 78 "MOOSE_LIBRARY_PATH)");
82 "The file name of the library (*.la file) that will be dynamically loaded.");
83 params.
addParam<
bool>(
"library_load_dependencies",
85 "Tells MOOSE to manually load library dependencies. This should not be " 86 "necessary and is here for debugging/troubleshooting.");
91 "The positions of the App locations. Each set of 3 values will represent a " 92 "Point. This and 'positions_file' cannot be both supplied. If this and " 93 "'positions_file'/'_objects' are not supplied, a single position (0,0,0) will be used");
94 params.
addParam<std::vector<FileName>>(
"positions_file",
95 "Filename(s) that should be looked in for positions. Each" 96 " set of 3 values in that file will represent a Point. " 97 "This and 'positions(_objects)' cannot be both supplied");
98 params.
addParam<std::vector<PositionsName>>(
"positions_objects",
99 "The name of a Positions object that will contain " 100 "the locations of the sub-apps created. This and " 101 "'positions(_file)' cannot be both supplied");
103 "output_in_position",
105 "If true this will cause the output from the MultiApp to be 'moved' by its position vector");
109 "If true this will cause the mesh from the MultiApp to be 'moved' by its position vector");
113 "The input file for each App. If this parameter only contains one input file " 114 "it will be used for all of the Apps. When using 'positions_from_file' it is " 115 "also admissable to provide one input_file per file.");
118 "Relative amount to 'inflate' the bounding box of this MultiApp.");
119 params.
addParam<Point>(
"bounding_box_padding",
121 "Additional padding added to the dimensions of the bounding box. The " 122 "values are added to the x, y and z dimension respectively.");
129 #ifdef LIBMESH_ENABLE_AMR 132 params.
setDocString(
"execute_on", exec_enum.getDocString());
137 "Maximum number of processors to give to each App in this " 138 "MultiApp. Useful for restricting small solves to just a few " 139 "procs so they don't get spread out");
142 "Minimum number of processors to give to each App in this " 143 "MultiApp. Useful for larger, distributed mesh solves.");
145 "wait_for_first_app_init",
147 "Create the first sub-application on rank 0, then MPI_Barrier before " 148 "creating the next N-1 apps (on all ranks). " 149 "This is only needed if your sub-application needs to perform some setup " 150 "actions in quiet, without other sub-applications working at the same time.");
154 "The time offset relative to the parent application for the purpose of " 155 "starting a subapp at a different time from the parent application. The " 156 "global time will be ahead by the offset specified here.");
162 "The time(s) at which to reset Apps given by the 'reset_apps' parameter. " 163 "Resetting an App means that it is destroyed and recreated, possibly " 164 "modeling the insertion of 'new' material for that app.");
165 params.
addParam<std::vector<unsigned int>>(
168 "The Apps that will be reset when 'reset_time' is hit. These are the App " 169 "'numbers' starting with 0 corresponding to the order of the App positions. " 170 "Resetting an App means that it is destroyed and recreated, possibly modeling " 171 "the insertion of 'new' material for that app.");
177 "The time at which Apps designated by move_apps are moved to move_positions.");
179 params.
addParam<std::vector<unsigned int>>(
182 "Apps, designated by their 'numbers' starting with 0 corresponding to the order " 183 "of the App positions, to be moved at move_time to move_positions");
184 params.
addParam<std::vector<Point>>(
185 "move_positions", {},
"The positions corresponding to each move_app.");
187 params.
addParam<std::vector<CLIArgString>>(
190 "Additional command line arguments to pass to the sub apps. If one set is provided the " 191 "arguments are applied to all, otherwise there must be a set for each sub app.");
193 params.
addParam<std::vector<FileName>>(
195 "File names that should be looked in for additional command line arguments " 196 "to pass to the sub apps. Each line of a file is set to each sub app. If only " 197 "one line is provided, it will be applied to all sub apps.");
202 "relaxation_factor>0 & relaxation_factor<2",
203 "Fraction of newly computed value to keep." 204 "Set between 0 and 2.");
208 "Use transformed_variables.",
209 "List of subapp variables to relax during Multiapp coupling iterations");
210 params.
addParam<std::vector<std::string>>(
211 "transformed_variables",
213 "List of subapp variables to use coupling algorithm on during Multiapp coupling iterations");
214 params.
addParam<std::vector<PostprocessorName>>(
215 "transformed_postprocessors",
217 "List of subapp postprocessors to use coupling " 218 "algorithm on during Multiapp coupling iterations");
219 params.
addParam<
bool>(
"keep_solution_during_restore",
221 "This is useful when doing MultiApp coupling iterations. It takes the " 222 "final solution from the previous coupling iteration" 223 "and re-uses it as the initial guess for the next coupling iteration");
224 params.
addParam<
bool>(
"keep_aux_solution_during_restore",
226 "This is useful when doing MultiApp coupling iterations. It takes the " 227 "final auxiliary solution from the previous coupling iteration" 228 "and re-uses it as the initial guess for the next coupling iteration");
230 "no_backup_and_restore",
232 "True to turn off restore for this multiapp. This is useful when doing steady-state " 233 "Picard iterations where we want to use the solution of previous Picard iteration as the " 234 "initial guess of the current Picard iteration.");
236 "max_multiapp_level",
238 "Integer set by user that will stop the simulation if the multiapp level " 239 "exceeds it. Useful for preventing infinite loops with multiapp simulations");
240 params.
deprecateParam(
"no_backup_and_restore",
"no_restore",
"01/01/2025");
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.");
258 "output_in_position",
259 "Positions / transformations of the MultiApp frame of reference");
263 params.
addParamNamesToGroup(
"relaxation_factor transformed_variables transformed_postprocessors " 264 "keep_solution_during_restore keep_aux_solution_during_restore " 266 "Fixed point iteration");
278 _fe_problem(*getCheckedPointerParam<
FEProblemBase *>(
"_fe_problem_base")),
279 _app_type(isParamValid(
"app_type") ?
std::string(getParam<
MooseEnum>(
"app_type"))
280 : _fe_problem.getMooseApp().type()),
281 _use_positions(getParam<bool>(
"use_positions")),
282 _input_files(getParam<
std::vector<FileName>>(
"input_files")),
283 _wait_for_first_app_init(getParam<bool>(
"wait_for_first_app_init")),
287 _orig_comm(_communicator.
get()),
289 _my_comm(_my_communicator.
get()),
291 _inflation(getParam<
Real>(
"bounding_box_inflation")),
292 _bounding_box_padding(getParam<Point>(
"bounding_box_padding")),
295 _output_in_position(getParam<bool>(
"output_in_position")),
296 _global_time_offset(getParam<
Real>(
"global_time_offset")),
297 _reset_times(getParam<
std::vector<
Real>>(
"reset_time")),
298 _reset_apps(getParam<
std::vector<unsigned
int>>(
"reset_apps")),
299 _reset_happened(false),
300 _move_time(getParam<
Real>(
"move_time")),
301 _move_apps(getParam<
std::vector<unsigned
int>>(
"move_apps")),
302 _move_positions(getParam<
std::vector<Point>>(
"move_positions")),
303 _move_happened(false),
305 _cli_args(getParam<
std::vector<CLIArgString>>(
"cli_args")),
306 _keep_solution_during_restore(getParam<bool>(
"keep_solution_during_restore")),
307 _keep_aux_solution_during_restore(getParam<bool>(
"keep_aux_solution_during_restore")),
308 _no_restore(getParam<bool>(
"no_restore")),
309 _run_in_position(getParam<bool>(
"run_in_position")),
310 _sub_app_backups(declareRestartableDataWithContext<
SubAppBackups>(
"sub_app_backups", this)),
311 _solve_step_timer(registerTimedSection(
"solveStep", 3,
"Executing MultiApps", false)),
312 _init_timer(registerTimedSection(
"init", 3,
"Initializing MultiApp")),
313 _backup_timer(registerTimedSection(
"backup", 3,
"Backing Up MultiApp")),
314 _restore_timer(registerTimedSection(
"restore", 3,
"Restoring MultiApp")),
315 _reset_timer(registerTimedSection(
"resetApp", 3,
"Resetting MultiApp"))
320 "'cli_args' and 'cli_args_files' cannot be specified simultaneously in MultiApp ");
325 "This MultiApps has been set to not use positions, " 326 "but a 'positions' parameter has been set.");
330 mooseError(
"reset_time and reset_apps may only be specified together");
334 std::sort(sorted_times.begin(), sorted_times.end());
336 paramError(
"reset_time",
"List of reset times must be sorted in increasing order");
344 init(num_apps, config);
363 "The number of items supplied must be 1 or equal to the number of sub apps.");
370 mooseError(
"The number of items supplied as command line argument to subapps must be 1 or " 371 "equal to the number of sub apps. Note: you use a multiapp that provides its own " 372 "command line parameters so the error is not in cli_args");
393 TIME_SECTION(
"createApps", 2,
"Instantiating Sub-Apps",
false);
405 getParam<std::string>(
"library_path"),
406 getParam<std::string>(
"library_name"),
407 getParam<bool>(
"library_load_dependencies"));
409 bool rank_did_quiet_init =
false;
415 rank_did_quiet_init =
true;
425 if (rank_did_quiet_init && i == local_app)
453 std::vector<FileName> cli_args_files = getParam<std::vector<FileName>>(
"cli_args_files");
454 std::vector<FileName> input_files = getParam<std::vector<FileName>>(
"input_files");
457 if (!cli_args_files.size())
458 paramError(
"cli_args_files",
"You need to provide at least one commandLine argument file ");
462 if (cli_args_files.size() != 1 && cli_args_files.size() != input_files.size())
464 "The number of commandLine argument files ",
465 cli_args_files.size(),
468 " must either be only one or match the number of input files ",
472 std::vector<std::string> cli_args;
473 for (
unsigned int p_file_it = 0; p_file_it < cli_args_files.size(); p_file_it++)
475 std::string cli_args_file = cli_args_files[p_file_it];
483 std::ifstream
is(cli_args_file.c_str());
486 while (std::getline(
is, line))
487 cli_args.push_back(line);
490 if (!cli_args.size())
492 "There is no commandLine argument in the commandLine argument file ",
503 if (cli_args.size() == 1)
504 for (MooseIndex(num_positions) num = 0; num < num_positions; num++)
506 else if (cli_args.size() == num_positions)
507 for (
auto && cli_arg : cli_args)
509 else if (cli_args.size() != num_positions)
511 "The number of commandLine argument strings ",
515 " must either be only one or match the number of positions ",
522 for (
auto && cli_arg : cli_args)
534 mooseError(
" The number of commandLine argument strings ",
536 " must either be only one or match the total " 537 "number of sub apps ",
541 mooseError(
"Cannot set commandLine arguments from both input_file and external files");
548 mooseError(
"The number of apps to move and the positions to move them to must be the same for " 555 mooseError(
"Only one 'positions' parameter may be specified");
559 _positions = getParam<std::vector<Point>>(
"positions");
562 mooseError(
"Not enough positions for the number of input files provided in MultiApp ",
567 std::vector<FileName> positions_files = getParam<std::vector<FileName>>(
"positions_file");
568 std::vector<FileName> input_files = getParam<std::vector<FileName>>(
"input_files");
570 if (input_files.size() != 1 && positions_files.size() != input_files.size())
571 mooseError(
"Number of input_files for MultiApp ",
573 " must either be only one or match the number of positions_file files");
576 if (input_files.size() != 1)
579 for (
unsigned int p_file_it = 0; p_file_it < positions_files.size(); p_file_it++)
581 std::string positions_file = positions_files[p_file_it];
587 for (
const auto & d : data)
593 for (
unsigned int i = 0; i < data.size(); ++i)
594 if (input_files.size() != 1)
600 const auto & positions_param_objs = getParam<std::vector<PositionsName>>(
"positions_objects");
601 const auto & input_files = getParam<std::vector<FileName>>(
"input_files");
603 if (input_files.size() != 1 && positions_param_objs.size() != input_files.size())
604 mooseError(
"Number of input_files for MultiApp ",
606 " must either be only one or match the number of positions_objects specified");
609 if (input_files.size() != 1)
613 unsigned int offset = 0;
615 for (
const auto p_obj_it :
index_range(positions_param_objs))
617 const std::string & positions_name = positions_param_objs[p_obj_it];
623 for (
const auto & d : data)
631 "'" + positions_name +
"' is not of the expected type. Should be a Positions");
634 for (
unsigned int i = 0; i < data.size(); ++i)
636 if (input_files.size() != 1)
641 offset += data.size();
649 mooseError(
"Not enough positions for the number of input files provided in MultiApp ",
654 "Number of positions and input files are not the same!");
661 Real timestep_tol = 1e-13;
667 bool backup_apps =
false;
683 transfer->getAppInfo();
689 auto app_ptr =
_apps[i];
691 app_ptr->getExecutioner()->feProblem().coordTransform().transformMesh(
694 app_ptr->getExecutioner()->feProblem().coordTransform().transformMesh(
695 app_ptr->getExecutioner()->feProblem().mesh(), Point(0, 0, 0));
714 for (
unsigned int i = 0; i <
_move_apps.size(); i++)
737 for (
const auto & app_ptr :
_apps)
739 auto * executioner = app_ptr->getExecutioner();
740 mooseAssert(executioner,
"Executioner is nullptr");
743 executioner->feProblem().outputStep(
EXEC_FINAL);
750 for (
const auto & app_ptr :
_apps)
752 auto * executioner = app_ptr->getExecutioner();
753 mooseAssert(executioner,
"Executioner is nullptr");
755 executioner->postExecute();
765 _console <<
"Backed up MultiApp ... ";
795 for (
unsigned int j = 0; j <
_apps[i]->getExecutioner()->feProblem().numSolverSystems();
805 auto & sub_multiapps =
806 _apps[i]->getExecutioner()->feProblem().getMultiAppWarehouse().getObjects();
810 for (
auto & multi_app : sub_multiapps)
826 _console <<
"Restoring MultiApp ... ";
843 for (
unsigned int j = 0; j <
_apps[i]->getExecutioner()->feProblem().numSolverSystems();
846 _apps[i]->getExecutioner()->feProblem().getSolverSystem(j).solution() =
850 _apps[i]->getExecutioner()->feProblem().getSolverSystem(j).update();
861 _apps[i]->getExecutioner()->feProblem().getAuxiliarySystem().solution() =
865 _apps[i]->getExecutioner()->feProblem().getAuxiliarySystem().update();
872 for (
const auto & app_ptr :
_apps)
873 if (app_ptr->feProblem().getDisplacedProblem())
874 app_ptr->feProblem().getDisplacedProblem()->updateMesh();
878 for (
auto & app_ptr :
_apps)
879 app_ptr->getExecutioner()->fixedPointSolve().clearFixedPointStatus();
885 for (
auto & sub_app :
887 sub_app->restore(
false);
897 "This parameter should only be provided in parent app");
905 const Real min_x = box.first(0);
906 const Real max_x = box.second(0);
907 const Real min_y = box.first(1);
908 const Real max_y = box.second(1);
909 const Real min_z = box.first(2);
910 const Real max_z = box.second(2);
912 std::array<Point, 8> box_corners = {{Point(min_x, min_y, min_z),
913 Point(max_x, min_y, min_z),
914 Point(min_x, max_y, min_z),
915 Point(max_x, max_y, min_z),
916 Point(min_x, min_y, max_z),
917 Point(max_x, min_y, max_z),
918 Point(min_x, max_y, max_z),
919 Point(max_x, max_y, max_z)}};
922 for (
auto & corner : box_corners)
923 corner = transform(corner);
926 Point new_box_min = box_corners[0];
927 Point new_box_max = new_box_min;
931 const Point & pt = box_corners[p];
932 if (new_box_min(d) > pt(d))
933 new_box_min(d) = pt(d);
935 if (new_box_max(d) < pt(d))
936 new_box_max(d) = pt(d);
938 box.first = new_box_min;
939 box.second = new_box_max;
954 : fe_problem_base.
mesh();
971 Point
min = bbox.min();
973 Point
max = bbox.max();
978 Point inflated_min =
min - inflation_amount;
979 Point inflated_max =
max + inflation_amount;
981 Point shifted_min = inflated_min;
982 Point shifted_max = inflated_max;
989 shifted_min(0) = -inflated_max(0);
990 shifted_min(1) = inflated_min(1);
991 shifted_min(2) = -inflated_max(0);
993 shifted_max(0) = inflated_max(0);
994 shifted_max(1) = inflated_max(1);
995 shifted_max(2) = inflated_max(0);
1000 BoundingBox transformed_bbox(shifted_min, shifted_max);
1002 return transformed_bbox;
1012 return BoundingBox(shifted_min, shifted_max);
1024 return _apps[local_app]->getExecutioner()->feProblem();
1031 "MultiApp::appProblem() is deprecated, call MultiApp::appProblemBase() instead.\n");
1037 return dynamic_cast<FEProblem &
>(
_apps[local_app]->getExecutioner()->feProblem());
1084 return _apps[local_app].get();
1099 std::map<std::string, unsigned int> m =
_apps[local_app]->getOutputWarehouse().getFileNumbers();
1104 _apps[local_app]->getOutputWarehouse().setFileNumbers(m);
1120 _apps[local_app]->setOutputPosition(p);
1122 paramError(
"run_in_position",
"Moving apps and running apps in position is not supported");
1131 for (
unsigned int i = 0; i <
_apps.size(); i++)
1140 std::string full_name;
1144 full_name =
_app.
name() +
"_" + multiapp_name;
1146 full_name = multiapp_name;
1154 std::vector<std::string> input_cli_args;
1159 auto app_cli =
_app.
commandLine()->initSubAppCommandLine(
name(), multiapp_name, input_cli_args);
1161 app_params.
set<std::shared_ptr<CommandLine>>(
"_command_line") = std::move(app_cli);
1166 <<
" on processor " <<
processor_id() <<
" with full name " << full_name
1167 << COLOR_DEFAULT << std::endl;
1171 #ifdef MOOSE_MFEM_ENABLED 1172 app_params.
set<std::shared_ptr<mfem::Device>>(
"_mfem_device") =
1175 app_params.
set<std::vector<std::string>>(
"_mfem_devices") =
1176 std::vector<std::string>(mfem_device_set.begin(), mfem_device_set.end());
1178 if (getParam<bool>(
"clone_master_mesh") || getParam<bool>(
"clone_parent_mesh"))
1181 _console << COLOR_CYAN <<
"Cloned parent app mesh will be used for MultiApp " <<
name()
1182 << COLOR_DEFAULT << std::endl;
1183 app_params.
set<
bool>(
"_use_master_mesh") =
true;
1194 auto parser = std::make_unique<Parser>(input_file);
1196 if (input_file.size())
1199 const auto & app_type = parser->getAppType();
1200 if (app_type.empty() &&
_app_type.empty())
1201 mooseWarning(
"The application type is not specified for ",
1203 ". Please use [Application] block to specify the application type.");
1204 if (!app_type.empty() && app_type !=
_app_type &&
1210 "' is not a registered application. The registered application is named: '",
1212 "'. Please double check the [Application] block to make sure the correct " 1213 "application is provided. \n");
1216 if (parser->getAppType().empty())
1219 app_params.
set<std::shared_ptr<Parser>>(
"_parser") = std::move(parser);
1221 auto & app =
_apps[i];
1223 app->setGlobalTimeOffset(start_time);
1232 "Sub-apps are already displaced, so they are already output in position");
1235 app->setupOptions();
1241 if (app->getOutputFileBase().empty())
1245 mooseError(
"Maximum multiapp level has been reached. This is likely caused by an infinite loop " 1246 "in your multiapp system. If additional multiapp levels are needed, " 1247 "max_multiapp_level can be specified in the MuliApps block.");
1250 _apps[i]->fixedPointConfig().sub_relaxation_factor = getParam<Real>(
"relaxation_factor");
1251 _apps[i]->fixedPointConfig().sub_transformed_vars =
1252 getParam<std::vector<std::string>>(
"transformed_variables");
1255 _apps[i]->fixedPointConfig().sub_transformed_vars =
1256 getParam<std::vector<std::string>>(
"relaxed_variables");
1257 _apps[i]->fixedPointConfig().sub_transformed_pps =
1258 getParam<std::vector<PostprocessorName>>(
"transformed_postprocessors");
1260 app->runInputFile();
1261 auto fixed_point_solve = &(
_apps[i]->getExecutioner()->fixedPointSolve());
1262 if (fixed_point_solve)
1263 fixed_point_solve->allocateStorage(
false);
1269 app->getExecutioner()->feProblem().coordTransform().transformMesh(
1272 app->getExecutioner()->feProblem().coordTransform().transformMesh(
1273 app->getExecutioner()->feProblem().mesh(), Point(0, 0, 0));
1277 std::vector<std::string>
1282 std::string combined_args;
1285 if (cla.size() == 1)
1286 combined_args = cla[0];
1290 cli_args_param =
"cli_args_files";
1294 else if (cla.size())
1299 cli_args_param =
"cli_args_files";
1308 if (combined_args.empty())
1314 for (
const auto & arg : args)
1318 const auto error =
"An empty MultiApp command line argument was provided. Your " 1319 "combined command line string has a ';' with no argument after it.";
1338 if (min_app_procs > nprocs)
1339 mooseError(
"minimum number of procs per app is higher than the available number of procs");
1340 else if (min_app_procs > max_app_procs)
1341 mooseError(
"minimum number of procs per app must be lower than the max procs per app");
1343 mooseAssert(rank < nprocs,
"rank must be smaller than the number of procs");
1349 std::max(
std::min(cast_int<processor_id_type>(nprocs / napps), max_app_procs), min_app_procs);
1352 cast_int<processor_id_type>(
std::min(
1354 mooseAssert(nprocs >= (nslots * slot_size),
1355 "Ensure that leftover procs is represented by an unsigned type");
1360 std::vector<int> slot_for_rank(nprocs);
1366 slot_for_rank[rankiter] = cast_int<int>(slot);
1368 slot_for_rank[rankiter] = -1;
1373 if (procs_in_slot == slot_size + 1 * (slot < leftover_procs && slot_size < max_app_procs))
1380 if (slot_for_rank[rank] < 0)
1382 return {0, 0, 0, 0,
false, 0};
1383 const processor_id_type slot_num = cast_int<processor_id_type>(slot_for_rank[rank]);
1385 const bool is_first_local_rank = rank == 0 || (slot_for_rank[rank - 1] != slot_for_rank[rank]);
1386 const dof_id_type n_local_apps = apps_per_slot + 1 * (slot_num < leftover_apps);
1390 if (slot_for_rank[rank] != slot_for_rank[rankiter])
1392 my_first_rank = cast_int<processor_id_type>(slot_for_rank[rankiter + 1]);
1399 const dof_id_type num_slot_apps = apps_per_slot + 1 * (slot < leftover_apps);
1400 app_index += num_slot_apps;
1404 return {n_local_apps, app_index, 1, slot_num, is_first_local_rank, my_first_rank};
1405 return {n_local_apps, app_index, n_local_apps, app_index, is_first_local_rank, my_first_rank};
1414 mooseCheckMPIErr(ierr);
1416 mooseCheckMPIErr(ierr);
1418 #ifdef LIBMESH_HAVE_SYS_UTSNAME_H 1419 struct utsname sysInfo;
1428 mooseCheckMPIErr(ierr);
1435 mooseError(
"Internal error, a processor has an undefined app.");
1441 mooseCheckMPIErr(ierr);
1456 std::stringstream ss;
1457 ss <<
"Requesting app " << global_app <<
", but processor " <<
processor_id() <<
" ";
1459 ss <<
"does not own any apps";
1465 mooseError(
"Invalid global_app!\n", ss.str());
1487 std::vector<std::string>
1498 const std::string multiapp_name =
1506 std::ostringstream multiapp_name;
1507 multiapp_name << base_name << std::setw(std::ceil(std::log10(total))) << std::setprecision(0)
1508 << std::setfill(
'0') << std::right << index;
1509 return multiapp_name.str();
1527 mooseAssert(multi_app,
"Not set");
1531 dataStore(stream,
static_cast<std::vector<std::unique_ptr<Backup>
> &>(backups),
nullptr);
1538 mooseAssert(multi_app,
"Not set");
1540 dataLoad(stream,
static_cast<std::vector<std::unique_ptr<Backup>
> &>(backups),
nullptr);
bool isRegistered(const std::string &app_name) const
Returns a Boolean indicating whether an application type has been registered.
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 hasLocalApp(unsigned int global_app) const
Whether or not the given global app number is on this processor.
std::vector< unsigned int > _reset_apps
The apps to be reset.
const std::set< std::string > & getMFEMDevices(Moose::PassKey< MultiApp >) const
Get the configured MFEM devices.
bool needsRestoration()
Whether or not this MultiApp should be restored at the beginning of each Picard iteration.
virtual libMesh::System & getSystem(const std::string &var_name) override
Returns the equation system containing the variable provided.
A MultiMooseEnum object to hold "execute_on" flags.
A class for creating restricted objects.
MultiApp(const InputParameters ¶meters)
std::vector< libMesh::BoundingBox > _bounding_box
This multi-app's bounding box.
std::vector< const Positions * > _positions_objs
The positions of all of the apps, using the Positions system.
std::shared_ptr< DisplacedProblem > displaced_problem
const unsigned int invalid_uint
void mooseDeprecated(Args &&... args) const
virtual void restore(bool force=true)
Restore the state of every Sub App.
virtual void backup()
Save off the state of every Sub App.
bool verboseMultiApps() const
Whether or not to use verbose printing for MultiApps.
NumericVector< Number > & solution()
const bool _use_positions
Toggle use of "positions".
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
const std::vector< CLIArgString > & _cli_args
CommandLine arguments (controllable!)
std::vector< unsigned int > _npositions_inputfile
Number of positions for each input file.
void dataLoad(std::istream &stream, SubAppBackups &backups, void *context)
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
void setupPositions()
Called just after construction to allow derived classes to set _positions and create sub-apps accordi...
std::shared_ptr< CommandLine > commandLine() const
Get the command line.
std::vector< unsigned int > _positions_index_offsets
The offsets, in case multiple Positions objects are specified.
const std::vector< Point > getDataAsPoints() const
Get the data in Point format.
Real _move_time
The time at which to move apps.
MooseAppPtr createShared(const std::string &app_type, const std::string &name, InputParameters parameters, MPI_Comm COMM_WORLD_IN)
Build an application object (must be registered)
const ExecFlagType & getCurrentExecuteOnFlag() const
Return/set the current execution flag.
Real appPostprocessorValue(unsigned int app, const std::string &name)
Get a Postprocessor value for a specified global app.
int _orig_rank
The mpi "rank" of this processor in the original communicator.
LocalRankConfig _rank_config
The app configuration resulting from calling init.
std::optional< std::string > _cli_args_param
The parameter that was used to set the command line args, if any.
std::string getOutputFileBase(bool for_non_moose_build_output=false) const
Get the output file base name.
T * get(const std::unique_ptr< T > &u)
The MooseUtils::get() specializations are used to support making forwards-compatible code changes fro...
std::vector< std::shared_ptr< MooseApp > > _apps
Pointers to each of the Apps.
dof_id_type first_local_app_index
The (global) index of the first local app for this rank.
FEProblemBase & feProblem()
Return a reference to this Executioner's FEProblemBase instance.
unsigned int multiAppLevel() const
The MultiApp Level.
virtual void parentOutputPositionChanged()
For apps outputting in position we need to change their output positions if their parent app moves...
std::vector< Point > _move_positions
The new positions for the apps to be moved.
Base class for MOOSE-based applications.
void dataStore(std::ostream &stream, SubAppBackups &backups, void *context)
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
void addAvailableFlags(const ExecFlagType &flag, Args... flags)
Add additional execute_on flags to the list of possible flags.
const PerfID _restore_timer
virtual std::unique_ptr< NumericVector< Number > > clone() const =0
const Parallel::Communicator & _communicator
Real _inflation
Relative bounding box inflation.
FEProblemBase & _fe_problem
The FEProblemBase this MultiApp is part of.
bool isRestarting() const
Whether or not this is a "restart" calculation.
const Positions & getPositionsObject(const std::string &name) const
Get the Positions object by its name.
virtual std::vector< std::string > getCommandLineArgs(const unsigned int local_app)
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
processor_id_type _min_procs_per_app
Minimum number of processors to give to each app.
virtual const std::string & name() const
Get the name of the class.
int _orig_num_procs
The number of processors in the original comm.
void mooseWarning(Args &&... args) const
Emits a warning prefixed with object name and type.
MooseApp & getMooseApp() const
Get the MooseApp this class is associated with.
const PerfID _backup_timer
auto max(const L &left, const R &right)
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())
Python like split functions for strings.
std::vector< Real > _reset_times
The times at which to reset apps.
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
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...
void createApps()
Create the provided number of apps.
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...
uint8_t processor_id_type
processor_id_type n_processors() const
const bool & _wait_for_first_app_init
Whether to create the first app on rank 0 while all other MPI ranks are idle.
const auto & registeredObjects() const
Returns a reference to the map from names to AppFactoryBuildInfo pointers.
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::NumericVector< libMesh::Number > & appTransferVector(unsigned int app, std::string var_name)
Get the vector to transfer to for this MultiApp.
bool _keep_solution_during_restore
Flag indicates if or not restart from the latest solution.
Every object that can be built by the factory should be derived from this class.
std::map< std::string, unsigned int > getFileNumbers()
Extracts the file numbers from the output objects.
processor_id_type _max_procs_per_app
Maximum number of processors to give to each app.
virtual std::vector< std::string > cliArgs() const
function that provides cli_args to subapps
const ExecFlagType EXEC_TIMESTEP_BEGIN
virtual void fillPositions()
must fill in _positions with the positions of the sub-aps
const ExecFlagType EXEC_PRE_MULTIAPP_SETUP
bool _move_happened
Whether or not the move has happened.
std::vector< MultiAppTransfer * > _associated_transfers
Transfers associated with this multiapp.
Helper class for holding Sub-app backups.
const PerfID _reset_timer
bool checkFileReadable(const std::string &filename, bool check_line_endings=false, bool throw_on_unreadable=true, bool check_for_git_lfs_pointer=true)
Checks to see if a file is readable (exists and permissions)
std::string trim(const std::string &str, const std::string &white_space=" \\\)
Standard scripting language trim function.
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...
std::string _app_type
The type of application to build.
std::unique_ptr< NumericVector< Number > > solution
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
void setFormatFlag(FormatFlag value)
void split(int color, int key, Communicator &target) const
FEProblemBase & appProblemBase(unsigned int app)
Get the FEProblemBase for the global app desired.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
PetscErrorCode PetscInt const PetscInt IS * is
std::vector< unsigned int > _move_apps
The apps to be moved.
Executioners are objects that do the actual work of solving your problem.
Base class for transient executioners that use a FixedPointSolve solve object for multiapp-main app i...
MooseApp & _app
The MOOSE application this is associated with.
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 read()
Perform the actual data reading.
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...
void buildComm()
Create an MPI communicator suitable for each app.
virtual void resetApp(unsigned int global_app, Real time=0.0)
"Reset" the App corresponding to the global App number passed in.
std::string stringify(const T &t)
conversion to string
AuxiliarySystem & getAuxiliarySystem()
static InputParameters validParams()
const std::string _name
The name of this class.
bool isFirstLocalRank() const
Interface for objects interacting with the PerfGraph.
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.
unsigned int _total_num_apps
The total number of apps to simulate.
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...
Executioner * getExecutioner() const
Retrieve the Executioner for this App.
void broadcast(T &data, const unsigned int root_id=0, const bool identical_sizes=false) const
Point getOutputPosition() const
Get the output position.
unsigned int _my_num_apps
The number of apps this object is involved in simulating.
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.
std::string _node_name
Node Name.
static AppFactory & instance()
Get the instance of the AppFactory.
bool _has_an_app
Whether or not this processor as an App at all
libMesh::Parallel::Communicator _my_communicator
The communicator object that holds the MPI_Comm that we're going to use.
void createApp(unsigned int i, Real start_time)
Helper function for creating an App instance.
bool usingPositions() const
Whether or not this MultiApp is using positions or its own way for constructing sub-apps.
unsigned int _first_local_app
The number of the first app on this processor.
void addAssociatedTransfer(MultiAppTransfer &transfer)
Add a transfer that is associated with this multiapp.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual std::shared_ptr< const DisplacedProblem > getDisplacedProblem() const
MooseApp * localApp(unsigned int local_app)
Get the local MooseApp object.
virtual void initialSetup() override
Method to be called in main-app initial setup for create sub-apps if using positions is false...
Utility class for reading delimited data (e.g., CSV data).
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...
Base class for all MultiAppTransfer objects.
bool is_first_local_rank
This is true if this rank is the primary/zero rank for a (sub)app slot.
FEProblem & appProblem(unsigned int app)
Get the FEProblem for the global app is part of.
IntRange< T > make_range(T beg, T end)
SubAppBackups & _sub_app_backups
The cached subapp backups (passed from the parent app)
virtual MooseMesh & mesh() override
virtual void postExecute()
Method called at the end of the simulation (after finalize).
bool _keep_aux_solution_during_restore
Flag indicates if or not restart the auxiliary system from the latest auxiliary solution.
bool _output_in_position
Whether or not to move the output of the MultiApp into position.
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
const InputParameters & _pars
Parameters of this object, references the InputParameters stored in the InputParametersWarehouse.
std::vector< Point > _positions
The positions of all of the apps, using input constant vectors (to be deprecated) ...
const InputParameters & parameters() const
Get the parameters of the object.
virtual void finalize()
Method called towards the end of the simulation to execute on final.
void readCommandLineArguments()
Fill command line arguments for sub apps.
int _my_rank
The mpi "rank" of this processor in the sub communicator.
Moose::CoordinateSystemType getCoordSystem(SubdomainID sid) const
dof_id_type num_local_apps
The number of (sub)apps that should/will be run locally on this rank.
virtual void createLocalApp(const unsigned int i)
Create the i-th local app.
std::vector< FileName > _input_files
The input file for each app's simulation.
Holds app partitioning information relevant to the a particular rank for a multiapp scenario...
virtual void preRunInputFile()
call back executed right before app->runInputFile()
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
InputParameters getValidParams(const std::string &name)
Get valid parameters for the object.
const UserObject & getUserObjectBase(const std::string &name, const THREAD_ID tid=0) const
Get the user object by its name.
Point _bounding_box_padding
Additional padding added to the bounding box, useful for 1D meshes.
const Real _global_time_offset
The offset time so the MultiApp local time relative to the global time.
void init(unsigned int num_apps, bool batch_mode=false)
Build communicators and reserve backups.
static InputParameters validParams()
const MPI_Comm & _orig_comm
The original comm handle.
static InputParameters validParams()
A MultiApp represents one or more MOOSE applications that are running simultaneously.
processor_id_type processor_id() const
void setAppOutputFileBase()
Sets all the app's output file bases.
bool isRecovering() const
Whether or not this is a "recover" calculation.
auto min(const L &left, const R &right)
std::shared_ptr< mfem::Device > getMFEMDevice(Moose::PassKey< MultiApp >)
Get the MFEM device object.
MPI_Comm & _my_comm
The MPI communicator this object is going to use.
const ExecFlagType EXEC_FINAL
const bool _run_in_position
Whether to run the child apps with their meshes transformed with the coordinate transforms.
virtual void moveApp(unsigned int global_app, Point p)
Move the global_app to Point p.
void ErrorVector unsigned int
virtual Executioner * getExecutioner(unsigned int app)
auto index_range(const T &sizable)
Base class for user-specific data.
const Point & position(unsigned int app) const
The physical position of a global App number.
OutputWarehouse & getOutputWarehouse()
Get the OutputWarehouse objects.
std::vector< std::string > _cli_args_from_file
CommandLine arguments from files.
const UserObject & appUserObjectBase(unsigned int app, const std::string &name)
Get a UserObject base for a specific global app.
const ExecFlagType EXEC_POST_ADAPTIVITY
unsigned int globalAppToLocal(unsigned int global_app)
Map a global App number to the local number.
void dynamicAppRegistration(const std::string &app_name, std::string library_path, const std::string &library_name, bool lib_load_deps)
std::vector< bool > _reset_happened
Whether or not apps have been reset at each time.
const ExecFlagType EXEC_INITIAL
std::vector< bool > _has_bounding_box
Flag if this multi-app computed its bounding box (valid only for non-displaced meshes) ...