Open rafferrari opened 5 years ago
In PlanetParameters.
I also am in the dark --- PlanetParameters
consists of just a source file with values, right? Do we change parameters by changing the source file?
I propose that we develop a user API that allows users to interact with the coupled model (and model components, since we will want a relatively uniform API across model components) in which users interact with the model using a script, without modifying source files or namelists.
For example, I think we want users to be able to run a model with a script that looks like
using CLIMA
earth = EarthParameters()
model = GlobalModel(planet_parameters=earth, otherkwargs...)
run!(model, otherargs...)
If we want to explore, for example, the effect of a planet's gravitational acceleration on their climate (but leaving all parameters the same for earth), we could write
using CLIMA
big_earth = EarthParameters(grav=15.1)
model = GlobalModel(planet_parameters=big_earth, otherkwargs...)
run!(model, otherargs...)
Raf's comment may be more relevant to a model on a tangent plane at a given latitude. A user could instantiate such a model with something along the lines
using CLIMA
earth = EarthParameters()
@parameter latitude = 43.3 "degrees"
model = FPlaneModel(planet_parameters=earth, latitude=latitude, otherkwargs...)
run!(model, otherargs...)
This can be implemented by using struct
s of parameters, combined with constructors that use the defaults currently contained in the PlanetParameters
module. We could then have something like
module PlanetParameters
export PlanetParameters
struct PlanetParameters{T<:AbstractParameter}
grav :: T
# etc
end
end # module
For Earth defaults, we might have
function EarthParameters(;
grav = 9.81,
# etc
)
return PlanetParameter(grav, otherargs...)
end
Sure, that will all be nice to have at some point. I'd just like get to the point of being able to run a model (for Earth) soon, before making it more general. If we have all parameters centrally collected, it'll be easy to generalize later.
@charleskawczynski I think @jkozdon mentioned a PR that has an example of Omega/rotation being used in some dynamics. I couldn't figure out which PR that was when I looked, or maybe its in a fork?
Indeed! This is something to think about when the model runs.
For clarification, how are the parameters used currently? Are they imported into some namespace and used as global variables? If they are properties of a struct
, we will want to access them as such, e.g. pp.grav
where pp = PlanetParameters()
.
Note that we will need this functionality to run LES (which are on an f-plane).
There are other quantities --- expansion coefficients for an oceanic equation of state, or microphysics (?) quantities that, strictly, are not properties of a 'planet'. We will probably to be able to set these via structs and constructors with defaults in the same manner. In fact, I propose that we form the majority of our interaction with the 'model' via structs.
This pattern can also be used for LES closures:
smag = ConstantSmagorinsky(C=0.13)
model = FPlaneModel(les_model=smag, latitude=latitude, otherkwargs...)
and turbulence / convection parameterizations:
edmf = EDMF(subdomains=3, αb=1/3)
model = GlobalModel(turbulence_model=edmf, otherkwargs...)
This pattern is currently implemented in Oceananigans.jl and OceanTurb.jl.
We may also want to think about using a different word for these quantities ('constants'?) and reserve 'parameters' for the changeable values that define a 'parameterization'.
We have discussed structures for adjustable parameters extensively in the past weeks, with @charleskawczynski , @lcw, @jkozdon, Peter Ahrens and others. It is important that we agree on structures for this across the project (atmosphere, land, ocean etc.) because these parameters are the principal input to the model from the perspective of the DA/ML algorithms.
PlanetParameters are called thus because they are planetary parameters (not all of them are what I would call constants). And, yes, they are distinct from other parameters, because we do not need to learn about them.
@charleskawczynski I think @jkozdon mentioned a PR that has an example of Omega/rotation being used in some dynamics. I couldn't figure out which PR that was when I looked, or maybe its in a fork?
@charleskawczynski I think @jkozdon mentioned a PR that has an example of Omega/rotation being used in some dynamics. I couldn't figure out which PR that was when I looked, or maybe its in a fork?
We may also have the Coriolis force in the turbulence convection module for stand-alone cases. But I agree with Tapio that, since the over-arching goal is to have DA/ML learn parameters, we should assume that something like EarthParameters
should be assumed constant.
@glwagner at the moment, I'm passing these parameters through a NamedTuple
(subject to change, perhaps to a struct
) to initialize and run the turbulence convection model:
turb_conv = TurbConv(params)
...
dostep!(turb_conv, params)
This way, we can push these parameters upstream and worry about what values they take later.
@charleskawczynski thanks! Are parameters then carried around atomically through the code via functions? Can you point to the source code where the magic happens? Why are the params passed both to TurbConv
and dostep!
? Thanks again for answering the many questions...
Sorry, I forgot to answer this earlier. I'm not sure if there are still questions @glwagner:
Are parameters then carried around atomically through the code via functions?
The only thing that needs to be carried around is param_set
, and all CLIMAParameter functions can be called with this object.
Can you point to the source code where the magic happens?
Where what magic happens?
Why are the params passed both to
TurbConv
anddostep!
?
All CLIMAParameter methods can be called locally with param_set
. If that's not being done consistently, then it may be something we could improve on.
Where do you set the rotation rate, i.e. Coriolis parameter?