mdpiper / model-coupling-thoughts

Thoughts, examples of model coupling
MIT License
0 stars 0 forks source link

Time step length control? #1

Open langevin-usgs opened 5 years ago

langevin-usgs commented 5 years ago

What about something like this to allow models to have a say in the time step length? I know that you could also use setter and getters for the time step length, but I think that might need to be more formalized with dedicated methods.

#! /usr/bin/env python

model0.initialize()
model1.initialize()

time = model0.get_current_time()
end_time = model0.get_end_time()

while time < end_time:

    deltat0 = model0.get_preferred_timestep_length()
    deltat1 = model1.get_preferred_timestep_length()
    deltat = min(deltat0, deltat1)

    model0.set_timestep_length(deltat)
    model1.set_timestep_length(deltat)

    has_converged = False
    while has_converged is False:

        state1 = model1.get_value("some_state_variable")
        model0.set_value("some_state_variable", state1)
        model0.solve()

        state0 = model0.get_value("boundary_flows")
        model1.set_value("boundary_flows", state0)
        model1.solve()

        has_converged = check_convergence(model0, model1, convergence_criteria)

    model1.update()
    model0.update()

    time += deltat
mdpiper commented 5 years ago

@langevin-usgs Yup! This is where the BMI update_frac function can be used. For example:

#! /usr/bin/env python

model0.initialize()
model1.initialize()

time = model0.get_current_time()
end_time = model0.get_end_time()

while time < end_time:

    deltat0 = model0.get_preferred_timestep_length()
    deltat1 = model1.get_preferred_timestep_length()
    deltat = min(deltat0, deltat1)

    has_converged = False
    while has_converged is False:

        state1 = model1.get_value("some_state_variable")
        model0.set_value("some_state_variable", state1)
        model0.solve()

        state0 = model0.get_value("boundary_flows")
        model1.set_value("boundary_flows", state0)
        model1.solve()

        has_converged = check_convergence(model0, model1, convergence_criteria)

    model1.update_frac(deltat)
    model0.update_frac(deltat)

    time = model0.get_current_time()
mdpiper commented 5 years ago

@langevin-usgs @jdhughes-usgs Another wrinkle: if each model exposes its time step through BMI (making it what we call an "exchange item"), then we can use get_value and set_value with it. Above, this would change

deltat0 = model0.get_preferred_timestep_length()
deltat1 = model1.get_preferred_timestep_length()
deltat = min(deltat0, deltat1)

to

deltat0 = model0.get_value("time_step")
deltat1 = model1.get_value("time_step")
deltat = min(deltat0, deltat1)