Skip to content

Commit

Permalink
add sub-cycling capabilities to MultiApp closes #1880
Browse files Browse the repository at this point in the history
r17959
  • Loading branch information
friedmud authored and permcody committed Feb 14, 2014
1 parent 0b9b03d commit 23e1b80
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 5 deletions.
2 changes: 2 additions & 0 deletions framework/include/multiapps/TransientMultiApp.h
Expand Up @@ -50,6 +50,8 @@ class TransientMultiApp :

private:
std::vector<Transient *> _transient_executioners;

bool _sub_cycling;
};

#endif // TRANSIENTMULTIAPP_H
51 changes: 46 additions & 5 deletions framework/src/multiapps/TransientMultiApp.C
Expand Up @@ -23,13 +23,17 @@ InputParameters validParams<TransientMultiApp>()
{
InputParameters params = validParams<MultiApp>();
params += validParams<TransientInterface>();

params.addParam<bool>("sub_cycling", false, "Set to true to allow this MultiApp to take smaller timesteps than the rest of the simulation. More than one timestep will be performed for each 'master' timestep");

return params;
}


TransientMultiApp::TransientMultiApp(const std::string & name, InputParameters parameters):
MultiApp(name, parameters),
TransientInterface(parameters, name, "multiapps")
TransientInterface(parameters, name, "multiapps"),
_sub_cycling(getParam<bool>("sub_cycling"))
{
if(!_has_an_app)
return;
Expand Down Expand Up @@ -91,10 +95,44 @@ TransientMultiApp::solveStep()
for(unsigned int i=0; i<_my_num_apps; i++)
{
Transient * ex = _transient_executioners[i];
ex->takeStep(_dt);
if(!ex->lastSolveConverged())
mooseWarning(_name<<_first_local_app+i<<" failed to converge!"<<std::endl);
ex->endStep();

if(_sub_cycling)
{
// Get the dt this app wants to take
Real dt = ex->computeConstrainedDT();

// Divide the "master" dt by that
Real partial_steps = _dt / dt;

unsigned int num_steps = 0;

if(partial_steps-std::floor(partial_steps) <= 2.0e-14)
num_steps = std::floor(partial_steps);
else
num_steps = std::ceil(partial_steps);

// Split the master dt up into the number of steps (so we can hit the time perfectly)
dt = _dt / (Real)num_steps;

// Now do all of the solves we need
for(unsigned int i=0; i<num_steps; i++)
{
ex->takeStep(dt);

if(!ex->lastSolveConverged())
mooseWarning("While sub_cycling "<<_name<<_first_local_app+i<<" failed to converge!"<<std::endl);

ex->endStep();
}
}
else
{
ex->takeStep(_dt);

if(!ex->lastSolveConverged())
mooseWarning(_name<<_first_local_app+i<<" failed to converge!"<<std::endl);
ex->endStep();
}
}

// Swap back
Expand All @@ -106,6 +144,9 @@ TransientMultiApp::solveStep()
Real
TransientMultiApp::computeDT()
{
if(_sub_cycling) // Bow out of the timestep selection dance
return std::numeric_limits<Real>::max();

Real smallest_dt = std::numeric_limits<Real>::max();

if(_has_an_app)
Expand Down
Binary file not shown.
Binary file not shown.
64 changes: 64 additions & 0 deletions test/tests/multiapps/sub_cycling/master.i
@@ -0,0 +1,64 @@
[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 = 4
dt = 0.1
petsc_options = '-snes_mf_operator -ksp_monitor'
petsc_options_iname = '-pc_type -pc_hypre_type'
petsc_options_value = 'hypre boomeramg'
[]

[Output]
output_initial = true
exodus = true
perf_log = true
[]

[MultiApps]
[./sub]
type = TransientMultiApp
app_type = MooseTestApp
execute_on = timestep
positions = '0 0 0'
input_files = sub.i
sub_cycling = true
[../]
[]

53 changes: 53 additions & 0 deletions test/tests/multiapps/sub_cycling/sub.i
@@ -0,0 +1,53 @@
[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 = 4
dt = 0.01
petsc_options = '-snes_mf_operator -ksp_monitor'
petsc_options_iname = '-pc_type -pc_hypre_type'
petsc_options_value = 'hypre boomeramg'
[]

[Output]
output_initial = true
exodus = true
perf_log = true
[]

7 changes: 7 additions & 0 deletions test/tests/multiapps/sub_cycling/tests
@@ -0,0 +1,7 @@
[Tests]
[./test]
type = 'Exodiff'
input = 'master.i'
exodiff = 'master_out.e master_out_sub0.e'
[../]
[]

0 comments on commit 23e1b80

Please sign in to comment.