CliMA / ClimateMachine.jl

Climate Machine: an Earth System Model that automatically learns from data
https://clima.github.io/ClimateMachine.jl/latest/
Other
452 stars 78 forks source link

Rotation #129

Open rafferrari opened 5 years ago

rafferrari commented 5 years ago

Where do you set the rotation rate, i.e. Coriolis parameter?

tapios commented 5 years ago

In PlanetParameters.

glwagner commented 5 years ago

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 structs 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
tapios commented 5 years ago

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.

christophernhill commented 5 years ago

@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?

glwagner commented 5 years ago

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'.

tapios commented 5 years ago

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.

jkozdon commented 5 years ago

@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?

97 added a sphere mesh, but we don't use it yet for anything.

charleskawczynski commented 5 years ago

@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.

glwagner commented 5 years ago

@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...

charleskawczynski commented 3 years ago

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 and dostep!?

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.