Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stepper System #8127

Closed
wants to merge 5 commits into from
Closed

Stepper System #8127

wants to merge 5 commits into from

Conversation

friedmud
Copy link
Contributor

@friedmud friedmud commented Nov 28, 2016

This PR aims to be a reimagining of #7849. I wanted to keep the core idea of #7849 (small algorithms feeding each other), but do it in a way that is familiar and natural within MOOSE. In addition to reusing some code by @rwcarlsen in #7849, I took inspiration from comments from @aeslaughter ( #7849 (comment) ) and @dschwen ( #7849 (comment) ) along with some of my own: #7849 (comment) and #7849 (comment) .

I had a few goals in mind as I crafted this PR:

  1. Each object should have a clear objective and that objective will be plain to see just by glancing at the code.
  2. Each object should have “meat”… keeping down the proliferation of tiny objects that do nothing.
  3. Expose useful objects to the users
  4. A single object should be enough for 80% of use-cases
  5. Combining two objects should be enough for 95% of use-cases
  6. The most common workflow should be a normal one for MOOSE: slight modification of existing algorithms
  7. Parameters should be passed through valid_params()
  8. Common data should be provided through inheritance
  9. Other data can be requested through interfaces (just like everywhere else in MOOSE)
  10. Data flow between objects should be done with “coupling” (just like everywhere else in MOOSE).
  11. A large amount of customization / flexibility should be available from the input by mixing/matching objects (just like everywhere else in MOOSE)
  12. Objects should be built by the Factory (like all other MOOSE objects)
  13. Objects should be stored in a Warehouse and make use of DependencyResolverInterface (like Materials, MeshModifiers, AuxKernels and many other things in MOOSE).

I believe I’ve met these objectives. The result is something fully MOOSE-like.

What I’ve arrived at uses a directed, acyclic graph (DAG) of small algorithms that feed dt through each other. These new objects are called Steppers. They are wholly separate from TimeSteppers (TimeSteppers will be deprecated and eventually removed). Steppers can consume dt from other Steppers by coupling to them (calling getStepperDT() through StepperInterface… like normal).

A large part of the complexity of #7849 came from the mechanism for combining algorithms: tiny “combiner” algorithms (some as small as a single if statement). To keep this out of my current design I’ve adopted a different information flow: “filtering”. dt is “produced” by some Steppers… while others take in that dt and “filter” it (often constraining it). A graph of these produces the final DT.

This means that Steppers can generally be broken into two categories: Producers and Filters. There is no actual distinction in the API (some Steppers can be both). Here are some examples of each:

Producers:

  • SimpleStepper (essentially what used to be ConstantDT)
  • ConstantStepper (actually constant! Errors out if a solve fails!)
  • IterationAdaptiveStepper (the key adaptivity algorithm from IterationAdaptiveDT that @rwcarlsen pulled out in Refactoring and cleaning up time steppers #7849)
  • PiecewiseStepper (similar to the old FunctionDT - which didn’t use a Function!)
  • PostprocessorStepper

Filters:

  • LimitStepper (enforce min/max)
  • FixedTimesStepper (enforces that particular times are hit exactly)
  • KnotTimesStepper (force dt at partcular times)
  • etc.

(BTW: I’m open to changing these names… let’s try to get them right while we have the chance!)

(Note: I would like to make it clear that much of the code that ended up in these Steppers came from @rwcarlsen in #7849. Like I said: there was some really good code in there... just wrapped up in the wrong implementation).

Using these it’s simple to dial up many of the things our users have asked for over the years. For instance, you can now use the normal time stepper (SimpleStepper) but choose a few points in time to hit perfectly:

[Executioner]
  [./Steppers]
    [./simple]
      type = SimpleStepper
      dt = 1
    [../]
    [./fixed]
      type = FixedTimesStepper
      incoming_stepper = simple
      times = '2.23 4.79 7.12' # This will ensure that these times are hit perfectly
    [../]
  [../]
[]

This used to only be possible using the Output system’s “sync times” or by abusing IterationAdaptiveDT. It’s now really straightforward to do right in the input file. This is how I believe 99% of our users will interact with the system. They will pick a “Producer” that is close to what they want and then use “Filters” to tailor dt to their needs.

Speaking of IterationAdaptiveDT… it grew into an abomination… it was actually several timestepping algorithms smashed together (you could even turn off the adaptivity!). The only reason it existed like this is because, until now, users could only choose one object for dt computation. So, IterationAdaptiveDT just had more and more stuff thrown into it so that you could choose different combinations of algorithms. When most people used IterationAdaptiveDT they would use the core timestep adaptivity algorithm… and then typically select one more modifcation to that. This is now very simple to do in the new system so there is no need to have a massive stepper object like IterationAdaptiveDT.

For instance, what used to be:

  [./TimeStepper]
    type = IterationAdaptiveDT
    dt = 1.0
    optimal_iterations = 10
    time_t = '0.0, 5.0'
    time_dt = '1.0, 5.0'
  [../]

Is now:

  [./Steppers]
    [./adapt]
      type = IterationAdaptiveStepper
      dt = 1.0
      optimal_iterations = 10
    [../]
    [./knots]
      type = KnotTimesStepper
      incoming_stepper = adapt
      times = '0.0, 5.0'
      dts = '1.0, 5.0'
    [../]
  [../]

The IterationAdaptiveStepper is a “Producer” and then you can “Filter” it in any way you want to achieve your desired goal. While it seems there is a bit more to do... it's actually easier to use because the options for each object are greatly paired down instead of being confronted with a wall of (often contradictary) options like in IterationAdaptiveDT.

For instance, the iteration_adaptive/hit_function_knot test used to have this in it:

  [./TimeStepper]
    type = IterationAdaptiveDT
    dt = 0.9
    optimal_iterations = 10
    force_step_every_function_point = true
    max_function_change = 1e20
    timestep_limiting_function = knot
  [../]

It's actually abusing the IterationAdaptiveDT object to just solve at specific times. It now looks like this:

  [./Steppers]
    [./fixed]
      type = FixedTimesStepper
      times = '0 1 2'
    [../]
  [../]

Instead of abusing an object... you just dial up exactly what you want.

In addition, this way of working is perfectly MOOSE-like. For instance, mirroring the way MeshModifiers work one after another to produce the final mesh.

Inside of a Stepper things are also greatly simplified over what was in #7849. Instead of the mess in

StepperBlock * inner = BaseStepper::converged(BaseStepper::mult(_growth_factor, BaseStepper::ptr(&_last_dt)), BaseStepper::mult(0.5, BaseStepper::ptr(&_last_dt)));
we now have:

Real
SimpleStepper::computeDT()
{
  return _prev_dt = std::min(_input_dt, _growth_factor * _prev_dt);
}

So SimpleStepper can live up to its name!

There are still a few things left to do... but I'm out of time for now. Here are a few things:

  • More comments everywhere
  • More tests (maybe try to revive the unit tests from Refactoring and cleaning up time steppers #7849 ?)
  • Implement PredictorCorrectorStepper
  • Deprecate old TimeSteppers (start with ConstantDT being deprecated soon... then progress toward finally deprecating IterationAdaptiveDT
  • Switch over all input files that currently use TimeSteppers (I did a bunch, but I'm out of time)
  • Take a closer look at the backup() and restore() methods to make sure they are cleaning up old backups
  • Make some decisions on the interface for _dt in Steppers (right now access is just _dt[0]. Refactoring and cleaning up time steppers #7849 used a function which might be a good idea. I'm up for discussion.
  • Rename many of the member variables of Stepper to be more in line with MOOSE: i.e. _time->_t, etc.
  • Error checking for bad / missing coupling between Steppers (must be done by postprocessing the DAG due to late binding)
  • Take a hard look at where the Steppers are stored and where FEProblem::computeDT() are. They are currently in FEProblem but I could be swayed to put them in Transient.
  • Take a closer look at Transient::lastSolveConverged() and how convergence is found/stored in general. It's kind of a mess.
  • Codify the way coupling is checked for. Right now isParamValid() is being used... but we should really add StepperInterface::isStepperCoupled() or something similar.
  • Fully flesh out default coupling. Right now it simply returns numeric_limits::max()... which does the right thing for all of our current Steppers. However, we should allow the specification of default coupling (including the specification of incoming_stepper value right from the input file... just as with Postprocessors, Functions, etc.
  • Finish DT2Stepper::computeFailedDT()
  • Error check for multiple graph endpoints (i.e. multiple, distinct dts getting computed)
  • Take a look at SteperInfo... currently that data is duplicated in Transient and in FEProblem::_stepper_info. It should really only live in the object. Most likely that object needs to be restartable/recoverable.
  • Stepper member variables should be const references

I'll update this list as we generate more TODOs through discussion.

@friedmud
Copy link
Contributor Author

Oh man - I based this on @rwcarlsen 's branch... in the meantime the FEProblem shuffle went through... so there are mega merge conflicts. Let me see if I can fix 'em...

@friedmud friedmud force-pushed the stepper branch 3 times, most recently from 89932d2 to 8e1e009 Compare November 28, 2016 03:08
@friedmud
Copy link
Contributor Author

Epic rebase!

I ended up squashing all of @rwcarlsen 's commits down into one commit... and all of my commits down into one commit. Trying to rebase ~170 commits with FEProblemBase changing just wasn't happening.

As it was... I had to manually copy my FEProblem changes to FEProblemBase...

@aeslaughter
Copy link
Contributor

What about making the new steppers block stand-alone, outside the Executioner. I don't prefer the sub-blocks in general, I think the nested indentation and open/close getpot operators make the input file more cluttered.

[Executioner]
  stepper = foo
[]

[Steppers]
  [./foo]
    type = SimpleStepper
 [../]
[]

Other than this, I like the design. I haven't looked at the code yet.

@friedmud
Copy link
Contributor Author

@aeslaughter that sounds good to me. I had the same thought myself... but I ended up keeping it this way just for consistency with the old block.

Anyone else have an opinion on that?

@rwcarlsen
Copy link
Contributor

I like the ability to customize steppers in the input file. It is something I toyed with including my original PR, but ended up not adding because it seemed there was enough opposition I was hesitant to invest the time. Other than that, my (obviously biased) opinion is that this is not much of an improvement. But that ship has sailed. A few big-picture thoughts/questions from my first look (more to come later):

  • I agree with @aeslaughter on avoiding the block nesting.

  • I don't like pulling the converged/not handling away from steppers (i.e. separating the stepper interface into computeDT and computeFailedDT. It makes writing new steppers more confusing, and it is harder to follow control flow logic when looking at a stepper. I think things like mooseError("you can't not converge for constant dt") hint that it is probably not the best approach. I think it would be better to have the branching be a stepper layer.

  • The same goes for computeInitialDT - pull it into its own stepper layer rather than have it complicating the Stepper interface.

  • I really think it would be super valuable to keep unit testing. Unit tests could replace a lot of input-file tests that are terribly slow in comparison and provide much less targeted feedback about failures.

  • What is your plan for supporting canned pre-composed steppers? This doesn't seem to be addressed here.

  • What about error handling - when users specify more than one root producer (or none)? Just something to think about.

  • If you are just going to fan out StepperInfo's fields directly into Stepper, then there is no need for StepperInfo any more. It should either be a field on Stepper or should be eliminated.

  • I'd like to see many of the Stepper fields be const and private. Also, ones that have history feel better as functions for access (e.g. dt() instead of _dt[0]).

  • It looks like support for generic tree stepper composition has been removed - you can only create trees that have arbitrary branching underneath through one child. I can no longer have:

    A -> B
    A -> C
    B -> D
    B -> E
    C -> F
    C -> G

    Instead I am limited to:

    A -> B
    A -> C
    C -> D
    C -> E

    where B cannot have a sub-tree.

    While the description of this limitation is CS'y, in practice I think this will result in poorer stepper reuse and more difficult to follow stepping logic/behavior.

Copy link
Member

@permcody permcody left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking pretty good. Several minor comments.


protected:
/// The ExodusII file that is being read
std::string _mesh_file;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -101,7 +108,7 @@ Transient::Transient(const InputParameters & parameters) :
_at_sync_point(declareRecoverableData<bool>("at_sync_point", false)),
_first(declareRecoverableData<bool>("first", true)),
_multiapps_converged(declareRecoverableData<bool>("multiapps_converged", true)),
_last_solve_converged(declareRecoverableData<bool>("last_solve_converged", true)),
_last_solve_converged(/*declareRecoverableData<bool>("last_solve_converged", */true/*)*/),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

formatting

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually need to remove the dead code there too. Good catch.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

auto & steppers = stepper_warehouse.getActiveObjects();

// Grab the output name for the last one
auto last_name = steppers.back()->outputName();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably should assert here. Yes, I know we call init above but it's just smart to be defensive in case something changes in the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

auto params = _app.getFactory().getValidParams("LimitStepper");
params.set<StepperName>("incoming_stepper") = last_name;
_console<<"dtMin(): "<<dtMin()<<std::endl;
_console<<"dtMax(): "<<dtMax()<<std::endl;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spacing around binary operators.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those are actually print statements that should come out anyway!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


ConstantStepper::~ConstantStepper()
{
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's get in the habit of dropping empty dtors in non-base classes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do - I meant to remove all of these. I'm not sure why they crept into my code here... they just came from whatever MooseObject I happen to copy from to create the first Stepper ;-)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

#define KNOTTIMESSTEPPER_H

#include "Stepper.h"
#include "LinearInterpolation.h"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move to .C file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

#define LIMITSTEPPER_H

#include "Stepper.h"
#include "LinearInterpolation.h"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move to .C file

#define POSTPROCESSORSTEPPER_H

#include "Stepper.h"
#include "LinearInterpolation.h"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move to .C file

const Real & _input_dt;

/// Number of steps in the same direction
int _n_steps;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably should be unsigned unless that causes a sign issue later in computation.

@@ -0,0 +1,113 @@
#ifndef STEPPERINFO_H
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing Header

@friedmud
Copy link
Contributor Author

I agree with @aeslaughter on avoiding the block nesting.

I think I do too.

I don't like pulling the converged/not handling away from steppers (i.e. separating the stepper interface into computeDT and computeFailedDT. It makes writing new steppers more confusing, and it is harder to follow control flow logic when looking at a stepper. I think things like mooseError("you can't not converge for constant dt") hint that it is probably not the best approach. I think it would be better to have the branching be a stepper layer.
The same goes for computeInitialDT - pull it into its own stepper layer rather than have it complicating the Stepper interface.

I completely disagree with this. Checking for convergence... and for initial are both somewhat complicated subjects. It's not something Steppers should be doing... nor is it something we want spread through user code. We want it in one place (like it is in this PR) so that we can change it internally as we refactor things (like the Executioners) and the Stepper code is completely agnostic to those changes.

In addition... all of the converged() checks in your PR generated the most mess. Because of your composition you had to generate the same values twice down multiple branches and then tie them back together. It was messy and hard to follow. By having very explicit virtual functions that do one thing and do it well... things are more clear. Not too mention that this is similar to how TimeSteppers were originally so the interface is familiar.

This also allowed for removing most of the "branching" that was present in your PR. If we're computing "initial" DT we don't need to go through a whole huge graph of composed objects... we just need to go straight down the "initial" branch... which is what this does without all of the complication on the user's end. Just compare the number of objects that need to be created in this PR and yours...

I think things like mooseError("you can't not converge for constant dt") hint that it is probably not the best approach.

No - this is not a not implemented! or something like that... it's an actual error for a condition that needs to be checked. Even in your system you would have to have a convergence check and throw an error here.

I really think it would be super valuable to keep unit testing. Unit tests could replace a lot of input-file tests that are terribly slow in comparison and provide much less targeted feedback about failures.

Unit testing is good when possible... and I think it should be doable here. Just need to create an FEProblem and fill up StepperInfo and call FEProblem::computeDT(). You can see that this is on my TODO list above.

What is your plan for supporting canned pre-composed steppers? This doesn't seem to be addressed here.

It is already addressed. You can see it in action here: https://github.com/idaholab/moose/pull/8127/files#diff-206dbf39c28026b828236e2cf0e33314R44

That said: we shouldn't do it much. It should only be done when it would be SUPER inconvenient to put multiple blocks in the input file. For instance, the KnotTimesStepper I just linked to takes a list of times. We want to enforce that those times are perfectly hit so we want to use a FixedTimesStepper to do that. However: doing it with two blocks in the input file would be incredibly inconvenient because you would need to have a complete copy of the times list in each block. By creating a sub-Stepper like this it is automatic.

What about error handling - when users specify more than one root producer (or none)? Just something to think about.

The "no root producer" case is not possible. All of the pure "filtering" steppers have required parameters for the Stepper they couple to... so if you try to just provide a filter you will get an immediate error from the parser.

Multiple root producers is perfectly fine... the actual check should be about multiple endpoints. I'll add that to the TODO list. @permcody can the DependencyResolver do this automatically?

If you are just going to fan out StepperInfo's fields directly into Stepper, then there is no need for StepperInfo any more. It should either be a field on Stepper or should be eliminated.

Not true. All of the Steppers need to reference the same data. That data has to live somewhere. It's better to have it in a StepperInfo object than to put that data directly into FEProblem. If we were going to eliminate something I would say eliminate the info from Transient. I'll add that to the TODO.

I'd like to see many of the Stepper fields be const and private.

I agree. I'll add it to the TODO

Also, ones that have history feel better as functions for access (e.g. dt() instead of _dt[0]).

Yeah - I have this in my TODO above. I would actually like to make dt have: _dt, _dt_old and _dt_older to mirror how things are done elsewhere. But I don't have a really strong feeling for that.

It looks like support for generic tree stepper composition has been removed - you can only create trees that have arbitrary branching underneath through one child. I can no longer have:

A -> B
A -> C
B -> D
B -> E
C -> F
C -> G

Instead I am limited to:

A -> B
A -> C
C -> D
C -> E

where B cannot have a sub-tree.

I don't understand your graphs. It looks like you have multiple endpoints... that means multiple, independent, dts will be produced. That doesn't make any sense. Maybe your arrow are backwards from the arrows in my mind? Are you drawing them as "A -> B" means "A depends-on B" or as "A provides-to B"? (The latter one is how I'm thinking of it).

It doesn't matter though. This PR allows you to create any tree structure you want. You can have multiple producers each with their own filters and then tie them back together through a final filter if you want. Steppers can couple in as many Steppers as you like... so anything is possible.

It's actually much more flexible that your composition system. In your system you had to often compute things twice because you need to use the same values down multiple branches.

For instance:

https://github.com/rwcarlsen/moose/blob/f514a3a567404c9dfe88840e3da997a53aa2e799/framework/src/timesteppers/ConstantDT.C#L41

and

https://github.com/rwcarlsen/moose/blob/f514a3a567404c9dfe88840e3da997a53aa2e799/framework/src/timesteppers/FunctionDT.C#L46

In this system... since it's a graph one node can be consumed by multiple other nodes. So you can have a producer that you filter in two different ways and then tie the results back together at the end.

BTW: This is all theoretical because none of our current Steppers require anything like this. By eliminating all of the converged() checking and doing min() inside the filters it completely straightened out a lot of the branching... leading to MUCH simpler flow. Just look at how many objects your Steppers had to use to get something done vs the one or two that are now used in this PR.

Copy link
Contributor Author

@friedmud friedmud left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't mean to start a review...

Real
DT2Stepper::computeFailedDT()
{
// This isn't complete
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means that I haven't tested the failure modes of DT2 yet. I need to make sure that it unwraps properly if you fail in each of the 3 different solves. I'll add that to the TODO.

@rwcarlsen
Copy link
Contributor

rwcarlsen commented Nov 28, 2016 via email

@friedmud
Copy link
Contributor Author

Yes - this was a weakness of my approach that I wasn't fond of - but in
reality I would expect this code to be so far from a "hot spot" that it
probablly wouldn't matter much in practice.

Not a performance issue (although, theoretically it could be, or it could even be a memory issue if you had to read in a large data structure (like an Exodus file) in multiple branches). Mostly: it just makes things more complicated than they need to be. Our users would have to actually think about how they would need to generate multiple copies of values to pass down different different branches... yuck.

I guess you would say it's a "code smell" 😄

The flip side though is that steppers need to be coded carefully so that they can correctly handle being called multiple times for the single simulation dt computation.

Not in this PR. Every Stepper is only called once... no matter how many times their output value is consumed.

@permcody
Copy link
Member

Multiple root producers is perfectly fine... the actual check should be about multiple endpoints. I'll > add that to the TODO list. @permcody can the DependencyResolver do this automatically?

The DependencyResolver can handle any acyclic directed graph. There is no limitation on the structure of the vertices and edges in that graph. There can be many possible valid orderings for a given graph, but that's just fine.

@rwcarlsen
Copy link
Contributor

rwcarlsen commented Nov 28, 2016

The flip side though is that steppers need to be coded carefully so that they can correctly handle being called multiple times for the single simulation dt computation.

Not in this PR. Every Stepper is only called once... no matter how many times their output value is consumed.

Right [facepalm] - not sure what I was thinking when I wrote that...

@friedmud
Copy link
Contributor Author

It still isn't clear to me how the min() is implemented/used - could you
elaborate a bit on this?

The min() is simply inside the filters. No need to add another node to the graph.

For instance... look at FixedTimesStepper: https://github.com/idaholab/moose/pull/8127/files#diff-7a00209a3eaa5f5c309cd0de9e937a57R54

In your system you would have had two branches and tied them back together with a MinOf node. I've eliminated the MinOf node. In general I prefer writing C++ instead of linking together tiny objects. It is clearer for our intended audience (and for us as well) and simplifies the graph by a lot.

@rwcarlsen
Copy link
Contributor

This doesn't replace current time-stepper implementations - it just provides a new architecture along side. I think it would really help the executioner refactoring effort (regardless of who does it) if we didn't have to tip-toe around the existing time stepper implementations. Just my 2 bits.

@friedmud
Copy link
Contributor Author

This doesn't replace current time-stepper implementations - it just provides a new architecture along side. I think it would really help the executioner refactoring effort (regardless of who does it) if we didn't have to tip-toe around the existing time stepper implementations. Just my 2 bits.

I haven't removed the current TimeStepper yet. There will be a deprecation period (a short one for some of them, sightly longer for others) where we get people to change their inout files over to the new system. We will also quickly add in a legacy_timestepper option that we will default to false so that no new Stork-based apps ever see the old systrm at all.

The Executioner refactor will take way longer than the deprecation period. It's not even clear that we are going to do an executioner refactor right now. But that's a conversation for a different thread.

@permcody
Copy link
Member

permcody commented Nov 28, 2016 via email

@friedmud
Copy link
Contributor Author

I think I would rather delete it then comment it out... it will be a pretty large chunk of commented code. We can always resurrect it later...

@dschwen
Copy link
Member

dschwen commented Nov 28, 2016

Atom grays out #if 0 blocks like comments... just sayin' ;-)

friedmud added a commit to friedmud/moose that referenced this pull request Nov 28, 2016
@tonkmr
Copy link
Contributor

tonkmr commented Nov 29, 2016

How hard would it be to work in adaptive time stepping based on integration error estimators into this system?

@friedmud
Copy link
Contributor Author

Very easy I would think. I mean: the DT2Stepper is already doing something like that, right?

The great part about this new system is that you can code up your adaptive time stepping scheme... and then easily combine it with several others. For instance, from the input file, you can add your adaptive Stepper and then also add a FixedTimesStepper to force the timesteps to hit some times perfectly. This new system really makes it easy to tweak time stepping to achieve your goals.

@friedmud
Copy link
Contributor Author

friedmud commented Feb 5, 2017

Ok - rebased this and repushed it. Let's see what the testing system says about it...

@friedmud
Copy link
Contributor Author

friedmud commented Feb 5, 2017

@permcody Ok - the only thing that is failing is 2 tests in Yak. I'm taking a look at it now to see if I can spot the issue.

That said: Everything is not using the new system yet. With this PR I left the old system so we can transition. A bigger task is to work through all of the input files and switch them over to the new system and get them working, etc.

I'm really not going to have time to do that... that's going to have to be an ongoing effort for a while.

We definitely can make it so that when you try to use the old system it actually invokes the new one. I've held off on that for now because I want to give us time to do more testing... but eventually it will be the right thing to do (for a while, until we remove the old syntax all together).

@friedmud
Copy link
Contributor Author

friedmud commented Feb 5, 2017

@YaqiWang I just looked at those tests... and the new behavior looks to be more correct than the old behavior!

For instance: in actions/neutron_saaf_pn_cfem.dt2_transient_action_test you have dt = 0.01... but your gold file takes a step of 0.005 for the first timestep! (which doesn't make any sense). With this PR the simulation takes an initial timestep of 0.01 like it should.

Can you take a look at those couple of tests that are failing here and either regold them... or, if you think they are right like they are, tell me why?

Thanks!

@YaqiWang
Copy link
Contributor

YaqiWang commented Feb 6, 2017

I know I am not sure if the gold file are correct or not with the old DT2. We can disable it for now. DT2 implementation needs to be verified anyway.

@permcody
Copy link
Member

permcody commented Feb 6, 2017

@YaqiWang - If you are willing to disable them, let's go with that. Then we can review this PR and get it merged.

@YaqiWang
Copy link
Contributor

YaqiWang commented Feb 6, 2017

OK, a MR is sent in Yak. BTW, the other failing test is due to file naming conflict. It is irrelevant with this PR. It should have been fixed.

@moosebuild
Copy link
Contributor

Job App tests:linux-gnu on 04181c8 : invalidated by @YaqiWang

Retest after a bug fix and disabling DT2 test

@permcody
Copy link
Member

permcody commented Feb 8, 2017

@idaholab/moose-team - ready for review...

@moosebuild
Copy link
Contributor

Job Precheck:linux-gnu on 04181c8 : invalidated by @rwcarlsen

permcody pushed a commit to permcody/moose that referenced this pull request Feb 15, 2017
permcody pushed a commit to permcody/moose that referenced this pull request Feb 15, 2017
@permcody
Copy link
Member

Migrating to #8554.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants