Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…into ap/unitlessSolver
  • Loading branch information
anastasia-popova committed Feb 6, 2024
2 parents f7ab25c + 65c8033 commit 5c70bb0
Show file tree
Hide file tree
Showing 21 changed files with 1,408 additions and 552 deletions.
13 changes: 13 additions & 0 deletions NOTICE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Copyright (c) 2022, the California Institute of Technology (Caltech)

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
27 changes: 13 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# CloudMicrophysics.jl
A package containing a library of cloud microphysics and aerosol parameterizations.
See [our documentation](https://clima.github.io/CloudMicrophysics.jl/dev/) for the list of available schemes.

|||
|---------------------:|:----------------------------------------------|
Expand Down Expand Up @@ -72,38 +73,36 @@ See the [Pkg docs](https://docs.julialang.org/en/v1/stdlib/Pkg/)

## Contributing

The CloudMicrophysics.jl package is being actively developed
CloudMicrophysics.jl is being actively developed
and welcomes contributions and feedback.
There is a variety of projects big and small that are available to take up as
fun research projects for interested students and other contributors.
Below is a list of possible examples,
but other suggestions and ideas are always welcome!

- The CloudMicrophysics.jl package should be tested against a high-resolution model.
- CloudMicrophysics.jl should be tested against a high-resolution model.
We have chosen [PySDM](https://github.com/atmos-cloud-sim-uj/PySDM)
as our high-resolution benchmark.
PySDM is a package for simulating the dynamics of population of particles
and is based on the [Super-Droplet algorithm](https://doi.org/10.1002/qj.441).
Possible tasks in this project would include testing the aerosol activation parameterization
against PySDM in an adiabatic parcel setup, or testing the 1-moment
microphysics parameterization against PySDM in an already implemented
against PySDM in adiabatic parcel setup, or testing the 1-moment
microphysics parameterization against PySDM in an
[1-dimensional](https://github.com/CliMA/Kinematic1D.jl) or
2-dimensional prescribed flow setup.
2-dimensional prescribed flow setups.
This could be extended further into a calibration exercise using the
[EnsembleKalmanProcesses.jl](https://github.com/CliMA/EnsembleKalmanProcesses.jl) package.
An example pipeline can be seen in the
[EKP.jl docs](https://clima.github.io/EnsembleKalmanProcesses.jl/dev/examples/Cloudy_example/)
where [Cloudy.jl](https://github.com/CliMA/Cloudy.jl) parameters are calibrated.

- The CloudMicrophysics.jl package should be tested against observations.
We are focusing on the ice-free precipitation first. The tests include
comparisons against [CFODDs](https://doi.org/10.1175/JAS-D-20-0321.1) and
against [Stratocumulus LWP(N) patterns](https://doi.org/10.5194/acp-19-10191-2019).

- Adding an aerosol model and coupling it with the aerosol activation
parameterization.
[MAM4](https://doi.org/10.5194/gmd-9-505-2016) could be the aerosol model to implement.
[MAM4](https://doi.org/10.5194/gmd-9-505-2016) could be the aerosol model to implement,
but we are also searching for some simpler alternatives first.
This is a big project and an opportunity for a more long term contribution.

- Adding the [P3 scheme](https://doi.org/10.1175/JAS-D-14-0065.1) for ice phase microphysics.

- Adding more accurate fall speed parameterization based on
[Chen et. al. 2022](https://doi.org/10.1016/j.atmosres.2022.106171).

- Adding precipitation susceptibility tests based on
[Glassmeier and Lohmann 2016](https://doi.org/10.1175/JAS-D-16-0008.1).
2 changes: 2 additions & 0 deletions docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ Dierckx = "39dd38d3-220a-591b-8e3c-4c3a8c710a94"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
DocumenterCitations = "daee34ce-89f3-4625-b898-19384cb65244"
Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306"
OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
RootSolvers = "7181ea78-2dcb-4de3-ab41-2b8ab5a31e74"
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
Thermodynamics = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c"
UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228"

[compat]
CLIMAParameters = "0.8"
Expand Down
4 changes: 2 additions & 2 deletions docs/bibliography.bib
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ @article{Jensen2022
number = {17},
pages = {e2022JD036535},
keywords = {cirrus, nucleation, freezing},
doi = {https://doi.org/10.1029/2022JD036535},
doi = {10.1029/2022JD036535},
url = {https://agupubs.onlinelibrary.wiley.com/doi/abs/10.1029/2022JD036535},
note = {e2022JD036535 2022JD036535},
year = {2022}
Expand Down Expand Up @@ -616,7 +616,7 @@ @article{Vehkamaki2002
volume = {107},
number = {D22},
year = {2002},
doi = {110.1029/2002JD002184}
doi = {10.1029/2002JD002184}
}

@article{Wang2006,
Expand Down
51 changes: 47 additions & 4 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,37 @@ ENV["GKSwstype"] = "nul"

using CloudMicrophysics, Documenter
using DocumenterCitations
using Literate

bib = CitationBibliography(joinpath(@__DIR__, "bibliography.bib"))

pages = Any[
"Home" => "index.md",
const GUIDES_DIR = joinpath(@__DIR__, "src/guides/")
const LITERATED_GUIDES_DIR = joinpath(@__DIR__, "src/guides/literated")

if isempty(get(ENV, "CI", ""))
# only needed when building docs locally; set automatically when built under CI
# https://fredrikekre.github.io/Literate.jl/v2/outputformats/#Configuration
extra_literate_config = Dict(
"repo_root_path" => abspath(joinpath(@__DIR__, "..")),
"repo_root_url" => "file://" * abspath(joinpath(@__DIR__, "..")),
)
else
extra_literate_config = Dict()
end

# To be literated
UnliteratedGuides = ["GettingStarted.jl", "Parameters.jl", "SimpleModel.jl"]
for Guide in UnliteratedGuides
filepath = joinpath(GUIDES_DIR, Guide)
Literate.markdown(
filepath,
LITERATED_GUIDES_DIR;
flavor = Literate.DocumenterFlavor(),
config = extra_literate_config,
)
end

Parameterizations = [
"0-moment precipitation microphysics" => "Microphysics0M.md",
"1-moment precipitation microphysics" => "Microphysics1M.md",
"2-moment precipitation microphysics" => "Microphysics2M.md",
Expand All @@ -18,12 +44,29 @@ pages = Any[
"Water Activity" => "WaterActivity.md",
"Ice Nucleation" => "IceNucleation.md",
"Aerosol Nucleation" => "AerosolNucleation.md",
"Precipitation Susceptibility" => "PrecipitationSusceptibility.md",
]

Models = [
"Adiabatic parcel model" => "IceNucleationParcel0D.md",
"Box Model" => "IceNucleationBox0D.md",
"Precipitation Susceptibility" => "PrecipitationSusceptibility.md",
]

Guides = [
"Getting started" => "guides/literated/GettingStarted.md",
"Handling parameters" => "guides/literated/Parameters.md",
"Building a model" => "guides/literated/SimpleModel.md",
]

pages = Any[
"Home" => "index.md",
"Parameterizations" => Parameterizations,
"How to guides" => Guides,
"Models" => Models,
"API" => "API.md",
"References" => "References.md",
"Developer's Guide" => "DevelopersGuide.md",
"Glossary" => "Glossary.md",
"References" => "References.md",
]

mathengine = MathJax(
Expand Down
98 changes: 5 additions & 93 deletions docs/src/AerosolActivation.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,104 +257,16 @@ where:
- ``S_{ci}`` is the mode critical supersaturation,
- ``S_{max}`` is the maximum supersaturation.

## Example figures

```@example
import Plots
import CloudMicrophysics
import CLIMAParameters
import Thermodynamics
const PL = Plots
const AM = CloudMicrophysics.AerosolModel
const AA = CloudMicrophysics.AerosolActivation
const CMP = CloudMicrophysics.Parameters
const TD = Thermodynamics
FT = Float64
tps = Thermodynamics.Parameters.ThermodynamicsParameters(FT)
aip = CMP.AirProperties(FT)
ap = CMP.AerosolActivationParameters(FT)
# Atmospheric conditions
T = 294.0 # air temperature
p = 1000.0 *1e2 # air pressure
w = 0.5 # vertical velocity
# We need the phase partition here only so that we can compute the
# moist R_m and cp_m in aerosol activation module.
# We are assuming here saturated conditions and no liquid water or ice.
# This is consistent with the assumptions of the aerosol activation scheme.
p_vs = TD.saturation_vapor_pressure(tps, T, TD.Liquid())
q_vs = 1 / (1 - TD.Parameters.molmass_ratio(tps) * (p_vs - p) / p_vs)
q = TD.PhasePartition(q_vs, 0.0, 0.0)
# Abdul-Razzak and Ghan 2000 Figure 1 mode 1
# https://doi.org/10.1029/1999JD901161
r_dry = 0.05 * 1e-6 # um
stdev = 2.0 # -
N_1 = 100.0 * 1e6 # 1/m3
# Sulfate - universal parameters
sulfate = CMP.Sulfate(FT)
n_components_1 = 1
mass_fractions_1 = (1.0,)
paper_mode_1_B = AM.Mode_B(
r_dry,
stdev,
N_1,
mass_fractions_1,
(sulfate.ϵ,),
(sulfate.ϕ,),
(sulfate.M,),
(sulfate.ν,),
(sulfate.ρ,),
n_components_1,
)
N_2_range = range(0, stop=5000 * 1e6, length=100)
N_act_frac_B = Vector{Float64}(undef, 100)
it = 1
for N_2 in N_2_range
n_components_2 = 1
mass_fractions_2 = (1.0,)
paper_mode_2_B = AM.Mode_B(
r_dry,
stdev,
N_2,
mass_fractions_2,
(sulfate.ϵ,),
(sulfate.ϕ,),
(sulfate.M,),
(sulfate.ν,),
(sulfate.ρ,),
n_components_2,
)
AD_B = AM.AerosolDistribution((paper_mode_1_B, paper_mode_2_B))
N_act_frac_B[it] = AA.N_activated_per_mode(ap, AD_B, aip, tps, T, p, w, q)[1] / N_1
global it += 1
end
# data read from Fig 1 in Abdul-Razzak and Ghan 2000
# using https://automeris.io/WebPlotDigitizer/
include("plots/ARGdata.jl")
PL.plot(N_2_range * 1e-6, N_act_frac_B, label="CliMA-B", xlabel="Mode 2 aerosol number concentration [1/cm3]", ylabel="Mode 1 number fraction activated")
PL.scatter!(Fig1_x_obs, Fig1_y_obs, markercolor = :black, label="paper observations")
PL.plot!(Fig1_x_param, Fig1_y_param, linecolor = :black, label="paper parameterization")
PL.savefig("Abdul-Razzak_and_Ghan_fig_1.svg")
```
![](Abdul-Razzak_and_Ghan_fig_1.svg)

## Example of Aerosol Activation from ARG2000

The figures below have been reproduced from [Abdul-RazzakandGhan2000](@cite)
using the aerosol activation parameterization implemented in this project.

```@example
include("plots/ARGplots_fig1.jl")
```
![](Abdul-Razzak_and_Ghan_fig_1.svg)

```@example
include("plots/ARGplots.jl")
make_ARG_figX(2)
Expand Down
22 changes: 10 additions & 12 deletions docs/src/DevelopersGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ In the PR you can describe which parts of the relevant issue are solved and what
After creating a PR on GitHub, you will find that every following commit & push you make
will go through continuous integration (CI) checks:

- The, `ci / ci 1.8.1 ` runs the tests on Ubuntu, Windows and OSX machines
using GitHub Actions.
- The, `ci` runs the tests on Ubuntu, Windows and OSX machines using GitHub Actions.
The tests include some unit tests and very simple performance tests.
It may happen that the tests pass on your local machine,
but fail on one of the machines provided in the cloud for the CI.
Expand Down Expand Up @@ -50,7 +49,7 @@ After creating a PR on GitHub, you will find that every following commit & push
We strive to keep the test coverage high, but this test is not strictly required to pass before merging a PR.

Once the PR is opened, you can request reviewers to look over and approve your work.
To keep things tidy, we want PRs to have very few (ideally only one) commit
To keep things tidy, we want PRs to have few (ideally only one) commit
before merging to the main branch.
You can squash and rebase multiple commits into one
in your favorite editor (VS Code, Vim etc).
Expand Down Expand Up @@ -83,11 +82,11 @@ See [Pkg.jl docs](https://pkgdocs.julialang.org/v1/managing-packages/#Adding-reg
in different modules depending on which aspect of aerosol and cloud microphysics
they address.
When adding a new function, decide if a new module is required, or add to the existing one.
If the added function will be used in other modules, export the function. Avoid exporting
functions that are only used within the module it is defined in or functions that have the
same name as a function already in the API.
Avoid shortening words or phrases when naming new functions. The name of the function
should be self-explanatory yet brief.
If the added function will be used in other modules, export the function.
Avoid exporting functions that are only used within the module it is defined in
or functions that have the same name as a function already in the API.
Avoid shortening words or phrases when naming new functions.
The name of the function should be self-explanatory yet brief.
All functions should have docstrings describing the API, as well as
documentation focusing on the scientific aspects of what they do.
All functions should have their own unit, performance and GPU tests.
Expand Down Expand Up @@ -121,7 +120,8 @@ Examples can be found in the source files.
Be sure to add the function to `API.md` in the docs folder.
Missing docstrings and functions in the API cause the documentation build to break.

To build and work the documentation locally, you can use [LiveServer.jl](https://github.com/tlienart/LiveServer.jl#serve-docs). This will compile the documentation to a local server that is updated whenever you make changes.
To build and work the documentation locally, you can use [LiveServer.jl](https://github.com/tlienart/LiveServer.jl#serve-docs).
This will compile the documentation to a local server that is updated whenever you make changes.
Alternatively, you can save the documentation to a static webpage: `julia --project=docs docs/make.jl`.
The index page will be saved in `docs/build` folder.

Expand All @@ -133,10 +133,8 @@ Unit tests aim to ensure that parameterizations make physical sense.
They can be found in the `test` folder under files named after corresponding source files.
If you create a new function, please also create a new test that checks it.
If creating a new file for unit tests, make sure you import `Test` and any other necessary libraries.
There is some boilerplate code needed to create the set with free parameters
There is some boilerplate code needed to create the sets with free parameters
based on the default `toml` file from [CLIMAParameters](https://github.com/CliMA/CLIMAParameters.jl).
This would be the `include(joinpath(pkgdir(CM), "test", "create_parameters.jl"))` line found in
the existing unit tests.

Some possible tests include checking if the returned values agree with values
in the literature, if something is smaller/greater at warmer/cooler
Expand Down
30 changes: 30 additions & 0 deletions docs/src/Glossary.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
## 1-moment scheme

A scheme that predicts one moment of the particle size distribution (PSD).
Typically it's the 3rd moment of PSD.
The scheme's prognostic variable is the specific humidity (mass fraction)
of water in each category, which is proportional to the 3rd moment of PSD.

## 2-moment scheme

A scheme that predicts two moments of the particle size distribution (PSD).
Typically those are the 3rd and the 0th moments of PSD.
The scheme's prognostic variables are the specific humidity (mass fraction)
and number concentration of particles in each category,
which are proportional to the 3rd and 0th moment of (PSD)

## Aerosol activation scheme

Aerosol particles serve as condensation nuclei for forming cloud droplets.
An aerosol activation scheme predicts the number concentrations
of newly formed cloud droplets for a given population of aerosol particles.
The scheme is needed when using 2-moment microphysics.

## Ice nucleation scheme

Aerosol particles and cloud droplets serve as nuclei for forming ice crystals.
The pathways include water vapor deposition on dust, heterogeneous and
homogeneous freezing of water droplets.
Ice nucleation schemes are needed to predict the number concentrations
of newly formed ice crystals.
The schemes are needed when using 2-moment microphysics scheme.
Loading

0 comments on commit 5c70bb0

Please sign in to comment.