-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce namelists #32
Comments
True, although I strongly recommend implementing a programmatic interface like Oceananigans has! |
I skimmed through Oceananigans and through ClimaAtmos. I could really find how you manage your parameters. can you point me to how its done? |
Parameters are managed locally by the objects they pertain to, for example struct FPlane{FT} <: AbstractRotation
f :: FT
end represents Coriolis forces on an f-plane with Coriolis parameter https://github.com/CliMA/Oceananigans.jl/blob/main/src/Coriolis/f_plane.jl The user must supply In other words, there is no designated "parameter file" --- all parameters that are invoked in a numerical experiment should be available in the user's script. There is a piece of software that can be used to manage parameters in a more "global" sense: https://github.com/CliMA/ClimaParams.jl However I think it makes sense to use ClimaParams to extract and set parameters within a user-type script rather than to bake it directly into a model constructor. I built up an example of what it might look like to use https://github.com/CliMA/ClimaParams.jl/tree/main/examples/OceananigansSingleColumnSimulation |
This is a different user interface paradigm than traditional software. |
Yes indeed it is a little different. Thanks for providing the minimal example. So what I take from this is:
I like that. |
We do provide some defaults for convenience, eg I don't totally understand what you mean by needing to change all parameters globally in a development stage. Development should generally proceed along these lines:
It's crucial to actually invoke the user interface in the tests. The user interface is not just "sugar" on top of the package, its actually the end goal itself. The internal software design should be, in some sense, subservient to the user interface. The tests must use the user interface, because one of the hardest challenges of long term software is the maintainence burden imposed by testing. The goal of the user interface is to make it as easy as possible to invoke the functionality of the package, and one of its most important applications is in the writing of tests. Perhaps more broadly there shouldn't be any challenge in running tests with different parameter values if parameters are not hardcoded (but are rather passed into functions / types when they are constructed), right? |
If you would like to implement a test and use it with multiple parameter values then you can
|
Here's an example of a function that tests whether time-stepping runs without an error, taking in the "turbulence closure" as an argument: |
so there are some constants like 'g_Earth' that are defined in the module namespace.
Well my user interface wasn't completely defined, but I stared testing of course. I just have to rewrite them. This will remain a problem since the model will grow in complexity with time. |
Not sure I deserve to endure such a savage wink... I disagree that the constant is hard coded. It is only the default value that is hard coded. Any place where gravitational acceleration is used, it is drawn from the type and not the constant. If a user needs to change this value, they don't change source code. They have to provide a new value when they build the type in question (here Please let me know that you understand this point without winking...
I strongly suggest not doing this |
fine, I go your point. I just like savage winks. |
Thanks for clarifying, that was very helpful! |
Yes agreed there is fuzziness there. Our approach is that Oceananigans is fundamentally a library for building models rather than a model itself. Therefore, it functionally should have no defaults. People who provide models -- like the Clima Params example, or ClimaOcean, are the people who have to introduce defaults. Those actors introduce an additional interface like the one in the example. I think for this code you should think of it like Oceananigans, as a library. In that sense there should not be defaults. Develop a user interface where specifying parameters is effortless. Then, you don't have to worry about the "extra work" of writing parameters -- it's easy enough. Later, you will implement an actual model using this code. When you get to that, develop a layer on top of this library that provides default parameters. |
This approach has the huge advantage that embedding or linking this code with an Oceananigans model will be super easy because the interface will be ready for it. If you require users to fiddle with a yml file in order to use th code it's going to make things annoying down the road. Imagine if all codes did that -- we'd end up with a jungle of yml. |
Okey, that is indeed very helpful. So the applied wave model should be its own library seeds from PiCLES & Oceananigans. PiCLES it self depends on some Oceananigans stuff. It will be some work to enabling PiCLES on the different grid types, but we can worry about that later .. |
What are the parameters that you need to specify? |
I think there are about 3 groups:
most of then are at the interface level already, or defaults when the struct is initialized PiCLES/src/Models/WaveGrowthModels2D.jl Lines 124 to 138 in 734cf90
PiCLES/src/ParticleSystems/particle_waves_v5.jl Lines 34 to 50 in 734cf90
|
Have you designed types / structs to represent the different terms in the model equations? Those structs would be the right place to store those parameters. Examples in Oceananigns are
We call this the "time-stepper", and dedicate a struct for that.
Initialization should use a design like Oceananigans with its |
Try not to group too many parameters in structs with generic names --- use small, specific structs with informative names. For example You may also want to use callbacks to implement some features, rather than baking them into the time integration. That will allow them to be changed more easily by users. |
thanks. there are inconsistencies, but I knew I'll have to re-order them at some point, that's why this issue. I don't really understand why we need to have a struct for a single variable like |
ah, If I have a struct for the variable I can store the default parameter there rather than at the initialization of the model. It gets more modular. |
Any equation of motion has one Coriolis term, For By designing the model this way, Internally, those types are used via multiple dispatch to add the correct contribution to the tendency of the equation of motion. For example: |
It might be a good idea to become familiar with the Oceananigans user interface and try to set up a few problems using it. That will help you grok the philosophy behind the design --- the philosophy is non-trivial and super important. |
Many parameters are currently hard-coded in the run file or the object definition.
parameters should be set through namelists.yml and then changed if needed
The text was updated successfully, but these errors were encountered: