thetisproject / thetis

Finite element flow solver for simulating coastal and estuarine flows.
Other
68 stars 28 forks source link

Allow single timestep control over Thetis run #368

Open stephankramer opened 3 months ago

stephankramer commented 3 months ago

This issue has come up coupling Thetis to a goal-based mesh-adaptivity framework goalie but would equally be important coupling Thetis to other models via a coupling framework: Thetis only provides per timestep control via callbacks, which keeps Thetis in charge of runtime, and does not cater for an external framework to request a single timestep to be performed.

Two potential implementations that I can think of:

  1. Simply separate the timestep code into a separate (user callable) method
  2. Use a generator approach. So change the current code

    def iterate(self, ...):
       <prep-stuff>
       while t<t_end:
           <timestep-code>

    to either 1:

    def advance(self):
        <timestep-code>
    
    def prep-stuff(self):
       <prep_stuff>
    
    def iterate(self, ...):
      self.prep_stuff()
       while t<t_end:
          self.advance()

    or 2:

    def iterate(self, ...):
        for t in self.generator(...):
             pass
    
    def generator(self, ...):
       <prep-stuff>
       while t<t_end:
          <timestep-code>
          yield t

    where in both cases the user can use solver_obj.iterate() in exactly the same way as before.

To get per time-step control, in case 1, the user (coupling framework) would have to do three things

    solver_obj.prep_stuff()
    while t<t_end:  # i.e. repeat the timestep logic
        solver_obj.advance()
        # user code

whereas in case 2, that would simply be:

   for t in solver_obj.generator():
        # user code

or if there's some further logic, or other looping requirements:

   thetis_timestepper = solver_obj.generator()
   while t_Thetis<t_end and .... :
      t_Thetis = thetis_timestepper.next()

So at the moment I'm inclined to go for option 2.

thangel commented 3 months ago

The work of @fragkouan should be useful here - sometimes a few iteration have to take place between coupling https://github.com/fragkouan/thetis_wci/blob/138b2204c8fa3aea4ddda383168d17b0384146ee/thetis/solver2d.py#L1063