-
Notifications
You must be signed in to change notification settings - Fork 8
Oscar/seq drydep set h coeff #353
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
fedd8d5
10d4efc
2511c4c
5fd42f1
b04cb38
6ece7a1
9e26d73
521ee47
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,7 @@ | ||
| #ifndef MAM4XX_SEQ_DRYDEP_HPP | ||
| #define MAM4XX_SEQ_DRYDEP_HPP | ||
|
|
||
| #include <haero/math.hpp> | ||
| #include <mam4xx/mam4_types.hpp> | ||
|
|
||
| namespace mam4::seq_drydep { // C++ version of E3SM's seq_drydep_mod.F90 | ||
|
|
@@ -14,6 +15,9 @@ constexpr int NSeas = 5; | |
| // number of land use types | ||
| constexpr int NLUse = 11; | ||
|
|
||
| // number of gas species in dry dep list. | ||
| constexpr int n_drydep = 3; | ||
|
|
||
| //========================================= | ||
| // data for E3SM dry deposition of tracers | ||
| //========================================= | ||
|
|
@@ -55,13 +59,83 @@ struct Data { | |
| int so2_ndx; | ||
| }; | ||
|
|
||
| // This function computes the H coefficients corresponding to the given surface | ||
| // temperature. It must be implemented by the client application as an on-device | ||
| // Kokkos function, and must be defined IN THE TRANSLATION UNIT IN WHICH IT'S | ||
| // CALLED because we don't use relocatable device code. The function can be | ||
| // implemented in the atmospheric host model or in a testing environment, for | ||
| // example. | ||
| KOKKOS_FUNCTION void setHCoeff(Real sfc_temp, Real heff[maxspc]); | ||
| // Define the Species enum for dry deposition species identification | ||
| // BAD CONSTANT | ||
| enum class GasDrydepSpecies { H2O2, H2SO4, SO2, CO2, NH3 }; | ||
| /** | ||
| * Calculates Henry's law coefficients based on surface temperature and other | ||
| * parameters. | ||
| * | ||
| * @param sfc_temp The surface temperature in Kelvin. [input] | ||
| * @param heff Array where the calculated Henry's law coefficients will be | ||
| * stored. [output] | ||
| */ | ||
| KOKKOS_INLINE_FUNCTION | ||
| void set_hcoeff_scalar(const Real sfc_temp, Real heff[]) { | ||
|
|
||
| // Define dheff array with size n_species_table*6 | ||
| // NOTE: We are hard-coding the table dheff with only 3 species: | ||
| // H2O2, H2SO4, SO2. | ||
| // The original table can be found in the seq_drydep_mod.F90 module. | ||
| // BAD CONSTANT | ||
| const GasDrydepSpecies drydep_list[n_drydep] = { | ||
| GasDrydepSpecies::H2O2, GasDrydepSpecies::H2SO4, GasDrydepSpecies::SO2}; | ||
| // --- data for effective Henry's Law coefficient --- | ||
| constexpr Real dheff[n_drydep * 6] = { | ||
| 8.70e+04, 7320., 2.2e-12, -3730., 0., 0., // H2O2 | ||
| 1.e+11, 6014., 0., 0., 0., 0., // H2SO4 | ||
| 1.36e+00, 3100., 1.30e-02, 1960., 6.6e-08, 1500. // SO2 | ||
| }; | ||
| // NOTE: we are using fortran indexing. | ||
| constexpr int mapping[n_drydep] = {1, 2, 3}; | ||
| // BAD CONSTANT | ||
| constexpr Real ph = 1.e-5; // measure of the acidity (dimensionless) | ||
|
|
||
| const Real t0 = 298.0; // Standard Temperature | ||
| const Real ph_inv = 1.0 / ph; // Inverse of PH | ||
|
|
||
| const Real wrk = (t0 - sfc_temp) / (t0 * sfc_temp); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we add an EKAT ASSERT before line 97 to guard against dividing by zero? or something similar....
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, that is a good point. I also think it is unlikely to get into divide by zero error here. |
||
|
|
||
| for (int m = 0; m < n_drydep; ++m) { | ||
| const int l = mapping[m] - 1; // Adjust for 0-based indexing | ||
| const int id = 6 * l; | ||
| Real e298 = dheff[id]; // Adjusted for 0-based indexing | ||
| Real dhr = dheff[id + 1]; // Adjusted for 0-based indexing | ||
| heff[m] = haero::exp(dhr * wrk) * e298; | ||
|
|
||
| // Calculate coefficients based on the drydep tables | ||
| if (dheff[id + 2] != 0.0 && dheff[id + 4] == 0.0) { | ||
| e298 = dheff[id + 2]; | ||
| dhr = dheff[id + 3]; | ||
| Real dk1 = haero::exp(dhr * wrk) * e298; | ||
| heff[m] = | ||
| (heff[m] != 0.0) ? heff[m] * (1.0 + dk1 * ph_inv) : dk1 * ph_inv; | ||
| } | ||
|
|
||
| // For coefficients that are non-zero AND CO2 or NH3 handle things this way | ||
| if (dheff[id + 4] != 0.0) { | ||
| GasDrydepSpecies species = drydep_list[m]; | ||
| if (species == GasDrydepSpecies::CO2 || | ||
| species == GasDrydepSpecies::NH3 || | ||
| species == GasDrydepSpecies::SO2) { | ||
| e298 = dheff[id + 2]; | ||
| dhr = dheff[id + 3]; | ||
| Real dk1 = haero::exp(dhr * wrk) * e298; | ||
| e298 = dheff[id + 4]; | ||
| dhr = dheff[id + 5]; | ||
| Real dk2 = haero::exp(dhr * wrk) * e298; | ||
| if (species == GasDrydepSpecies::CO2 || | ||
| species == GasDrydepSpecies::SO2) { | ||
| heff[m] *= (1.0 + dk1 * ph_inv * (1.0 + dk2 * ph_inv)); | ||
| } else if (species == GasDrydepSpecies::NH3) { | ||
| heff[m] *= (1.0 + dk1 * ph / dk2); | ||
| } else { | ||
| EKAT_KERNEL_ERROR_MSG("ERROR: Bad species encountered.\n"); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| } // namespace mam4::seq_drydep | ||
|
|
||
|
|
||
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both
t0andph_invcan beconstexpras they are known at compile time.