diff --git a/README.md b/README.md index f01f38c59..d7d99cd9b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # CloudMicrophysics.jl A package containing a library of cloud microphysics and aerosol parameterizations. +See [our documentation](docs-dev-url) for the list of available schemes. ||| |---------------------:|:----------------------------------------------| @@ -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). diff --git a/docs/Project.toml b/docs/Project.toml index 0bcf528ff..b5b59f122 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -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" diff --git a/docs/make.jl b/docs/make.jl index 6f619a178..f937a1a4d 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -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", @@ -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( diff --git a/docs/src/DevelopersGuide.md b/docs/src/DevelopersGuide.md index 762f62277..2fcec8fc9 100644 --- a/docs/src/DevelopersGuide.md +++ b/docs/src/DevelopersGuide.md @@ -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. @@ -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). @@ -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. @@ -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. @@ -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 diff --git a/docs/src/Glossary.md b/docs/src/Glossary.md new file mode 100644 index 000000000..38d139a80 --- /dev/null +++ b/docs/src/Glossary.md @@ -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. diff --git a/docs/src/IceNucleationParcel0D.md b/docs/src/IceNucleationParcel0D.md index f5f0abe6f..1117889b7 100644 --- a/docs/src/IceNucleationParcel0D.md +++ b/docs/src/IceNucleationParcel0D.md @@ -124,7 +124,7 @@ The crux of the problem is modeling the ``\frac{dq_l}{dt}`` and ``\frac{dq_i}{dt ## Condensation The diffusional growth of individual cloud droplet is described by -([see discussion](https://clima.github.io/CloudMicrophysics.jl/previews/PR103/Microphysics1M/#Snow-autoconversion)), +([see discussion](https://clima.github.io/CloudMicrophysics.jl/dev/Microphysics1M/#Snow-autoconversion)), ```math \begin{equation} r_l \frac{dr_l}{dt} = \frac{1}{\rho_l} \, (S_l - 1) \, G_l(T) @@ -216,7 +216,7 @@ Following the water activity based immersion freezing model (ABIFM), the ABIFM d \label{eq:ABIFM_P_ice} \end{equation} ``` -where ``N_{liq}`` is total number of ice nuclei containing droplets and +where ``N_{liq}`` is total number of ice nuclei containing droplets and ``A`` is surface area of those droplets. ## Homogeneous Freezing @@ -230,7 +230,7 @@ The ice production rate from homogeneous freezing can then be determined: \label{eq:hom_P_ice} \end{equation} ``` -where ``N_{liq}`` is total number of ice nuclei containing droplets and +where ``N_{liq}`` is total number of ice nuclei containing droplets and ``V`` is the volume of those droplets. ## Example figures @@ -239,7 +239,7 @@ Here we show various example simulation results from the adiabatic parcel model. This includes examples with deposition nucleation on dust, liquid processes only, immersion freezing with condensation and deposition growth, and homogeneous freezing with deposition growth. - + We start with deposition freezing on dust. The model is run three times for 30 minutes simulation time, (shown by three different colors on the plot). @@ -273,8 +273,8 @@ include("../../parcel/Immersion_Freezing.jl") ``` ![](immersion_freezing.svg) -The following plots show the parcel model running with homogeneous freezing and - depositional growth assuming a lognormal distribution of aerosols. +The following plots show the parcel model running with homogeneous freezing and + depositional growth assuming a lognormal distribution of aerosols. It is compared against [Jensen2022](@cite). Note that running with the initial conditions described in [Jensen2022](@cite) results in a ``\Delta a_w`` smaller than the minimum valid value for the ``J_{hom}`` parameterization. We have forced diff --git a/docs/src/guides/GettingStarted.jl b/docs/src/guides/GettingStarted.jl new file mode 100644 index 000000000..37e9fc5e3 --- /dev/null +++ b/docs/src/guides/GettingStarted.jl @@ -0,0 +1,40 @@ +# # Getting started + +# This guide shows how to call a function from `CloudMicrophysics.jl` package. +# Please consult our [README](https://github.com/CliMA/CloudMicrophysics.jl?tab=readme-ov-file#installation-and-running-instructions) +# for the CloudMicrophysics.jl installation instructions. + +# In this guide will call the `accretion` function that parameterizes the growth of rain drops +# through collisions with cloud droples. +# Check the [API documentation](https://clima.github.io/CloudMicrophysics.jl/dev/API/#CloudMicrophysics.Microphysics2M.accretion) +# and the [parameterization documentation](https://clima.github.io/CloudMicrophysics.jl/dev/Microphysics2M/#Accretion) +# for more details. + +# We start by defining the single precision floating point type +# that will be used in the computations. +# We import the `Microphysics2M` module in which the `accretion` function is defined +# and the `Parameters` module in which we store the default values of free parameters. +FT = Float32 + +import CloudMicrophysics.Microphysics2M as CM2 +import CloudMicrophysics.Parameters as CMP + +nothing #hide + +# We grab the parameters needed by the accretion function from the parameters module +# and define the example input values. +# Note that both the free parameters and the input values are of the same floating point type. +# All values are defined in base SI units. +const SB2006 = CMP.SB2006(FT) +qₗ = FT(1e-3) # Cloud liquid water specific humidity +qᵣ = FT(5e-4) # Rain water specific humidity +ρₐ = FT(1) # Air density +Nₗ = FT(1e8) # Cloud droplet number concentration + +nothing #hide + +# Finally, we call `accretion`, which will return the accretion rates for +# cloud and rain water specific humidities, as well as cloud and rain water number concentrations. +(; dq_rai_dt, dq_liq_dt, dN_rai_dt, dN_liq_dt) = + CM2.accretion(SB2006, qₗ, qᵣ, ρₐ, Nₗ) +@info("Accretion rates: ", dq_rai_dt, dq_liq_dt, dN_rai_dt, dN_liq_dt) diff --git a/docs/src/guides/Parameters.jl b/docs/src/guides/Parameters.jl new file mode 100644 index 000000000..203561c4f --- /dev/null +++ b/docs/src/guides/Parameters.jl @@ -0,0 +1,102 @@ +# # Handling parameters + +# This guide shows how to overwrite the default free parameters values and +# how to dispatch between different parameterization options based on parameters types. + +# ## Overwriting parameters + +# `CloudMicrophysics.jl` is designed to allow easy parameter calibrations. +# As a result, free parameters are not hard-coded in the source code but are instead +# passed as arguments to functions. The default values are stored in a separate +# repository [CLIMAParameters.jl](https://github.com/CliMA/CLIMAParameters.jl) in a `toml` file. + +# We start by importing the `CLIMAParameters` package and the needed +# `CloudMicrophysics.jl` modules. We define the precision type. + +import CLIMAParameters as CP +import CloudMicrophysics.Parameters as CMP +import CloudMicrophysics.Microphysics1M as CM1 +import CloudMicrophysics.Microphysics2M as CM2 +import CloudMicrophysics.HetIceNucleation as CMI_het + +FT = Float32 + +nothing #hide + +# We define the default parameters struct using the default `toml` file via the constructor +# provided in the `CloudMicrophysics.jl` `Parameters` module. +# Additionally, we create a `toml` file in which we save the name, value and type +# of the parameter we are changing. In a typical application, this step would be done +# via the calibration algorithm searching for optimal parameters values. +# We create a second struct with changed parameters based on the `override_dict.toml` file. +const default = CMP.Rain(FT) + +override_file = joinpath("override_dict.toml") +open(override_file, "w") do io + println(io, "[rain_autoconversion_timescale]") + println(io, "value = " * string(1)) + println(io, "type = \"float\"") +end +toml_dict = CP.create_toml_dict(FT; override_file) +isfile(override_file) && rm(override_file; force = true) +const overwrite = CMP.Rain(FT, toml_dict) + +nothing #hide + +# Overwriting the parameters can also be done using dictionaries instead of toml files. +# As an example we create a dictionary were we define a different value of the +# rain autoconversion time scale and create another parameter struct based on it. +override_file = Dict( + "rain_autoconversion_timescale" => + Dict("value" => 13, "type" => "float"), +) +toml_dict2 = CP.create_toml_dict(FT; override_file) +const overwrite2 = CMP.Rain(FT, toml_dict2) + +nothing #hide + +# Finally we check the values of the rain autoconversion timescales +# and the corresponding rain formation rates. +qₗ = FT(1e-3) +default_acnv = CM1.conv_q_liq_to_q_rai(default.acnv1M, qₗ) # Rain autoconversion rate +overwrite_acnv = CM1.conv_q_liq_to_q_rai(overwrite.acnv1M, qₗ) # Rain autoconversion rate +overwrite_acnv2 = CM1.conv_q_liq_to_q_rai(overwrite2.acnv1M, qₗ) # Rain autoconversion rate + +@info("Default:", default.acnv1M.τ, default_acnv) +@info("Overwrite:", overwrite.acnv1M.τ, overwrite_acnv) +@info("Overwrite from dict:", overwrite2.acnv1M.τ, overwrite_acnv2) + +# ## Dispatching over parameter types + +# `CloudMicrophysics.jl` `Parameters` module introduces type hierarchy that is used to +# dispatch over different parameterization options and inputs. +# For example `ABIFM_J` accepts `Illite` or `Kaolinite` +# as input type and will return immersion freezing nucleation rate coefficient +# that corresponds to the two different aerosol types. +const aerosol1 = CMP.Illite(FT) +const aerosol2 = CMP.Kaolinite(FT) + +Δa_w = FT(0.28) +J1 = CMI_het.ABIFM_J(aerosol1, Δa_w) +J2 = CMI_het.ABIFM_J(aerosol2, Δa_w) + +@info("ABIFM derived J: ", J1, J2) + +# Similarily, the 2 moment microphysics offers different rain autoconversion +# formulations based on parameterizations from the literature. +# We can chose between them based on the free parameters type that is passed in as argument. + +const KK2000 = CMP.KK2000(FT) # Khairoutdinov and Kogan (2000) +const B1994 = CMP.B1994(FT) # Beheng (1994) +const TC1980 = CMP.TC1980(FT) # Tripoli and Cotton (1980) +const LD2004 = CMP.LD2004(FT) # Liu and Daum (2004) + +qₗ = FT(1e-3) +ρₐ = FT(1) +N = FT(1e8) +KK2000_rate = CM2.conv_q_liq_to_q_rai(KK2000, qₗ, ρₐ, N_d = N) +TC1980_rate = CM2.conv_q_liq_to_q_rai(TC1980, qₗ, ρₐ, N_d = N) +LD2004_rate = CM2.conv_q_liq_to_q_rai(LD2004, qₗ, ρₐ, N_d = N) +B1994_rate = CM2.conv_q_liq_to_q_rai(B1994, qₗ, ρₐ, N_d = N) + +@info("Autoconversion: ", KK2000_rate, B1994_rate, TC1980_rate, LD2004_rate) diff --git a/docs/src/guides/SimpleModel.jl b/docs/src/guides/SimpleModel.jl new file mode 100644 index 000000000..381bb518c --- /dev/null +++ b/docs/src/guides/SimpleModel.jl @@ -0,0 +1,68 @@ +# # Simple Model + +# This guide shows how to build a simple model using `CloudMicrophysics.jl` parameterizations +# and `OrdinaryDiffEq.jl` solver. + +# We start by importing the needed external packages and `CloudMicrophysics.jl` modules. +import OrdinaryDiffEq as ODE +import UnicodePlots as UP +import CloudMicrophysics.Parameters as CMP +import CloudMicrophysics.Microphysics1M as CM1 + +nothing #hide + +# We define the problem for the ordinary differential equations solver. +# The `dY` and `Y` are the tendencies and the state vector of the solved problem, +# `p` stores the additional parameters of the simulation and `t` is the simulation time. +# See the [OrdinaryDiffEq.jl](https://github.com/SciML/OrdinaryDiffEq.jl) for more details +# about the solver interface. +function rain_formation(dY, Y, p, t) + FT = eltype(Y) # Floating point precision type + (; ρₐ, rain, liquid, ce, v_term) = p # Additional parameters passed through p + + qₗ = Y[1] # Cloud water specific humidity + qᵣ = Y[2] # Rain water specific humidity + + acnv = CM1.conv_q_liq_to_q_rai(rain.acnv1M, qₗ) # Rain autoconversion rate + accr = CM1.accretion(liquid, rain, v_term.rain, ce, qₗ, qᵣ, ρₐ) # Rain accretion rate + + dY[1] = -acnv - accr # Add the tendecies for cloud water + dY[2] = acnv + accr # and rain +end + +nothing #hide + +# We choose the simulation precision type and grab the default values of simulation parameters. +# We store the simulation parameters in the named tuple `p`. +FT = Float32 + +rain = CMP.Rain(FT) # Rain drop parameters for the 1-moment scheme +liquid = CMP.CloudLiquid(FT) # Cloud droplet parameters for the 1-moment scheme +ce = CMP.CollisionEff(FT) # Collision efficiencies +v_term = CMP.Blk1MVelType(FT) # Terminal velocity parameters +ρₐ = FT(1) # Air density +p = (; ρₐ, rain, liquid, ce, v_term) + +nothing #hide + +# Finally we define the simulation time and initial conditions for cloud and rain water specific humidities. +# We define the ODE problem, pass it to the solver, and visualize the results. +t₀ = FT(0) +t_end = FT(10 * 60) +TS = (t₀, t_end) + +qₗ0 = FT(5e-3) +qᵣ0 = FT(0) +IC = [FT(qₗ0), FT(qᵣ0)] + +problem = ODE.ODEProblem(rain_formation, IC, TS, p) +sol = ODE.solve(problem, ODE.Tsit5(), reltol = eps(FT), abstol = eps(FT)) + +plt = UP.lineplot( + sol.t, + sol[1, :] .* 1e3, + name = "cloud", + xlabel = "time [s]", + ylabel = "q [g/kg]", +) +UP.lineplot!(plt, sol.t, sol[2, :] .* 1e3, name = "rain") diff --git a/docs/src/index.md b/docs/src/index.md index 1e4955e42..c035f48bd 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -1,38 +1,56 @@ # CloudMicrophysics.jl -The CloudMicrophysics.jl is a library of bulk cloud microphysics and aerosol schemes. - -The goal of a cloud microphysics scheme is to represent the micro-scale processes - leading to the formation of clouds and precipitation. -Bulk microphysics schemes represent overall properties of cloud and precipitation particles, - instead of solving for the evolution of individual cloud droplets or ice crystals. -Bulk schemes typically consider different somewhat arbitrary water categories - such as cloud water, cloud ice, rain and snow. -They then predict total mass and (optionally) number concentration of particles in each category. -A scheme that predicts the total mass of particles per category is called 1-moment, - because the total mass of particles is proportional to the 3rd moment of the particle size distribution. -A scheme that predicts the total mass and number concentration of particles per category is called 2-moment, - because the predicted quantities are proportional to the 3rd and 0th moment of the particle size distribution. -Aerosol particles serve as nuclei for forming cloud droplets and ice crystals. -Additional schemes are needed to predict how many cloud droplets or ice crystals - form for a given population of aerosol particles, when using a 2-moment microphysics scheme. - -So far CloudMicrophysics.jl includes: - - 0-moment scheme that instantly removes the precipitable cloud condensate, - - 1-moment scheme for warm rain and mixed-phase clouds (cloud water and ice, ran and snow (aggregate)), - - 2-moment scheme for warm rain clouds (cloud water and rain), - - collection of different 2-moment autoconversion and accretion functions, - - experimental non-equilibrium cloud formation scheme, - - a collection of logistic functions for smooth transitions at thresholds, - - aerosol activation scheme, - - ice nucleation scheme through water vapor deposition on dust aerosol. - -This documentation provides some use examples for different available schemes, - along with derivation notes and links to the literature. -The CI tests include unit tests and some very simple performance benchmarks and GPU tests. - -## Authors - -`CloudMicrophysics.jl` is being developed by the - [Climate Modeling Alliance](https://clima.caltech.edu/). +The `CloudMicrophysics.jl` is a library of bulk cloud microphysics and aerosol schemes: + - `library` means that `CloudMicrophysics.jl` provides a variety of parameterizations + that can be used to define tendencies in different numerical models. + - `cloud microphysics and aerosol schemes` mean that the parameterizations represent + small-scale processes leading to the formation of clouds on aerosol particles and + the formation of precipitation. + - `bulk schemes` mean that the schemes parameterize behavior of populations + of particles (aerosol, cloud and precipitation), instead of tracking the evolution + of individual cloud droplets or ice crystals. Bulk schemes typically consider different + somewhat arbitrary water categories such as cloud water, cloud ice, rain and snow. + They predict total mass and (optionally) number concentration of particles in each category. + +## Features + +`CloudMicrophysics.jl` is designed to allow data driven parameter calibrations. +All free parameters are passed as inputs to the functions and can be easily overwritten by the user. +The package is tested on Unix, OSX and Windows. +The package can be used on both CPUs and GPUs. + +Available parameterizations: + - 0-moment scheme that instantly removes the precipitable cloud condensate, + - [1-moment scheme](https://clima.github.io/CloudMicrophysics.jl/dev/Glossary/#1-moment-scheme) + for warm rain and mixed-phase clouds (cloud water and ice, ran and snow (aggregate)), + - [2-moment scheme](https://clima.github.io/CloudMicrophysics.jl/dev/Glossary/#2-moment-scheme) + for warm rain clouds (cloud water and rain), + - collection of different 2-moment autoconversion and accretion functions, + - experimental non-equilibrium cloud formation scheme, + - a collection of logistic functions for smooth transitions at thresholds, + - [aerosol activation scheme](https://clima.github.io/CloudMicrophysics.jl/dev/Glossary/#aerosol-activation-scheme) + - [ice nucleation scheme](https://clima.github.io/CloudMicrophysics.jl/dev/Glossary/#ice-nucleation-scheme) + via water vapor deposition on dust aerosol, heterogeneous and homogeneous freezing of droplets. + +## Documentation outline + + - `Parameterizations` provide notes on the derivations and assumptions behind each of the implemented schemes. + The scripts that generate different plots in the documentation are stored in `docs/src/plots` folder, + and can serve as usage examples of the schemes. + - `How to guides` provide simple examples on how to get started using the package. + - `Models` discuss two 0-dimensional models that are build using the package and are focused on + testing different ice nucleation schemes. + - `API` provides package interface documentation. + - `Developer's Guide ` offers some hints for beginner contributors. + - `Glossary` explains some basic terminology. + - `References` provide links to the publications on which we based our implementations. + +## Contributing and license + +`CloudMicrophysics.jl` is developed by the [Climate Modeling Alliance](https://clima.caltech.edu/) and +is released under the Apache License Version 2.0. Please check +[contributing](https://github.com/CliMA/CloudMicrophysics.jl?tab=readme-ov-file#contributing) +section if you would like to contribute to the project and are looking for ideas. +Please open an issue or reach out to us if you have any questions or comments. + ![Clima logo](assets/Clima_logo.png)