Skip to content

Commit

Permalink
Merge pull request #12756 from permcody/multiap_start_time
Browse files Browse the repository at this point in the history
Multiapp start time
  • Loading branch information
friedmud committed Jan 28, 2019
2 parents 7f694b2 + f5ee4a8 commit fd0f8e8
Show file tree
Hide file tree
Showing 14 changed files with 187 additions and 32 deletions.
4 changes: 0 additions & 4 deletions framework/include/multiapps/FullSolveMultiApp.h
Expand Up @@ -33,10 +33,6 @@ class FullSolveMultiApp : public MultiApp


virtual bool solveStep(Real dt, Real target_time, bool auto_advance = true) override; virtual bool solveStep(Real dt, Real target_time, bool auto_advance = true) override;


virtual void incrementTStep() override {}

virtual void finishStep() override {}

virtual bool isSolved() const override { return _solved; } virtual bool isSolved() const override { return _solved; }


private: private:
Expand Down
14 changes: 4 additions & 10 deletions framework/include/multiapps/MultiApp.h
Expand Up @@ -112,16 +112,7 @@ class MultiApp : public MooseObject, public SetupInterface, public Restartable
* which is called either directly from solveStep() for loose coupling cases * which is called either directly from solveStep() for loose coupling cases
* or through finishStep() for Picard coupling cases) * or through finishStep() for Picard coupling cases)
*/ */
virtual void incrementTStep() {} virtual void incrementTStep(Real /*target_time*/) {}

/**
* Deprecated method. Use finishStep
*/
virtual void advanceStep()
{
mooseDeprecated("advanceStep() is deprecated; please use finishStep() instead");
finishStep();
}


/** /**
* Calls multi-apps executioners' endStep and postStep methods which creates output and advances * Calls multi-apps executioners' endStep and postStep methods which creates output and advances
Expand Down Expand Up @@ -399,6 +390,9 @@ class MultiApp : public MooseObject, public SetupInterface, public Restartable
/// Whether or not to move the output of the MultiApp into position /// Whether or not to move the output of the MultiApp into position
bool _output_in_position; bool _output_in_position;


/// The offset time so the MultiApp local time relative to the global time
const Real _global_time_offset;

/// The time at which to reset apps /// The time at which to reset apps
Real _reset_time; Real _reset_time;


Expand Down
2 changes: 1 addition & 1 deletion framework/include/multiapps/TransientMultiApp.h
Expand Up @@ -40,7 +40,7 @@ class TransientMultiApp : public MultiApp


virtual bool solveStep(Real dt, Real target_time, bool auto_advance = true) override; virtual bool solveStep(Real dt, Real target_time, bool auto_advance = true) override;


virtual void incrementTStep() override; virtual void incrementTStep(Real target_time) override;


virtual void finishStep() override; virtual void finishStep() override;


Expand Down
8 changes: 7 additions & 1 deletion framework/src/multiapps/MultiApp.C
Expand Up @@ -112,6 +112,11 @@ validParams<MultiApp>()
false, false,
"If true this will cause the output from the MultiApp to be 'moved' by its position vector"); "If true this will cause the output from the MultiApp to be 'moved' by its position vector");


params.addParam<Real>("global_time_offset",
0,
"The time offset relative to the master application for the purpose of "
"starting a subapp at different time from the master application. The "
"global time will be ahead by the offset specified here.");
params.addParam<Real>("reset_time", params.addParam<Real>("reset_time",
std::numeric_limits<Real>::max(), std::numeric_limits<Real>::max(),
"The time at which to reset Apps given by the 'reset_apps' parameter. " "The time at which to reset Apps given by the 'reset_apps' parameter. "
Expand Down Expand Up @@ -173,6 +178,7 @@ MultiApp::MultiApp(const InputParameters & parameters)
_bounding_box_padding(getParam<Point>("bounding_box_padding")), _bounding_box_padding(getParam<Point>("bounding_box_padding")),
_max_procs_per_app(getParam<unsigned int>("max_procs_per_app")), _max_procs_per_app(getParam<unsigned int>("max_procs_per_app")),
_output_in_position(getParam<bool>("output_in_position")), _output_in_position(getParam<bool>("output_in_position")),
_global_time_offset(getParam<Real>("global_time_offset")),
_reset_time(getParam<Real>("reset_time")), _reset_time(getParam<Real>("reset_time")),
_reset_apps(getParam<std::vector<unsigned int>>("reset_apps")), _reset_apps(getParam<std::vector<unsigned int>>("reset_apps")),
_reset_happened(false), _reset_happened(false),
Expand Down Expand Up @@ -229,7 +235,7 @@ MultiApp::initialSetup()
_app_type, getParam<std::string>("library_path"), getParam<std::string>("library_name")); _app_type, getParam<std::string>("library_path"), getParam<std::string>("library_name"));


for (unsigned int i = 0; i < _my_num_apps; i++) for (unsigned int i = 0; i < _my_num_apps; i++)
createApp(i, _app.getGlobalTimeOffset()); createApp(i, _global_time_offset);
} }


void void
Expand Down
41 changes: 29 additions & 12 deletions framework/src/multiapps/TransientMultiApp.C
Expand Up @@ -110,27 +110,38 @@ TransientMultiApp::TransientMultiApp(const InputParameters & parameters)
{ {
// Transfer interpolation only makes sense for sub-cycling solves // Transfer interpolation only makes sense for sub-cycling solves
if (_interpolate_transfers && !_sub_cycling) if (_interpolate_transfers && !_sub_cycling)
mooseError("MultiApp ", paramError("interpolate_transfers",
"MultiApp ",
name(), name(),
" is set to interpolate_transfers but is not sub_cycling! That is not valid!"); " is set to interpolate_transfers but is not sub_cycling! That is not valid!");


// Subcycling overrides catch up, we don't want to confuse users by allowing them to set both. // Subcycling overrides catch up, we don't want to confuse users by allowing them to set both.
if (_sub_cycling && _catch_up) if (_sub_cycling && _catch_up)
mooseError("MultiApp ", paramError("catch_up",
"MultiApp ",
name(), name(),
" sub_cycling and catch_up cannot both be set to true simultaneously."); " \"sub_cycling\" and \"catch_up\" cannot both be set to true simultaneously.");


if (_sub_cycling && _keep_solution_during_restore) if (_sub_cycling && _keep_solution_during_restore)
mooseError("In MultiApp ", paramError("keep_solution_during_restore",
"In MultiApp ",
name(), name(),
" it doesn't make any sense to keep a solution during restore when doing " " it doesn't make any sense to keep a solution during restore when doing "
"sub_cycling. Consider trying catch_up steps instead"); "sub_cycling. Consider trying \"catch_up\" steps instead");


if (!_catch_up && _keep_solution_during_restore) if (!_catch_up && _keep_solution_during_restore)
mooseError("In MultiApp ", paramError("keep_solution_during_restore",
"In MultiApp ",
name(), name(),
" `keep_solution_during_restore` requires `catch_up = true`. Either disable " " \"keep_solution_during_restore\" requires \"catch_up = true\". Either disable "
"`keep_solution_during_restart` or set `catch_up = true`"); "\"keep_solution_during_restart\" or set \"catch_up = true\"");

if (_sub_cycling && _tolerate_failure)
paramInfo("tolerate_failure",
"In MultiApp ",
name(),
" both \"sub_cycling\" and \"tolerate_failure\" are set to true. \"tolerate_failure\""
" will be ignored.");
} }


NumericVector<Number> & NumericVector<Number> &
Expand Down Expand Up @@ -220,7 +231,6 @@ TransientMultiApp::solveStep(Real dt, Real target_time, bool auto_advance)


for (unsigned int i = 0; i < _my_num_apps; i++) for (unsigned int i = 0; i < _my_num_apps; i++)
{ {

FEProblemBase & problem = appProblemBase(_first_local_app + i); FEProblemBase & problem = appProblemBase(_first_local_app + i);


Transient * ex = _transient_executioners[i]; Transient * ex = _transient_executioners[i];
Expand Down Expand Up @@ -441,7 +451,7 @@ TransientMultiApp::solveStep(Real dt, Real target_time, bool auto_advance)
} }
} }
} }
else else // auto_advance == false
{ {
if (!ex->lastSolveConverged()) if (!ex->lastSolveConverged())
{ {
Expand Down Expand Up @@ -520,14 +530,21 @@ TransientMultiApp::solveStep(Real dt, Real target_time, bool auto_advance)
} }


void void
TransientMultiApp::incrementTStep() TransientMultiApp::incrementTStep(Real target_time)
{ {
if (!_sub_cycling) if (!_sub_cycling)
{ {
for (unsigned int i = 0; i < _my_num_apps; i++) for (unsigned int i = 0; i < _my_num_apps; i++)
{ {
Transient * ex = _transient_executioners[i]; Transient * ex = _transient_executioners[i];
ex->incrementStepOrReject();
// The App might have a different local time from the rest of the problem
Real app_time_offset = _apps[i]->getGlobalTimeOffset();

// Only increment the step if we are after (target_time) the
// start_time (app_time_offset) of this sub_app.
if (app_time_offset < target_time)
ex->incrementStepOrReject();
} }
} }
} }
Expand Down
2 changes: 1 addition & 1 deletion framework/src/problems/FEProblemBase.C
Expand Up @@ -3608,7 +3608,7 @@ FEProblemBase::incrementMultiAppTStep(ExecFlagType type)


if (multi_apps.size()) if (multi_apps.size())
for (const auto & multi_app : multi_apps) for (const auto & multi_app : multi_apps)
multi_app->incrementTStep(); multi_app->incrementTStep(_time);
} }


void void
Expand Down
Expand Up @@ -31,8 +31,6 @@ class LevelSetReinitializationMultiApp : public MultiApp
LevelSetReinitializationMultiApp(const InputParameters & parameters); LevelSetReinitializationMultiApp(const InputParameters & parameters);


virtual void initialSetup() override; virtual void initialSetup() override;
virtual void incrementTStep() override {}
virtual void finishStep() override {}
virtual bool solveStep(Real dt, Real target_time, bool auto_advance = true) override; virtual bool solveStep(Real dt, Real target_time, bool auto_advance = true) override;


protected: protected:
Expand Down
27 changes: 26 additions & 1 deletion test/tests/multiapps/check_error/tests
@@ -1,56 +1,81 @@
[Tests] [Tests]
design = "MultiApps/index.md"
[./input_file] [./input_file]
type = 'RunException' type = 'RunException'
input = 'check_error.i' input = 'check_error.i'
expect_err = 'missing required parameter' expect_err = 'missing required parameter'

issues = "#4101 #4113"
requirement = "The system shall detect input file problems with sub app input files."
[../] [../]


[./unused_subapp_param] [./unused_subapp_param]
type = 'RunException' type = 'RunException'
input = 'check_error.i' input = 'check_error.i'
cli_args = 'MultiApps/multi/input_files="sub_unused.i"' cli_args = 'MultiApps/multi/input_files="sub_unused.i"'
expect_err = 'unused parameter' expect_err = 'unused parameter'

issues = "#4101 #4113"
requirement = "The system shall CLI argument problems related to sub app input files."
[../] [../]


[./positions] [./positions]
type = 'RunException' type = 'RunException'
input = 'check_error.i' input = 'check_error.i'
expect_err = 'Not enough positions for the number of input files' expect_err = 'Not enough positions for the number of input files'
cli_args = 'MultiApps/multi/input_files="sub1.i sub2.i"' cli_args = 'MultiApps/multi/input_files="sub1.i sub2.i"'

issues = "#1845 #3556 #5784"
requirement = "The system show error when the number of input files is great than one and doesn't match the number of provided sub app positions."
[../] [../]


[./not_enough_positions] [./not_enough_positions]
type = 'RunException' type = 'RunException'
input = 'check_error.i' input = 'check_error.i'
expect_err = 'Not enough positions for the number of input files' expect_err = 'Not enough positions for the number of input files'
cli_args = 'MultiApps/multi/input_files="sub1.i sub2.i" MultiApps/multi/positions="0 1 0"' cli_args = 'MultiApps/multi/input_files="sub1.i sub2.i" MultiApps/multi/positions="0 1 0"'

issues = "#1845 #3556 #5784"
requirement = "The system show error when the number of input files is great than one and doesn't match the number of provided sub app positions when using CLI overrides."
[../] [../]


[./not_enough_position_files] [./not_enough_position_files]
type = 'RunException' type = 'RunException'
input = 'check_error.i' input = 'check_error.i'
expect_err = 'Number of input_files for MultiApp' expect_err = 'Number of input_files for MultiApp'
cli_args = 'MultiApps/multi/input_files="sub1.i sub2.i" MultiApps/multi/positions_file="position1"' cli_args = 'MultiApps/multi/input_files="sub1.i sub2.i" MultiApps/multi/positions_file="position1"'

issues = "#1845 #3556 #5784"
requirement = "The system shall error when the number of sub app input files doesn't match the number of provided positions files."
[../] [../]


[./both_positions] [./both_positions]
type = 'RunException' type = 'RunException'
input = 'check_error.i' input = 'check_error.i'
expect_err = 'Both \'positions\' and \'positions_file\' cannot be specified simultaneously in MultiApp' expect_err = 'Both \'positions\' and \'positions_file\' cannot be specified simultaneously in MultiApp'
cli_args = 'MultiApps/multi/input_files="sub1.i sub2.i" MultiApps/multi/positions="0 1 0" MultiApps/multi/positions_file="position1"' cli_args = 'MultiApps/multi/input_files="sub1.i sub2.i" MultiApps/multi/positions="0 1 0" MultiApps/multi/positions_file="position1"'

issues = "#1845 #3556 #5784"
requirement = "The system shall error when both positions are provided in the input file along with a separate file of positions."
[../] [../]


[./bad_positions] [./bad_positions]
type = 'RunException' type = 'RunException'
input = 'check_error.i' input = 'check_error.i'
expect_err = 'Number of entries in \'positions_file\'' expect_err = 'Number of entries in \'positions_file\''
cli_args = 'MultiApps/multi/input_files="sub1.i" MultiApps/multi/positions_file="bad_positions.txt"' cli_args = 'MultiApps/multi/input_files="sub1.i" MultiApps/multi/positions_file="bad_positions.txt"'

issues = "#1845 #3556 #5784"
requirement = "The system shall error when the multiapp positions file is malformed."
[../] [../]


[./sub_cycling_and_catch_up] [./sub_cycling_and_catch_up]
type = 'RunException' type = 'RunException'
input = 'check_error.i' input = 'check_error.i'
expect_err = 'sub_cycling and catch_up cannot both be set to true' expect_err = '"sub_cycling" and "catch_up" cannot both be set to true'
cli_args = 'MultiApps/multi/input_files="sub1.i" MultiApps/multi/positions="0 1 0" MultiApps/multi/sub_cycling=true MultiApps/multi/catch_up=true' cli_args = 'MultiApps/multi/input_files="sub1.i" MultiApps/multi/positions="0 1 0" MultiApps/multi/sub_cycling=true MultiApps/multi/catch_up=true'

issues = "#6127"
requirement = "The system shall error when the Multiapp parameter sub_cycling and catch_up are both set to true."
[../] [../]
[] []
Binary file not shown.
Binary file not shown.
Binary file not shown.
58 changes: 58 additions & 0 deletions test/tests/multiapps/time_offset/master.i
@@ -0,0 +1,58 @@
[Mesh]
type = GeneratedMesh
dim = 2
nx = 10
ny = 10
[]

[Variables]
[./u]
[../]
[]

[Kernels]
[./diff]
type = Diffusion
variable = u
[../]
[./td]
type = TimeDerivative
variable = u
[../]
[]

[BCs]
[./left]
type = DirichletBC
variable = u
boundary = left
value = 0
[../]
[./right]
type = DirichletBC
variable = u
boundary = right
value = 1
[../]
[]

[Executioner]
type = Transient
num_steps = 10
dt = 0.2

petsc_options_iname = '-pc_type -pc_hypre_type'
petsc_options_value = 'hypre boomeramg'
[]

[Outputs]
exodus = true
[]

[MultiApps]
[./sub_app]
type = TransientMultiApp
input_files = 'sub.i'
global_time_offset = 0.8
[../]
[]
50 changes: 50 additions & 0 deletions test/tests/multiapps/time_offset/sub.i
@@ -0,0 +1,50 @@
[Mesh]
type = GeneratedMesh
dim = 2
nx = 10
ny = 10
[]

[Variables]
[./u]
[../]
[]

[Kernels]
[./diff]
type = Diffusion
variable = u
[../]
[./td]
type = TimeDerivative
variable = u
[../]
[]

[BCs]
[./left]
type = DirichletBC
variable = u
boundary = left
value = 0
[../]
[./right]
type = DirichletBC
variable = u
boundary = right
value = 1
[../]
[]

[Executioner]
type = Transient
num_steps = 10
dt = 1 # This will be constrained by the master solve

petsc_options_iname = '-pc_type -pc_hypre_type'
petsc_options_value = 'hypre boomeramg'
[]

[Outputs]
exodus = true
[]
11 changes: 11 additions & 0 deletions test/tests/multiapps/time_offset/tests
@@ -0,0 +1,11 @@
[Tests]
[start_time]
type = Exodiff
input = master.i
exodiff = master_out_sub_app0.e

issues = #12755
requirement = "The system shall support a time offset between the master and a subapp when using the Multiapp system."
design = "TransientMultiApp.md"
[]
[]

0 comments on commit fd0f8e8

Please sign in to comment.