enrico-dev / enrico

ENRICO: Exascale Nuclear Reactor Investigative COde
https://enrico-docs.readthedocs.io
BSD 3-Clause "New" or "Revised" License
63 stars 26 forks source link

Allow fission source to be re-used from last Picard iteration #11

Open paulromano opened 5 years ago

paulromano commented 5 years ago

Moving issue 24 from gitlab originally submitted by @aprilnovak:

Convergence can be improved if the fission source in iteration i+1 is taken from iteration i. The CoupledDriver currently calls the following OpenMC functions, in this order:

  1. openmc_simulation_init: initialization stuff to be performed once per multiphysics solve; openmc_reset(); initialize_source()
  2. openmc_run: loop over batches
  3. openmc_statepoint_write()
  4. openmc_simulation_finalize(): finalization stuff to be performed once per multiphysics solve; write tally results.

From my understanding, this means that we're doing a lot of duplicate work for each Picard iteration that we could reduce by dividing openmc_simulation_init and openmc_simulation_finalize into smaller functions that perform tasks needed once per multiphysics solve (like initializing the source, if we want to re-use it between Picard iterations) and once per iteration (like resetting tallies).

paulromano commented 5 years ago

Comment by @aprilnovak:

@paulromano, what do you think about adding a new method to OpenMC, called something like openmc_simulation_reset() that performs actions needed at the start of each Picard iteration? OpenmcDriver::init_step() would call openmc_simulation_reset() instead of openmc_simulation_init(), which would be moved to the constructor.

Then, openmc_simulation_finalize() would be moved from OpenmcDriver::finalize_step() to the destructor?

Or, because openmc_simulation_init() and openmc_simulation_finalize() are only called from openmc_run(), we can move some functionalities from them to openmc_init()/openmc_finalize() so that the methods with simulation in their name are interpreted as actions to do once per Picard iteration, while those without simulation are interpreted as actions to do once per coupled physics solve.

paulromano commented 5 years ago

There is meaning attached to the simulation functions right now -- generally speaking they allocate / reset / deallocate global variables that are only using during the simulation. We denote these variables by the openmc::simulation:: namespace in OpenMC, which includes things like:

So, I don't think moving anything there to openmc_init or openmc_finalize is the right solution, but I like the idea of something a little finer-grained that gives the user explicitly control over what they want to happen between iterations. Right now, there's actually very little we'd need to change to use the source distribution from the previous iteration because openmc_simulation_finalize doesn't actually get rid of it right now. The only problem is that openmc_simulation_init always resamples a source. I think introducing openmc_simulation_reset is probably what we want, but we should spec this out to make sure we're covering all use cases.