climt
climt copied to clipboard
The ability to use different state values in different modules
- CliMT version: 0.16.3
- Python version: 3.6.5
- Operating System: OSx
Description
Per Joy's request: I am trying to run a one-dimensional model that holds fixed the radiative properties of atmospheric water vapor. I've hacked a way to do it by creating two separate Adams-Bashforth tendency steppers, one for the radiative modules and one for the rest. In the radiative stepper, I prescribe a constant humidity profile at every step, whereas for the other stepper I allow the humidity to evolve. But if there were some wrapper or another method of being able to do this that were as easy as "humidity.rad=constant", that would help expand the innate capabilities of CliMT.
What I Did
time_stepper_phys = AdamsBashforth([slab, moist_convection])
time_stepper_rad = AdamsBashforth([radiation_lw, radiation_sw])
# Day length to match Shanshan
run_days = 10950
run_length = int((run_days * 24 * 60) / dt_minutes)
for i in range(run_length):
rad_state_fixed_q = copy.deepcopy(state)
phys_unfixed_q = rad_state_fixed_q['specific_humidity'].values[:].copy()
rad_state_fixed_q['specific_humidity'].values[:] = control_q.copy()
diagnostics, state = time_stepper_rad(rad_state_fixed_q, timestep)
state['specific_humidity'].values[:] = phys_unfixed_q.copy()
state.update(diagnostics)
You could do this by creating a FixedInputWrapper
which wraps a component and sets pre-specified inputs to constant value. It would look something like (untested):
class FixedInputWrapper(object):
def __init__(self, wrapped_component, fixed_state):
self._component = wrapped_component
self._fixed_state = fixed_state
@property
def input_properties(self):
return_dict = {}
for name, properties in self._component.input_properties:
if name not in self._fixed_state:
return_dict[name] = properties
return return_dict
def __getattr__(self, item):
return getattr(self._component, item)
def __call__(self, state, *args, **kwargs):
state.update(self._fixed_state)
return self._component(state, *args, **kwargs)
You would use it like:
fixed_state = {
'specific_humidity': initial_state['specific_humidity'],
}
radiation = FixedInputWrapper(RRTM(), fixed_state)
radiation_stepper = AdamsBashforth(radiation)
After that, you could use the radiation_stepper
as normal, and it will always use the fixed array as input.
Note that you really want to just fix the humidity as input for the TendencyComponent
and not for the Stepper
, because otherwise the stepper will output the fixed humidity as the humidity for the next time step. Doing it with a wrapper on a TendencyComponent
like above will make it so the radiative heating is computed with fixed humidity, but the humidity in the prognostic state will not be over-written.
It would be more appropriate to contribute this wrapper upstream into Sympl than into CliMT, but it's also fine to just have as an external example wrapper a user can put into their code.
Yes, this should find its way to sympl eventually.
Thank you @mcgibbon , that sounds very helpful.
Do you or @JoyMonteiro think that there could be a problem with how I structured my code to try and get the desired effect?
Just as a check, I can try the TendencyComponent approach and see if the results are any different than my script.
I have been thinking about this, and there will be a difference if you use two timesteppers instead of a wrapper like @mcgibbon suggested.
This is because the input state to the second timestepper is the output of the first one. Thus, some components see a different model state than the convection scheme.
I don't think this should be a huge issue, however. You should verify that the model output seems scientifically sensible.
Thanks, Joy. I'll give both runs a try and see if any differences result. Hope your paper worries are over or near-over for the time being!
I would love to talk with you sometime soon about the code, just so I can get a firm understanding on everything we've discussed. Let me know if you're available.
Best wishes, Haynes
On Thu, Nov 7, 2019 at 10:21 PM JoyMonteiro [email protected] wrote:
I have been thinking about this, and there will be a difference if you use two timesteppers instead of a wrapper like @mcgibbon https://github.com/mcgibbon suggested.
This is because the input state to the second timestepper is the output of the first one. Thus, some components see a different model state than the convection scheme.
I don't think this should be a huge issue, however. You should verify that the model output seems scientifically sensible.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/CliMT/climt/issues/115?email_source=notifications&email_token=AEOYOYGNTMXQRTZ76BKSSCDQSTSMVA5CNFSM4JG2EWR2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEDOV3FQ#issuecomment-551378326, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEOYOYFLU75TQEEGDSCGZ53QSTSMVANCNFSM4JG2EWRQ .