From e700a9ddaca0ffb1c0485788769072ff9c2161cb Mon Sep 17 00:00:00 2001 From: AlexisRenchon Date: Tue, 16 Jul 2024 03:57:47 -0700 Subject: [PATCH] Add SoilCanopyModel diagnostics This PR finalizes the addition of SoilCanopyModel diagnostics. It also adds a macro to generate land compute functions, an optional argument for period averaging for default diagnostics, an optional argument for ":long" (all) or ":short" (a few essentials) for default diagnostics. Diagnostics are now used in global_soil_canopy.jl. EnergyHydrology model diagnostics_compute methods have been added. Co-authored-by: AlexisRenchon Co-authored-by: SBozzolo Co-authored-by: kmdeck Co-authored-by: braghiere --- .buildkite/Manifest.toml | 334 +++++---- .buildkite/Project.toml | 4 +- .buildkite/pipeline.yml | 4 +- docs/src/diagnostics/make_diagnostic_table.jl | 9 +- docs/src/diagnostics/users_diagnostics.md | 10 +- .../integrated/global/global_soil_canopy.jl | 102 ++- experiments/long_runs/land.jl | 30 +- experiments/long_runs/soil.jl | 16 +- .../Bucket/global_bucket_function.jl | 8 +- src/ClimaLand.jl | 2 +- src/diagnostics/bucket_compute_methods.jl | 119 ---- src/diagnostics/default_diagnostics.jl | 87 ++- src/diagnostics/define_diagnostics.jl | 644 +++++++++++------- src/diagnostics/diagnostic.jl | 3 +- src/diagnostics/land_compute_methods.jl | 152 +++++ src/diagnostics/soilcanopy_compute_methods.jl | 603 ---------------- 16 files changed, 915 insertions(+), 1212 deletions(-) delete mode 100644 src/diagnostics/bucket_compute_methods.jl create mode 100644 src/diagnostics/land_compute_methods.jl delete mode 100644 src/diagnostics/soilcanopy_compute_methods.jl diff --git a/.buildkite/Manifest.toml b/.buildkite/Manifest.toml index 65a5878adf..91b9eb8695 100644 --- a/.buildkite/Manifest.toml +++ b/.buildkite/Manifest.toml @@ -2,12 +2,12 @@ julia_version = "1.10.4" manifest_format = "2.0" -project_hash = "ec4f7d2c4723052ebe1d11f9619ed44dcedb650c" +project_hash = "8bf4280ae518624e2eecdd78d73fb9c6d91ad4cf" [[deps.ADTypes]] -git-tree-sha1 = "6778bcc27496dae5723ff37ee30af451db8b35fe" +git-tree-sha1 = "99a6f5d0ce1c7c6afdb759daa30226f71c54f6b0" uuid = "47edcb42-4c32-4615-8424-f2b9edc5f35b" -version = "1.6.2" +version = "1.7.1" weakdeps = ["ChainRulesCore", "EnzymeCore"] [deps.ADTypes.extensions] @@ -293,10 +293,10 @@ weakdeps = ["ChainRulesCore", "EnzymeCore", "SpecialFunctions"] SpecialFunctionsExt = "SpecialFunctions" [[deps.CUDA_Driver_jll]] -deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] -git-tree-sha1 = "97df9d4d6be8ac6270cb8fd3b8fc413690820cbd" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "325058b426c2b421e3d2df3d5fa646d72d2e3e7e" uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" -version = "0.9.1+1" +version = "0.9.2+0" [[deps.CUDA_Runtime_Discovery]] deps = ["Libdl"] @@ -318,9 +318,9 @@ version = "9.0.0+1" [[deps.Cairo]] deps = ["Cairo_jll", "Colors", "Glib_jll", "Graphics", "Libdl", "Pango_jll"] -git-tree-sha1 = "d0b3f8b4ad16cb0a2988c6788646a5e6a17b6b1b" +git-tree-sha1 = "7b6ad8c35f4bc3bca8eb78127c8b99719506a5fb" uuid = "159f3aea-2a34-519c-b102-8c37f9878175" -version = "1.0.5" +version = "1.1.0" [[deps.CairoMakie]] deps = ["CRC32c", "Cairo", "Colors", "FileIO", "FreeType", "GeometryBasics", "LinearAlgebra", "Makie", "PrecompileTools"] @@ -334,12 +334,6 @@ git-tree-sha1 = "a2f1c8c668c8e3cb4cca4e57a8efdb09067bb3fd" uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" version = "1.18.0+2" -[[deps.Calculus]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "f641eb0a4f00c343bbc32346e1217b86f3ce9dad" -uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" -version = "0.5.1" - [[deps.ChainRules]] deps = ["Adapt", "ChainRulesCore", "Compat", "Distributed", "GPUArraysCore", "IrrationalConstants", "LinearAlgebra", "Random", "RealDot", "SparseArrays", "SparseInverseSubset", "Statistics", "StructArrays", "SuiteSparse"] git-tree-sha1 = "227985d885b4dbce5e18a96f9326ea1e836e5a03" @@ -357,18 +351,15 @@ weakdeps = ["SparseArrays"] ChainRulesCoreSparseArraysExt = "SparseArrays" [[deps.ClimaAnalysis]] -deps = ["NCDatasets", "OrderedCollections", "Reexport", "Statistics"] -git-tree-sha1 = "8e11ef61b19226e8f3bd63004bed583bb1a4d107" +deps = ["Dates", "Interpolations", "NCDatasets", "NaNStatistics", "OrderedCollections", "Reexport", "Statistics"] +git-tree-sha1 = "e13d742cd5a5ad287cf72ab22cb0927780cfe596" uuid = "29b5916a-a76c-4e73-9657-3c8fd22e65e6" -version = "0.5.6" +version = "0.5.7" +weakdeps = ["GeoMakie", "Makie"] [deps.ClimaAnalysis.extensions] - CairoMakieExt = "CairoMakie" GeoMakieExt = "GeoMakie" - - [deps.ClimaAnalysis.weakdeps] - CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" - GeoMakie = "db073c08-6b98-4ee5-b6a4-5efafb3259c6" + MakieExt = "Makie" [[deps.ClimaComms]] git-tree-sha1 = "ec303a4a66dc0a0ebe15a639a7e685afeaa0daef" @@ -382,9 +373,9 @@ weakdeps = ["CUDA", "MPI"] [[deps.ClimaCore]] deps = ["Adapt", "BandedMatrices", "BlockArrays", "ClimaComms", "CubedSphere", "DataStructures", "DocStringExtensions", "ForwardDiff", "GaussQuadrature", "GilbertCurves", "HDF5", "InteractiveUtils", "IntervalSets", "KrylovKit", "LinearAlgebra", "MultiBroadcastFusion", "NVTX", "PkgVersion", "RecursiveArrayTools", "RootSolvers", "SparseArrays", "StaticArrays", "Statistics", "Unrolled"] -git-tree-sha1 = "fa5335ad4b4596c70882c42366172b52aad7a499" +git-tree-sha1 = "3c05a897d67276ff8cfbdac4c92a5ad1da599c00" uuid = "d414da3d-4745-48bb-8d80-42e94e092884" -version = "0.14.10" +version = "0.14.11" weakdeps = ["CUDA", "Krylov"] [deps.ClimaCore.extensions] @@ -399,15 +390,15 @@ version = "0.4.5" [[deps.ClimaDiagnostics]] deps = ["Accessors", "ClimaComms", "ClimaCore", "Dates", "NCDatasets", "SciMLBase"] -git-tree-sha1 = "228ff3bc4dbd7329ef054f9bfbbe34075234ca25" +git-tree-sha1 = "4f8abbf3af5a78b36bc40a33ef7e3fa1d3e8f138" uuid = "1ecacbb8-0713-4841-9a07-eb5aa8a2d53f" -version = "0.2.3" +version = "0.2.4" [[deps.ClimaLand]] deps = ["Adapt", "ArtifactWrappers", "ClimaComms", "ClimaCore", "ClimaDiagnostics", "ClimaUtilities", "DataFrames", "Dates", "DocStringExtensions", "Insolation", "Interpolations", "IntervalSets", "LazyArtifacts", "LinearAlgebra", "NCDatasets", "SciMLBase", "StaticArrays", "SurfaceFluxes", "Thermodynamics", "UnrolledUtilities"] path = ".." uuid = "08f4d4ce-cf43-44bb-ad95-9d2d5f413532" -version = "0.14.1" +version = "0.14.2" [deps.ClimaLand.extensions] CreateParametersExt = "ClimaParams" @@ -424,9 +415,9 @@ version = "0.14.1" [[deps.ClimaParams]] deps = ["DocStringExtensions", "TOML", "Test"] -git-tree-sha1 = "c4c372b4c4c7d1cd2bc71daf2689d83f494206c2" +git-tree-sha1 = "2c6841b4b71bb0a370616a2b7c7708bfb2ab8caf" uuid = "5c42b081-d73a-476f-9059-fd94b934656c" -version = "0.10.10" +version = "0.10.12" [[deps.ClimaTimeSteppers]] deps = ["ClimaComms", "Colors", "DataStructures", "DiffEqBase", "DiffEqCallbacks", "KernelAbstractions", "Krylov", "LinearAlgebra", "LinearOperators", "NVTX", "SciMLBase", "StaticArrays"] @@ -446,9 +437,9 @@ version = "0.7.33" [[deps.ClimaUtilities]] deps = ["Artifacts", "Dates"] -git-tree-sha1 = "f516cf47cf12eaade1e326e7566738147a2e924a" +git-tree-sha1 = "d572737e623699c37cdc8bb63d789fedc3dd3a95" uuid = "b3f4f4ca-9299-4f7f-bd9b-81e1242a7513" -version = "0.1.11" +version = "0.1.13" [deps.ClimaUtilities.extensions] ClimaUtilitiesClimaCommsCUDAExt = ["ClimaComms", "CUDA"] @@ -476,9 +467,9 @@ version = "0.1.13" [[deps.CodecZlib]] deps = ["TranscodingStreams", "Zlib_jll"] -git-tree-sha1 = "b8fe8546d52ca154ac556809e10c75e6e7430ac8" +git-tree-sha1 = "bce6804e5e6044c6daab27bb533d1295e4a2e759" uuid = "944b1d66-785c-5afd-91f1-9de20f533193" -version = "0.7.5" +version = "0.7.6" [[deps.ColorBrewer]] deps = ["Colors", "JSON", "Test"] @@ -531,16 +522,11 @@ git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7" uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" version = "0.3.0" -[[deps.CommonWorldInvalidations]] -git-tree-sha1 = "ae52d1c52048455e85a387fbee9be553ec2b68d0" -uuid = "f70d9fcc-98c5-4d4a-abd7-e4cdeebd8ca8" -version = "1.0.0" - [[deps.Compat]] deps = ["TOML", "UUIDs"] -git-tree-sha1 = "b1c55339b7c6c350ee89f2c1604299660525b248" +git-tree-sha1 = "8ae8d32e09f0dcf42a36b90d4e17f5dd2e4c4215" uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.15.0" +version = "4.16.0" weakdeps = ["Dates", "LinearAlgebra"] [deps.Compat.extensions] @@ -593,6 +579,12 @@ git-tree-sha1 = "439e35b0b36e2e5881738abc8857bd92ad6ff9a8" uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" version = "0.6.3" +[[deps.CoordinateTransformations]] +deps = ["LinearAlgebra", "StaticArrays"] +git-tree-sha1 = "f9d7112bfff8a19a3a4ea4e03a8e6a91fe8456bf" +uuid = "150eb455-5306-5404-9cee-2592286d6298" +version = "0.6.3" + [[deps.CpuId]] deps = ["Markdown"] git-tree-sha1 = "fcbb72b032692610bfbdb15018ac16a36cf2e406" @@ -649,9 +641,9 @@ version = "0.1.2" [[deps.DelaunayTriangulation]] deps = ["AdaptivePredicates", "EnumX", "ExactPredicates", "Random"] -git-tree-sha1 = "1abb6a8541775a0bf82749ac8373a34e9f2f71e0" +git-tree-sha1 = "b5f1c6532d2ea71e99b74231b0a3d53fba846ced" uuid = "927a84f5-c5f4-47a5-9785-b46e178433df" -version = "1.1.1" +version = "1.1.3" [[deps.DelimitedFiles]] deps = ["Mmap"] @@ -660,10 +652,10 @@ uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" version = "1.9.1" [[deps.DiffEqBase]] -deps = ["ArrayInterface", "ConcreteStructs", "DataStructures", "DocStringExtensions", "EnumX", "EnzymeCore", "FastBroadcast", "FastClosures", "ForwardDiff", "FunctionWrappers", "FunctionWrappersWrappers", "LinearAlgebra", "Logging", "Markdown", "MuladdMacro", "Parameters", "PreallocationTools", "PrecompileTools", "Printf", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLOperators", "Setfield", "Static", "StaticArraysCore", "Statistics", "Tricks", "TruncatedStacktraces"] -git-tree-sha1 = "72950e082d2241a1da1c924147943e2918471af9" +deps = ["ArrayInterface", "ConcreteStructs", "DataStructures", "DocStringExtensions", "EnumX", "EnzymeCore", "FastBroadcast", "FastClosures", "ForwardDiff", "FunctionWrappers", "FunctionWrappersWrappers", "LinearAlgebra", "Logging", "Markdown", "MuladdMacro", "Parameters", "PreallocationTools", "PrecompileTools", "Printf", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLOperators", "Setfield", "SparseArrays", "Static", "StaticArraysCore", "Statistics", "Tricks", "TruncatedStacktraces"] +git-tree-sha1 = "d1e8a4642e28b0945bde6e2e1ac569b9e0abd728" uuid = "2b5f629d-d688-5b77-993f-72d75c75574e" -version = "6.152.2" +version = "6.151.5" [deps.DiffEqBase.extensions] DiffEqBaseCUDAExt = "CUDA" @@ -675,7 +667,6 @@ version = "6.152.2" DiffEqBaseMeasurementsExt = "Measurements" DiffEqBaseMonteCarloMeasurementsExt = "MonteCarloMeasurements" DiffEqBaseReverseDiffExt = "ReverseDiff" - DiffEqBaseSparseArraysExt = "SparseArrays" DiffEqBaseTrackerExt = "Tracker" DiffEqBaseUnitfulExt = "Unitful" @@ -689,7 +680,6 @@ version = "6.152.2" Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7" MonteCarloMeasurements = "0987c9cc-fe09-11e8-30f0-b96dd679fdca" ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" - SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" @@ -717,9 +707,9 @@ version = "1.15.1" [[deps.DifferentiationInterface]] deps = ["ADTypes", "Compat", "DocStringExtensions", "FillArrays", "LinearAlgebra", "PackageExtensionCompat", "SparseArrays", "SparseMatrixColorings"] -git-tree-sha1 = "33cf7b202a00a233c5b24cb3aae9b523a527a5a1" +git-tree-sha1 = "5f9a52dc40218e85daa695600733f5ccaa7eb80b" uuid = "a0c0ee7d-e4b9-4e03-894e-1c5f64a51d63" -version = "0.5.10" +version = "0.5.13" [deps.DifferentiationInterface.extensions] DifferentiationInterfaceChainRulesCoreExt = "ChainRulesCore" @@ -774,9 +764,9 @@ uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" [[deps.Distributions]] deps = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] -git-tree-sha1 = "9c405847cc7ecda2dc921ccf18b47ca150d7317e" +git-tree-sha1 = "0e0a1264b0942f1f3abb2b30891f2a590cc652ac" uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" -version = "0.25.109" +version = "0.25.110" [deps.Distributions.extensions] DistributionsChainRulesCoreExt = "ChainRulesCore" @@ -799,12 +789,6 @@ deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" version = "1.6.0" -[[deps.DualNumbers]] -deps = ["Calculus", "NaNMath", "SpecialFunctions"] -git-tree-sha1 = "5837a837389fccf076445fce071c8ddaea35a566" -uuid = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74" -version = "0.6.8" - [[deps.EarCut_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "e3290f2d49e661fbd94046d7e3726ffcb2d41053" @@ -822,9 +806,9 @@ uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" version = "1.0.4" [[deps.EnzymeCore]] -git-tree-sha1 = "d445df66dd8761a4c27df950db89c6a3a0629fe7" +git-tree-sha1 = "8f205a601760f4798a10f138c3940f0451d95188" uuid = "f151be2c-9106-41f4-ab19-57ee4f262869" -version = "0.7.7" +version = "0.7.8" weakdeps = ["Adapt"] [deps.EnzymeCore.extensions] @@ -968,10 +952,10 @@ weakdeps = ["PDMats", "SparseArrays", "Statistics"] FillArraysStatisticsExt = "Statistics" [[deps.FiniteDiff]] -deps = ["ArrayInterface", "LinearAlgebra", "Requires", "Setfield", "SparseArrays"] -git-tree-sha1 = "2de436b72c3422940cbe1367611d137008af7ec3" +deps = ["ArrayInterface", "LinearAlgebra", "Setfield", "SparseArrays"] +git-tree-sha1 = "f9219347ebf700e77ca1d48ef84e4a82a6701882" uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" -version = "2.23.1" +version = "2.24.0" [deps.FiniteDiff.extensions] FiniteDiffBandedMatricesExt = "BandedMatrices" @@ -991,19 +975,21 @@ version = "0.8.5" [[deps.Flux]] deps = ["Adapt", "ChainRulesCore", "Compat", "Functors", "LinearAlgebra", "MLUtils", "MacroTools", "NNlib", "OneHotArrays", "Optimisers", "Preferences", "ProgressLogging", "Random", "Reexport", "SparseArrays", "SpecialFunctions", "Statistics", "Zygote"] -git-tree-sha1 = "edacf029ed6276301e455e34d7ceeba8cc34078a" +git-tree-sha1 = "fbf100b4bed74c9b6fac0ebd1031e04977d35b3b" uuid = "587475ba-b771-5e3f-ad9e-33799f191a9c" -version = "0.14.16" +version = "0.14.19" [deps.Flux.extensions] FluxAMDGPUExt = "AMDGPU" FluxCUDAExt = "CUDA" FluxCUDAcuDNNExt = ["CUDA", "cuDNN"] + FluxEnzymeExt = "Enzyme" FluxMetalExt = "Metal" [deps.Flux.weakdeps] AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" Metal = "dde4c033-4e86-420c-a63e-0dd931031962" cuDNN = "02a925ec-e4fe-4b08-9a7e-0d78e3d38ccd" @@ -1121,12 +1107,51 @@ git-tree-sha1 = "eb6f1f48aa994f3018cbd029a17863c6535a266d" uuid = "d54b0c1a-921d-58e0-8e36-89d8069c0969" version = "0.5.8" +[[deps.GeoFormatTypes]] +git-tree-sha1 = "59107c179a586f0fe667024c5eb7033e81333271" +uuid = "68eda718-8dee-11e9-39e7-89f7f65f511f" +version = "0.4.2" + [[deps.GeoInterface]] deps = ["Extents"] git-tree-sha1 = "9fff8990361d5127b770e3454488360443019bb3" uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" version = "1.3.5" +[[deps.GeoInterfaceMakie]] +deps = ["GeoInterface", "GeometryBasics", "MakieCore"] +git-tree-sha1 = "3f87fd8414194dd25ea5d0371c3950985e3c8d86" +uuid = "0edc0954-3250-4c18-859d-ec71c1660c08" +version = "0.1.8" + +[[deps.GeoInterfaceRecipes]] +deps = ["GeoInterface", "RecipesBase"] +git-tree-sha1 = "fb1156076f24f1dfee45b3feadb31d05730a49ac" +uuid = "0329782f-3d07-4b52-b9f6-d3137cf03c7a" +version = "1.0.2" + +[[deps.GeoJSON]] +deps = ["Extents", "GeoFormatTypes", "GeoInterface", "GeoInterfaceMakie", "GeoInterfaceRecipes", "JSON3", "StructTypes", "Tables"] +git-tree-sha1 = "e2ae0c6d4f6b8c49eccc261fef29c290998e44a5" +uuid = "61d90e0f-e114-555e-ac52-39dfb47a3ef9" +version = "0.8.1" +weakdeps = ["Makie"] + + [deps.GeoJSON.extensions] + GeoJSONMakieExt = "Makie" + +[[deps.GeoMakie]] +deps = ["Colors", "Downloads", "GeoInterface", "GeoJSON", "Geodesy", "GeometryBasics", "ImageIO", "LinearAlgebra", "Makie", "Proj", "Reexport", "Statistics", "StructArrays"] +git-tree-sha1 = "cd10770fef1d33132ec73c21fae1047a00ff3831" +uuid = "db073c08-6b98-4ee5-b6a4-5efafb3259c6" +version = "0.6.5" + +[[deps.Geodesy]] +deps = ["CoordinateTransformations", "Dates", "LinearAlgebra", "StaticArrays"] +git-tree-sha1 = "ed98a4429bf0a033ccc5e036120181dd52f06d31" +uuid = "0ef565a4-170c-5f04-8de2-149903a85f3d" +version = "1.1.0" + [[deps.GeometryBasics]] deps = ["EarCut_jll", "Extents", "GeoInterface", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"] git-tree-sha1 = "b62f2b2d76cee0d61a2ef2b3118cd2a3215d3134" @@ -1220,10 +1245,10 @@ uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" version = "2.11.1+0" [[deps.HypergeometricFunctions]] -deps = ["DualNumbers", "LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] -git-tree-sha1 = "f218fe3736ddf977e0e772bc9a586b2383da2685" +deps = ["LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] +git-tree-sha1 = "7c4195be1649ae622304031ed46a2f4df989f1eb" uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" -version = "0.3.23" +version = "0.3.24" [[deps.IRTools]] deps = ["InteractiveUtils", "MacroTools"] @@ -1348,14 +1373,14 @@ weakdeps = ["Random", "RecipesBase", "Statistics"] IntervalSetsStatisticsExt = "Statistics" [[deps.InverseFunctions]] -deps = ["Test"] -git-tree-sha1 = "18c59411ece4838b18cd7f537e56cf5e41ce5bfd" +git-tree-sha1 = "2787db24f4e03daf859c6509ff87764e4182f7d1" uuid = "3587e190-3f89-42d0-90ee-14403ec27112" -version = "0.1.15" -weakdeps = ["Dates"] +version = "0.1.16" +weakdeps = ["Dates", "Test"] [deps.InverseFunctions.extensions] - DatesExt = "Dates" + InverseFunctionsDatesExt = "Dates" + InverseFunctionsTestExt = "Test" [[deps.InvertedIndices]] git-tree-sha1 = "0dc7b50b8d436461be01300fd8cd45aa0274b038" @@ -1401,6 +1426,18 @@ git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" version = "0.21.4" +[[deps.JSON3]] +deps = ["Dates", "Mmap", "Parsers", "PrecompileTools", "StructTypes", "UUIDs"] +git-tree-sha1 = "eb3edce0ed4fa32f75a0a11217433c31d56bd48b" +uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" +version = "1.14.0" + + [deps.JSON3.extensions] + JSON3ArrowExt = ["ArrowTypes"] + + [deps.JSON3.weakdeps] + ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" + [[deps.JpegTurbo]] deps = ["CEnum", "FileIO", "ImageCore", "JpegTurbo_jll", "TOML"] git-tree-sha1 = "fa6d0bcff8583bac20f1ffa708c3913ca605c611" @@ -1433,9 +1470,9 @@ version = "0.6.0" [[deps.KernelAbstractions]] deps = ["Adapt", "Atomix", "InteractiveUtils", "LinearAlgebra", "MacroTools", "PrecompileTools", "Requires", "SparseArrays", "StaticArrays", "UUIDs", "UnsafeAtomics", "UnsafeAtomicsLLVM"] -git-tree-sha1 = "d0448cebd5919e06ca5edc7a264631790de810ec" +git-tree-sha1 = "0fac59881e91c7233a9b0d47f4b7d9432e534f0f" uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -version = "0.9.22" +version = "0.9.23" weakdeps = ["EnzymeCore"] [deps.KernelAbstractions.extensions] @@ -1477,9 +1514,9 @@ version = "3.0.0+1" [[deps.LLVM]] deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Requires", "Unicode"] -git-tree-sha1 = "020abd49586480c1be84f57da0017b5d3db73f7c" +git-tree-sha1 = "2470e69781ddd70b8878491233cd09bc1bd7fc96" uuid = "929cbde3-209d-540e-8aea-75f648917ca0" -version = "8.0.0" +version = "8.1.0" weakdeps = ["BFloat16s"] [deps.LLVM.extensions] @@ -1487,9 +1524,9 @@ weakdeps = ["BFloat16s"] [[deps.LLVMExtra_jll]] deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "c2636c264861edc6d305e6b4d528f09566d24c5e" +git-tree-sha1 = "597d1c758c9ae5d985ba4202386a607c675ee700" uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" -version = "0.0.30+0" +version = "0.0.31+0" [[deps.LLVMLoopInfo]] git-tree-sha1 = "2e5c102cfc41f48ae4740c7eca7743cc7e7b75ea" @@ -1498,9 +1535,9 @@ version = "1.0.0" [[deps.LLVMOpenMP_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "d986ce2d884d49126836ea94ed5bfb0f12679713" +git-tree-sha1 = "e16271d212accd09d52ee0ae98956b8a05c4b626" uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" -version = "15.0.7+0" +version = "17.0.6+0" [[deps.LRUCache]] git-tree-sha1 = "b3cc6698599b10e652832c2f23db3cab99d51b59" @@ -1524,16 +1561,18 @@ version = "1.3.1" [[deps.Latexify]] deps = ["Format", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "OrderedCollections", "Requires"] -git-tree-sha1 = "5b0d630f3020b82c0775a51d05895852f8506f50" +git-tree-sha1 = "ce5f5621cac23a86011836badfedf664a612cee4" uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" -version = "0.16.4" +version = "0.16.5" [deps.Latexify.extensions] DataFramesExt = "DataFrames" + SparseArraysExt = "SparseArrays" SymEngineExt = "SymEngine" [deps.Latexify.weakdeps] DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" SymEngine = "123dc426-2d89-5057-bbad-38513e3affd8" [[deps.LayoutPointers]] @@ -1544,9 +1583,9 @@ version = "0.1.17" [[deps.LazyArrays]] deps = ["ArrayLayouts", "FillArrays", "LinearAlgebra", "MacroTools", "SparseArrays"] -git-tree-sha1 = "b8ea0abe6cc872996e87356951d286d25d485aba" +git-tree-sha1 = "507b423197fdd9e77b74aa2532c0a05eb7eb4004" uuid = "5078a376-72f3-5289-bfd5-ec5146d43c02" -version = "2.1.9" +version = "2.2.0" [deps.LazyArrays.extensions] LazyArraysBandedMatricesExt = "BandedMatrices" @@ -1646,9 +1685,9 @@ version = "2.40.1+0" [[deps.LineSearches]] deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"] -git-tree-sha1 = "7bbea35cec17305fc70a0e5b4641477dc0789d9d" +git-tree-sha1 = "e4c3be53733db1051cc15ecf573b1042b3a712a1" uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" -version = "7.2.0" +version = "7.3.0" [[deps.LinearAlgebra]] deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] @@ -1672,9 +1711,9 @@ version = "2.8.0" [[deps.LinearSolve]] deps = ["ArrayInterface", "ChainRulesCore", "ConcreteStructs", "CpuId", "DocStringExtensions", "EnumX", "FastLapackInterface", "GPUArraysCore", "InteractiveUtils", "KLU", "Krylov", "LazyArrays", "Libdl", "LinearAlgebra", "MKL_jll", "Markdown", "PrecompileTools", "Preferences", "RecursiveFactorization", "Reexport", "SciMLBase", "SciMLOperators", "Setfield", "SparseArrays", "Sparspak", "StaticArraysCore", "UnPack"] -git-tree-sha1 = "bae39cec701960d14dc7d3c05491c1bfd922fa1d" +git-tree-sha1 = "ee625f4053362526950661ce3022c7a483c6f8e5" uuid = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" -version = "2.31.1" +version = "2.32.0" [deps.LinearSolve.extensions] LinearSolveBandedMatricesExt = "BandedMatrices" @@ -1917,9 +1956,9 @@ version = "4.5.1" [[deps.NNlib]] deps = ["Adapt", "Atomix", "ChainRulesCore", "GPUArraysCore", "KernelAbstractions", "LinearAlgebra", "Pkg", "Random", "Requires", "Statistics"] -git-tree-sha1 = "190dcada8cf9520198058c4544862b1f88c6c577" +git-tree-sha1 = "ae52c156a63bb647f80c26319b104e99e5977e51" uuid = "872c559c-99b0-510c-b3b7-b6c96a88d5cd" -version = "0.9.21" +version = "0.9.22" [deps.NNlib.extensions] NNlibAMDGPUExt = "AMDGPU" @@ -1953,6 +1992,12 @@ git-tree-sha1 = "0877504529a3e5c3343c6f8b4c0381e57e4387e4" uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" version = "1.0.2" +[[deps.NaNStatistics]] +deps = ["PrecompileTools", "Static", "StaticArrayInterface"] +git-tree-sha1 = "643573fb1771d2ae140b775c18e4278578051c03" +uuid = "b946abbf-3ea7-4610-9019-9858bfdeaf2d" +version = "0.6.41" + [[deps.NameResolution]] deps = ["PrettyPrint"] git-tree-sha1 = "1a0fa0e9613f46c9b8c11eee38ebb4f590013c5e" @@ -1977,9 +2022,9 @@ version = "1.2.0" [[deps.NonlinearSolve]] deps = ["ADTypes", "ArrayInterface", "ConcreteStructs", "DiffEqBase", "FastBroadcast", "FastClosures", "FiniteDiff", "ForwardDiff", "LazyArrays", "LineSearches", "LinearAlgebra", "LinearSolve", "MaybeInplace", "PrecompileTools", "Preferences", "Printf", "RecursiveArrayTools", "Reexport", "SciMLBase", "SimpleNonlinearSolve", "SparseArrays", "SparseDiffTools", "StaticArraysCore", "SymbolicIndexingInterface", "TimerOutputs"] -git-tree-sha1 = "3adb1e5945b5a6b1eaee754077f25ccc402edd7f" +git-tree-sha1 = "bcd8812e751326ff1d4b2dd50764b93df51f143b" uuid = "8913a72c-1f9b-4ce2-8d82-65094dcecaec" -version = "3.13.1" +version = "3.14.0" [deps.NonlinearSolve.extensions] NonlinearSolveBandedMatricesExt = "BandedMatrices" @@ -2113,6 +2158,12 @@ git-tree-sha1 = "67186a2bc9a90f9f85ff3cc8277868961fb57cbd" uuid = "f57f5aa1-a3ce-4bc8-8ab9-96f992907883" version = "0.4.3" +[[deps.PROJ_jll]] +deps = ["Artifacts", "JLLWrappers", "LibCURL_jll", "Libdl", "Libtiff_jll", "SQLite_jll"] +git-tree-sha1 = "84aa844bd56f62282116b413fbefb45e370e54d6" +uuid = "58948b4f-47e0-5654-a9ad-f609743f8632" +version = "901.300.0+1" + [[deps.PackageExtensionCompat]] git-tree-sha1 = "fb28e33b8a95c4cee25ce296c817d89cc2e53518" uuid = "65ce6f38-6b18-4e1d-a461-8949797d7930" @@ -2204,10 +2255,10 @@ version = "1.40.5" Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" [[deps.Polyester]] -deps = ["ArrayInterface", "BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "ManualMemory", "PolyesterWeave", "Requires", "Static", "StaticArrayInterface", "StrideArraysCore", "ThreadingUtilities"] -git-tree-sha1 = "9ff799e8fb8ed6717710feee3be3bc20645daa97" +deps = ["ArrayInterface", "BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "ManualMemory", "PolyesterWeave", "Static", "StaticArrayInterface", "StrideArraysCore", "ThreadingUtilities"] +git-tree-sha1 = "6d38fea02d983051776a856b7df75b30cf9a3c1f" uuid = "f517fe37-dbe3-4b94-8317-1923a5111588" -version = "0.7.15" +version = "0.7.16" [[deps.PolyesterWeave]] deps = ["BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "Static", "ThreadingUtilities"] @@ -2228,9 +2279,9 @@ version = "1.4.3" [[deps.PreallocationTools]] deps = ["Adapt", "ArrayInterface", "ForwardDiff"] -git-tree-sha1 = "d7f3f63331c7c8c81245b4ee2815b7d496365833" +git-tree-sha1 = "6c62ce45f268f3f958821a1e5192cf91c75ae89c" uuid = "d236fae5-4411-538c-8e31-a6e3d9e00b46" -version = "0.4.23" +version = "0.4.24" [deps.PreallocationTools.extensions] PreallocationToolsReverseDiffExt = "ReverseDiff" @@ -2293,6 +2344,12 @@ git-tree-sha1 = "8f6bc219586aef8baf0ff9a5fe16ee9c70cb65e4" uuid = "92933f4c-e287-5a05-a399-4b506db050ca" version = "1.10.2" +[[deps.Proj]] +deps = ["CEnum", "CoordinateTransformations", "GeoFormatTypes", "GeoInterface", "NetworkOptions", "PROJ_jll"] +git-tree-sha1 = "0af230735907f040d52854afc600c17b58e9e73a" +uuid = "c94c279d-25a6-4763-9509-64d165bea63e" +version = "1.7.1" + [[deps.PtrArrays]] git-tree-sha1 = "f011fbb92c4d401059b2212c05c0601b70f8b759" uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d" @@ -2331,10 +2388,10 @@ uuid = "74087812-796a-5b5d-8853-05524746bad3" version = "1.7.0" [[deps.RandomNumbers]] -deps = ["Random", "Requires"] -git-tree-sha1 = "043da614cc7e95c703498a491e2c21f58a2b8111" +deps = ["Random"] +git-tree-sha1 = "c6ec94d2aaba1ab2ff983052cf6a606ca5985902" uuid = "e6cf234a-135c-5ec9-84dd-332b85af5143" -version = "1.5.3" +version = "1.6.0" [[deps.RangeArrays]] git-tree-sha1 = "b9039e93773ddcfc828f12aadf7115b4b4d225f5" @@ -2370,10 +2427,10 @@ uuid = "01d81517-befc-4cb6-b9ec-a95719d0359c" version = "0.6.12" [[deps.RecursiveArrayTools]] -deps = ["Adapt", "ArrayInterface", "DocStringExtensions", "GPUArraysCore", "IteratorInterfaceExtensions", "LinearAlgebra", "RecipesBase", "SparseArrays", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables"] -git-tree-sha1 = "b450d967a770fb13d0e26358f58375e20361cf9c" +deps = ["Adapt", "ArrayInterface", "DocStringExtensions", "GPUArraysCore", "IteratorInterfaceExtensions", "LinearAlgebra", "RecipesBase", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables"] +git-tree-sha1 = "b034171b93aebc81b3e1890a036d13a9c4a9e3e0" uuid = "731186ca-8d62-57ce-b412-fbd966d074cd" -version = "3.26.0" +version = "3.27.0" [deps.RecursiveArrayTools.extensions] RecursiveArrayToolsFastBroadcastExt = "FastBroadcast" @@ -2381,6 +2438,7 @@ version = "3.26.0" RecursiveArrayToolsMeasurementsExt = "Measurements" RecursiveArrayToolsMonteCarloMeasurementsExt = "MonteCarloMeasurements" RecursiveArrayToolsReverseDiffExt = ["ReverseDiff", "Zygote"] + RecursiveArrayToolsSparseArraysExt = ["SparseArrays"] RecursiveArrayToolsTrackerExt = "Tracker" RecursiveArrayToolsZygoteExt = "Zygote" @@ -2390,6 +2448,7 @@ version = "3.26.0" Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7" MonteCarloMeasurements = "0987c9cc-fe09-11e8-30f0-b96dd679fdca" ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" @@ -2424,9 +2483,9 @@ version = "0.7.1" [[deps.Rmath_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "d483cd324ce5cf5d61b77930f0bbd6cb61927d21" +git-tree-sha1 = "e60724fd3beea548353984dc61c943ecddb0e29a" uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" -version = "0.4.2+0" +version = "0.4.3+0" [[deps.RootSolvers]] deps = ["ForwardDiff"] @@ -2466,6 +2525,12 @@ git-tree-sha1 = "456f610ca2fbd1c14f5fcf31c6bfadc55e7d66e0" uuid = "476501e8-09a2-5ece-8869-fb82de89a1fa" version = "0.6.43" +[[deps.SQLite_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "004fffbe2711abdc7263a980bbb1af9620781dd9" +uuid = "76ed43ae-9a5d-5a62-8c75-30186b810ce8" +version = "3.45.3+0" + [[deps.SafeTestsets]] git-tree-sha1 = "81ec49d645af090901120a1542e67ecbbe044db3" uuid = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" @@ -2473,9 +2538,9 @@ version = "0.1.0" [[deps.SciMLBase]] deps = ["ADTypes", "Accessors", "ArrayInterface", "CommonSolve", "ConstructionBase", "Distributed", "DocStringExtensions", "EnumX", "Expronicon", "FunctionWrappersWrappers", "IteratorInterfaceExtensions", "LinearAlgebra", "Logging", "Markdown", "PrecompileTools", "Preferences", "Printf", "RecipesBase", "RecursiveArrayTools", "Reexport", "RuntimeGeneratedFunctions", "SciMLOperators", "SciMLStructures", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables"] -git-tree-sha1 = "7f0e208db50f5fee2386b6d8dc9608d580059331" +git-tree-sha1 = "79564263adfdeb7a7110316c0bf0da55b95ab281" uuid = "0bca4576-84f4-4d90-8ffe-ffa030f20462" -version = "2.48.1" +version = "2.49.0" [deps.SciMLBase.extensions] SciMLBaseChainRulesCoreExt = "ChainRulesCore" @@ -2497,10 +2562,11 @@ version = "2.48.1" Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" [[deps.SciMLOperators]] -deps = ["ArrayInterface", "DocStringExtensions", "LinearAlgebra", "MacroTools", "Setfield", "SparseArrays", "StaticArraysCore"] -git-tree-sha1 = "10499f619ef6e890f3f4a38914481cc868689cd5" +deps = ["ArrayInterface", "DocStringExtensions", "LinearAlgebra", "MacroTools", "Setfield", "StaticArraysCore"] +git-tree-sha1 = "23b02c588ac9a17ecb276cc62ab37f3e4fe37b32" uuid = "c0aeaf25-5076-4817-a8d5-81caf7dfa961" -version = "0.3.8" +version = "0.3.9" +weakdeps = ["SparseArrays"] [[deps.SciMLStructures]] deps = ["ArrayInterface"] @@ -2568,9 +2634,9 @@ version = "1.1.0" [[deps.SimpleNonlinearSolve]] deps = ["ADTypes", "ArrayInterface", "ConcreteStructs", "DiffEqBase", "DiffResults", "DifferentiationInterface", "FastClosures", "FiniteDiff", "ForwardDiff", "LinearAlgebra", "MaybeInplace", "PrecompileTools", "Reexport", "SciMLBase", "Setfield", "StaticArraysCore"] -git-tree-sha1 = "03c21a4c373c7c3aa77611430068badaa073d740" +git-tree-sha1 = "4d7a7c177bcb4c6dc465f09db91bfdb28c578919" uuid = "727e6d20-b764-4bd8-a329-72de5adea6c7" -version = "1.11.0" +version = "1.12.0" [deps.SimpleNonlinearSolve.extensions] SimpleNonlinearSolveChainRulesCoreExt = "ChainRulesCore" @@ -2612,9 +2678,9 @@ version = "1.10.0" [[deps.SparseDiffTools]] deps = ["ADTypes", "Adapt", "ArrayInterface", "Compat", "DataStructures", "FiniteDiff", "ForwardDiff", "Graphs", "LinearAlgebra", "PackageExtensionCompat", "Random", "Reexport", "SciMLOperators", "Setfield", "SparseArrays", "StaticArrayInterface", "StaticArrays", "Tricks", "UnPack", "VertexSafeGraphs"] -git-tree-sha1 = "469f51f8c4741ce944be2c0b65423b518b1405b0" +git-tree-sha1 = "c9e5d7ee75cf6a1ca3a22c9a6a4ef451792cf62b" uuid = "47a9eef4-7e08-11e9-0b38-333d64bd3804" -version = "2.19.0" +version = "2.20.0" [deps.SparseDiffTools.extensions] SparseDiffToolsEnzymeExt = "Enzyme" @@ -2637,10 +2703,10 @@ uuid = "dc90abb0-5640-4711-901d-7e5b23a2fada" version = "0.1.2" [[deps.SparseMatrixColorings]] -deps = ["ADTypes", "Compat", "DocStringExtensions", "LinearAlgebra", "Random", "SparseArrays"] -git-tree-sha1 = "ad048e784b816e4de5553a13f1daf148412f3dbd" +deps = ["ADTypes", "Compat", "DataStructures", "DocStringExtensions", "LinearAlgebra", "Random", "SparseArrays"] +git-tree-sha1 = "996dff77d814c45c3f2342fa0113e4ad31e712e8" uuid = "0a514795-09f3-496d-8182-132a7b665d35" -version = "0.3.6" +version = "0.4.0" [[deps.Sparspak]] deps = ["Libdl", "LinearAlgebra", "Logging", "OffsetArrays", "Printf", "SparseArrays", "Test"] @@ -2671,16 +2737,16 @@ uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" version = "0.1.1" [[deps.Static]] -deps = ["CommonWorldInvalidations", "IfElse", "PrecompileTools"] -git-tree-sha1 = "87d51a3ee9a4b0d2fe054bdd3fc2436258db2603" +deps = ["IfElse"] +git-tree-sha1 = "d2fdac9ff3906e27f7a618d47b676941baa6c80c" uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" -version = "1.1.1" +version = "0.8.10" [[deps.StaticArrayInterface]] -deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Requires", "SparseArrays", "Static", "SuiteSparse"] -git-tree-sha1 = "8963e5a083c837531298fc41599182a759a87a6d" +deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Static"] +git-tree-sha1 = "96381d50f1ce85f2663584c8e886a6ca97e60554" uuid = "0d7ed370-da01-4f52-bd93-41d350b8b718" -version = "1.5.1" +version = "1.8.0" weakdeps = ["OffsetArrays", "StaticArrays"] [deps.StaticArrayInterface.extensions] @@ -2756,6 +2822,12 @@ weakdeps = ["Adapt", "GPUArraysCore", "SparseArrays", "StaticArrays"] StructArraysSparseArraysExt = "SparseArrays" StructArraysStaticArraysExt = "StaticArrays" +[[deps.StructTypes]] +deps = ["Dates", "UUIDs"] +git-tree-sha1 = "ca4bccb03acf9faaf4137a9abc1881ed1841aa70" +uuid = "856f2bd8-1eba-4b0a-8007-ebc267875bd4" +version = "1.10.0" + [[deps.SuiteSparse]] deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" @@ -2777,9 +2849,9 @@ weakdeps = ["ClimaParams"] [[deps.SymbolicIndexingInterface]] deps = ["Accessors", "ArrayInterface", "RuntimeGeneratedFunctions", "StaticArraysCore"] -git-tree-sha1 = "2dd32da03adaf43fd91494e38ef3df0ab2e6c20e" +git-tree-sha1 = "c9fce29fb41a10677e24f74421ebe31220b81ad0" uuid = "2efcf032-c050-4f8e-a9bb-153293bab1f5" -version = "0.3.27" +version = "0.3.28" [[deps.TOML]] deps = ["Dates"] @@ -2852,13 +2924,9 @@ uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" version = "0.5.24" [[deps.TranscodingStreams]] -git-tree-sha1 = "96612ac5365777520c3c5396314c8cf7408f436a" +git-tree-sha1 = "e84b3a11b9bece70d14cce63406bbc79ed3464d2" uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.11.1" -weakdeps = ["Random", "Test"] - - [deps.TranscodingStreams.extensions] - TestExt = ["Test", "Random"] +version = "0.11.2" [[deps.Transducers]] deps = ["Adapt", "ArgCheck", "BangBang", "Baselet", "CompositionsBase", "ConstructionBase", "DefineSingletons", "Distributed", "InitialValues", "Logging", "Markdown", "MicroCollections", "Requires", "Setfield", "SplittablesBase", "Tables"] @@ -2960,9 +3028,9 @@ version = "0.2.1" [[deps.UnsafeAtomicsLLVM]] deps = ["LLVM", "UnsafeAtomics"] -git-tree-sha1 = "bf2c553f25e954a9b38c9c0593a59bb13113f9e5" +git-tree-sha1 = "4073c836c2befcb041e5fe306cb6abf621eb3140" uuid = "d80eeb9a-aca5-4d75-85e5-170c8b632249" -version = "0.1.5" +version = "0.2.0" [[deps.Unzip]] git-tree-sha1 = "ca0969166a028236229f63514992fc073799bb78" diff --git a/.buildkite/Project.toml b/.buildkite/Project.toml index 7550071bcd..a53e331c9e 100644 --- a/.buildkite/Project.toml +++ b/.buildkite/Project.toml @@ -7,8 +7,8 @@ CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" ClimaAnalysis = "29b5916a-a76c-4e73-9657-3c8fd22e65e6" ClimaComms = "3a4d1b5c-c61d-41fd-a00a-5873ba7a1b0d" ClimaCore = "d414da3d-4745-48bb-8d80-42e94e092884" -ClimaDiagnostics = "1ecacbb8-0713-4841-9a07-eb5aa8a2d53f" ClimaCoreMakie = "908f55d8-4145-4867-9c14-5dad1a479e4d" +ClimaDiagnostics = "1ecacbb8-0713-4841-9a07-eb5aa8a2d53f" ClimaLand = "08f4d4ce-cf43-44bb-ad95-9d2d5f413532" ClimaParams = "5c42b081-d73a-476f-9059-fd94b934656c" ClimaTimeSteppers = "595c0a79-7f3d-439a-bc5a-b232dc3bde79" @@ -18,6 +18,7 @@ Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" DelimitedFiles = "8bb1440f-4735-579b-a4ab-409b98df4dab" Flux = "587475ba-b771-5e3f-ad9e-33799f191a9c" Formatting = "59287772-0a20-5a39-b81b-1366585eb4c0" +GeoMakie = "db073c08-6b98-4ee5-b6a4-5efafb3259c6" HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3" Insolation = "e98cc03f-d57e-4e3c-b70c-8d51efe9e0d8" Interpolations = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" @@ -41,5 +42,6 @@ Thermodynamics = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" cuDNN = "02a925ec-e4fe-4b08-9a7e-0d78e3d38ccd" [compat] +ClimaAnalysis = "0.5.7" ClimaTimeSteppers = "0.7" Statistics = "1" diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 73c638a8ff..d6f435a180 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -119,7 +119,7 @@ steps: - label: "Global Run CPU" command: "julia --color=yes --project=.buildkite experiments/integrated/global/global_soil_canopy.jl" - artifact_paths: "experiments/integrated/global/plots/*png" + artifact_paths: "experiments/integrated/global/output_active/*png" agents: slurm_mem: 16G @@ -147,7 +147,7 @@ steps: command: "julia --color=yes --project=.buildkite experiments/standalone/Bucket/global_bucket_function.jl" artifact_paths: - "experiments/standalone/Bucket/artifacts/*cpu*" - - "experiments/global_bucket_function/output_active/*.png" + - "experiments/standalone/Bucket/artifacts_function/output_active/*.png" - label: "Global Bucket on CPU (static map albedo)" key: "bucket_era5_cpu" diff --git a/docs/src/diagnostics/make_diagnostic_table.jl b/docs/src/diagnostics/make_diagnostic_table.jl index e7b7cedab6..4839efd307 100644 --- a/docs/src/diagnostics/make_diagnostic_table.jl +++ b/docs/src/diagnostics/make_diagnostic_table.jl @@ -16,7 +16,14 @@ for d in values(CL.Diagnostics.ALL_DIAGNOSTICS) push!(comments, d.comments) push!(standard_names, d.standard_name) end -data = hcat(short_names, long_names, units, comments, standard_names) +i = sortperm(short_names) # indices of short_names sorted alphabetically +data = hcat( + short_names[i], + long_names[i], + units[i], + comments[i], + standard_names[i], +) pretty_table( data; autowrap = true, diff --git a/docs/src/diagnostics/users_diagnostics.md b/docs/src/diagnostics/users_diagnostics.md index 0c9728b579..b01aa58724 100644 --- a/docs/src/diagnostics/users_diagnostics.md +++ b/docs/src/diagnostics/users_diagnostics.md @@ -24,7 +24,7 @@ output_dir = ClimaUtilities.OutputPathGenerator.generate_output_path("base_outpu 2. define a space -Your diagnostics will be written in time and space. These may be defined in your model, but usually land model space is a sphere with no vertical dimension. +Your diagnostics will be written in time and space. These may be defined in your model, but usually land model space is a sphere with no vertical dimension. You may have variables varying with soil depth, and so you will need: ``` @@ -46,7 +46,7 @@ providing the space and output_dir defined in steps 1. and 2. Now that you defined your model and your writter, you can create a callback function to be called when solving your model. For example: ``` -diags = ClimaLand.CLD.default_diagnostics(model, 1.0; output_writer = nc_writer) +diags = ClimaLand.default_diagnostics(model, 1.0; output_writer = nc_writer) diagnostic_handler = ClimaDiagnostics.DiagnosticsHandler(diags, Y, p, t0; dt = Δt) @@ -58,6 +58,10 @@ sol = SciMLBase.solve(prob, ode_algo; dt = Δt, callback = diag_cb) Your diagnostics have now been written in netcdf files in your output folder. +Note that by default, `default_diagnostics` assign two optional kwargs: `output_vars = :long` and `average_period` = :daily. +`output_vars = :long` will write all available diagnostics, whereas `output_vars = :short` will only write essentials diagnostics. +`average_period` defines the period over which diagnostics are averaged, it can be set to `:hourly`, `:daily` and `:monthly`. + # Custom Diagnostics When defining a custom diagnostic, follow these steps: @@ -82,7 +86,7 @@ end compute! = (out, Y, p, t) -> compute_bowen_ratio!(out, Y, p, t, land_model), ) ``` - - Define how to schedule your variables. For example, you want the seasonal maximum of your variables, where season is defined as 90 days. + - Define how to schedule your variables. For example, you want the seasonal maximum of your variables, where season is defined as 90 days. ``` seasonal_maxs(short_names...; output_writer, t_start) = common_diagnostics( 90 * 24 * 60 * 60 * one(t_start), diff --git a/experiments/integrated/global/global_soil_canopy.jl b/experiments/integrated/global/global_soil_canopy.jl index 137e244b84..7d57c34470 100644 --- a/experiments/integrated/global/global_soil_canopy.jl +++ b/experiments/integrated/global/global_soil_canopy.jl @@ -19,16 +19,22 @@ using ClimaLand.Canopy import ClimaLand import ClimaLand.Parameters as LP -using CairoMakie +import CairoMakie +import GeoMakie using Statistics using Dates import NCDatasets +import ClimaDiagnostics +import ClimaAnalysis +import ClimaAnalysis.Visualize as viz +import ClimaUtilities + regridder_type = :InterpolationsRegridder extrapolation_bc = (Interpolations.Periodic(), Interpolations.Flat(), Interpolations.Flat()) context = ClimaComms.context() -outdir = joinpath(pkgdir(ClimaLand), "experiments/integrated/global/plots") +outdir = joinpath(pkgdir(ClimaLand), "experiments/integrated/global") !ispath(outdir) && mkpath(outdir) device_suffix = @@ -361,76 +367,48 @@ prob = SciMLBase.ODEProblem( p, ) -saveat = [t0, tf] -sv = (; - t = Array{Float64}(undef, length(saveat)), - saveval = Array{NamedTuple}(undef, length(saveat)), +# ClimaDiagnostics +output_dir = ClimaUtilities.OutputPathGenerator.generate_output_path(outdir) + +nc_writer = ClimaDiagnostics.Writers.NetCDFWriter(subsurface_space, output_dir) + +diags = ClimaLand.default_diagnostics( + land, + t0; + output_writer = nc_writer, + average_period = :hourly, ) -saving_cb = ClimaLand.NonInterpSavingCallback(sv, saveat) + +diagnostic_handler = + ClimaDiagnostics.DiagnosticsHandler(diags, Y, p, t0; dt = dt) + +diag_cb = ClimaDiagnostics.DiagnosticsCallback(diagnostic_handler) + updateat = Array(t0:(3600 * 3):tf) drivers = ClimaLand.get_drivers(land) updatefunc = ClimaLand.make_update_drivers(drivers) driver_cb = ClimaLand.DriverUpdateCallback(updateat, updatefunc) -cb = SciMLBase.CallbackSet(driver_cb, saving_cb) -@time sol = SciMLBase.solve( + +sol = ClimaComms.@time ClimaComms.device() SciMLBase.solve( prob, ode_algo; dt = dt, - callback = cb, - adaptive = false, - saveat = saveat, + callback = SciMLBase.CallbackSet(driver_cb, diag_cb), ) -if device_suffix == "cpu" - longpts = range(-180.0, 180.0, 101) - latpts = range(-90.0, 90.0, 101) - hcoords = [ - ClimaCore.Geometry.LatLongPoint(lat, long) for long in longpts, - lat in reverse(latpts) - ] - remapper = ClimaCore.Remapping.Remapper(surface_space, hcoords) - S = ClimaLand.Domains.top_center_to_surface( - (sol.u[end].soil.ϑ_l .- θ_r) ./ (ν .- θ_r), - ) - S_ice = ClimaLand.Domains.top_center_to_surface(sol.u[end].soil.θ_i ./ ν) - T_soil = ClimaLand.Domains.top_center_to_surface(sv.saveval[end].soil.T) - SW = sv.saveval[end].drivers.SW_d - - GPP = sv.saveval[end].canopy.photosynthesis.GPP .* 1e6 - T_canopy = sol.u[end].canopy.energy.T - fields = [S, S_ice, T_soil, GPP, T_canopy, SW] - titles = [ - "Effective saturation", - "Effective ice saturation", - "Temperature (K) - Soil", - "GPP", - "Temperature (K) - Canopy", - "Incident SW", - ] - plotnames = ["S", "Sice", "temp", "gpp", "temp_canopy", "sw"] - mask_remap = ClimaCore.Remapping.interpolate(remapper, soil_params_mask_sfc) - for (id, x) in enumerate(fields) - title = titles[id] - plotname = plotnames[id] - x_remap = ClimaCore.Remapping.interpolate(remapper, x) - - fig = Figure(size = (600, 400)) - ax = Axis( - fig[1, 1], - xlabel = "Longitude", - ylabel = "Latitude", - title = title, - ) - clims = extrema(x_remap) - CairoMakie.heatmap!( - ax, - longpts, - latpts, - oceans_to_value.(x_remap, mask_remap, 0.0), - colorrange = clims, +# ClimaAnalysis +simdir = ClimaAnalysis.SimDir(output_dir) + +for short_name in ClimaAnalysis.available_vars(simdir) + var = get(simdir; short_name) + times = var.dims["time"] + for t in times + fig = CairoMakie.Figure(size = (800, 600)) + kwargs = ClimaAnalysis.has_altitude(var) ? Dict(:z => 1) : Dict() + viz.heatmap2D_on_globe!( + fig, + ClimaAnalysis.slice(var, time = t; kwargs...), ) - Colorbar(fig[:, end + 1], colorrange = clims) - outfile = joinpath(outdir, "$plotname.png") - CairoMakie.save(outfile, fig) + CairoMakie.save(joinpath(output_dir, "$short_name.png"), fig) end end diff --git a/experiments/long_runs/land.jl b/experiments/long_runs/land.jl index 7aed2cd370..f9a79ce126 100644 --- a/experiments/long_runs/land.jl +++ b/experiments/long_runs/land.jl @@ -23,10 +23,10 @@ using ClimaUtilities.ClimaArtifacts import Interpolations using Insolation -using ClimaDiagnostics -using ClimaAnalysis +import ClimaDiagnostics +import ClimaAnalysis import ClimaAnalysis.Visualize as viz -using ClimaUtilities +import ClimaUtilities import ClimaUtilities.TimeVaryingInputs: TimeVaryingInput import ClimaUtilities.SpaceVaryingInputs: SpaceVaryingInput @@ -42,6 +42,7 @@ import ClimaLand.Parameters as LP using Statistics using CairoMakie +import GeoMakie using Dates import NCDatasets @@ -598,11 +599,11 @@ function setup_prob(t0, tf, Δt; outdir = outdir, nelements = (101, 15)) nc_writer = ClimaDiagnostics.Writers.NetCDFWriter(subsurface_space, outdir) - diags = ClimaLand.CLD.default_diagnostics( + diags = ClimaLand.default_diagnostics( land, t0; output_writer = nc_writer, - output_vars = :short, + output_vars = :long, ) diagnostic_handler = @@ -646,14 +647,17 @@ setup_and_solve_problem(; greet = true); # read in diagnostics and make some plots! #### ClimaAnalysis #### simdir = ClimaAnalysis.SimDir(outdir) -short_names_2D = ["gpp", "ct", "slw", "si"] -times = 0.0:(60.0 * 60.0 * 12):(60.0 * 60.0 * 24 * 7) -for t in times - for short_name in short_names_2D - var = get(simdir; short_name) +short_names = ["gpp", "swc", "si", "sie"] +for short_name in short_names + var = get(simdir; short_name) + times = ClimaAnalysis.times(var) + for t in times fig = CairoMakie.Figure(size = (800, 600)) - kwargs = short_name in short_names_2D ? Dict() : Dict(:z => 1) - viz.plot!(fig, var, time = t; kwargs...) - CairoMakie.save(joinpath(root_path, "$short_name $t.png"), fig) + kwargs = ClimaAnalysis.has_altitude(var) ? Dict(:z => 1) : Dict() + viz.heatmap2D_on_globe!( + fig, + ClimaAnalysis.slice(var, time = t; kwargs...), + ) + CairoMakie.save(joinpath(root_path, "$(short_name)_$t.png"), fig) end end diff --git a/experiments/long_runs/soil.jl b/experiments/long_runs/soil.jl index dfb1c0be64..36e162739d 100644 --- a/experiments/long_runs/soil.jl +++ b/experiments/long_runs/soil.jl @@ -420,8 +420,7 @@ function setup_prob(t0, tf, Δt; outdir = outdir, nelements = (101, 15)) nc_writer = ClimaDiagnostics.Writers.NetCDFWriter(subsurface_space, outdir) - diags = - ClimaLand.CLD.default_diagnostics(soil, t0; output_writer = nc_writer) + diags = ClimaLand.default_diagnostics(soil, t0; output_writer = nc_writer) diagnostic_handler = ClimaDiagnostics.DiagnosticsHandler(diags, Y, p, t0; dt = Δt) @@ -464,14 +463,15 @@ setup_and_solve_problem(; greet = true); # read in diagnostics and make some plots! #### ClimaAnalysis #### simdir = ClimaAnalysis.SimDir(outdir) -short_names_2D = ["slw", "si", "tsoil"] -times = 0.0:(60.0 * 60.0 * 24 * 20):(60.0 * 60.0 * 24 * 60) -for t in times - for short_name in short_names_2D +short_names = ["swc", "si", "sie"] +for short_name in short_names + var = get(simdir; short_name) + times = ClimaAnalysis.times(var) + for t in times var = get(simdir; short_name) fig = CairoMakie.Figure(size = (800, 600)) - kwargs = short_name in short_names_2D ? Dict() : Dict(:z => 1) + kwargs = ClimaAnalysis.has_altitude(var) ? Dict(:z => 1) : Dict() viz.plot!(fig, var, time = t; kwargs...) - CairoMakie.save(joinpath(root_path, "$short_name $t.png"), fig) + CairoMakie.save(joinpath(root_path, "$(short_name)_$t.png"), fig) end end diff --git a/experiments/standalone/Bucket/global_bucket_function.jl b/experiments/standalone/Bucket/global_bucket_function.jl index 926346362f..2572ba23c8 100644 --- a/experiments/standalone/Bucket/global_bucket_function.jl +++ b/experiments/standalone/Bucket/global_bucket_function.jl @@ -162,15 +162,13 @@ prob = SciMLBase.ODEProblem( ); # ClimaDiagnostics -base_output_dir = "global_bucket_function/" -output_dir = - ClimaUtilities.OutputPathGenerator.generate_output_path(base_output_dir) +output_dir = ClimaUtilities.OutputPathGenerator.generate_output_path(outdir) space = bucket_domain.space.subsurface nc_writer = ClimaDiagnostics.Writers.NetCDFWriter(space, output_dir) -diags = ClimaLand.CLD.default_diagnostics(model, t0; output_writer = nc_writer) +diags = ClimaLand.default_diagnostics(model, t0; output_writer = nc_writer) diagnostic_handler = ClimaDiagnostics.DiagnosticsHandler(diags, Y, p, t0; dt = Δt) @@ -212,7 +210,7 @@ for short_name in vcat(short_names_2D..., short_names_3D...) var = get(simdir; short_name) fig = CairoMakie.Figure(size = (800, 600)) kwargs = short_name in short_names_2D ? Dict() : Dict(:z => 1) - viz.plot!(fig, var, lat = 0; kwargs...) + viz.plot!(fig, var, lon = 0, lat = 0; kwargs...) CairoMakie.save(joinpath(output_dir, "$short_name.png"), fig) end diff --git a/src/ClimaLand.jl b/src/ClimaLand.jl index ab762f0980..2b80b08ab5 100644 --- a/src/ClimaLand.jl +++ b/src/ClimaLand.jl @@ -320,6 +320,6 @@ include("integrated/soil_canopy_model.jl") # Diagnostics include(joinpath("diagnostics", "Diagnostics.jl")) -import .Diagnostics as CLD # ClimaLand Diagnostics +import .Diagnostics: default_diagnostics end diff --git a/src/diagnostics/bucket_compute_methods.jl b/src/diagnostics/bucket_compute_methods.jl deleted file mode 100644 index 9ab65958f6..0000000000 --- a/src/diagnostics/bucket_compute_methods.jl +++ /dev/null @@ -1,119 +0,0 @@ -# stored in p - -function compute_albedo!(out, Y, p, t, land_model::BucketModel) - if isnothing(out) - return copy(p.bucket.α_sfc) - else - out .= p.bucket.α_sfc - end -end - -function compute_net_radiation!(out, Y, p, t, land_model::BucketModel) - if isnothing(out) - return copy(p.bucket.R_n) - else - out .= p.bucket.R_n - end -end - -function compute_surface_temperature!(out, Y, p, t, land_model::BucketModel) - if isnothing(out) - return copy(p.bucket.T_sfc) - else - out .= p.bucket.T_sfc - end -end - -function compute_surface_specific_humidity!( - out, - Y, - p, - t, - land_model::BucketModel, -) - if isnothing(out) - return copy(p.bucket.q_sfc) - else - out .= p.bucket.q_sfc - end -end - -function compute_latent_heat_flux!(out, Y, p, t, land_model::BucketModel) - if isnothing(out) - return copy(p.bucket.turbulent_fluxes.lhf) - else - out .= p.bucket.turbulent_fluxes.lhf - end -end - -function compute_aerodynamic_resistance!(out, Y, p, t, land_model::BucketModel) - if isnothing(out) - return copy(p.bucket.turbulent_fluxes.r_ae) - else - out .= p.bucket.turbulent_fluxes.r_ae - end -end - -function compute_sensible_heat_flux!(out, Y, p, t, land_model::BucketModel) - if isnothing(out) - return copy(p.bucket.turbulent_fluxes.shf) - else - out .= p.bucket.turbulent_fluxes.shf - end -end - -function compute_vapor_flux!(out, Y, p, t, land_model::BucketModel) - if isnothing(out) - return copy(p.bucket.turbulent_fluxes.vapor_flux) - else - out .= p.bucket.turbulent_fluxes.vapor_flux - end -end - -function compute_surface_air_density!(out, Y, p, t, land_model::BucketModel) - if isnothing(out) - return copy(p.bucket.ρ_sfc) - else - out .= p.bucket.ρ_sfc - end -end - -# stored in Y - -function compute_soil_temperature!(out, Y, p, t, land_model::BucketModel) - if isnothing(out) - return copy(Y.bucket.T) - else - out .= Y.bucket.T - end -end - -function compute_subsurface_water_storage!( - out, - Y, - p, - t, - land_model::BucketModel, -) - if isnothing(out) - return copy(Y.bucket.W) - else - out .= Y.bucket.W - end -end - -function compute_surface_water_content!(out, Y, p, t, land_model::BucketModel) - if isnothing(out) - return copy(Y.bucket.Ws) - else - out .= Y.bucket.Ws - end -end - -function compute_snow_water_equivalent!(out, Y, p, t, land_model::BucketModel) - if isnothing(out) - return copy(Y.bucket.σS) - else - out .= Y.bucket.σS - end -end diff --git a/src/diagnostics/default_diagnostics.jl b/src/diagnostics/default_diagnostics.jl index feadb6e2f3..f87471b284 100644 --- a/src/diagnostics/default_diagnostics.jl +++ b/src/diagnostics/default_diagnostics.jl @@ -62,7 +62,7 @@ function default_diagnostics(land_model::BucketModel, t_start; output_writer) "wsoil", "wsfc", "ssfc", - ] # TO DO: would it be helpful to return this list? + ] default_outputs = hourly_averages(bucket_diagnostics...; output_writer, t_start) @@ -75,51 +75,84 @@ function default_diagnostics( t_start; output_writer, output_vars = :long, + average_period = :daily, ) define_diagnostics!(land_model) if output_vars == :long soilcanopy_diagnostics = [ - "rn_canopy", - "rn_soil", - "lhf_soil", - "lhf_canopy", - "shf_canopy", - "shf_soil", - "vflux", - "tsoil", - "slw", - "infil", - "scd", - "scms", + "sif", + "ra", "gs", - "mt", "trans", - "rain", # do we want? - "an", + "crae", + "clhf", + "cshf", + # "lwp", # last(p.canopy.hydraulics.ψ) errors + # "fa", # return a Tuple + "far", + "lai", + "msf", + "rai", + "sai", "gpp", + "an", "rd", "vcmax25", - "par", - "apar", - "rpar", - "tpar", "nir", "anir", "rnir", "tnir", - "swn", + "par", + "apar", + "rpar", + "tpar", "lwn", - "ra", - "soilco2", + "swn", + "soc", + "airp", + "rain", + "lwd", + "swd", + "snow", + "sza", + "qsfc", + "ws", + "infil", + "shc", + "stc", + "swp", + "soilrn", + "tsoil", + "soilrae", + "soillhf", + "soilshf", + "hr", + "scd", + "scms", + "ct", + "sco2", + "swc", + # "pwc", # return a Tuple + "si", + "sie", ] elseif output_vars == :short - soilcanopy_diagnostics = ["gpp", "ct", "ai", "slw", "si"] + soilcanopy_diagnostics = ["gpp", "ct", "lai", "swc", "si"] + end + + if average_period == :hourly + default_outputs = + hourly_averages(soilcanopy_diagnostics...; output_writer, t_start) + elseif average_period == :daily + default_outputs = + daily_averages(soilcanopy_diagnostics...; output_writer, t_start) + elseif average_period == :monthly # !! this is currently 30 days, not exact month + default_outputs = + monthly_averages(soilcanopy_diagnostics...; output_writer, t_start) end - default_outputs = - hourly_averages(soilcanopy_diagnostics...; output_writer, t_start) return [default_outputs...] end @@ -133,7 +166,7 @@ function default_diagnostics( define_diagnostics!(land_model) - soil_diagnostics = ["slw", "si", "tsoil"] + soil_diagnostics = ["swc", "si", "sie"] default_outputs = daily_averages(soil_diagnostics...; output_writer, t_start) diff --git a/src/diagnostics/define_diagnostics.jl b/src/diagnostics/define_diagnostics.jl index b4f24380c2..7663be92f3 100644 --- a/src/diagnostics/define_diagnostics.jl +++ b/src/diagnostics/define_diagnostics.jl @@ -1,4 +1,4 @@ -# General helper functions for undefined diagnostics for a particular model +# General helper functions for undefined diagnostics for a particular model error_diagnostic_variable(variable, land_model::T) where {T} = error("Cannot compute $variable with model = $T") @@ -31,7 +31,9 @@ compute function for `land_model`. """ function define_diagnostics!(land_model) - # Stored in p + ### BucketModel ### + + ## Stored in p (diagnostics variables stored in the cache) ## # Albedo add_diagnostic_variable!( @@ -65,17 +67,6 @@ function define_diagnostics!(land_model) compute_surface_temperature!(out, Y, p, t, land_model), ) - # Surface specific humidity - add_diagnostic_variable!( - short_name = "qsfc", - long_name = "Surface Specific Humidity", - standard_name = "surface_specific_humidity", - units = "", - comments = "Ratio of water vapor mass to total moist air parcel mass.", - compute! = (out, Y, p, t) -> - compute_surface_specific_humidity!(out, Y, p, t, land_model), - ) - # Latent heat flux add_diagnostic_variable!( short_name = "lhf", @@ -131,7 +122,7 @@ function define_diagnostics!(land_model) compute_surface_air_density!(out, Y, p, t, land_model), ) - # Stored in Y + ## Stored in Y (prognostic or state variables) ## # Soil temperature (3D) at depth add_diagnostic_variable!( @@ -179,133 +170,282 @@ function define_diagnostics!(land_model) ###### SoilCanopyModel ###### + ## stored in p (diagnostics variables stored in the cache) ## + + ## Canopy Module ## + + ### Canopy - Solar Induced Fluorescence + # Solar Induced Fluorescence add_diagnostic_variable!( - short_name = "slw", - long_name = "Soil Liquid Water", - standard_name = "soil_liquid_water", - units = "m^3 m^-3", - comments = "Soil moisture, the liquid water volume per soil volume. This liquid water is located in the soil pores.", + short_name = "sif", + long_name = "Solar Induced Fluorescence", + standard_name = "solar_induced_fluorescence", + units = "W m^-2", + comments = "The fluorescence of leaves induced by solar radiation at 755nm. This quantity is correlated with photosynthesis activity.", compute! = (out, Y, p, t) -> - compute_soil_water_liquid!(out, Y, p, t, land_model), + compute_solar_induced_fluorescence!(out, Y, p, t, land_model), ) + ### Canopy - Autotrophic respiration + # Autotrophic respiration add_diagnostic_variable!( - short_name = "infil", - long_name = "Infiltration", - standard_name = "infiltration", - units = "m s^-1", # double check - comments = "The flux of liquid water into the soil.", + short_name = "ra", + long_name = "Autotrophic Respiration", + standard_name = "autotrophic_respiration", + units = "kg C m^-2 s^-1", + comments = "The canopy autotrophic respiration, the sum of leaves, stems and roots respiration.", compute! = (out, Y, p, t) -> - compute_infiltration!(out, Y, p, t, land_model), + compute_autotrophic_respiration!(out, Y, p, t, land_model), ) + ### Canopy - Conductance + # Stomatal conductance add_diagnostic_variable!( - short_name = "scd", - long_name = "Soil CO2 Diffusivity", - standard_name = "soil_co2_diffusivity", - units = "", # need to add - comments = "The diffusivity of CO2 in the porous phase of the soil. Depends on soil texture, moisture, and temperature.", + short_name = "gs", + long_name = "Stomatal Conductance", + standard_name = "stomatal_conductance", + units = "mol H2O m^-2 s^-1", + comments = "The conductance of leaves. This depends on stomatal opening. It varies with factors such as soil moisture or atmospheric water demand.", compute! = (out, Y, p, t) -> - compute_soilco2_diffusivity!(out, Y, p, t, land_model), + compute_stomatal_conductance!(out, Y, p, t, land_model), ) + # Canopy transpiration add_diagnostic_variable!( - short_name = "scms", - long_name = "Soil CO2 Microbial Source", - standard_name = "soil_co2_microbial_source", - units = "", # check - comments = "The production of CO2 by microbes in the soil. Vary by layers of soil depth.", + short_name = "trans", + long_name = "Canopy Transpiration", + standard_name = "canopy_transpiration", + units = "m s^-1", + comments = "The water evaporated from the canopy due to leaf transpiration (flux of water volume, m^3 of water per m^2 of ground).", compute! = (out, Y, p, t) -> - compute_soilco2_source_microbe!(out, Y, p, t, land_model), + compute_canopy_transpiration!(out, Y, p, t, land_model), ) + ### Canopy - Energy + # Canopy aerodynamic resistance add_diagnostic_variable!( - short_name = "gs", - long_name = "Stomatal Conductance", - standard_name = "stomatal_conductance", - units = "m s^-1", - comments = "The conductance of leaves. This depends on stomatal opening. It varies with factors such as soil moisture or atmospheric water demand.", + short_name = "crae", + long_name = "Canopy Aerodynamic Resistance", + standard_name = "canopy_aerodynamic_resistance", + units = "s m^-1", + comments = "The canopy aerodynamic resistance. Aerodynamic resistance (r_a) is a measure of how much the air near the Earth's surface resists the movement of water vapor and heat from the surface into the air.", compute! = (out, Y, p, t) -> - compute_stomatal_conductance!(out, Y, p, t, land_model), + compute_canopy_aerodynamic_resistance!(out, Y, p, t, land_model), ) + # Canopy latent heat flux add_diagnostic_variable!( - short_name = "mt", - long_name = "Medlyn Term", - standard_name = "medlyn_term", - units = "", # check - comments = "", + short_name = "clhf", + long_name = "Canopy Latent Heat Flux", + standard_name = "canopy_latent_heat_flux", + units = "W m^-2", + comments = "The energy used for canopy transpiration.", compute! = (out, Y, p, t) -> - compute_medlyn_term!(out, Y, p, t, land_model), + compute_canopy_latent_heat_flux!(out, Y, p, t, land_model), ) + # Canopy sensible heat flux add_diagnostic_variable!( - short_name = "trans", - long_name = "Canopy Transpiration", - standard_name = "canopy_transpiration", - units = "", # check - comments = "The water evaporated from the canopy due to leaf transpiration.", + short_name = "cshf", + long_name = "Canopy Sensible Heat Flux", + standard_name = "canopy_sensible_heat_flux", + units = "W m^-2", + comments = "The energy used for canopy temperature change.", compute! = (out, Y, p, t) -> - compute_canopy_transpiration!(out, Y, p, t, land_model), + compute_canopy_sensible_heat_flux!(out, Y, p, t, land_model), ) - add_diagnostic_variable!( # not actually computed, but read from input or atmosphere model, and stored in p... - short_name = "rain", - long_name = "Rainfall", - standard_name = "rainfall", + ### Canopy - Hydraulics + # Leaf water potential + + #= + add_diagnostic_variable!( + short_name = "lwp", + long_name = "Leaf Water Potential", + standard_name = "leaf_water_potential", units = "m", - comments = "Precipitation of liquid water.", + comments = "The water potential of a leaf.", compute! = (out, Y, p, t) -> - compute_rainfall!(out, Y, p, t, land_model), + compute_leaf_water_potential!(out, Y, p, t, land_model), ) + # Flux per ground area add_diagnostic_variable!( - short_name = "an", - long_name = "Leaf Net Photosynthesis", - standard_name = "leaf_net_photosynthesis", - units = "", # check - comments = "Net photosynthesis of a leaf.", + short_name = "fa", + long_name = "Flux Per Ground Area", + standard_name = "flux_per_ground_area", + units = "m s^-1", + comments = "Flux of water volume per m^2 of plant per second, multiplied by the area index (plant area/ground area).", compute! = (out, Y, p, t) -> - compute_photosynthesis_net_leaf!(out, Y, p, t, land_model), + compute_flux_per_ground_area!(out, Y, p, t, land_model), + ) + =# + + # Root flux per ground area + add_diagnostic_variable!( + short_name = "far", + long_name = "Root flux per ground area", + standard_name = "root_flux_per_ground_area", + units = "m s^-1", + comments = "Flux of water volume per m^2 of root per second, multiplied by the area index (root area/ground area).", + compute! = (out, Y, p, t) -> + compute_root_flux_per_ground_area!(out, Y, p, t, land_model), + ) + + # Leaf area index + add_diagnostic_variable!( + short_name = "lai", + long_name = "Leaf area Index", + standard_name = "leaf_area_index", + units = "m^2 m^-2", + comments = "The area index of leaves, expressed in surface area of leaves per surface area of ground.", + compute! = (out, Y, p, t) -> + compute_leaf_area_index!(out, Y, p, t, land_model), + ) + + # Moisture stress factor + add_diagnostic_variable!( + short_name = "msf", + long_name = "Moisture Stress Factor", + standard_name = "moisture_stress_factor", + units = "", + comments = "Sensitivity of plants conductance to soil water content. Unitless", + compute! = (out, Y, p, t) -> + compute_moisture_stress_factor!(out, Y, p, t, land_model), + ) + + # Root area index + add_diagnostic_variable!( + short_name = "rai", + long_name = "Root area Index", + standard_name = "root_area_index", + units = "m^2 m^-2", + comments = "The area index of roots, expressed in surface area of roots per surface area of ground.", + compute! = (out, Y, p, t) -> + compute_root_area_index!(out, Y, p, t, land_model), + ) + + # Stem area index + add_diagnostic_variable!( + short_name = "sai", + long_name = "Stem area Index", + standard_name = "stem_area_index", + units = "m^2 m^-2", + comments = "The area index of stems, expressed in surface area of stems per surface area of ground.", + compute! = (out, Y, p, t) -> + compute_stem_area_index!(out, Y, p, t, land_model), ) + ### Canopy - Photosynthesis + # GPP - Gross Primary Productivity add_diagnostic_variable!( short_name = "gpp", long_name = "Gross Primary Productivity", standard_name = "gross_primary_productivity", - units = "", - comments = "Net photosynthesis of the canopy.", + units = "mol CO2 m^-2 s^-1", + comments = "Net photosynthesis (carbon assimilation) of the canopy. This is equivalent to leaf net assimilation scaled to the canopy level.", compute! = (out, Y, p, t) -> compute_photosynthesis_net_canopy!(out, Y, p, t, land_model), ) + # Leaf net photosynthesis + add_diagnostic_variable!( + short_name = "an", + long_name = "Leaf Net Photosynthesis", + standard_name = "leaf_net_photosynthesis", + units = "mol CO2 m^-2 s^-1", + comments = "Net photosynthesis (carbon assimilation) of a leaf, computed for example by the Farquhar model.", + compute! = (out, Y, p, t) -> + compute_photosynthesis_net_leaf!(out, Y, p, t, land_model), + ) + + # Leaf respiration add_diagnostic_variable!( short_name = "rd", long_name = "Leaf Respiration", standard_name = "leaf_dark_respiration", - units = "", + units = "mol CO2 m^-2 s^-1", comments = "Leaf respiration, called dark respiration because usually measured in the abscence of radiation.", compute! = (out, Y, p, t) -> compute_respiration_leaf!(out, Y, p, t, land_model), ) + # Vcmax25 add_diagnostic_variable!( short_name = "vcmax25", long_name = "Vcmax25", standard_name = "vcmax25", - units = "", + units = "mol CO2 m^-2 s^-1", comments = "The parameter vcmax at 25 degree celsius. Important for the Farquhar model of leaf photosynthesis.", compute! = (out, Y, p, t) -> compute_vcmax25!(out, Y, p, t, land_model), ) + ### Canopy - Radiative Transfer + # NIR - near infrared radiaton + add_diagnostic_variable!( + short_name = "nir", + long_name = "Near Infrared Radiation", + standard_name = "near_infrared_radiation", + units = "mol photons m^-2 s^-1", + comments = "The amount of near infrared radiation reaching the canopy.", + compute! = (out, Y, p, t) -> + compute_near_infrared_radiation_down!(out, Y, p, t, land_model), + ) + + # ANIR - absorbed near infrared radiation + add_diagnostic_variable!( + short_name = "anir", + long_name = "Absorbed Near Infrared Radiation", + standard_name = "absorbed_near_infrared_radiation", + units = "mol photons m^-2 s^-1", + comments = "The amount of near infrared radiation absorbed by the canopy.", + compute! = (out, Y, p, t) -> + compute_near_infrared_radiation_absorbed!(out, Y, p, t, land_model), + ) + + # RNIR - reflected near infrared radiation + add_diagnostic_variable!( + short_name = "rnir", + long_name = "Reflected Near Infrared Radiation", + standard_name = "reflected_near_infrared_radiation", + units = "mol photons m^-2 s^-1", + comments = "The amount of near infrared radiation reflected by the canopy.", + compute! = (out, Y, p, t) -> + compute_near_infrared_radiation_reflected!( + out, + Y, + p, + t, + land_model, + ), + ) + + # TNIR - transmitted near infrared radiation + add_diagnostic_variable!( + short_name = "tnir", + long_name = "Transmitted Near Infrared Radiation", + standard_name = "transmitted_near_infrared_radiation", + units = "mol photons m^-2 s^-1", + comments = "The amount of near infrared radiation transmitted by the canopy.", + compute! = (out, Y, p, t) -> + compute_near_infrared_radiation_transmitted!( + out, + Y, + p, + t, + land_model, + ), + ) + + # PAR - photosynthetically active radiation add_diagnostic_variable!( short_name = "par", long_name = "Photosynthetically Active Radiation", standard_name = "photosynthetically_active_radiation", - units = "", + units = "mol photons m^-2 s^-1", comments = "The subset of total radiation that activates photosynthesis reaching the canopy.", compute! = (out, Y, p, t) -> - compute_photosynthetically_active_radiation!( + compute_photosynthetically_active_radiation_down!( out, Y, p, @@ -314,11 +454,12 @@ function define_diagnostics!(land_model) ), ) + # APAR - absorbed photosynthetically active radiation add_diagnostic_variable!( short_name = "apar", long_name = "Absorbed Photosynthetically Active Radiation", standard_name = "absorbed_photosynthetically_active_radiation", - units = "", + units = "mol photons m^-2 s^-1", comments = "The amount of photosynthetically active radiation absorbed by the leaf. The rest if reflected or transmitted.", compute! = (out, Y, p, t) -> compute_photosynthetically_active_radiation_absorbed!( @@ -330,11 +471,12 @@ function define_diagnostics!(land_model) ), ) + # RPAR - reflected photosynthetically active radiation add_diagnostic_variable!( short_name = "rpar", long_name = "Reflected Photosynthetically Active Radiation", standard_name = "reflected_photosynthetically_active_radiation", - units = "", + units = "mol photons m^-2 s^-1", comments = "The amount of photosynthetically active radiation reflected by leaves.", compute! = (out, Y, p, t) -> compute_photosynthetically_active_radiation_reflected!( @@ -346,11 +488,12 @@ function define_diagnostics!(land_model) ), ) + # TPAR - transmitted photosynthetically active radiation add_diagnostic_variable!( short_name = "tpar", long_name = "Transmitted Photosynthetically Active Radiation", standard_name = "transmitted_photosynthetically_active_radiation", - units = "", + units = "mol photons m^-2 s^-1", comments = "The amount of photosynthetically active radiation transmitted by leaves.", compute! = (out, Y, p, t) -> compute_photosynthetically_active_radiation_transmitted!( @@ -362,284 +505,321 @@ function define_diagnostics!(land_model) ), ) + # Net longwave radiation add_diagnostic_variable!( - short_name = "nir", - long_name = "Near Infrared Radiation", - standard_name = "near_infrared_radiation", + short_name = "lwn", + long_name = "Net Longwave Radiation", + standard_name = "net_longwave_radiation", units = "W m^-2", - comments = "The amount of near infrared radiation reaching the canopy.", + comments = "The net (in minus out) longwave radiation at the surface.", compute! = (out, Y, p, t) -> - compute_near_infrared_radiation!(out, Y, p, t, land_model), + compute_radiation_longwave_net!(out, Y, p, t, land_model), ) + # Net shortwave radiation add_diagnostic_variable!( - short_name = "anir", - long_name = "Absorbed Near Infrared Radiation", - standard_name = "absorbed_near_infrared_radiation", + short_name = "swn", + long_name = "Net Shortwave Radiation", + standard_name = "net_shortwave_radiation", units = "W m^-2", - comments = "The amount of near infrared radiation reaching the canopy.", + comments = "The net (in minus out) shortwave radiation at the surface.", compute! = (out, Y, p, t) -> - compute_near_infrared_radiation_absorbed!(out, Y, p, t, land_model), + compute_radiation_shortwave_net!(out, Y, p, t, land_model), ) + ## Drivers Module ## + # Soil organic carbon add_diagnostic_variable!( - short_name = "rnir", - long_name = "Reflected Near Infrared Radiation", - standard_name = "reflected_near_infrared_radiation", - units = "W m^-2", - comments = "The amount of near infrared radiation reaching the canopy.", + short_name = "soc", + long_name = "Soil organic carbon", + standard_name = "soil_organic_carbon", + units = "kg C m^-3", + comments = "Mass of organic carbon per volume of soil.", compute! = (out, Y, p, t) -> - compute_near_infrared_radiation_reflected!( - out, - Y, - p, - t, - land_model, - ), + compute_soil_organic_carbon!(out, Y, p, t, land_model), ) + # Air pressure add_diagnostic_variable!( - short_name = "tnir", - long_name = "Transmitted Near Infrared Radiation", - standard_name = "transmitted_near_infrared_radiation", - units = "W m^-2", - comments = "The amount of near infrared radiation reaching the canopy.", + short_name = "airp", + long_name = "Air pressure", + standard_name = "air_pressure", + units = "Pa", + comments = "The air pressure.", compute! = (out, Y, p, t) -> - compute_near_infrared_radiation_transmitted!( - out, - Y, - p, - t, - land_model, - ), + compute_pressure!(out, Y, p, t, land_model), ) + # Rainfall add_diagnostic_variable!( - short_name = "swn", - long_name = "Net Shortwave Radiation", - standard_name = "net_shortwave_radiation", - units = "W m^-2", - comments = "The net (in minus out) radiation at the surface.", + short_name = "rain", + long_name = "Rainfall", + standard_name = "rainfall", + units = "m s^-1", + comments = "Precipitation of liquid water volume (m^3 of water per m^2 of ground per second).", compute! = (out, Y, p, t) -> - compute_radiation_shortwave_net!(out, Y, p, t, land_model), + compute_rainfall!(out, Y, p, t, land_model), ) + # Net longwave radiation add_diagnostic_variable!( - short_name = "lwn", - long_name = "Net Longwave Radiation", - standard_name = "net_longwave_radiation", + short_name = "lwd", + long_name = "Down Longwave Radiation", + standard_name = "down_longwave_radiation", units = "W m^-2", - comments = "The net (in minus out) radiation at the surface.", + comments = "The down (in) longwave radiation at the surface.", compute! = (out, Y, p, t) -> - compute_radiation_longwave_net!(out, Y, p, t, land_model), + compute_radiation_longwave_down!(out, Y, p, t, land_model), ) + # Net shortwave radiation add_diagnostic_variable!( - short_name = "ra", - long_name = "Autotrophic Respiration", - standard_name = "autotrophic_respiration", - units = "mol m^-2 s^-1", - comments = "Canopy autotrophic respiration, the sum of leaves, stems and roots respiration.", + short_name = "swd", + long_name = "Short Longwave Radiation", + standard_name = "short_longwave_radiation", + units = "W m^-2", + comments = "The short (in) longwave radiation at the surface.", compute! = (out, Y, p, t) -> - compute_autotrophic_respiration!(out, Y, p, t, land_model), + compute_radiation_shortwave_down!(out, Y, p, t, land_model), ) + # Snowfall add_diagnostic_variable!( - short_name = "soilco2", - long_name = "Soil CO2 concentration", - standard_name = "soil_co2", - units = "", - comments = "Concentration of CO2 in the air of soil pores.", - compute! = (out, Y, p, t) -> compute_soilco2!(out, Y, p, t, land_model), - ) - - add_diagnostic_variable!( - short_name = "soilrn", - long_name = "Soil Net Radiation", - standard_name = "soil_net_radiation", - units = "W m^-2", - comments = "Net radiation at the soil surface.", + short_name = "snow", + long_name = "Snowfall", + standard_name = "snowfall", + units = "m s^-1", + comments = "The precipitation of snow in liquid water volume (m^3 of water per m^2 of ground per second).", compute! = (out, Y, p, t) -> - compute_soil_net_radiation!(out, Y, p, t, land_model), + compute_snowfall!(out, Y, p, t, land_model), ) + # Solar zenith angle add_diagnostic_variable!( - short_name = "soillhf", - long_name = "Soil Latent Heat Flux", - standard_name = "soil_Latent_Heat_Flux", - units = "W m^-2", - comments = "Soil evaporation.", + short_name = "sza", + long_name = "Solar Zenith Angle", + standard_name = "solar_zenith_angle", + units = "", + comments = "Solar zenith angle.", compute! = (out, Y, p, t) -> - compute_soil_latent_heat_flux!(out, Y, p, t, land_model), + compute_solar_zenith_angle!(out, Y, p, t, land_model), ) + # Specific humidity add_diagnostic_variable!( - short_name = "soilshf", - long_name = "Soil Sensible Heat Flux", - standard_name = "soil_sensible_Heat_Flux", - units = "W m^-2", - comments = "Soil sensible heat flux.", + short_name = "qsfc", + long_name = "Surface Specific Humidity", + standard_name = "surface_specific_humidity", + units = "", + comments = "Ratio of water vapor mass to total moist air parcel mass.", compute! = (out, Y, p, t) -> - compute_soil_sensible_heat_flux!(out, Y, p, t, land_model), + compute_specific_humidity!(out, Y, p, t, land_model), ) + # Wind speed add_diagnostic_variable!( - short_name = "soilrae", - long_name = "Soil Aerodynamic Resistance", - standard_name = "soil_aerodynamic_resistance", - units = "", - comments = "Soil aerodynamic resistance.", + short_name = "ws", + long_name = "Wind Speed", + standard_name = "wind_speed", + units = "m s^-1", + comments = "The average wind speed.", compute! = (out, Y, p, t) -> - compute_soil_aerodynamic_resistance!(out, Y, p, t, land_model), + compute_wind_speed!(out, Y, p, t, land_model), ) + ## Soil Module ## + # Infiltration add_diagnostic_variable!( - short_name = "hr", - long_name = "Heterotrophic Respiration", - standard_name = "heterotrophic_respiration", - units = "mol m^-2 s^-1", - comments = "CO2 efflux at the soil surface due to microbial decomposition of soil organic matter.", + short_name = "infil", + long_name = "Infiltration", + standard_name = "infiltration", + units = "m s^-1", + comments = "The flux of liquid water volume into the soil (m^3 of water per m^2 of ground per second).", compute! = (out, Y, p, t) -> - compute_heterotrophic_respiration!(out, Y, p, t, land_model), + compute_infiltration!(out, Y, p, t, land_model), ) + # Soil hydraulic conductivity add_diagnostic_variable!( short_name = "shc", long_name = "Soil Hydraulic Conductivity", standard_name = "soil_hydraulic_conductivity", - units = "", + units = "m s^-1", comments = "Soil hydraulic conductivity.", compute! = (out, Y, p, t) -> compute_soil_hydraulic_conductivity!(out, Y, p, t, land_model), ) + # Soil thermal conductivity add_diagnostic_variable!( short_name = "stc", long_name = "Soil Thermal Conductivity", standard_name = "soil_thermal_conductivity", - units = "", + units = "W m^-1 K^-1", comments = "Soil thermal conductivity.", compute! = (out, Y, p, t) -> compute_soil_thermal_conductivity!(out, Y, p, t, land_model), ) + # Soil Water Potential add_diagnostic_variable!( short_name = "swp", long_name = "Soil Water Potential", standard_name = "soil_water_potential", - units = "", + units = "Pa", comments = "Soil water potential.", compute! = (out, Y, p, t) -> compute_soil_water_potential!(out, Y, p, t, land_model), ) + # Soil net radiation add_diagnostic_variable!( - short_name = "sza", - long_name = "Solar Zenith Angle", - standard_name = "solar_zenith_angle", - units = "", - comments = "Solar zenith angle.", + short_name = "soilrn", + long_name = "Soil Net Radiation", + standard_name = "soil_net_radiation", + units = "W m^-2", + comments = "Net radiation at the soil surface.", compute! = (out, Y, p, t) -> - compute_solar_zenith_angle!(out, Y, p, t, land_model), + compute_soil_net_radiation!(out, Y, p, t, land_model), ) + ### Soil - Turbulent Fluxes + # Soil aerodynamic resistance add_diagnostic_variable!( - short_name = "msf", - long_name = "Moisture Stress Factor", - standard_name = "moisture_stress_factor", - units = "", - comments = "Sensitivity of plants conductance to soil water content.", + short_name = "soilrae", + long_name = "Soil Aerodynamic Resistance", + standard_name = "soil_aerodynamic_resistance", + units = "s m^-1", + comments = "The soil aerodynamic resistance. Aerodynamic resistance is a measure of how much the air near the Earth's surface resists the movement of water vapor and heat from the surface into the air.", compute! = (out, Y, p, t) -> - compute_moisture_stress_factor!(out, Y, p, t, land_model), + compute_soil_aerodynamic_resistance!(out, Y, p, t, land_model), ) + # Soil latent heat flux add_diagnostic_variable!( - short_name = "cwp", - long_name = "Canopy Water Potential", - standard_name = "canopy_water_potential", - units = "", - comments = "The water potential of the canopy.", + short_name = "soillhf", + long_name = "Soil Latent Heat Flux", + standard_name = "soil_Latent_Heat_Flux", + units = "W m^-2", + comments = "Soil latent heat flux, the amount of liquid water evaporated by the soil, expressed in energy units (W m^-2).", compute! = (out, Y, p, t) -> - compute_canopy_water_potential!(out, Y, p, t, land_model), + compute_soil_latent_heat_flux!(out, Y, p, t, land_model), ) + # Soil sensible heat flux add_diagnostic_variable!( - short_name = "fa", - long_name = "Cross Section", - standard_name = "cross_section", - units = "", - comments = "The area of stem relative to ground area.", #?? + short_name = "soilshf", + long_name = "Soil Sensible Heat Flux", + standard_name = "soil_sensible_Heat_Flux", + units = "W m^-2", + comments = "Soil sensible heat flux, the amount of energy exchanged between the soil and atmosphere to change the temperature of the soil.", compute! = (out, Y, p, t) -> - compute_cross_section!(out, Y, p, t, land_model), + compute_soil_sensible_heat_flux!(out, Y, p, t, land_model), ) + ### Soil - SoilCO2 + # Heterotrophic respiration add_diagnostic_variable!( - short_name = "far", - long_name = "Root Cross Section", - standard_name = "Cross Section", - units = "", - comments = "The area of roots relative to ground area.", #?? + short_name = "hr", + long_name = "Heterotrophic Respiration", + standard_name = "heterotrophic_respiration", + units = "mol m^-2 s^-1", + comments = "The CO2 efflux at the soil surface due to microbial decomposition of soil organic matter. This is not necessarily equal to CO2 production by microbes, as co2 diffusion through the soil pores takes time.", compute! = (out, Y, p, t) -> - compute_cross_section_roots!(out, Y, p, t, land_model), + compute_heterotrophic_respiration!(out, Y, p, t, land_model), ) + # Soil CO2 diffusivity add_diagnostic_variable!( - short_name = "ai", - long_name = "Area Index", - standard_name = "area_index", - units = "", - comments = "The area index of leaves.", + short_name = "scd", + long_name = "Soil CO2 Diffusivity", + standard_name = "soil_co2_diffusivity", + units = "m^2 s^-1", + comments = "The diffusivity of CO2 in the porous phase of the soil. Depends on soil texture, moisture, and temperature.", compute! = (out, Y, p, t) -> - compute_area_index!(out, Y, p, t, land_model), + compute_soilco2_diffusivity!(out, Y, p, t, land_model), ) + # Soil CO2 microbial source add_diagnostic_variable!( - short_name = "clhf", - long_name = "Canopy Latent Heat Flux", - standard_name = "canopy_latent_heat_flux", - units = "", - comments = "Canopy evaporation.", #?? of steam, leaves, roots? + short_name = "scms", + long_name = "Soil CO2 Microbial Source", + standard_name = "soil_co2_microbial_source", + units = "kg C m^-2 s^-1", + comments = "The production of CO2 by microbes in the soil. Vary by layers of soil depth.", compute! = (out, Y, p, t) -> - compute_canopy_latent_heat_flux!(out, Y, p, t, land_model), + compute_soilco2_source_microbe!(out, Y, p, t, land_model), ) + ## Stored in Y (prognostic or state variables) ## + + # Canopy temperature add_diagnostic_variable!( - short_name = "cshf", - long_name = "Canopy Sensible Heat Flux", - standard_name = "canopy_sensible_heat_flux", - units = "", - comments = "Canopy sensible heat flux.", #?? of steam, leaves, roots? + short_name = "ct", + long_name = "Canopy Temperature", + standard_name = "canopy_temperature", + units = "K", + comments = "Canopy temperature.", compute! = (out, Y, p, t) -> - compute_canopy_sensible_heat_flux!(out, Y, p, t, land_model), + compute_canopy_temperature!(out, Y, p, t, land_model), ) + # Soil CO2 add_diagnostic_variable!( - short_name = "crae", - long_name = "Canopy Aerodynamic Resistance", - standard_name = "canopy_aerodynamic_resistance", - units = "", - comments = "Canopy aerodynamic_resistance.", #?? of steam, leaves, roots? + short_name = "sco2", + long_name = "Soil CO2", + standard_name = "soil_co2", + units = "kg C m^3", + comments = "Concentration of CO2 in the porous air space of the soil.", + compute! = (out, Y, p, t) -> compute_soilco2!(out, Y, p, t, land_model), + ) + + # Soil water content + add_diagnostic_variable!( + short_name = "swc", + long_name = "Soil Water Content", + standard_name = "soil_water_content", + units = "m^3 m^-3", + comments = "The volume of soil water per volume of soil.", compute! = (out, Y, p, t) -> - compute_canopy_aerodynamic_resistance!(out, Y, p, t, land_model), + compute_soil_water_content!(out, Y, p, t, land_model), ) + # Plant water content + + #= add_diagnostic_variable!( - short_name = "ct", - long_name = "Canopy Temperature", - standard_name = "canopy_temperature", - units = "K", - comments = "Canopy temperature.", #?? of steam, leaves, roots? + short_name = "pwc", + long_name = "Plant Water Content", + standard_name = "plant_water_content", + units = "m^3 m^-3", + comments = "The volume of plant water per volume of plant.", compute! = (out, Y, p, t) -> - compute_canopy_temperature!(out, Y, p, t, land_model), + compute_plant_water_content!(out, Y, p, t, land_model), ) + =# + # return a Tuple + # Soil ice add_diagnostic_variable!( short_name = "si", long_name = "Soil Ice", standard_name = "soil_ice", units = "m^3 m^-3", - comments = "soil ice.", + comments = "The volume of soil ice per volume of soil.", compute! = (out, Y, p, t) -> - compute_soil_ice!(out, Y, p, t, land_model), + compute_soil_ice_content!(out, Y, p, t, land_model), ) + + # Soil internal energy + add_diagnostic_variable!( + short_name = "sie", + long_name = "Soil Internal Energy", + standard_name = "soil_internal_energy", + units = "W m^-2", + comments = "The energy per volume of soil.", + compute! = (out, Y, p, t) -> + compute_soil_internal_energy!(out, Y, p, t, land_model), + ) + end diff --git a/src/diagnostics/diagnostic.jl b/src/diagnostics/diagnostic.jl index 4894dd3f9c..fecc9b5fc9 100644 --- a/src/diagnostics/diagnostic.jl +++ b/src/diagnostics/diagnostic.jl @@ -89,8 +89,7 @@ function get_diagnostic_variable(short_name) end # Do you want to define more diagnostics? Add them here -include("bucket_compute_methods.jl") -include("soilcanopy_compute_methods.jl") +include("land_compute_methods.jl") # define_diagnostics.jl contains the list of all the diagnostics include("define_diagnostics.jl") diff --git a/src/diagnostics/land_compute_methods.jl b/src/diagnostics/land_compute_methods.jl new file mode 100644 index 0000000000..9855112cf3 --- /dev/null +++ b/src/diagnostics/land_compute_methods.jl @@ -0,0 +1,152 @@ +""" + @diagnostic_compute name model compute + +Macro generating a function to compute a land diagnostic, +needed in the ClimaDiagnostics framework. + +See the ClimaDiagnostics docmentation for more information. + +For example, +@diagnostic_compute "soil_net_radiation" SoilCanopyModel p.soil.R_n + +generates the function + +function compute_soil_net_radiation!(out, Y, p, t, land_model::SoilCanopyModel) + if isnothing(out) + return copy(p.soil.R_n) + else + out .= p.soil.R_n + end +end +""" +macro diagnostic_compute(name, model, compute) + function_name = Symbol("compute_", name, "!") + return esc(quote + function $function_name(out, Y, p, t, land_model::$model) + if isnothing(out) + return copy($compute) + else + out .= $compute + end + end + end) +end + + + +### BucketModel ### + +# variables stored in p (diagnostics variables stored in the cache) +@diagnostic_compute "aerodynamic_resistance" BucketModel p.bucket.turbulent_fluxes.r_ae +@diagnostic_compute "albedo" BucketModel p.bucket.α_sfc +@diagnostic_compute "latent_heat_flux" BucketModel p.bucket.turbulent_fluxes.lhf +@diagnostic_compute "net_radiation" BucketModel p.bucket.R_n +@diagnostic_compute "sensible_heat_flux" BucketModel p.bucket.turbulent_fluxes.shf +@diagnostic_compute "surface_air_density" BucketModel p.bucket.ρ_sfc +@diagnostic_compute "specific_humidity" BucketModel p.bucket.q_sfc +@diagnostic_compute "surface_temperature" BucketModel p.bucket.T_sfc +@diagnostic_compute "vapor_flux" BucketModel p.bucket.turbulent_fluxes.vapor_flux + +# variables stored in Y (prognostic or state variables) +@diagnostic_compute "snow_water_equivalent" BucketModel Y.bucket.σS +@diagnostic_compute "soil_temperature" BucketModel Y.bucket.T +@diagnostic_compute "subsurface_water_storage" BucketModel Y.bucket.W +@diagnostic_compute "surface_water_content" BucketModel Y.bucket.Ws + +### SoilCanopyModel ### + +# variables stored in p (diagnostics variables stored in the cache) + +## Canopy Module ## + +# Canopy - Solar Induced Fluorescence +@diagnostic_compute "solar_induced_fluorescence" SoilCanopyModel p.canopy.sif.SIF + +# Canopy - Autotrophic respiration +@diagnostic_compute "autotrophic_respiration" SoilCanopyModel p.canopy.autotrophic_respiration.Ra + +# Canopy - Conductance +@diagnostic_compute "stomatal_conductance" SoilCanopyModel p.canopy.conductance.gs +@diagnostic_compute "canopy_transpiration" SoilCanopyModel p.canopy.conductance.transpiration + +# Canopy - Energy +@diagnostic_compute "canopy_aerodynamic_resistance" SoilCanopyModel p.canopy.energy.r_ae +@diagnostic_compute "canopy_latent_heat_flux" SoilCanopyModel p.canopy.energy.lhf +@diagnostic_compute "canopy_sensible_heat_flux" SoilCanopyModel p.canopy.energy.shf + +# Canopy - Hydraulics +#@diagnostic_compute "leaf_water_potential" SoilCanopyModel last( +# p.canopy.hydraulics.ψ, +#) +# @diagnostic_compute "flux_per_ground_area" SoilCanopyModel p.canopy.hydraulics.fa # return a Tuple +@diagnostic_compute "root_flux_per_ground_area" SoilCanopyModel p.canopy.hydraulics.fa_roots +@diagnostic_compute "leaf_area_index" SoilCanopyModel p.canopy.hydraulics.area_index.leaf +@diagnostic_compute "moisture_stress_factor" SoilCanopyModel p.canopy.hydraulics.β +@diagnostic_compute "root_area_index" SoilCanopyModel p.canopy.hydraulics.area_index.root +@diagnostic_compute "stem_area_index" SoilCanopyModel p.canopy.hydraulics.area_index.stem + +# Canopy - Photosynthesis +@diagnostic_compute "photosynthesis_net_canopy" SoilCanopyModel p.canopy.photosynthesis.GPP +@diagnostic_compute "photosynthesis_net_leaf" SoilCanopyModel p.canopy.photosynthesis.An +@diagnostic_compute "respiration_leaf" SoilCanopyModel p.canopy.photosynthesis.Rd +@diagnostic_compute "vcmax25" SoilCanopyModel p.canopy.photosynthesis.Vcmax25 + +# Canopy - Radiative Transfer +@diagnostic_compute "near_infrared_radiation_down" SoilCanopyModel p.canopy.radiative_transfer.inc_nir +@diagnostic_compute "near_infrared_radiation_absorbed" SoilCanopyModel p.canopy.radiative_transfer.nir.abs +@diagnostic_compute "near_infrared_radiation_reflected" SoilCanopyModel p.canopy.radiative_transfer.nir.refl +@diagnostic_compute "near_infrared_radiation_transmitted" SoilCanopyModel p.canopy.radiative_transfer.nir.trans +@diagnostic_compute "photosynthetically_active_radiation_down" SoilCanopyModel p.canopy.radiative_transfer.inc_par +@diagnostic_compute "photosynthetically_active_radiation_absorbed" SoilCanopyModel p.canopy.radiative_transfer.par.abs +@diagnostic_compute "photosynthetically_active_radiation_reflected" SoilCanopyModel p.canopy.radiative_transfer.par.refl +@diagnostic_compute "photosynthetically_active_radiation_transmitted" SoilCanopyModel p.canopy.radiative_transfer.par.trans +@diagnostic_compute "radiation_longwave_net" SoilCanopyModel p.canopy.radiative_transfer.LW_n +@diagnostic_compute "radiation_shortwave_net" SoilCanopyModel p.canopy.radiative_transfer.SW_n + +## Drivers Module ## + +@diagnostic_compute "soil_organic_carbon" SoilCanopyModel p.drivers.soc # need to fix this in src/shared_utilities/drivers +@diagnostic_compute "pressure" SoilCanopyModel p.drivers.P +@diagnostic_compute "rainfall" SoilCanopyModel p.drivers.P_liq +@diagnostic_compute "radiation_longwave_down" SoilCanopyModel p.drivers.LW_d +@diagnostic_compute "radiation_shortwave_down" SoilCanopyModel p.drivers.SW_d +@diagnostic_compute "snowfall" SoilCanopyModel p.drivers.P_snow +@diagnostic_compute "solar_zenith_angle" SoilCanopyModel p.drivers.θs +@diagnostic_compute "specific_humidity" SoilCanopyModel p.drivers.q +@diagnostic_compute "wind_speed" SoilCanopyModel p.drivers.u + +## Soil Module ## + +@diagnostic_compute "infiltration" SoilCanopyModel p.soil.infiltration +@diagnostic_compute "soil_hydraulic_conductivity" SoilCanopyModel p.soil.K +@diagnostic_compute "soil_thermal_conductivity" SoilCanopyModel p.soil.κ +@diagnostic_compute "soil_water_potential" SoilCanopyModel p.soil.ψ +@diagnostic_compute "soil_net_radiation" SoilCanopyModel p.soil.R_n +@diagnostic_compute "soil_temperature" SoilCanopyModel p.soil.T + +# Soil - Turbulent Fluxes +@diagnostic_compute "soil_aerodynamic_resistance" SoilCanopyModel p.soil.turbulent_fluxes.r_ae +@diagnostic_compute "soil_latent_heat_flux" SoilCanopyModel p.soil.turbulent_fluxes.lhf +@diagnostic_compute "soil_sensible_heat_flux" SoilCanopyModel p.soil.turbulent_fluxes.shf +@diagnostic_compute "vapor_flux" SoilCanopyModel p.soil.turbulent_fluxes.vapor_flux + +# Soil - SoilCO2 +@diagnostic_compute "heterotrophic_respiration" SoilCanopyModel p.soilco2.top_bc +@diagnostic_compute "soilco2_diffusivity" SoilCanopyModel p.soilco2.D +@diagnostic_compute "soilco2_source_microbe" SoilCanopyModel p.soilco2.Sm + +# variables stored in Y (prognostic or state variables) + +@diagnostic_compute "canopy_temperature" SoilCanopyModel Y.canopy.energy.T +@diagnostic_compute "soilco2" SoilCanopyModel Y.soilco2.C +@diagnostic_compute "soil_water_content" SoilCanopyModel Y.soil.ϑ_l +# @diagnostic_compute "plant_water_content" SoilCanopyModel Y.canopy.hydraulics.ϑ_l # return a Tuple +@diagnostic_compute "soil_ice_content" SoilCanopyModel Y.soil.θ_i +@diagnostic_compute "soil_internal_energy" SoilCanopyModel Y.soil.ρe_int + +### EnergyHydrology ### + +@diagnostic_compute "soil_water_content" EnergyHydrology Y.soil.ϑ_l +@diagnostic_compute "soil_ice_content" EnergyHydrology Y.soil.θ_i +@diagnostic_compute "soil_internal_energy" EnergyHydrology Y.soil.ρe_int +@diagnostic_compute "soil_temperature" EnergyHydrology p.soil.T diff --git a/src/diagnostics/soilcanopy_compute_methods.jl b/src/diagnostics/soilcanopy_compute_methods.jl deleted file mode 100644 index eef836b786..0000000000 --- a/src/diagnostics/soilcanopy_compute_methods.jl +++ /dev/null @@ -1,603 +0,0 @@ -# stored in p - -function compute_soil_net_radiation!(out, Y, p, t, land_model::SoilCanopyModel) - if isnothing(out) - return copy(p.soil.R_n) - else - out .= p.soil.R_n - end -end - -function compute_soil_latent_heat_flux!( - out, - Y, - p, - t, - land_model::SoilCanopyModel, -) - if isnothing(out) - return copy(p.soil.turbulent_flux.lhf) # is this different from canopy.energy.lhf? - else - out .= p.soil.turbulent_flux.lhf - end -end - -function compute_soil_aerodynamic_resistance!( - out, - Y, - p, - t, - land_model::SoilCanopyModel, -) - if isnothing(out) - return copy(p.soil.turbulent_fluxes.r_ae) - else - out .= p.soil.turbulent_fluxes.r_ae - end -end - -function compute_soil_sensible_heat_flux!( - out, - Y, - p, - t, - land_model::SoilCanopyModel, -) - if isnothing(out) - return copy(p.soil.turbulent_fluxes.shf) - else - out .= p.soil.turbulent_fluxes.shf - end -end - -function compute_vapor_flux!(out, Y, p, t, land_model::SoilCanopyModel) - if isnothing(out) - return copy(p.soil.turbulent_fluxes.vapor_flux) - else - out .= p.soil.turbulent_fluxes.vapor_flux - end -end - -function compute_soil_temperature!( - out, - Y, - p, - t, - land_model::Union{SoilCanopyModel, EnergyHydrology}, -) - if isnothing(out) - return copy(top_center_to_surface(p.soil.T)) - else - out .= top_center_to_surface(p.soil.T) - end -end - -function compute_soil_water_liquid!( - out, - Y, - p, - t, - land_model::Union{SoilCanopyModel, EnergyHydrology}, -) - if isnothing(out) - return copy(top_center_to_surface(p.soil.θ_l)) # or is it in Y.soil? - else - out .= top_center_to_surface(p.soil.θ_l) - end -end - -function compute_infiltration( - out, - Y, - p, - t, - land_model::Union{SoilCanopyModel, EnergyHydrology}, -) - if isnothing(out) - return copy(p.soil.infiltration) - else - out .= p.soil.infiltration - end -end - -function compute_soilco2_diffusivity(out, Y, p, t, land_model::SoilCanopyModel) - if isnothing(out) - return copy(p.soilco2.D) # NOTE: we will need a method to compute surface co2 efflux - else - out .= p.soilco2.D - end -end - -function compute_soilco2_source_microbe( - out, - Y, - p, - t, - land_model::SoilCanopyModel, -) - if isnothing(out) - return copy(p.soilco2.Sm) - else - out .= p.soilco2.Sm - end -end - -function compute_stomatal_conductance(out, Y, p, t, land_model::SoilCanopyModel) - if isnothing(out) - return copy(p.canopy.conductance.gs) # doublecheck: stomata, not canopy - else - out .= p.canopy.conductance.gs - end -end - -function compute_medlyn_term(out, Y, p, t, land_model::SoilCanopyModel) - if isnothing(out) - return copy(p.canopy.conductance.medlyn_term) - else - out .= p.canopy.conductance.medlyn_term - end -end - -function compute_canopy_transpiration(out, Y, p, t, land_model::SoilCanopyModel) - if isnothing(out) - return copy(p.canopy.transpiration) # doublecheck: canopy, not leaf - else - out .= p.canopy.transpiration - end -end - -function compute_rainfall(out, Y, p, t, land_model::SoilCanopyModel) - if isnothing(out) - return copy(p.drivers.P_liq) # I guess this is read and put it p. not computed. curious if we should handle this differently. - else - out .= p.drivers.P_liq - end -end - -function compute_snowfall(out, Y, p, t, land_model::SoilCanopyModel) - if isnothing(out) - return copy(p.drivers.P_snow) # following comment above, we could have a default getting only model output, and one also getting some inputs like drivers - else - out .= p.drivers.P_snow - end -end - -function compute_pressure(out, Y, p, t, land_model::SoilCanopyModel) - if isnothing(out) - return copy(p.drivers.P) # not sure if precip or pressure - else - out .= p.drivers.P - end -end - -function compute_wind_speed(out, Y, p, t, land_model::SoilCanopyModel) - if isnothing(out) - return copy(p.drivers.u) - else - out .= p.drivers.u - end -end - -function compute_specific_humidity(out, Y, p, t, land_model::SoilCanopyModel) - if isnothing(out) - return copy(p.drivers.q) # check if this is correct. Also, check if Bucket has it and same name or not. - else - out .= p.drivers.q - end -end - -function compute_air_co2(out, Y, p, t, land_model::SoilCanopyModel) - if isnothing(out) - return copy(p.drivers.c_co2) - else - out .= p.drivers.c_co2 - end -end - -function compute_radiation_shortwave_down( - out, - Y, - p, - t, - land_model::SoilCanopyModel, -) - if isnothing(out) - return copy(p.drivers.SW_d) - else - out .= p.drivers.SW_d - end -end - -function compute_radiation_longwave_down( - out, - Y, - p, - t, - land_model::SoilCanopyModel, -) - if isnothing(out) - return copy(p.drivers.LW_d) - else - out .= p.drivers.LW_d - end -end - -function compute_photosynthesis_net_leaf( - out, - Y, - p, - t, - land_model::SoilCanopyModel, -) - if isnothing(out) - return copy(p.canopy.photosynthesis.An) - else - out .= p.canopy.photosynthesis.An - end -end - -function compute_photosynthesis_net_canopy!( - out, - Y, - p, - t, - land_model::SoilCanopyModel, -) # could be gross primary productivity, but this is consistent with leaf - if isnothing(out) - return copy(p.canopy.photosynthesis.GPP) - else - out .= p.canopy.photosynthesis.GPP - end -end - -function compute_respiration_leaf(out, Y, p, t, land_model::SoilCanopyModel) - if isnothing(out) - return copy(p.canopy.photosynthesis.Rd) - else - out .= p.canopy.photosynthesis.Rd - end -end - -function compute_vcmax25(out, Y, p, t, land_model::SoilCanopyModel) - if isnothing(out) - return copy(p.canopy.photosynthesis.vcmax25) - else - out .= p.canopy.photosynthesis.vcmax25 - end -end - -function compute_photosynthetically_active_radiation( - out, - Y, - p, - t, - land_model::SoilCanopyModel, -) - if isnothing(out) - return copy(p.canopy.radiative_transfer.par) - else - out .= p.canopy.radiative_transfer.par - end -end - -function compute_photosynthetically_active_radiation_absorbed( - out, - Y, - p, - t, - land_model::SoilCanopyModel, -) - if isnothing(out) - return copy(p.canopy.radiative_transfer.apar) - else - out .= p.canopy.radive_transfer.apar - end -end - -function compute_photosynthetically_active_radiation_reflected( - out, - Y, - p, - t, - land_model::SoilCanopyModel, -) - if isnothing(out) - return copy(p.canopy.radiative_transfer.rpar) - else - out .= p.canopy.radiative_transfer.rpar - end -end - -function compute_photosynthetically_active_radiation_transmitted( - out, - Y, - p, - t, - land_model::SoilCanopyModel, -) - if isnothing(out) - return copy(p.canopy.radiative_transfer.tpar) - else - out .= p.canopy.radiative_transfer.tpar - end -end - -function compute_near_infrared_radiation( - out, - Y, - p, - t, - land_model::SoilCanopyModel, -) - if isnothing(out) - return copy(p.canopy.radiative_transfer.nir) - else - out .= p.canopy.radiative_transfer.nir - end -end - -function compute_near_infrared_radiation_absorbed( - out, - Y, - p, - t, - land_model::SoilCanopyModel, -) - if isnothing(out) - return copy(p.canopy.radiative_transfer.anir) - else - out .= p.canopy.radiative_transfer.anir - end -end - -function compute_near_infrared_radiation_reflected( - out, - Y, - p, - t, - land_model::SoilCanopyModel, -) - if isnothing(out) - return copy(p.canopy.radiative_transfer.rnir) - else - out .= p.canopy.radiative_transfer.rnir - end -end - -function compute_near_infrared_radiation_transmitted( - out, - Y, - p, - t, - land_model::SoilCanopyModel, -) - if isnothing(out) - return copy(p.canopy.radiative_transfer.tnir) - else - out .= p.canopy.radiative_transfer.tnir - end -end - -function compute_radiation_shortwave_net( - out, - Y, - p, - t, - land_model::SoilCanopyModel, -) - if isnothing(out) - return copy(p.canopy.radiative_transfer.SW_n) - else - out .= p.canopy.radiative_transfer.SW_n - end -end - -function compute_radiation_longwave_net( - out, - Y, - p, - t, - land_model::SoilCanopyModel, -) - if isnothing(out) - return copy(p.canopy.radiative_transfer.LW_n) - else - out .= p.canopy.radiative_transfer.LW_n - end -end - -function compute_autotrophic_respiration( - out, - Y, - p, - t, - land_model::SoilCanopyModel, -) - if isnothing(out) - return copy(p.canopy.autotrophic_respiration.Ra) - else - out .= p.canopy.autotrophic_respiration.Ra - end -end - -function compute_soilco2(out, Y, p, t, land_model::SoilCanopyModel) - if isnothing(out) - return copy(Y.soilco2.C) - else - out .= Y.soilco2.C - end -end - -function compute_heterotrophic_respiration( - out, - Y, - p, - t, - land_model::SoilCanopyModel, -) - if isnothing(out) - return copy(p.soilco2.top_bc) - else - p.soilco2.top_bc - end -end - -function compute_soil_hydraulic_conductivity( - out, - Y, - p, - t, - land_model::SoilCanopyModel, -) - if isnothing(out) - return copy(p.soil.K) - else - p.soil.K - end -end - -function compute_soil_water_potential(out, Y, p, t, land_model::SoilCanopyModel) - if isnothing(out) - return copy(p.soil.ψ) - else - p.soil.ψ - end -end - -function compute_soil_thermal_conductivity( - out, - Y, - p, - t, - land_model::SoilCanopyModel, -) - if isnothing(out) - return copy(p.soil.κ) - else - p.soil.κ - end -end - -function compute_solar_zenith_angle(out, Y, p, t, land_model::SoilCanopyModel) - if isnothing(out) - return copy(p.drivers.θs) - else - p.drivers.θs - end -end - -function compute_moisture_stress_factor( - out, - Y, - p, - t, - land_model::SoilCanopyModel, -) - if isnothing(out) - return copy(p.canopy.hydraulics.β) - else - p.canopy.hydraulics.β - end -end - -function compute_canopy_water_potential( - out, - Y, - p, - t, - land_model::SoilCanopyModel, -) - if isnothing(out) - return copy(p.canopy.hydraulics.ψ) - else - p.canopy.hydraulics.ψ - end -end - -function compute_cross_section(out, Y, p, t, land_model::SoilCanopyModel) - if isnothing(out) - return copy(p.canopy.hydraulics.fa) - else - p.canopy.hydraulics.fa - end -end - -function compute_cross_section_roots(out, Y, p, t, land_model::SoilCanopyModel) - if isnothing(out) - return copy(p.canopy.hydraulics.fa_roots) - else - p.canopy.hydraulics.fa_roots - end -end - -function compute_area_index!(out, Y, p, t, land_model::SoilCanopyModel) - if isnothing(out) - return copy(p.canopy.hydraulics.area_index.leaf) - else - out .= p.canopy.hydraulics.area_index.leaf - end -end - -function compute_canopy_latent_heat_flux( - out, - Y, - p, - t, - land_model::SoilCanopyModel, -) - if isnothing(out) - return copy(p.canopy.energy.lhf) - else - p.canopy.canopy.lhf - end -end - -function compute_canopy_sensible_heat_flux( - out, - Y, - p, - t, - land_model::SoilCanopyModel, -) - if isnothing(out) - return copy(p.canopy.energy.shf) - else - p.canopy.canopy.shf - end -end - -function compute_canopy_aerodynamic_resistance( - out, - Y, - p, - t, - land_model::SoilCanopyModel, -) - if isnothing(out) - return copy(p.canopy.energy.r_ae) - else - p.canopy.canopy.r_ae - end -end - -function compute_canopy_temperature!(out, Y, p, t, land_model::SoilCanopyModel) - if isnothing(out) - return copy(Y.canopy.energy.T) - else - out .= Y.canopy.energy.T - end -end - -function compute_soil_ice!( - out, - Y, - p, - t, - land_model::Union{SoilCanopyModel, EnergyHydrology}, -) - if isnothing(out) - return copy(top_center_to_surface(Y.soil.θ_i)) - else - out .= top_center_to_surface(Y.soil.θ_i) - end -end