From 22bda7961c3acd81fd318324c6b5177261c000f3 Mon Sep 17 00:00:00 2001 From: Ben Wibking Date: Tue, 13 Feb 2024 11:51:27 -0500 Subject: [PATCH 01/21] add cooling documentation --- docs/cooling_curves_LambdaHD.png | Bin 0 -> 37673 bytes docs/cooling_notes.md | 102 ++++++++++++++++++++++++++ docs/plot_lambda.py | 52 ++++++++++++++ docs/schure_table_2.txt | 112 +++++++++++++++++++++++++++++ docs/sutherland_dopita_table_6.txt | 97 +++++++++++++++++++++++++ 5 files changed, 363 insertions(+) create mode 100644 docs/cooling_curves_LambdaHD.png create mode 100644 docs/cooling_notes.md create mode 100644 docs/plot_lambda.py create mode 100644 docs/schure_table_2.txt create mode 100644 docs/sutherland_dopita_table_6.txt diff --git a/docs/cooling_curves_LambdaHD.png b/docs/cooling_curves_LambdaHD.png new file mode 100644 index 0000000000000000000000000000000000000000..24479cea6e613dd04a2b46e36add8549624d1ace GIT binary patch literal 37673 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 W3@TARDHWzgl#;xPT#1bF^Zx;CSdbn7 literal 0 HcmV?d00001 diff --git a/docs/cooling_notes.md b/docs/cooling_notes.md new file mode 100644 index 00000000..99fa5ec4 --- /dev/null +++ b/docs/cooling_notes.md @@ -0,0 +1,102 @@ +--- +title: Cooling function conventions +author: Ben Wibking +date: February 12, 2024 +--- + +# Summary + +Several different conventions exist for the definition of a collisional ionization equilibrium (CIE) cooling curve. They are explained in detail below, with references. + +# Conventions + +## $n^2 \Lambda$ convention + +This convention uses the *total number density* $n$ to define the volumetric cooling rate. The total particle number density is defined as the sum of the number of ions, neutrals, and electrons divided by the volume. + +The total number density $n$ is related to the dimensionless mean molecular weight $\mu$ by: + +$$n = \frac{\rho}{\mu m_H} \, ,$$ {#eq:number_density} + +where $\rho$ is the mass density of the fluid, $m_H$ is the mass of the hydrogen atom, and $\mu$ is the dimensionless mean molecular weight. This may be taken as the definition of $\mu$. + +In this convention, the volumetric cooling rate is given by + +$$S_{cool} = n^2 \Lambda(T) \, ,$$ {#eq:cooling_rate_nsqLambda} + +where $S_{cool}$ is the volumetric cooling source term, $n$ is the total number density and $\Lambda(T)$ is the CIE cooling curve in this convention. + +This convention is used by the PLUTO code (see the [PLUTO User Guide](http://plutocode.ph.unito.it/userguide.pdf), section 9.2, equation 9.5). + +## $n_i n_e \Lambda$ convention + +In this convention, the volumetric cooling rate is given by + +$$S_{cool} = n_i n_e \Lambda(T) \, ,$$ {#eq:cooling_rate_nineLambda} + +where $S_{cool}$ is the volumetric cooling source term, $n_i$ is the number density of ions (*usually* including neutrals by convention, but this difference should be negligible when CIE is valid), $n_e$ is the number density of electrons, and $\Lambda(T)$ is the CIE cooling curve in this convention. + +This convention is adopted by Sutherland and Dopita (1993) in their tabulation of CIE cooling curves (their section 5.2; see also their equations 51-58). + +Sutherland and Dopita additionally comment: *"The normalization factor for the cooling function $\Lambda_N$ is taken as $n_t n_e$ where $n_t$ is the total number density of ions and $n_e$ is the total number density of electrons. This definition is generally valid and independent of composition. It differs from the commonly used factor $n_H n_e$ or even $n_e^2$ commonly used in hydrogen-rich plasmas."* + + +## $n_H n_e \Lambda$ convention + +In this convention, the volumetric cooling rate is given by + +$$S_{cool} = n_H n_e \Lambda(T) \, ,$$ {#eq:cooling_rate_nHneLambda} + +where $S_{cool}$ is the volumetric cooling source term, $n_H$ is the number density of hydrogen *nuclei* (not ions), $n_e$ is the number density of electrons, and $\Lambda(T)$ is the CIE cooling curve in this convention. + +This convention is adopted by Schure et al. (2009) in their definition of $\Lambda_N$. However, this is **not** the same $\Lambda_N$ as used by Sutherland and Dopita (1993)! + +This convention is adopted by Gnat and Sternberg (2007) in their definition of $\Lambda$. + +## $n_H^2 \Lambda$ convention + +In this convention, the volumetric cooling rate is given by + +$$S_{cool} = n_H^2 \Lambda(T) \, ,$$ {#eq:cooling_rate_nHsqLambda} + +where $S_{cool}$ is the volumetric cooling source term, $n_H$ is the number density of hydrogen *nuclei* (not ions), and $\Lambda(T)$ is the CIE cooling curve in this convention. + +This convention is adopted by Dalgarno and McCray (1972) (their equation 24), and Schure et al. (2009) in their definition of $\Lambda_{hd}$ (their equation 2). + +### AthenaPK implementation + +This is the convention adopted by AthenaPK, except $n_H$ is computed assuming zero metals in the mass budget: +$$ x_H = 1 - Y \, , $$ +$$ n_H = X_H \rho / m_H = (1 - Y) \rho / m_H \, .$$ + +The difference in neglecting metals in the mass budget in computing $n_H$ is only a $\sim 2$ percent effect on $n_H$ (since metals are 2 percent by mass for solar metallicity) and a $\sim 4$ percent effect on the source term. + +The Schure table in the GitHub repository uses the using the $n_H n_e$ convention, rather than the $n_H^2$ convention. This causes an error in the cooling rate of $n_e / n_H$, or about 20 percent for temperatures above $10^{5.5}$ K. + +Above $\sim 10^4$ K, there is a percent-level error in the mean molecular weight due to neglecting the metal contribution to the electron fraction. *Users should be aware that at low absolute electron fraction, metals contribute a substantial proportion of the metals, so this approximation is no longer valid below $\sim 10^4$ K.* The temperature is computed as: +$$ T = \left( \frac{\rho}{\mu m_H} \right)^{-1} \left( \frac{P}{k_B} \right) \, ,$$ +where the dimensionless mean molecular weight $\mu$ is computed assuming a zero metallicity gas: +$$ \mu = \left( \frac{3}{4} Y + 2(1 - Y) \right)^{-1} = \left( 2 - \frac{5}{4} Y \right)^{-1} \, ,$$ +where $Y$ is the Helium mass fraction. + +For a more precise calculation of $\mu$ assuming a scaled-solar composition of metals, we have: +$$ \mu = \left( 1 - x_e \right) \left( X + \frac{Y}{4} + \frac{Z}{\bar A} \right)^{-1} \, , $$ +where $\bar A$ is the mass-weighted mean atomic weight of metals: +$$ \bar A = 16 \, .$$ + +Additionally, for full ionization for all species, we have: +$$ x_e = \frac{X + 2 Y (m_H/m_{He}) + (\bar A/2) Z (m_H/m_{\bar Z})}{2 X + 3 Y (m_H/m_{He}) + (1 + \bar A/2) Z (m_H/m_{\bar Z})} \approx \frac{X + Y/2 + Z/2}{2 X + 3 Y/4 + (1/{\bar A} + 1/2) Z}$$ + +For $Y = 0.24$ and $Z = 0.02$, the mean molecular weight for complete ionization is $\mu \approx 0.60$ (if $Z = 0$, then this yields $\mu \approx 0.59$). + +## $n_e^2 \Lambda$ convention + +In this convention, the volumetric cooling rate is given by + +$$S_{cool} = n_e^2 \Lambda(T) \, ,$$ {#eq:cooling_rate_nHsqLambda} + +where $S_{cool}$ is the volumetric cooling source term, $n_e$ is the number density of electrons, and $\Lambda(T)$ is the CIE cooling curve in this convention. + +For the case of a hydrogen-only fully-ionized plasma *only*, this is equivalent to the $n_H^2 \Lambda$ convention, since each hydrogen atom contributes exactly one electron and there are no other sources of electrons. + +I am not aware of any common tables that use this convention. However, it is noted as one of the possible conventions by Sutherland and Dopita (1993). diff --git a/docs/plot_lambda.py b/docs/plot_lambda.py new file mode 100644 index 00000000..95baad1c --- /dev/null +++ b/docs/plot_lambda.py @@ -0,0 +1,52 @@ +import numpy as np +import matplotlib.pyplot as plt + +if __name__ == "__main__": + ## plot *solar abundance* CIE cooling curves + + ## Sutherland and Dopita (1993) [NOTE: n_i n_e convention for Lambda_N, where n_t == n_i in their notation] + # Columns: Log(T), n_e, n_H, n_t, log(\Lambda_net), log(\Lambda_N) + sd_LogT, sd_ne, sd_nH, sd_nt, sd_logLambdaNet, sd_logLambdaN = np.loadtxt("sutherland_dopita_table_6.txt", unpack=True) + # convert to Lambda_hd: + sd_LambdaN = 10.**sd_logLambdaN + sd_LambdaHD = (sd_ne * sd_nt * sd_LambdaN) / sd_nH**2 + # convert to nH ne Lambda(T): + sd_nHneLambda = (sd_ne * sd_nt * sd_LambdaN) / (sd_nH * sd_ne) + + ## Schure et al. (2009) [NOTE: n_H n_e convention for Lambda_N; n_H^2 convention for Lambda_hd] + # Columns: log T (K), log Λ_N (erg s^−1 cm^3), log Λ_hd (erg s^−1 cm^3), n_e/n_H + # BEWARE: This Lambda_N is NOT the same as the Sutherland and Dopita Lambda_N! + s_LogT, s_logLambdaN, s_logLambdaHD, s_ne_over_nH = np.loadtxt("schure_table_2.txt", unpack=True) + s_LambdaHD = 10.**s_logLambdaHD + + ## Gnat and Sternberg (2007) [NOTE: n_H n_e convention for Lambda] + # Columns: Temperature Lambda(Z=1e-3) Lambda(Z=1e-2) Lambda(Z=1e-1) Lambda(Z=1) Lambda(Z=2) + gs_T, gs_LambdaZem3, gs_LambdaZem2, gs_LambdaZem1, gs_LambdaZ1, gs_LambdaZ2 = np.loadtxt("gnat_sternberg_cie_table.txt", unpack=True, skiprows=23) + # NOTE: There is not enough information in this table alone to compute n_e! + # (The electron fraction must be computed from datafile2a.txt) + + # plot nH^2-normalized Lambda(T) + plt.figure() + plt.plot(sd_LogT, sd_LambdaHD, label = r"Sutherland & Dopita $\Lambda_{hd}$ for $Z_{\odot}$") + plt.plot(s_LogT, s_LambdaHD, label = r"Schure et al. $\Lambda_{hd}$ for $Z_{\odot}$") + # (Gnat & Sternberg cannot be converted to this convention without the electron fraction, which is missing.) + plt.yscale('log') + plt.ylim(1e-23, 3e-21) + plt.xlabel(r"$\log T$ (K)") + plt.ylabel(r"$\Lambda(T)$ [$n_H^2$ convention]") + plt.legend() + plt.tight_layout() + plt.savefig("cooling_curves_LambdaHD.png") + + # plot nH ne-normalized Lambda(T) + plt.figure() + plt.plot(sd_LogT, sd_nHneLambda, label = r"Sutherland & Dopita $\Lambda$ for $Z_{\odot}$") + plt.plot(s_LogT, 10.**s_logLambdaN, label = r"Schure et al. $\Lambda$ for $Z_{\odot}$") + plt.plot(np.log10(gs_T), gs_LambdaZ1, label = r"Gnat & Sternberg $\Lambda$ for $Z_{\odot}$") + plt.yscale('log') + plt.ylim(1e-23, 3e-21) + plt.xlabel(r"$\log T$ (K)") + plt.ylabel(r"$\Lambda(T)$ [$n_H n_e$ convention]") + plt.legend() + plt.tight_layout() + plt.savefig("cooling_curves_nHneLambda.png") diff --git a/docs/schure_table_2.txt b/docs/schure_table_2.txt new file mode 100644 index 00000000..a3409335 --- /dev/null +++ b/docs/schure_table_2.txt @@ -0,0 +1,112 @@ +## This is an exact reproduction of "Table 2. Cooling curve for solar metallicity" from Schure et al. (2009). +## log T (K), log Λ_N (erg s^−1 cm^3), log Λ_hd (erg s^−1 cm^3), n_e/n_H +3.8 -25.7331 -30.6104 1.3264e-05 +3.84 -25.0383 -29.4107 4.2428e-05 +3.88 -24.4059 -28.4601 8.8276e-05 +3.92 -23.8288 -27.5743 0.00017967 +3.96 -23.3027 -26.3766 0.00084362 +4.0 -22.8242 -25.289 0.0034295 +4.04 -22.3917 -24.2684 0.013283 +4.08 -22.0067 -23.3834 0.042008 +4.12 -21.6818 -22.5977 0.12138 +4.16 -21.4529 -21.9689 0.30481 +4.2 -21.3246 -21.5972 0.53386 +4.24 -21.3459 -21.4615 0.76622 +4.28 -21.4305 -21.4789 0.89459 +4.32 -21.5293 -21.5497 0.95414 +4.36 -21.6138 -21.6211 0.98342 +4.4 -21.6615 -21.6595 1.0046 +4.44 -21.6551 -21.6426 1.0291 +4.48 -21.5919 -21.5688 1.0547 +4.52 -21.5092 -21.4771 1.0767 +4.56 -21.4124 -21.3755 1.0888 +4.6 -21.3085 -21.2693 1.0945 +4.64 -21.2047 -21.1644 1.0972 +4.68 -21.1067 -21.0658 1.0988 +4.72 -21.0194 -20.9778 1.1004 +4.76 -20.9413 -20.8986 1.1034 +4.8 -20.8735 -20.8281 1.1102 +4.84 -20.8205 -20.77 1.1233 +4.88 -20.7805 -20.7223 1.1433 +4.92 -20.7547 -20.6888 1.1638 +4.96 -20.7455 -20.6739 1.1791 +5.0 -20.7565 -20.6815 1.1885 +5.04 -20.782 -20.7051 1.1937 +5.08 -20.8008 -20.7229 1.1966 +5.12 -20.7994 -20.7208 1.1983 +5.16 -20.7847 -20.7058 1.1993 +5.2 -20.7687 -20.6896 1.1999 +5.24 -20.759 -20.6797 1.2004 +5.28 -20.7544 -20.6749 1.2008 +5.32 -20.7505 -20.6709 1.2012 +5.36 -20.7545 -20.6748 1.2015 +5.4 -20.7888 -20.7089 1.202 +5.44 -20.8832 -20.8031 1.2025 +5.48 -21.045 -20.9647 1.203 +5.52 -21.2286 -21.1482 1.2035 +5.56 -21.3737 -21.2932 1.2037 +5.6 -21.4573 -21.3767 1.2039 +5.64 -21.4935 -21.4129 1.204 +5.68 -21.5098 -21.4291 1.2041 +5.72 -21.5345 -21.4538 1.2042 +5.76 -21.5863 -21.5055 1.2044 +5.8 -21.6548 -21.574 1.2045 +5.84 -21.7108 -21.63 1.2046 +5.88 -21.7424 -21.6615 1.2047 +5.92 -21.7576 -21.6766 1.2049 +5.96 -21.7696 -21.6886 1.205 +6.0 -21.7883 -21.7073 1.2051 +6.04 -21.8115 -21.7304 1.2053 +6.08 -21.8303 -21.7491 1.2055 +6.12 -21.8419 -21.7607 1.2056 +6.16 -21.8514 -21.7701 1.2058 +6.2 -21.869 -21.7877 1.206 +6.24 -21.9057 -21.8243 1.2062 +6.28 -21.969 -21.8875 1.2065 +6.32 -22.0554 -21.9738 1.2067 +6.36 -22.1488 -22.0671 1.207 +6.4 -22.2355 -22.1537 1.2072 +6.44 -22.3084 -22.2265 1.2075 +6.48 -22.3641 -22.2821 1.2077 +6.52 -22.4033 -22.3213 1.2078 +6.56 -22.4282 -22.3462 1.2079 +6.6 -22.4408 -22.3587 1.208 +6.64 -22.4443 -22.3622 1.2081 +6.68 -22.4411 -22.359 1.2082 +6.72 -22.4334 -22.3512 1.2083 +6.76 -22.4242 -22.342 1.2083 +6.8 -22.4164 -22.3342 1.2084 +6.84 -22.4134 -22.3312 1.2084 +6.88 -22.4168 -22.3346 1.2085 +6.92 -22.4267 -22.3445 1.2085 +6.96 -22.4418 -22.3595 1.2086 +7.0 -22.4603 -22.378 1.2086 +7.04 -22.483 -22.4007 1.2087 +7.08 -22.5112 -22.4289 1.2087 +7.12 -22.5449 -22.4625 1.2088 +7.16 -22.5819 -22.4995 1.2088 +7.2 -22.6177 -22.5353 1.2089 +7.24 -22.6483 -22.5659 1.2089 +7.28 -22.6719 -22.5895 1.2089 +7.32 -22.6883 -22.6059 1.2089 +7.36 -22.6985 -22.6161 1.2089 +7.4 -22.7032 -22.6208 1.209 +7.44 -22.7037 -22.6213 1.209 +7.48 -22.7008 -22.6184 1.209 +7.52 -22.695 -22.6126 1.209 +7.56 -22.6869 -22.6045 1.209 +7.6 -22.6769 -22.5945 1.209 +7.64 -22.6655 -22.5831 1.209 +7.68 -22.6531 -22.5707 1.209 +7.72 -22.6397 -22.5573 1.209 +7.76 -22.6258 -22.5434 1.209 +7.8 -22.6111 -22.5287 1.209 +7.84 -22.5964 -22.514 1.209 +7.88 -22.5816 -22.4992 1.209 +7.92 -22.5668 -22.4844 1.209 +7.96 -22.5519 -22.4695 1.209 +8.0 -22.5367 -22.4543 1.209 +8.04 -22.5216 -22.4392 1.209 +8.08 -22.5062 -22.4237 1.2091 +8.12 -22.4912 -22.4087 1.2091 +8.16 -22.4753 -22.3928 1.2091 \ No newline at end of file diff --git a/docs/sutherland_dopita_table_6.txt b/docs/sutherland_dopita_table_6.txt new file mode 100644 index 00000000..764ec52d --- /dev/null +++ b/docs/sutherland_dopita_table_6.txt @@ -0,0 +1,97 @@ +## This is a reproduction of Table 6 of Sutherland and Dopita (1993). +## [NOTE: Only columns 1-6 are reproduced in this file. Log(U), Log(tau_cool), and the "general plasma properties" are not included.] +## [Headings included in the printed table:] +## CIE Cooling Curve : Solar Abundances +## Number Densities; Cooling Properties; General Plasma Properties +## Log(T), n_e, n_H, n_t, log(\Lambda_net), log(\Lambda_N) +4.0 0.0023 1.0 1.099 -25.65 -23.06 +4.05 0.0142 1.0 1.099 -24.27 -22.46 +4.1 0.0704 1.0 1.099 -23.28 -22.17 +4.15 0.2534 1.0 1.099 -22.47 -21.92 +4.2 0.5678 1.0 1.099 -21.99 -21.79 +4.25 0.8177 1.0 1.099 -21.84 -21.8 +4.3 0.9324 1.0 1.099 -21.85 -21.86 +4.35 0.978 1.0 1.099 -21.87 -21.9 +4.4 1.004 1.0 1.099 -21.84 -21.88 +4.45 1.035 1.0 1.099 -21.77 -21.82 +4.5 1.067 1.0 1.099 -21.66 -21.73 +4.55 1.086 1.0 1.099 -21.56 -21.63 +4.6 1.094 1.0 1.099 -21.45 -21.53 +4.65 1.098 1.0 1.099 -21.34 -21.42 +4.7 1.1 1.0 1.099 -21.24 -21.32 +4.75 1.102 1.0 1.099 -21.14 -21.22 +4.8 1.11 1.0 1.099 -21.05 -21.14 +4.85 1.128 1.0 1.099 -20.97 -21.07 +4.9 1.154 1.0 1.099 -20.91 -21.01 +4.95 1.176 1.0 1.099 -20.87 -20.98 +5.0 1.188 1.0 1.099 -20.87 -20.99 +5.05 1.195 1.0 1.099 -20.9 -21.02 +5.1 1.198 1.0 1.099 -20.91 -21.03 +5.15 1.199 1.0 1.099 -20.89 -21.01 +5.2 1.2 1.0 1.099 -20.86 -20.98 +5.25 1.201 1.0 1.099 -20.85 -20.97 +5.3 1.201 1.0 1.099 -20.84 -20.96 +5.35 1.201 1.0 1.099 -20.84 -20.96 +5.4 1.202 1.0 1.099 -20.87 -20.99 +5.45 1.203 1.0 1.099 -21.01 -21.13 +5.5 1.203 1.0 1.099 -21.23 -21.35 +5.55 1.204 1.0 1.099 -21.43 -21.55 +5.6 1.204 1.0 1.099 -21.54 -21.66 +5.65 1.204 1.0 1.099 -21.58 -21.71 +5.7 1.204 1.0 1.099 -21.59 -21.71 +5.75 1.204 1.0 1.099 -21.59 -21.71 +5.8 1.204 1.0 1.099 -21.64 -21.76 +5.85 1.205 1.0 1.099 -21.74 -21.86 +5.9 1.205 1.0 1.099 -21.81 -21.93 +5.95 1.205 1.0 1.099 -21.83 -21.95 +6.0 1.205 1.0 1.099 -21.84 -21.96 +6.05 1.205 1.0 1.099 -21.84 -21.96 +6.1 1.206 1.0 1.099 -21.83 -21.96 +6.15 1.206 1.0 1.099 -21.82 -21.95 +6.2 1.206 1.0 1.099 -21.82 -21.94 +6.25 1.206 1.0 1.099 -21.85 -21.97 +6.3 1.207 1.0 1.099 -21.95 -22.07 +6.35 1.207 1.0 1.099 -22.08 -22.2 +6.4 1.207 1.0 1.099 -22.19 -22.31 +6.45 1.208 1.0 1.099 -22.27 -22.39 +6.5 1.208 1.0 1.099 -22.32 -22.44 +6.55 1.208 1.0 1.099 -22.35 -22.48 +6.6 1.208 1.0 1.099 -22.38 -22.5 +6.65 1.208 1.0 1.099 -22.41 -22.53 +6.7 1.208 1.0 1.099 -22.44 -22.56 +6.75 1.208 1.0 1.099 -22.46 -22.59 +6.8 1.208 1.0 1.099 -22.48 -22.6 +6.85 1.209 1.0 1.099 -22.48 -22.6 +6.9 1.209 1.0 1.099 -22.46 -22.59 +6.95 1.209 1.0 1.099 -22.45 -22.57 +7.0 1.209 1.0 1.099 -22.45 -22.57 +7.05 1.209 1.0 1.099 -22.46 -22.59 +7.1 1.209 1.0 1.099 -22.49 -22.62 +7.15 1.209 1.0 1.099 -22.53 -22.65 +7.2 1.209 1.0 1.099 -22.56 -22.68 +7.25 1.209 1.0 1.099 -22.58 -22.7 +7.3 1.209 1.0 1.099 -22.6 -22.72 +7.35 1.209 1.0 1.099 -22.61 -22.73 +7.4 1.209 1.0 1.099 -22.61 -22.73 +7.45 1.209 1.0 1.099 -22.61 -22.73 +7.5 1.209 1.0 1.099 -22.6 -22.73 +7.55 1.209 1.0 1.099 -22.6 -22.72 +7.6 1.209 1.0 1.099 -22.59 -22.71 +7.65 1.209 1.0 1.099 -22.37 -22.7 +7.7 1.209 1.0 1.099 -22.36 -22.68 +7.75 1.209 1.0 1.099 -22.34 -22.67 +7.8 1.209 1.0 1.099 -22.33 -22.65 +7.85 1.209 1.0 1.099 -22.51 -22.64 +7.9 1.209 1.0 1.099 -22.49 -22.62 +7.95 1.209 1.0 1.099 -22.48 -22.6 +8.0 1.209 1.0 1.099 -22.46 -22.58 +8.05 1.209 1.0 1.099 -22.44 -22.36 +8.1 1.209 1.0 1.099 -22.42 -22.34 +8.15 1.209 1.0 1.099 -22.4 -22.33 +8.2 1.209 1.0 1.099 -22.38 -22.51 +8.25 1.209 1.0 1.099 -22.36 -22.49 +8.3 1.209 1.0 1.099 -22.34 -22.47 +8.35 1.209 1.0 1.099 -22.32 -22.45 +8.4 1.209 1.0 1.099 -22.3 -22.43 +8.45 1.209 1.0 1.099 -22.28 -22.4 +8.5 1.209 1.0 1.099 -22.26 -22.38 \ No newline at end of file From c16a495b63a201a753e6e7cf1edf07dc3cbf94d5 Mon Sep 17 00:00:00 2001 From: forrestglines Date: Mon, 19 Feb 2024 12:35:22 -0700 Subject: [PATCH 02/21] Fix spacing for github markdown --- docs/cooling_notes.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/docs/cooling_notes.md b/docs/cooling_notes.md index 99fa5ec4..26116b62 100644 --- a/docs/cooling_notes.md +++ b/docs/cooling_notes.md @@ -66,26 +66,37 @@ This convention is adopted by Dalgarno and McCray (1972) (their equation 24), an ### AthenaPK implementation This is the convention adopted by AthenaPK, except $n_H$ is computed assuming zero metals in the mass budget: + $$ x_H = 1 - Y \, , $$ + $$ n_H = X_H \rho / m_H = (1 - Y) \rho / m_H \, .$$ The difference in neglecting metals in the mass budget in computing $n_H$ is only a $\sim 2$ percent effect on $n_H$ (since metals are 2 percent by mass for solar metallicity) and a $\sim 4$ percent effect on the source term. -The Schure table in the GitHub repository uses the using the $n_H n_e$ convention, rather than the $n_H^2$ convention. This causes an error in the cooling rate of $n_e / n_H$, or about 20 percent for temperatures above $10^{5.5}$ K. +The Schure table in the GitHub repository uses the $n_H n_e$ convention, rather than the $n_H^2$ convention. This causes an error in the cooling rate of $n_e / n_H$, or about 20 percent for temperatures above $10^{5.5}$ K. Above $\sim 10^4$ K, there is a percent-level error in the mean molecular weight due to neglecting the metal contribution to the electron fraction. *Users should be aware that at low absolute electron fraction, metals contribute a substantial proportion of the metals, so this approximation is no longer valid below $\sim 10^4$ K.* The temperature is computed as: + $$ T = \left( \frac{\rho}{\mu m_H} \right)^{-1} \left( \frac{P}{k_B} \right) \, ,$$ where the dimensionless mean molecular weight $\mu$ is computed assuming a zero metallicity gas: + $$ \mu = \left( \frac{3}{4} Y + 2(1 - Y) \right)^{-1} = \left( 2 - \frac{5}{4} Y \right)^{-1} \, ,$$ + where $Y$ is the Helium mass fraction. For a more precise calculation of $\mu$ assuming a scaled-solar composition of metals, we have: + $$ \mu = \left( 1 - x_e \right) \left( X + \frac{Y}{4} + \frac{Z}{\bar A} \right)^{-1} \, , $$ + where $\bar A$ is the mass-weighted mean atomic weight of metals: + $$ \bar A = 16 \, .$$ Additionally, for full ionization for all species, we have: -$$ x_e = \frac{X + 2 Y (m_H/m_{He}) + (\bar A/2) Z (m_H/m_{\bar Z})}{2 X + 3 Y (m_H/m_{He}) + (1 + \bar A/2) Z (m_H/m_{\bar Z})} \approx \frac{X + Y/2 + Z/2}{2 X + 3 Y/4 + (1/{\bar A} + 1/2) Z}$$ + +$$ x_e = \frac{X + 2 Y (m_H/m_{He}) + (\bar A/2) Z (m_H/m_{\bar Z})}{2 X + 3 Y (m_H/m_{He}) + (1 + \bar A/2) +Z (m_H/m_{\bar Z})} \approx \frac{X + Y/2 + Z/2}{2 X + 3 Y/4 + (1/{\bar A} + 1/2) Z}$$ + For $Y = 0.24$ and $Z = 0.02$, the mean molecular weight for complete ionization is $\mu \approx 0.60$ (if $Z = 0$, then this yields $\mu \approx 0.59$). From d2d1bbcb17b2632086887a30f342afdf3a8b619f Mon Sep 17 00:00:00 2001 From: Ben Wibking Date: Mon, 19 Feb 2024 15:38:33 -0500 Subject: [PATCH 03/21] fix typo "metals" -> "electrons" --- docs/cooling_notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/cooling_notes.md b/docs/cooling_notes.md index 26116b62..4365be1e 100644 --- a/docs/cooling_notes.md +++ b/docs/cooling_notes.md @@ -75,7 +75,7 @@ The difference in neglecting metals in the mass budget in computing $n_H$ is onl The Schure table in the GitHub repository uses the $n_H n_e$ convention, rather than the $n_H^2$ convention. This causes an error in the cooling rate of $n_e / n_H$, or about 20 percent for temperatures above $10^{5.5}$ K. -Above $\sim 10^4$ K, there is a percent-level error in the mean molecular weight due to neglecting the metal contribution to the electron fraction. *Users should be aware that at low absolute electron fraction, metals contribute a substantial proportion of the metals, so this approximation is no longer valid below $\sim 10^4$ K.* The temperature is computed as: +Above $\sim 10^4$ K, there is a percent-level error in the mean molecular weight due to neglecting the metal contribution to the electron fraction. *Users should be aware that at low absolute electron fraction, metals contribute a substantial proportion of the electrons, so this approximation is no longer valid below $\sim 10^4$ K.* The temperature is computed as: $$ T = \left( \frac{\rho}{\mu m_H} \right)^{-1} \left( \frac{P}{k_B} \right) \, ,$$ where the dimensionless mean molecular weight $\mu$ is computed assuming a zero metallicity gas: From 3daf5c9108261ac4c168c253d5fdc345f4c03bb1 Mon Sep 17 00:00:00 2001 From: Philipp Grete Date: Wed, 21 Aug 2024 21:34:41 +0200 Subject: [PATCH 04/21] Add isotropic thermal conduction and RKL2 supertimestepping (#1) * Add simple anisotropic step function test * Separate FillDerived and EstimateTimestep in driver in prep for STS list * Add diffflux parameter * Add RKL2 STS task list * Add calc of RKL2 stages * Remove unncessary register for rkl2 * Adopt STS RKL2 variable naming * Move calc of dt_diff into PreStep * Make tlim an argument for diff step test * Adjust RKL2 conv test to gaussian profile * Add conv panel to conv plot * auto-format * rename diffusion integrator parameter * Add isotropic thermal conduction * Add isotropic cond to conv test * Add RKL2 conv test * Add new dt max ratio for rkl2 param * Add prolongation and fluxcorrect to RKL2 task list * Use base container as active STS container (workaround some AMR bug for using prolong/restric with non-base containers) * Add isotropic Spitzer thermal conduction timestep * Calc isotropic, non-const thermal diff * Fix calc of saturated heat flux * Add LimO3 limiter * Add limo3 convergence * Fix LimO3 recon * Fix saturated conduction prefactor * Remove calc of saturated conduction from cond coeff * Add upwinded saturated conduction in x-dir * Add saturated conduction prefactor * Add x2 and x3 sat cond fluxes * Increase default rkl2 ratio to 400 and allow flux correction for all integrators * Remove parabolic timestep constraint for saturated conduction limit regime * Add perturb to cloud pgen * Add perturb to B (knowing this is not great...) * Revert "Add perturb to B (knowing this is not great...)" This reverts commit 1d0cb198c92b9eee579d3ecb5617d0629b1f9941. * Revert "Add perturb to cloud pgen" This reverts commit 6df018fe852fe4c285ac5929ed61d5fc67b17ddf. * Limit cooling to upper bound of TFloor and cooling table cutoff * Add oblique B field * Update coords and driver * Fix test cases and add success check * Add changelog * Address comments --- .github/workflows/ci.yml | 1 + CHANGELOG.md | 1 + README.md | 3 +- docs/input.md | 50 +- inputs/diffusion.in | 8 +- src/CMakeLists.txt | 1 + src/hydro/diffusion/conduction.cpp | 468 +++++++++++++----- src/hydro/diffusion/diffusion.cpp | 31 ++ src/hydro/diffusion/diffusion.hpp | 26 +- src/hydro/hydro.cpp | 147 ++++-- src/hydro/hydro.hpp | 1 + src/hydro/hydro_driver.cpp | 361 +++++++++++++- src/main.cpp | 1 + src/main.hpp | 4 +- src/pgen/cloud.cpp | 17 +- src/pgen/diffusion.cpp | 22 +- src/units.hpp | 2 + tst/regression/CMakeLists.txt | 3 + .../aniso_therm_cond_gauss_conv/__init__.py | 0 .../aniso_therm_cond_gauss_conv.py | 221 +++++++++ .../aniso_therm_cond_ring_conv/README.md | 2 +- 21 files changed, 1168 insertions(+), 202 deletions(-) create mode 100644 src/hydro/diffusion/diffusion.cpp create mode 100644 tst/regression/test_suites/aniso_therm_cond_gauss_conv/__init__.py create mode 100644 tst/regression/test_suites/aniso_therm_cond_gauss_conv/aniso_therm_cond_gauss_conv.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e24e197b..05049ba7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,6 +53,7 @@ jobs: build/tst/regression/outputs/cluster_hse/analytic_comparison.png build/tst/regression/outputs/cluster_tabular_cooling/convergence.png build/tst/regression/outputs/aniso_therm_cond_ring_conv/ring_convergence.png + build/tst/regression/outputs/aniso_therm_cond_gauss_conv/cond.png build/tst/regression/outputs/field_loop/field_loop.png build/tst/regression/outputs/riemann_hydro/shock_tube.png build/tst/regression/outputs/turbulence/parthenon.hst diff --git a/CHANGELOG.md b/CHANGELOG.md index 83bc715d..47b1e93d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Current develop (i.e., `main` branch) ### Added (new features/APIs/variables/...) +- [[PR 1]](https://github.com/parthenon-hpc-lab/athenapk/pull/1) Add isotropic thermal conduction and RKL2 supertimestepping ### Changed (changing behavior/API/variables/...) - [[PR 84]](https://github.com/parthenon-hpc-lab/athenapk/pull/84) Bump Parthenon to latest develop (2024-02-15) diff --git a/README.md b/README.md index 04881cd0..13d7280a 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,8 @@ Current features include - HLLE (hydro and MHD), HLLC (hydro), and HLLD (MHD) Riemann solvers - adiabatic equation of state - MHD based on hyperbolic divergence cleaning following Dedner+ 2002 - - anisotropic thermal conduction + - isotropic and anisotropic thermal conduction + - operator-split, second-order RKL2 supertimestepping for diffusive terms - optically thin cooling based on tabulated cooling tables with either Townsend 2009 exact integration or operator-split subcycling - static and adaptive mesh refinement - problem generators for diff --git a/docs/input.md b/docs/input.md index f7023463..11dae8c5 100644 --- a/docs/input.md +++ b/docs/input.md @@ -69,15 +69,22 @@ conserved to primitive conversion if both are defined. #### Diffusive processes -##### Anisotropic thermal conduction (required MHD) +##### Isotropic (hydro and MHD) and anisotropic thermal conduction (only MHD) In the presence of magnetic fields thermal conduction is becoming anisotropic with the flux along the local magnetic field direction typically being much stronger than the flux perpendicular to the magnetic field. From a theoretical point of view, thermal conduction is included in the system of MHD equations by an additional term in the total energy equation: ```math -\delta_t E + \nabla \cdot (... + \mathbf{F}) \quad \mathrm{with}\\ -\mathbf{F} = - \kappa \mathbf{\hat b} (\mathbf{\hat b \cdot \nabla T}) +\delta_t E + \nabla \cdot (... + \mathbf{F}_\mathrm{c}) +``` +where the full thermal conduction flux $`\mathbf{F}_\mathrm{c}`$ contains both the classic thermal conduction +```math +\mathbf{F}_\mathrm{classic} = - \kappa \mathbf{\hat b} (\mathbf{\hat b \cdot \nabla T}) +``` +as well as the saturated flux (as introduced by [^CM77]) +```math +\mathbf{F}_\mathrm{sat} = - 5 \phi \rho^{-1/2} p^{3/2} \mathrm{sgn}(\mathbf{\hat b \cdot \nabla T}) \mathbf{\hat b} ``` From an implementation point of view, two options implemented and can be configured within a `` block in the input file. @@ -86,23 +93,52 @@ the integration step (before flux correction in case of AMR, and calculating the Moreover, they are implemented explicitly, i.e., they add a (potentially very restrictive) constraint to the timestep due to the scaling with $`\propto \Delta_x^2`$. Finally, we employ limiters for calculating the temperature gradients following Sharma & Hammett (2007)[^SH07]. This prevents unphysical conduction against the gradient, which may be introduced because the off-axis gradients are not centered on the interfaces. +Similarly, to account for the different nature of classic and saturated fluxes (parabolic and hyperbolic, respectively), +we follow [^M+12] and use a smooth transition +```math +\mathbf{F}_\mathrm{c} = \frac{q}{q + F_\mathrm{classic}} \mathbf{F}_\mathrm{classic} \quad \mathrm{with} \quad q = 5 \phi \rho^{-1/2} p^{3/2} +``` +and upwinding of the hyperbolic, saturated fluxes. -To enable conduction, set +To enable thermal conduction, set Parameter: `conduction` (string) - `none` : No thermal conduction +- `isotropic` : Isotropic thermal conduction +- `anisotropic` : Anisotropic thermal conduction + +In addition the coefficient (or diffusivity) needs to be set + +Parameter: `conduction_coeff` (string) - `spitzer` : Anisotropic thermal conduction with a temperature dependent classic Spitzer thermal conductivity $`\kappa (T) = c_\kappa T^{5/2} \mathrm{erg/s/K/cm}`$ and - $`c_\kappa`$ being constant prefactor (set via `diffusion/spitzer_cond_in_erg_by_s_K_cm` with a default value of $`4.6\times10^{-7}`$). Note, as indicated by the units in the input parameter name, this kind of thermal conductivity requires a full set of units + $`c_\kappa`$ being constant prefactor (set via the additional `diffusion/spitzer_cond_in_erg_by_s_K_cm` parameter with a default value of $`4.6\times10^{-7}`$ which assumes a fully ionized hydrogen plasma [^CM77] with $`\ln \lambda = 40`$ approximating ICM conditions). Note, as indicated by the units in the input parameter name, this kind of thermal conductivity requires a full set of units to be defined for the simulation. -- `thermal_diff` : Contrary to a temperature dependent conductivity, a simple thermal diffusivity can be used instead for which +- `fixed` : Contrary to a temperature dependent conductivity, a simple thermal diffusivity can be used instead for which the conduction flux is $`\mathbf{F} = - \chi \rho \mathbf{\hat b} (\mathbf{\hat b \cdot \nabla \frac{p_\mathrm{th}}{\rho}})`$ -Here, the strength, $`\chi`$, is controlled via the `thermal_diff_coeff_code` parameter in code units. +Here, the strength, $`\chi`$, is controlled via the additional `thermal_diff_coeff_code` parameter in code units. Given the dimensions of $`L^2/T`$ it is referred to a thermal diffusivity rather than thermal conductivity. +Parameter: `conduction_sat_phi` (float) +- Default value 0.3\ +Factor to account for the uncertainty in the estimated of saturated fluxes, see [^CM77]. +Default value corresponds to the typical value used in literature and goes back to [^MMM80] and [^BM82]. + + [^SH07]: P. Sharma and G. W. Hammett, "Preserving monotonicity in anisotropic diffusion," Journal of Computational Physics, vol. 227, no. 1, Art. no. 1, 2007, doi: https://doi.org/10.1016/j.jcp.2007.07.026. +[^M+12]: + A. Mignone, C. Zanni, P. Tzeferacos, B. van Straalen, P. Colella, and G. Bodo, “THE PLUTO CODE FOR ADAPTIVE MESH COMPUTATIONS IN ASTROPHYSICAL FLUID DYNAMICS,” The Astrophysical Journal Supplement Series, vol. 198, Art. no. 1, Dec. 2011, doi: https://doi.org/10.1088/0067-0049/198/1/7 + +[^CM77]: + L. Cowie and C. F. McKee, “The evaporation of spherical clouds in a hot gas. I. Classical and saturated mass loss rates.,” , vol. 211, pp. 135–146, Jan. 1977, doi: https://doi.org/10.1086/154911 + +[^MMM80]: + C. E. Max, C. F. McKee, and W. C. Mead, “A model for laser driven ablative implosions,” The Physics of Fluids, vol. 23, Art. no. 8, 1980, doi: https://doi.org/10.1063/1.863183 + +[^BM82]: + S. A. Balbus and C. F. McKee, “The evaporation of spherical clouds in a hot gas. III - Suprathermal evaporation,” , vol. 252, pp. 529–552, Jan. 1982, doi: https://doi.org/10.1086/159581 ### Additional MHD options in `` block diff --git a/inputs/diffusion.in b/inputs/diffusion.in index a1a3f723..44d02bcb 100644 --- a/inputs/diffusion.in +++ b/inputs/diffusion.in @@ -14,7 +14,8 @@ Bx = 1.0 # Bx for x1 step function (permutated for iprobs in other direction By = 0.0 # By for x1 step function (permutated for iprobs in other directions) #iprob = 10 # Diffusion of Gaussian profile in x1 direction -sigma = 0.1 # standard deviation of Gaussian for iprob=10 +t0 = 0.5 # Temporal offset for initial Gaussian profile +amp = 1e-6 # Amplitude of Gaussian profile iprob = 20 # ring diffusion in x1-x2 plane; 21 for x2-x3 plane; 22 for x3-x1 plane @@ -59,8 +60,11 @@ reconstruction = dc gamma = 2.0 -conduction = thermal_diff +integrator = unsplit +conduction = anisotropic +conduction_coeff = fixed thermal_diff_coeff_code = 0.01 +rkl2_max_dt_ratio = 400.0 file_type = hdf5 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5d8fd375..ddcf09b7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,6 +7,7 @@ add_executable( eos/adiabatic_glmmhd.cpp units.hpp eos/adiabatic_hydro.cpp + hydro/diffusion/diffusion.cpp hydro/diffusion/diffusion.hpp hydro/diffusion/conduction.cpp hydro/hydro_driver.cpp diff --git a/src/hydro/diffusion/conduction.cpp b/src/hydro/diffusion/conduction.cpp index 1e2bf0d6..d6e57d30 100644 --- a/src/hydro/diffusion/conduction.cpp +++ b/src/hydro/diffusion/conduction.cpp @@ -1,6 +1,6 @@ //======================================================================================== // AthenaPK - a performance portable block structured AMR astrophysical MHD code. -// Copyright (c) 2021, Athena-Parthenon Collaboration. All rights reserved. +// Copyright (c) 2021-2023, Athena-Parthenon Collaboration. All rights reserved. // Licensed under the 3-clause BSD License, see LICENSE file for details //======================================================================================== // Athena++ astrophysical MHD code @@ -12,31 +12,29 @@ //! \brief // Parthenon headers +#include #include // AthenaPK headers #include "../../main.hpp" +#include "config.hpp" #include "diffusion.hpp" +#include "utils/error_checking.hpp" using namespace parthenon::package::prelude; +// Calculate the thermal *diffusivity*, \chi, in code units as the energy flux itself +// is calculated from -\chi \rho \nabla (p/\rho). KOKKOS_INLINE_FUNCTION -Real ThermalDiffusivity::Get(const Real pres, const Real rho, const Real gradTmag) const { - if (conduction_ == Conduction::thermal_diff) { +Real ThermalDiffusivity::Get(const Real pres, const Real rho) const { + if (conduction_coeff_type_ == ConductionCoeff::fixed) { return coeff_; - } else if (conduction_ == Conduction::spitzer) { - const Real T = mbar_over_kb_ * pres / rho; - const Real kappa = coeff_ * std::pow(T, 5. / 2.); // Full spitzer - const Real chi_spitzer = kappa * mbar_over_kb_ / rho; - - // Saturated total flux: fac * \rho * c_{s,isoth}^3 - // In practice: fac * \rho * c_{s,isoth}^3 * (gradT / gradTmag) - // where T is calculated based on p/rho in the code. - // Thus, everything is in code units and no conversion is required. - // The \rho above is cancelled as we convert the condution above to a diffusvity here. - const Real chi_sat = - 0.34 * std::pow(pres / rho, 3.0 / 2.0) / (gradTmag + TINY_NUMBER); - return std::min(chi_spitzer, chi_sat); + } else if (conduction_coeff_type_ == ConductionCoeff::spitzer) { + const Real T_cgs = mbar_ / kb_ * pres / rho; + const Real kappa_spitzer = coeff_ * std::pow(T_cgs, 5. / 2.); // Full spitzer + + // Convert conductivity to diffusivity + return kappa_spitzer * mbar_ / kb_ / rho; } else { return 0.0; @@ -64,74 +62,207 @@ Real EstimateConductionTimestep(MeshData *md) { const auto gm1 = hydro_pkg->Param("AdiabaticIndex"); const auto &thermal_diff = hydro_pkg->Param("thermal_diff"); + const auto &flux_sat_prefac = hydro_pkg->Param("conduction_sat_prefac"); + + if (thermal_diff.GetType() == Conduction::isotropic && + thermal_diff.GetCoeffType() == ConductionCoeff::fixed) { + // TODO(pgrete): once mindx is properly calculated before this loop, we can get rid of + // it entirely. + // Using 0.0 as parameters rho and p as they're not used anyway for a fixed coeff. + const auto thermal_diff_coeff = thermal_diff.Get(0.0, 0.0); + Kokkos::parallel_reduce( + "EstimateConductionTimestep (iso fixed)", + Kokkos::MDRangePolicy>( + DevExecSpace(), {0, kb.s, jb.s, ib.s}, + {prim_pack.GetDim(5), kb.e + 1, jb.e + 1, ib.e + 1}, + {1, 1, 1, ib.e + 1 - ib.s}), + KOKKOS_LAMBDA(const int b, const int k, const int j, const int i, Real &min_dt) { + const auto &coords = prim_pack.GetCoords(b); + min_dt = fmin(min_dt, + SQR(coords.Dxc<1>(k, j, i)) / (thermal_diff_coeff + TINY_NUMBER)); + if (ndim >= 2) { + min_dt = fmin(min_dt, SQR(coords.Dxc<2>(k, j, i)) / + (thermal_diff_coeff + TINY_NUMBER)); + } + if (ndim >= 3) { + min_dt = fmin(min_dt, SQR(coords.Dxc<3>(k, j, i)) / + (thermal_diff_coeff + TINY_NUMBER)); + } + }, + Kokkos::Min(min_dt_cond)); + } else { + Kokkos::parallel_reduce( + "EstimateConductionTimestep (general)", + Kokkos::MDRangePolicy>( + DevExecSpace(), {0, kb.s, jb.s, ib.s}, + {prim_pack.GetDim(5), kb.e + 1, jb.e + 1, ib.e + 1}, + {1, 1, 1, ib.e + 1 - ib.s}), + KOKKOS_LAMBDA(const int b, const int k, const int j, const int i, Real &min_dt) { + const auto &coords = prim_pack.GetCoords(b); + const auto &prim = prim_pack(b); + const auto &rho = prim(IDN, k, j, i); + const auto &p = prim(IPR, k, j, i); + + const auto dTdx = 0.5 * + (prim(IPR, k, j, i + 1) / prim(IDN, k, j, i + 1) - + prim(IPR, k, j, i - 1) / prim(IDN, k, j, i - 1)) / + coords.Dxc<1>(i); + + const auto dTdy = ndim >= 2 + ? 0.5 * + (prim(IPR, k, j + 1, i) / prim(IDN, k, j + 1, i) - + prim(IPR, k, j - 1, i) / prim(IDN, k, j - 1, i)) / + coords.Dxc<2>(j) + : 0.0; + + const auto dTdz = ndim >= 3 + ? 0.5 * + (prim(IPR, k + 1, j, i) / prim(IDN, k + 1, j, i) - + prim(IPR, k - 1, j, i) / prim(IDN, k - 1, j, i)) / + coords.Dxc<3>(k) + : 0.0; + const auto gradTmag = sqrt(SQR(dTdx) + SQR(dTdy) + SQR(dTdz)); + + // No temperature gradient -> no thermal conduction-> no timestep restriction + if (gradTmag == 0.0) { + return; + } + auto thermal_diff_coeff = thermal_diff.Get(p, rho); + + if (thermal_diff.GetType() == Conduction::isotropic) { + min_dt = fmin(min_dt, SQR(coords.Dxc<1>(k, j, i)) / thermal_diff_coeff); + if (ndim >= 2) { + min_dt = fmin(min_dt, SQR(coords.Dxc<2>(k, j, i)) / thermal_diff_coeff); + } + if (ndim >= 3) { + min_dt = fmin(min_dt, SQR(coords.Dxc<3>(k, j, i)) / thermal_diff_coeff); + } + return; + } + const auto &Bx = prim(IB1, k, j, i); + const auto &By = prim(IB2, k, j, i); + const auto &Bz = prim(IB3, k, j, i); + const auto Bmag = sqrt(SQR(Bx) + SQR(By) + SQR(Bz)); + // Need to have some local field for anisotropic conduction + if (Bmag == 0.0) { + return; + } + + // In the saturated regime, i.e., when the ratio of classic to saturated fluxes + // is large, the equation becomes hyperbolic with the signal speed of the + // conduction front being comparable to the sound speed, see [Balsara, Tilley, + // and Howk MANRAS 2008]. Therefore, we don't need to contrain the "parabolic" + // timestep here (and the hyperbolic one is constrained automatically by the + // fluid EstimateTimestep call). + auto const flux_sat = flux_sat_prefac * std::sqrt(p / rho) * p; + auto const flux_classic = thermal_diff_coeff * rho * gradTmag; + if (flux_classic / flux_sat > 100.) { + return; + } + + const auto costheta = + fabs(Bx * dTdx + By * dTdy + Bz * dTdz) / (Bmag * gradTmag); + + min_dt = fmin(min_dt, SQR(coords.Dxc<1>(k, j, i)) / + (thermal_diff_coeff * fabs(Bx) / Bmag * costheta + + TINY_NUMBER)); + if (ndim >= 2) { + min_dt = fmin(min_dt, SQR(coords.Dxc<2>(k, j, i)) / + (thermal_diff_coeff * fabs(By) / Bmag * costheta + + TINY_NUMBER)); + } + if (ndim >= 3) { + min_dt = fmin(min_dt, SQR(coords.Dxc<3>(k, j, i)) / + (thermal_diff_coeff * fabs(Bz) / Bmag * costheta + + TINY_NUMBER)); + } + }, + Kokkos::Min(min_dt_cond)); + } + + return fac * min_dt_cond; +} + +//--------------------------------------------------------------------------------------- +//! Calculate isotropic thermal conduction with fixed coefficient + +void ThermalFluxIsoFixed(MeshData *md) { + auto pmb = md->GetBlockData(0)->GetBlockPointer(); + IndexRange ib = pmb->cellbounds.GetBoundsI(IndexDomain::interior); + IndexRange jb = pmb->cellbounds.GetBoundsJ(IndexDomain::interior); + IndexRange kb = pmb->cellbounds.GetBoundsK(IndexDomain::interior); + + std::vector flags_ind({Metadata::Independent}); + auto cons_pack = md->PackVariablesAndFluxes(flags_ind); + auto hydro_pkg = pmb->packages.Get("Hydro"); + + auto const &prim_pack = md->PackVariables(std::vector{"prim"}); + + const int ndim = pmb->pmy_mesh->ndim; + + const auto &thermal_diff = hydro_pkg->Param("thermal_diff"); + // Using fixed and uniform coefficient so it's safe to get it outside the kernel. + // Using 0.0 as parameters rho and p as they're not used anyway for a fixed coeff. + const auto thermal_diff_coeff = thermal_diff.Get(0.0, 0.0); - Kokkos::parallel_reduce( - "EstimateConductionTimestep", - Kokkos::MDRangePolicy>( - DevExecSpace(), {0, kb.s, jb.s, ib.s}, - {prim_pack.GetDim(5), kb.e + 1, jb.e + 1, ib.e + 1}, - {1, 1, 1, ib.e + 1 - ib.s}), - KOKKOS_LAMBDA(const int b, const int k, const int j, const int i, Real &min_dt) { + parthenon::par_for( + DEFAULT_LOOP_PATTERN, "Thermal conduction X1 fluxes (iso)", + parthenon::DevExecSpace(), 0, cons_pack.GetDim(5) - 1, kb.s, kb.e, jb.s, jb.e, ib.s, + ib.e + 1, KOKKOS_LAMBDA(const int b, const int k, const int j, const int i) { const auto &coords = prim_pack.GetCoords(b); + auto &cons = cons_pack(b); const auto &prim = prim_pack(b); - const auto &rho = prim(IDN, k, j, i); - const auto &p = prim(IPR, k, j, i); - // TODO(pgrete) when we introduce isotropic thermal conduction a lot of the - // following machinery should be hidden behind conditionals - const auto &Bx = prim(IB1, k, j, i); - const auto &By = prim(IB2, k, j, i); - const auto &Bz = prim(IB3, k, j, i); - const auto Bmag = sqrt(SQR(Bx) + SQR(By) + SQR(Bz)); - - const auto dTdx = 0.5 * - (prim(IPR, k, j, i + 1) / prim(IDN, k, j, i + 1) - - prim(IPR, k, j, i - 1) / prim(IDN, k, j, i - 1)) / - coords.Dxc<1>(i); - - const auto dTdy = 0.5 * - (prim(IPR, k, j + 1, i) / prim(IDN, k, j + 1, i) - - prim(IPR, k, j - 1, i) / prim(IDN, k, j - 1, i)) / - coords.Dxc<2>(j); - - const auto dTdz = ndim >= 3 - ? 0.5 * - (prim(IPR, k + 1, j, i) / prim(IDN, k + 1, j, i) - - prim(IPR, k - 1, j, i) / prim(IDN, k - 1, j, i)) / - coords.Dxc<3>(k) - : 0.0; - const auto gradTmag = sqrt(SQR(dTdx) + SQR(dTdy) + SQR(dTdz)); - auto thermal_diff_coeff = thermal_diff.Get(p, rho, gradTmag); + const auto T_i = prim(IPR, k, j, i) / prim(IDN, k, j, i); + const auto T_im1 = prim(IPR, k, j, i - 1) / prim(IDN, k, j, i - 1); + const auto dTdx = (T_i - T_im1) / coords.Dxc<1>(k, j, i); + const auto denf = 0.5 * (prim(IDN, k, j, i) + prim(IDN, k, j, i - 1)); + cons.flux(X1DIR, IEN, k, j, i) -= thermal_diff_coeff * denf * dTdx; + }); - const auto denom = Bmag * gradTmag; - // if either Bmag or gradTmag are 0, no anisotropic thermal conduction - if (denom == 0.0) { - return; - } - const auto costheta = fabs(Bx * dTdx + By * dTdy + Bz * dTdz) / denom; - - min_dt = fmin( - min_dt, SQR(coords.Dxc<1>(k, j, i)) / - (thermal_diff_coeff * fabs(Bx) / Bmag * costheta + TINY_NUMBER)); - if (ndim >= 2) { - min_dt = fmin(min_dt, SQR(coords.Dxc<2>(k, j, i)) / - (thermal_diff_coeff * fabs(By) / Bmag * costheta + - TINY_NUMBER)); - } - if (ndim >= 3) { - min_dt = fmin(min_dt, SQR(coords.Dxc<3>(k, j, i)) / - (thermal_diff_coeff * fabs(Bz) / Bmag * costheta + - TINY_NUMBER)); - } - }, - Kokkos::Min(min_dt_cond)); + if (ndim < 2) { + return; + } + /* Compute heat fluxes in 2-direction --------------------------------------*/ + parthenon::par_for( + DEFAULT_LOOP_PATTERN, "Thermal conduction X2 fluxes (iso)", + parthenon::DevExecSpace(), 0, cons_pack.GetDim(5) - 1, kb.s, kb.e, jb.s, jb.e + 1, + ib.s, ib.e, KOKKOS_LAMBDA(const int b, const int k, const int j, const int i) { + const auto &coords = prim_pack.GetCoords(b); + auto &cons = cons_pack(b); + const auto &prim = prim_pack(b); - return fac * min_dt_cond; + const auto T_j = prim(IPR, k, j, i) / prim(IDN, k, j, i); + const auto T_jm1 = prim(IPR, k, j - 1, i) / prim(IDN, k, j - 1, i); + const auto dTdy = (T_j - T_jm1) / coords.Dxc<2>(k, j, i); + const auto denf = 0.5 * (prim(IDN, k, j, i) + prim(IDN, k, j - 1, i)); + cons.flux(X2DIR, IEN, k, j, i) -= thermal_diff_coeff * denf * dTdy; + }); + /* Compute heat fluxes in 3-direction, 3D problem ONLY ---------------------*/ + if (ndim < 3) { + return; + } + + parthenon::par_for( + DEFAULT_LOOP_PATTERN, "Thermal conduction X3 fluxes (iso)", + parthenon::DevExecSpace(), 0, cons_pack.GetDim(5) - 1, kb.s, kb.e + 1, jb.s, jb.e, + ib.s, ib.e, KOKKOS_LAMBDA(const int b, const int k, const int j, const int i) { + const auto &coords = prim_pack.GetCoords(b); + auto &cons = cons_pack(b); + const auto &prim = prim_pack(b); + + const auto T_k = prim(IPR, k, j, i) / prim(IDN, k, j, i); + const auto T_km1 = prim(IPR, k - 1, j, i) / prim(IDN, k - 1, j, i); + const auto dTdz = (T_k - T_km1) / coords.Dxc<3>(k, j, i); + const auto denf = 0.5 * (prim(IDN, k, j, i) + prim(IDN, k - 1, j, i)); + cons.flux(X3DIR, IEN, k, j, i) -= thermal_diff_coeff * denf * dTdz; + }); } //--------------------------------------------------------------------------------------- -//! Calculate anisotropic thermal conduction +//! Calculate thermal conduction, general case, i.e., anisotropic and/or with varying +//! (incl. saturated) coefficient -void ThermalFluxAniso(MeshData *md) { +void ThermalFluxGeneral(MeshData *md) { auto pmb = md->GetBlockData(0)->GetBlockPointer(); IndexRange ib = pmb->cellbounds.GetBoundsI(IndexDomain::interior); IndexRange jb = pmb->cellbounds.GetBoundsJ(IndexDomain::interior); @@ -146,18 +277,18 @@ void ThermalFluxAniso(MeshData *md) { const int ndim = pmb->pmy_mesh->ndim; const auto &thermal_diff = hydro_pkg->Param("thermal_diff"); + const auto &flux_sat_prefac = hydro_pkg->Param("conduction_sat_prefac"); parthenon::par_for( - DEFAULT_LOOP_PATTERN, "Thermal conduction X1 fluxes", parthenon::DevExecSpace(), 0, - cons_pack.GetDim(5) - 1, kb.s, kb.e, jb.s, jb.e, ib.s, ib.e + 1, - KOKKOS_LAMBDA(const int b, const int k, const int j, const int i) { + DEFAULT_LOOP_PATTERN, "Thermal conduction X1 fluxes (general)", + parthenon::DevExecSpace(), 0, cons_pack.GetDim(5) - 1, kb.s, kb.e, jb.s, jb.e, ib.s, + ib.e + 1, KOKKOS_LAMBDA(const int b, const int k, const int j, const int i) { const auto &coords = prim_pack.GetCoords(b); auto &cons = cons_pack(b); const auto &prim = prim_pack(b); // Variables only required in 3D case Real dTdz = 0.0; - Real Bz = 0.0; // clang-format off /* Monotonized temperature difference dT/dy */ @@ -170,7 +301,7 @@ void ThermalFluxAniso(MeshData *md) { prim(IPR, k, j , i - 1) / prim(IDN, k, j , i - 1), prim(IPR, k, j , i - 1) / prim(IDN, k, j , i - 1) - prim(IPR, k, j - 1, i - 1) / prim(IDN, k, j - 1, i - 1)) / - coords.Dxc<2>(k, j, i); + coords.Dxc<2>( k, j, i); if (ndim >= 3) { /* Monotonized temperature difference dT/dz, 3D problem ONLY */ @@ -182,8 +313,7 @@ void ThermalFluxAniso(MeshData *md) { prim(IPR, k , j, i - 1) / prim(IDN, k , j, i - 1), prim(IPR, k , j, i - 1) / prim(IDN, k , j, i - 1) - prim(IPR, k - 1, j, i - 1) / prim(IDN, k - 1, j, i - 1)) / - coords.Dxc<3>(k, j, i); - Bz = 0.5 * (prim(IB3, k, j, i - 1) + prim(IB3, k, j, i)); + coords.Dxc<3>( k, j, i); } // clang-format on @@ -191,34 +321,69 @@ void ThermalFluxAniso(MeshData *md) { const auto T_im1 = prim(IPR, k, j, i - 1) / prim(IDN, k, j, i - 1); const auto dTdx = (T_i - T_im1) / coords.Dxc<1>(k, j, i); - // Calc interface values - const auto Bx = 0.5 * (prim(IB1, k, j, i - 1) + prim(IB1, k, j, i)); - const auto By = 0.5 * (prim(IB2, k, j, i - 1) + prim(IB2, k, j, i)); - auto B02 = SQR(Bx) + SQR(By) + SQR(Bz); - B02 = std::max(B02, TINY_NUMBER); /* limit in case B=0 */ - const auto bDotGradT = Bx * dTdx + By * dTdy + Bz * dTdz; - const auto denf = 0.5 * (prim(IDN, k, j, i) + prim(IDN, k, j, i - 1)); - const auto gradTmag = sqrt(SQR(dTdx) + SQR(dTdy) + SQR(dTdz)); const auto thermal_diff_f = - 0.5 * - (thermal_diff.Get(prim(IPR, k, j, i), prim(IDN, k, j, i), gradTmag) + - thermal_diff.Get(prim(IPR, k, j, i - 1), prim(IDN, k, j, i - 1), gradTmag)); - cons.flux(X1DIR, IEN, k, j, i) -= thermal_diff_f * denf * (Bx * bDotGradT) / B02; + 0.5 * (thermal_diff.Get(prim(IPR, k, j, i), prim(IDN, k, j, i)) + + thermal_diff.Get(prim(IPR, k, j, i - 1), prim(IDN, k, j, i - 1))); + const auto gradTmag = std::sqrt(SQR(dTdx) + SQR(dTdy) + SQR(dTdz)); + + // Calculate "classic" fluxes + Real flux_classic = 0.0; + Real flux_classic_mag = 0.0; + if (thermal_diff.GetType() == Conduction::anisotropic) { + const auto Bx = 0.5 * (prim(IB1, k, j, i - 1) + prim(IB1, k, j, i)); + const auto By = 0.5 * (prim(IB2, k, j, i - 1) + prim(IB2, k, j, i)); + const auto Bz = + ndim >= 3 ? 0.5 * (prim(IB3, k, j, i - 1) + prim(IB3, k, j, i)) : 0.0; + auto Bmag = std::sqrt(SQR(Bx) + SQR(By) + SQR(Bz)); + Bmag = std::max(Bmag, TINY_NUMBER); /* limit in case B=0 */ + const auto bx = Bx / Bmag; // unit vector component + const auto bDotGradT = (Bx * dTdx + By * dTdy + Bz * dTdz) / Bmag; + flux_classic = -thermal_diff_f * denf * bDotGradT * bx; + flux_classic_mag = std::abs(thermal_diff_f * denf * bDotGradT); + } else if (thermal_diff.GetType() == Conduction::isotropic) { + flux_classic = -thermal_diff_f * denf * dTdx; + flux_classic_mag = thermal_diff_f * denf * gradTmag; + } else { + PARTHENON_FAIL("Unknown thermal diffusion flux."); + } + + // Calculate saturated fluxes using upwinding, see (A3) in Mignone+12. + // Note that we are not concerned about the sign of flux_sat here. The way it is + // calculated it's always positive because we use it in the harmonic mean with + // the flux_classic_mag below. The correct sign is eventually picked up again from + // flux_classic. + Real flux_sat; + // Use first order limiting for now. + if (flux_classic > 0.0) { + flux_sat = flux_sat_prefac * std::sqrt(prim(IPR, k, j, i - 1) / denf) * + prim(IPR, k, j, i - 1); + } else if (flux_classic < 0.0) { + flux_sat = + flux_sat_prefac * std::sqrt(prim(IPR, k, j, i) / denf) * prim(IPR, k, j, i); + } else { + const auto presf = 0.5 * (prim(IPR, k, j, i) + prim(IPR, k, j, i - 1)); + flux_sat = flux_sat_prefac * std::sqrt(presf / denf) * presf; + } + + cons.flux(X1DIR, IEN, k, j, i) += + (flux_sat / (flux_sat + flux_classic_mag)) * flux_classic; }); + if (ndim < 2) { + return; + } /* Compute heat fluxes in 2-direction --------------------------------------*/ parthenon::par_for( - DEFAULT_LOOP_PATTERN, "Thermal conduction X2 fluxes", parthenon::DevExecSpace(), 0, - cons_pack.GetDim(5) - 1, kb.s, kb.e, jb.s, jb.e + 1, ib.s, ib.e, - KOKKOS_LAMBDA(const int b, const int k, const int j, const int i) { + DEFAULT_LOOP_PATTERN, "Thermal conduction X2 fluxes (general)", + parthenon::DevExecSpace(), 0, cons_pack.GetDim(5) - 1, kb.s, kb.e, jb.s, jb.e + 1, + ib.s, ib.e, KOKKOS_LAMBDA(const int b, const int k, const int j, const int i) { const auto &coords = prim_pack.GetCoords(b); auto &cons = cons_pack(b); const auto &prim = prim_pack(b); // Variables only required in 3D case Real dTdz = 0.0; - Real Bz = 0.0; // clang-format off /* Monotonized temperature difference dT/dx */ @@ -245,7 +410,6 @@ void ThermalFluxAniso(MeshData *md) { prim(IPR, k - 1, j - 1, i) / prim(IDN, k - 1, j - 1, i)) / coords.Dxc<3>(k, j, i); - Bz = 0.5 * (prim(IB3, k, j - 1, i) + prim(IB3, k, j, i)); } // clang-format on @@ -253,20 +417,50 @@ void ThermalFluxAniso(MeshData *md) { const auto T_jm1 = prim(IPR, k, j - 1, i) / prim(IDN, k, j - 1, i); const auto dTdy = (T_j - T_jm1) / coords.Dxc<2>(k, j, i); - // Calc interface values - const auto Bx = 0.5 * (prim(IB1, k, j - 1, i) + prim(IB1, k, j, i)); - const auto By = 0.5 * (prim(IB2, k, j - 1, i) + prim(IB2, k, j, i)); - Real B02 = SQR(Bx) + SQR(By) + SQR(Bz); - B02 = std::max(B02, TINY_NUMBER); /* limit in case B=0 */ - const auto bDotGradT = Bx * dTdx + By * dTdy + Bz * dTdz; - const auto denf = 0.5 * (prim(IDN, k, j, i) + prim(IDN, k, j - 1, i)); const auto gradTmag = sqrt(SQR(dTdx) + SQR(dTdy) + SQR(dTdz)); const auto thermal_diff_f = - 0.5 * - (thermal_diff.Get(prim(IPR, k, j, i), prim(IDN, k, j, i), gradTmag) + - thermal_diff.Get(prim(IPR, k, j - 1, i), prim(IDN, k, j - 1, i), gradTmag)); - cons.flux(X2DIR, IEN, k, j, i) -= thermal_diff_f * denf * (By * bDotGradT) / B02; + 0.5 * (thermal_diff.Get(prim(IPR, k, j, i), prim(IDN, k, j, i)) + + thermal_diff.Get(prim(IPR, k, j - 1, i), prim(IDN, k, j - 1, i))); + + // Calculate "classic" fluxes + Real flux_classic = 0.0; + Real flux_classic_mag = 0.0; + if (thermal_diff.GetType() == Conduction::anisotropic) { + const auto Bx = 0.5 * (prim(IB1, k, j - 1, i) + prim(IB1, k, j, i)); + const auto By = 0.5 * (prim(IB2, k, j - 1, i) + prim(IB2, k, j, i)); + const auto Bz = + ndim >= 3 ? 0.5 * (prim(IB3, k, j - 1, i) + prim(IB3, k, j, i)) : 0.0; + auto Bmag = std::sqrt(SQR(Bx) + SQR(By) + SQR(Bz)); + Bmag = std::max(Bmag, TINY_NUMBER); /* limit in case B=0 */ + const auto by = By / Bmag; // unit vector component + const auto bDotGradT = (Bx * dTdx + By * dTdy + Bz * dTdz) / Bmag; + flux_classic = -thermal_diff_f * denf * bDotGradT * by; + flux_classic_mag = std::abs(thermal_diff_f * denf * bDotGradT); + } else if (thermal_diff.GetType() == Conduction::isotropic) { + flux_classic = -thermal_diff_f * denf * dTdy; + flux_classic_mag = thermal_diff_f * denf * gradTmag; + } else { + PARTHENON_FAIL("Unknown thermal diffusion flux."); + } + + // Calculate saturated fluxes,see comment above. + Real flux_sat; + // Use first order limiting for now. + if (flux_classic > 0.0) { + flux_sat = flux_sat_prefac * std::sqrt(prim(IPR, k, j - 1, i) / denf) * + prim(IPR, k, j - 1, i); + } else if (flux_classic < 0.0) { + flux_sat = + flux_sat_prefac * std::sqrt(prim(IPR, k, j, i) / denf) * prim(IPR, k, j, i); + } else { + const auto presf = 0.5 * (prim(IPR, k, j, i) + prim(IPR, k, j - 1, i)); + flux_sat = flux_sat_prefac * std::sqrt(presf / denf) * presf; + } + + // Calc interface values + cons.flux(X2DIR, IEN, k, j, i) += + (flux_sat / (flux_sat + flux_classic_mag)) * flux_classic; }); /* Compute heat fluxes in 3-direction, 3D problem ONLY ---------------------*/ if (ndim < 3) { @@ -274,9 +468,9 @@ void ThermalFluxAniso(MeshData *md) { } parthenon::par_for( - DEFAULT_LOOP_PATTERN, "Thermal conduction X3 fluxes", parthenon::DevExecSpace(), 0, - cons_pack.GetDim(5) - 1, kb.s, kb.e + 1, jb.s, jb.e, ib.s, ib.e, - KOKKOS_LAMBDA(const int b, const int k, const int j, const int i) { + DEFAULT_LOOP_PATTERN, "Thermal conduction X3 fluxes (general)", + parthenon::DevExecSpace(), 0, cons_pack.GetDim(5) - 1, kb.s, kb.e + 1, jb.s, jb.e, + ib.s, ib.e, KOKKOS_LAMBDA(const int b, const int k, const int j, const int i) { const auto &coords = prim_pack.GetCoords(b); auto &cons = cons_pack(b); const auto &prim = prim_pack(b); @@ -311,20 +505,46 @@ void ThermalFluxAniso(MeshData *md) { const auto T_km1 = prim(IPR, k - 1, j, i) / prim(IDN, k - 1, j, i); const auto dTdz = (T_k - T_km1) / coords.Dxc<3>(k, j, i); - const auto Bx = 0.5 * (prim(IB1, k - 1, j, i) + prim(IB1, k, j, i)); - const auto By = 0.5 * (prim(IB2, k - 1, j, i) + prim(IB2, k, j, i)); - const auto Bz = 0.5 * (prim(IB3, k - 1, j, i) + prim(IB3, k, j, i)); - Real B02 = SQR(Bx) + SQR(By) + SQR(Bz); - B02 = std::max(B02, TINY_NUMBER); /* limit in case B=0 */ - const auto bDotGradT = Bx * dTdx + By * dTdy + Bz * dTdz; - const auto denf = 0.5 * (prim(IDN, k, j, i) + prim(IDN, k - 1, j, i)); const auto gradTmag = sqrt(SQR(dTdx) + SQR(dTdy) + SQR(dTdz)); const auto thermal_diff_f = - 0.5 * - (thermal_diff.Get(prim(IPR, k, j, i), prim(IDN, k, j, i), gradTmag) + - thermal_diff.Get(prim(IPR, k - 1, j, i), prim(IDN, k - 1, j, i), gradTmag)); + 0.5 * (thermal_diff.Get(prim(IPR, k, j, i), prim(IDN, k, j, i)) + + thermal_diff.Get(prim(IPR, k - 1, j, i), prim(IDN, k - 1, j, i))); + + // Calculate "classic" fluxes + Real flux_classic = 0.0; + Real flux_classic_mag = 0.0; + if (thermal_diff.GetType() == Conduction::anisotropic) { + const auto Bx = 0.5 * (prim(IB1, k - 1, j, i) + prim(IB1, k, j, i)); + const auto By = 0.5 * (prim(IB2, k - 1, j, i) + prim(IB2, k, j, i)); + const auto Bz = 0.5 * (prim(IB3, k - 1, j, i) + prim(IB3, k, j, i)); + auto Bmag = std::sqrt(SQR(Bx) + SQR(By) + SQR(Bz)); + Bmag = std::max(Bmag, TINY_NUMBER); /* limit in case B=0 */ + const auto bz = Bz / Bmag; // unit vector component + const auto bDotGradT = (Bx * dTdx + By * dTdy + Bz * dTdz) / Bmag; + flux_classic = -thermal_diff_f * denf * bDotGradT * bz; + flux_classic_mag = std::abs(thermal_diff_f * denf * bDotGradT); + } else if (thermal_diff.GetType() == Conduction::isotropic) { + flux_classic = -thermal_diff_f * denf * dTdz; + flux_classic_mag = thermal_diff_f * denf * gradTmag; + } else { + PARTHENON_FAIL("Unknown thermal diffusion flux."); + } + // Calculate saturated fluxes,see comment above. + Real flux_sat; + // Use first order limiting for now. + if (flux_classic > 0.0) { + flux_sat = flux_sat_prefac * std::sqrt(prim(IPR, k - 1, j, i) / denf) * + prim(IPR, k - 1, j, i); + } else if (flux_classic < 0.0) { + flux_sat = + flux_sat_prefac * std::sqrt(prim(IPR, k, j, i) / denf) * prim(IPR, k, j, i); + } else { + const auto presf = 0.5 * (prim(IPR, k, j, i) + prim(IPR, k - 1, j, i)); + flux_sat = flux_sat_prefac * std::sqrt(presf / denf) * presf; + } - cons.flux(X3DIR, IEN, k, j, i) -= thermal_diff_f * denf * (Bz * bDotGradT) / B02; + cons.flux(X3DIR, IEN, k, j, i) += + (flux_sat / (flux_sat + flux_classic_mag)) * flux_classic; }); } diff --git a/src/hydro/diffusion/diffusion.cpp b/src/hydro/diffusion/diffusion.cpp new file mode 100644 index 00000000..20617ca2 --- /dev/null +++ b/src/hydro/diffusion/diffusion.cpp @@ -0,0 +1,31 @@ +//======================================================================================== +// AthenaPK - a performance portable block structured AMR astrophysical MHD code. +// Copyright (c) 2021, Athena-Parthenon Collaboration. All rights reserved. +// Licensed under the 3-clause BSD License, see LICENSE file for details +//======================================================================================== +//! \file diffusion.cpp +//! \brief + +// Parthenon headers +#include + +// AthenaPK headers +#include "../../main.hpp" +#include "diffusion.hpp" + +using namespace parthenon::package::prelude; + +TaskStatus CalcDiffFluxes(StateDescriptor *hydro_pkg, MeshData *md) { + const auto &conduction = hydro_pkg->Param("conduction"); + if (conduction != Conduction::none) { + const auto &thermal_diff = hydro_pkg->Param("thermal_diff"); + + if (conduction == Conduction::isotropic && + thermal_diff.GetCoeffType() == ConductionCoeff::fixed) { + ThermalFluxIsoFixed(md); + } else { + ThermalFluxGeneral(md); + } + } + return TaskStatus::complete; +} diff --git a/src/hydro/diffusion/diffusion.hpp b/src/hydro/diffusion/diffusion.hpp index 273464d7..7d522902 100644 --- a/src/hydro/diffusion/diffusion.hpp +++ b/src/hydro/diffusion/diffusion.hpp @@ -69,23 +69,37 @@ KOKKOS_INLINE_FUNCTION Real lim4(const Real A, const Real B, const Real C, const struct ThermalDiffusivity { private: - Real mbar_over_kb_; + Real mbar_, me_, kb_; Conduction conduction_; + ConductionCoeff conduction_coeff_type_; // "free" coefficient/prefactor. Value depends on conduction is set in the constructor. Real coeff_; public: KOKKOS_INLINE_FUNCTION - ThermalDiffusivity(Conduction conduction, Real coeff, Real mbar_over_kb) - : coeff_(coeff), conduction_(conduction), mbar_over_kb_(mbar_over_kb) {} + ThermalDiffusivity(Conduction conduction, ConductionCoeff conduction_coeff_type, + Real coeff, Real mbar, Real me, Real kb) + : conduction_(conduction), conduction_coeff_type_(conduction_coeff_type), + coeff_(coeff), mbar_(mbar), me_(me), kb_(kb) {} KOKKOS_INLINE_FUNCTION - Real Get(const Real pres, const Real rho, const Real gradTmag) const; + Real Get(const Real pres, const Real rho) const; + + KOKKOS_INLINE_FUNCTION + Conduction GetType() const { return conduction_; } + + KOKKOS_INLINE_FUNCTION + ConductionCoeff GetCoeffType() const { return conduction_coeff_type_; } }; Real EstimateConductionTimestep(MeshData *md); -//! Calculate anisotropic thermal conduction -void ThermalFluxAniso(MeshData *md); +//! Calculate isotropic thermal conduction with fixed coefficient +void ThermalFluxIsoFixed(MeshData *md); +//! Calculate thermal conduction (general case incl. anisotropic and saturated) +void ThermalFluxGeneral(MeshData *md); + +// Calculate all diffusion fluxes, i.e., update the .flux views in md +TaskStatus CalcDiffFluxes(StateDescriptor *hydro_pkg, MeshData *md); #endif // HYDRO_DIFFUSION_DIFFUSION_HPP_ diff --git a/src/hydro/hydro.cpp b/src/hydro/hydro.cpp index e5402454..54a97b7f 100644 --- a/src/hydro/hydro.cpp +++ b/src/hydro/hydro.cpp @@ -55,6 +55,35 @@ parthenon::Packages_t ProcessPackages(std::unique_ptr &pin) { return packages; } +// Using this per cycle function to populate various variables in +// Params that require global reduction *and* need to be set/known when +// the task list is constructed (versus when the task list is being executed). +// TODO(next person touching this function): If more/separate feature are required +// please separate concerns. +void PreStepMeshUserWorkInLoop(Mesh *pmesh, ParameterInput *pin, SimTime &tm) { + auto hydro_pkg = pmesh->block_list[0]->packages.Get("Hydro"); + const auto num_partitions = pmesh->DefaultNumPartitions(); + + if ((hydro_pkg->Param("diffint") == DiffInt::rkl2) && + (hydro_pkg->Param("conduction") != Conduction::none)) { + auto dt_diff = std::numeric_limits::max(); + for (auto i = 0; i < num_partitions; i++) { + auto &md = pmesh->mesh_data.GetOrAdd("base", i); + + dt_diff = std::min(dt_diff, EstimateConductionTimestep(md.get())); + } +#ifdef MPI_PARALLEL + PARTHENON_MPI_CHECK(MPI_Allreduce(MPI_IN_PLACE, &dt_diff, 1, MPI_PARTHENON_REAL, + MPI_MIN, MPI_COMM_WORLD)); +#endif + hydro_pkg->UpdateParam("dt_diff", dt_diff); + const auto max_dt_ratio = hydro_pkg->Param("rkl2_max_dt_ratio"); + if (max_dt_ratio > 0.0 && tm.dt / dt_diff > max_dt_ratio) { + tm.dt = max_dt_ratio * dt_diff; + } + } +} + template Real HydroHst(MeshData *md) { auto hydro_pkg = md->GetBlockData(0)->GetBlockPointer()->packages.Get("Hydro"); @@ -404,6 +433,7 @@ std::shared_ptr Initialize(ParameterInput *pin) { pkg->AddParam<>("mu", mu); pkg->AddParam<>("mu_e", mu_e); pkg->AddParam<>("He_mass_fraction", He_mass_fraction); + pkg->AddParam<>("mbar", mu * units.atomic_mass_unit()); // Following convention in the astro community, we're using mh as unit for the mean // molecular weight pkg->AddParam<>("mbar_over_kb", mu * units.mh() / units.k_boltzmann()); @@ -444,36 +474,93 @@ std::shared_ptr Initialize(ParameterInput *pin) { auto conduction = Conduction::none; auto conduction_str = pin->GetOrAddString("diffusion", "conduction", "none"); - if (conduction_str == "spitzer") { - if (!pkg->AllParams().hasKey("mbar_over_kb")) { - PARTHENON_FAIL("Spitzer thermal conduction requires units and gas composition. " - "Please set a 'units' block and the 'hydro/He_mass_fraction' in " - "the input file."); - } - conduction = Conduction::spitzer; - - Real spitzer_coeff = - pin->GetOrAddReal("diffusion", "spitzer_cond_in_erg_by_s_K_cm", 4.6e-7); - // Convert to code units. No temp conversion as [T_phys] = [T_code]. - auto units = pkg->Param("units"); - spitzer_coeff *= units.erg() / (units.s() * units.cm()); - - auto mbar_over_kb = pkg->Param("mbar_over_kb"); - auto thermal_diff = ThermalDiffusivity(conduction, spitzer_coeff, mbar_over_kb); - pkg->AddParam<>("thermal_diff", thermal_diff); - - } else if (conduction_str == "thermal_diff") { - conduction = Conduction::thermal_diff; - Real thermal_diff_coeff_code = pin->GetReal("diffusion", "thermal_diff_coeff_code"); - auto thermal_diff = ThermalDiffusivity(conduction, thermal_diff_coeff_code, 0.0); - pkg->AddParam<>("thermal_diff", thermal_diff); - + if (conduction_str == "isotropic") { + conduction = Conduction::isotropic; + } else if (conduction_str == "anisotropic") { + conduction = Conduction::anisotropic; } else if (conduction_str != "none") { PARTHENON_FAIL( - "AthenaPK unknown conduction method. Options are: spitzer, thermal_diff"); + "Unknown conduction method. Options are: none, isotropic, anisotropic"); + } + // If conduction is enabled, process supported coefficients + if (conduction != Conduction::none) { + auto conduction_coeff_str = + pin->GetOrAddString("diffusion", "conduction_coeff", "none"); + auto conduction_coeff = ConductionCoeff::none; + + // Saturated conduction factor to account for "uncertainty", see + // Cowie & McKee 77 and a value of 0.3 is typical chosen (though using "weak + // evidence", see Balbus & MacKee 1982 and Max, McKee, and Mead 1980). + const auto conduction_sat_phi = + pin->GetOrAddReal("diffusion", "conduction_sat_phi", 0.3); + Real conduction_sat_prefac = 0.0; + + if (conduction_coeff_str == "spitzer") { + if (!pkg->AllParams().hasKey("mbar")) { + PARTHENON_FAIL("Spitzer thermal conduction requires units and gas composition. " + "Please set a 'units' block and the 'hydro/He_mass_fraction' in " + "the input file."); + } + conduction_coeff = ConductionCoeff::spitzer; + + // Default value assume fully ionized hydrogen plasma with Coulomb logarithm of 40 + // to approximate ICM conditions, i.e., 1.84e-5/ln Lambda = 4.6e-7. + Real spitzer_coeff = + pin->GetOrAddReal("diffusion", "spitzer_cond_in_erg_by_s_K_cm", 4.6e-7); + // Convert to code units. No temp conversion as [T_phys] = [T_code]. + auto units = pkg->Param("units"); + spitzer_coeff *= units.erg() / (units.s() * units.cm()); + + const auto mbar = pkg->Param("mbar"); + auto thermal_diff = + ThermalDiffusivity(conduction, conduction_coeff, spitzer_coeff, mbar, + units.electron_mass(), units.k_boltzmann()); + pkg->AddParam<>("thermal_diff", thermal_diff); + + const auto mu = pkg->Param("mu"); + // 6.86 again assumes a fully ionized hydrogen plasma in agreement with + // the assumptions above (technically this means mu = 0.5) and can be derived + // from eq (7) in CM77 assuming T_e = T_i. + conduction_sat_prefac = 6.86 * std::sqrt(mu) * conduction_sat_phi; + + } else if (conduction_coeff_str == "fixed") { + conduction_coeff = ConductionCoeff::fixed; + Real thermal_diff_coeff_code = + pin->GetReal("diffusion", "thermal_diff_coeff_code"); + auto thermal_diff = ThermalDiffusivity(conduction, conduction_coeff, + thermal_diff_coeff_code, 0.0, 0.0, 0.0); + pkg->AddParam<>("thermal_diff", thermal_diff); + // 5.0 prefactor comes from eq (8) in Cowie & McKee 1977 + // https://doi.org/10.1086/154911 + conduction_sat_prefac = 5.0 * conduction_sat_phi; + + } else { + PARTHENON_FAIL("Thermal conduction is enabled but no coefficient is set. Please " + "set diffusion/conduction_coeff to either 'spitzer' or 'fixed'"); + } + PARTHENON_REQUIRE(conduction_sat_prefac != 0.0, + "Saturated thermal conduction prefactor uninitialized."); + pkg->AddParam<>("conduction_sat_prefac", conduction_sat_prefac); } pkg->AddParam<>("conduction", conduction); + auto diffint_str = pin->GetOrAddString("diffusion", "integrator", "none"); + auto diffint = DiffInt::none; + if (diffint_str == "unsplit") { + diffint = DiffInt::unsplit; + } else if (diffint_str == "rkl2") { + diffint = DiffInt::rkl2; + auto rkl2_dt_ratio = pin->GetOrAddReal("diffusion", "rkl2_max_dt_ratio", -1.0); + pkg->AddParam<>("rkl2_max_dt_ratio", rkl2_dt_ratio); + } else if (diffint_str != "none") { + PARTHENON_FAIL("AthenaPK unknown integration method for diffusion processes. " + "Options are: none, unsplit, rkl2"); + } + if (diffint != DiffInt::none) { + pkg->AddParam("dt_diff", 0.0, true); // diffusive timestep constraint + } + pkg->AddParam<>("diffint", diffint); + if (fluid == Fluid::euler) { AdiabaticHydroEOS eos(pfloor, dfloor, efloor, vceil, eceil, gamma); pkg->AddParam<>("eos", eos); @@ -702,7 +789,9 @@ Real EstimateTimestep(MeshData *md) { min_dt = std::min(min_dt, tabular_cooling.EstimateTimeStep(md)); } - if (hydro_pkg->Param("conduction") != Conduction::none) { + // For RKL2 STS, the diffusive timestep is calculated separately in the driver + if ((hydro_pkg->Param("diffint") == DiffInt::unsplit) && + (hydro_pkg->Param("conduction") != Conduction::none)) { min_dt = std::min(min_dt, EstimateConductionTimestep(md)); } @@ -943,9 +1032,9 @@ TaskStatus CalculateFluxes(std::shared_ptr> &md) { }); } - const auto &conduction = pkg->Param("conduction"); - if (conduction != Conduction::none) { - ThermalFluxAniso(md.get()); + const auto &diffint = pkg->Param("diffint"); + if (diffint == DiffInt::unsplit) { + CalcDiffFluxes(pkg.get(), md.get()); } return TaskStatus::complete; diff --git a/src/hydro/hydro.hpp b/src/hydro/hydro.hpp index 0967d12e..d54e96b1 100644 --- a/src/hydro/hydro.hpp +++ b/src/hydro/hydro.hpp @@ -16,6 +16,7 @@ using namespace parthenon::package::prelude; namespace Hydro { parthenon::Packages_t ProcessPackages(std::unique_ptr &pin); +void PreStepMeshUserWorkInLoop(Mesh *pmesh, ParameterInput *pin, parthenon::SimTime &tm); std::shared_ptr Initialize(ParameterInput *pin); template diff --git a/src/hydro/hydro_driver.cpp b/src/hydro/hydro_driver.cpp index e33b1b0d..36bdce91 100644 --- a/src/hydro/hydro_driver.cpp +++ b/src/hydro/hydro_driver.cpp @@ -1,6 +1,6 @@ //======================================================================================== // AthenaPK - a performance portable block structured AMR astrophysical MHD code. -// Copyright (c) 2020-2022, Athena-Parthenon Collaboration. All rights reserved. +// Copyright (c) 2020-2023, Athena-Parthenon Collaboration. All rights reserved. // Licensed under the BSD 3-Clause License (the "LICENSE"). //======================================================================================== @@ -19,6 +19,7 @@ #include "../eos/adiabatic_hydro.hpp" #include "../pgen/cluster/agn_triggering.hpp" #include "../pgen/cluster/magnetic_tower.hpp" +#include "diffusion/diffusion.hpp" #include "glmmhd/glmmhd.hpp" #include "hydro.hpp" #include "hydro_driver.hpp" @@ -76,6 +77,310 @@ TaskStatus CalculateGlobalMinDx(MeshData *md) { return TaskStatus::complete; } +// Sets all fluxes to 0 +TaskStatus ResetFluxes(MeshData *md) { + auto pmb = md->GetBlockData(0)->GetBlockPointer(); + IndexRange ib = pmb->cellbounds.GetBoundsI(IndexDomain::interior); + IndexRange jb = pmb->cellbounds.GetBoundsJ(IndexDomain::interior); + IndexRange kb = pmb->cellbounds.GetBoundsK(IndexDomain::interior); + + // In principle, we'd only need to pack Metadata::WithFluxes here, but + // choosing to mirror other use in the code so that the packs are already cached. + std::vector flags_ind({Metadata::Independent}); + auto cons_pack = md->PackVariablesAndFluxes(flags_ind); + + const int ndim = pmb->pmy_mesh->ndim; + // Using separate loops for each dim as the launch overhead should be hidden + // by enough work over the entire pack and it allows to not use any conditionals. + parthenon::par_for( + DEFAULT_LOOP_PATTERN, "ResetFluxes X1", parthenon::DevExecSpace(), 0, + cons_pack.GetDim(5) - 1, 0, cons_pack.GetDim(4) - 1, kb.s, kb.e, jb.s, jb.e, ib.s, + ib.e + 1, + KOKKOS_LAMBDA(const int b, const int v, const int k, const int j, const int i) { + auto &cons = cons_pack(b); + cons.flux(X1DIR, v, k, j, i) = 0.0; + }); + + if (ndim < 2) { + return TaskStatus::complete; + } + parthenon::par_for( + DEFAULT_LOOP_PATTERN, "ResetFluxes X2", parthenon::DevExecSpace(), 0, + cons_pack.GetDim(5) - 1, 0, cons_pack.GetDim(4) - 1, kb.s, kb.e, jb.s, jb.e + 1, + ib.s, ib.e, + KOKKOS_LAMBDA(const int b, const int v, const int k, const int j, const int i) { + auto &cons = cons_pack(b); + cons.flux(X2DIR, v, k, j, i) = 0.0; + }); + + if (ndim < 3) { + return TaskStatus::complete; + } + parthenon::par_for( + DEFAULT_LOOP_PATTERN, "ResetFluxes X3", parthenon::DevExecSpace(), 0, + cons_pack.GetDim(5) - 1, 0, cons_pack.GetDim(4) - 1, kb.s, kb.e + 1, jb.s, jb.e, + ib.s, ib.e, + KOKKOS_LAMBDA(const int b, const int v, const int k, const int j, const int i) { + auto &cons = cons_pack(b); + cons.flux(X3DIR, v, k, j, i) = 0.0; + }); + return TaskStatus::complete; +} + +TaskStatus RKL2StepFirst(MeshData *md_Y0, MeshData *md_Yjm1, + MeshData *md_Yjm2, MeshData *md_MY0, const int s_rkl, + const Real tau) { + auto pmb = md_Y0->GetBlockData(0)->GetBlockPointer(); + IndexRange ib = pmb->cellbounds.GetBoundsI(IndexDomain::interior); + IndexRange jb = pmb->cellbounds.GetBoundsJ(IndexDomain::interior); + IndexRange kb = pmb->cellbounds.GetBoundsK(IndexDomain::interior); + + // Compute coefficients. Meyer+2014 eq. (18) + Real mu_tilde_1 = 4. / 3. / + (static_cast(s_rkl) * static_cast(s_rkl) + + static_cast(s_rkl) - 2.); + + // In principle, we'd only need to pack Metadata::WithFluxes here, but + // choosing to mirror other use in the code so that the packs are already cached. + std::vector flags_ind({Metadata::Independent}); + auto Y0 = md_Y0->PackVariablesAndFluxes(flags_ind); + auto Yjm1 = md_Yjm1->PackVariablesAndFluxes(flags_ind); + auto Yjm2 = md_Yjm2->PackVariablesAndFluxes(flags_ind); + auto MY0 = md_MY0->PackVariablesAndFluxes(flags_ind); + + const int ndim = pmb->pmy_mesh->ndim; + // Using separate loops for each dim as the launch overhead should be hidden + // by enough work over the entire pack and it allows to not use any conditionals. + parthenon::par_for( + DEFAULT_LOOP_PATTERN, "RKL first step", parthenon::DevExecSpace(), 0, + Y0.GetDim(5) - 1, 0, Y0.GetDim(4) - 1, kb.s, kb.e, jb.s, jb.e, ib.s, ib.e, + KOKKOS_LAMBDA(const int b, const int v, const int k, const int j, const int i) { + Yjm1(b, v, k, j, i) = + Y0(b, v, k, j, i) + mu_tilde_1 * tau * MY0(b, v, k, j, i); // Y_1 + Yjm2(b, v, k, j, i) = Y0(b, v, k, j, i); // Y_0 + }); + + return TaskStatus::complete; +} + +TaskStatus RKL2StepOther(MeshData *md_Y0, MeshData *md_Yjm1, + MeshData *md_Yjm2, MeshData *md_MY0, const Real mu_j, + const Real nu_j, const Real mu_tilde_j, const Real gamma_tilde_j, + const Real tau) { + auto pmb = md_Y0->GetBlockData(0)->GetBlockPointer(); + IndexRange ib = pmb->cellbounds.GetBoundsI(IndexDomain::interior); + IndexRange jb = pmb->cellbounds.GetBoundsJ(IndexDomain::interior); + IndexRange kb = pmb->cellbounds.GetBoundsK(IndexDomain::interior); + + // In principle, we'd only need to pack Metadata::WithFluxes here, but + // choosing to mirror other use in the code so that the packs are already cached. + std::vector flags_ind({Metadata::Independent}); + auto Y0 = md_Y0->PackVariablesAndFluxes(flags_ind); + auto Yjm1 = md_Yjm1->PackVariablesAndFluxes(flags_ind); + auto Yjm2 = md_Yjm2->PackVariablesAndFluxes(flags_ind); + auto MY0 = md_MY0->PackVariablesAndFluxes(flags_ind); + + const int ndim = pmb->pmy_mesh->ndim; + // Using separate loops for each dim as the launch overhead should be hidden + // by enough work over the entire pack and it allows to not use any conditionals. + parthenon::par_for( + DEFAULT_LOOP_PATTERN, "RKL other step", parthenon::DevExecSpace(), 0, + Y0.GetDim(5) - 1, 0, Y0.GetDim(4) - 1, kb.s, kb.e, jb.s, jb.e, ib.s, ib.e, + KOKKOS_LAMBDA(const int b, const int v, const int k, const int j, const int i) { + // First calc this step + const auto &coords = Yjm1.GetCoords(b); + const Real MYjm1 = + parthenon::Update::FluxDivHelper(v, k, j, i, ndim, coords, Yjm1(b)); + const Real Yj = mu_j * Yjm1(b, v, k, j, i) + nu_j * Yjm2(b, v, k, j, i) + + (1.0 - mu_j - nu_j) * Y0(b, v, k, j, i) + + mu_tilde_j * tau * MYjm1 + + gamma_tilde_j * tau * MY0(b, v, k, j, i); + // Then shuffle vars for next step + Yjm2(b, v, k, j, i) = Yjm1(b, v, k, j, i); + Yjm1(b, v, k, j, i) = Yj; + }); + + return TaskStatus::complete; +} + +// Assumes that prim and cons are in sync initially. +// Guarantees that prim and cons are in sync at the end. +void AddSTSTasks(TaskCollection *ptask_coll, Mesh *pmesh, BlockList_t &blocks, + const Real tau) { + + auto hydro_pkg = blocks[0]->packages.Get("Hydro"); + auto mindt_diff = hydro_pkg->Param("dt_diff"); + + // get number of RKL steps + // eq (21) using half hyperbolic timestep due to Strang split + int s_rkl = + static_cast(0.5 * (std::sqrt(9.0 + 16.0 * tau / mindt_diff) - 1.0)) + 1; + // ensure odd number of stages + if (s_rkl % 2 == 0) s_rkl += 1; + + if (parthenon::Globals::my_rank == 0) { + const auto ratio = 2.0 * tau / mindt_diff; + std::cout << "STS ratio: " << ratio << " Taking " << s_rkl << " steps." << std::endl; + if (ratio > 400.1) { + std::cout << "WARNING: ratio is > 400. Proceed at own risk." << std::endl; + } + } + + TaskID none(0); + + // Store initial u0 in u1 as "base" will continuously be updated but initial state Y0 is + // required for each stage. + TaskRegion ®ion_copy_out = ptask_coll->AddRegion(blocks.size()); + for (int i = 0; i < blocks.size(); i++) { + auto &tl = region_copy_out[i]; + auto &Y0 = blocks[i]->meshblock_data.Get("u1"); + auto &base = blocks[i]->meshblock_data.Get(); + tl.AddTask( + none, + [](MeshBlockData *dst, MeshBlockData *src) { + dst->Get("cons").data.DeepCopy(src->Get("cons").data); + dst->Get("prim").data.DeepCopy(src->Get("prim").data); + return TaskStatus::complete; + }, + Y0.get(), base.get()); + } + + TaskRegion ®ion_init = ptask_coll->AddRegion(blocks.size()); + for (int i = 0; i < blocks.size(); i++) { + auto &pmb = blocks[i]; + auto &tl = region_init[i]; + auto &base = pmb->meshblock_data.Get(); + + // Add extra registers. No-op for existing variables so it's safe to call every + // time. + // TODO(pgrete) this allocates all Variables, i.e., prim and cons vector, but only a + // subset is actually needed. Streamline to allocate only required vars. + pmb->meshblock_data.Add("MY0", base); + pmb->meshblock_data.Add("Yjm2", base); + } + + const int num_partitions = pmesh->DefaultNumPartitions(); + TaskRegion ®ion_calc_fluxes_step_init = ptask_coll->AddRegion(num_partitions); + for (int i = 0; i < num_partitions; i++) { + auto &tl = region_calc_fluxes_step_init[i]; + auto &base = pmesh->mesh_data.GetOrAdd("base", i); + const auto any = parthenon::BoundaryType::any; + auto start_bnd = tl.AddTask(none, parthenon::StartReceiveBoundBufs, base); + auto start_flxcor_recv = + tl.AddTask(none, parthenon::StartReceiveFluxCorrections, base); + + // Reset flux arrays (not guaranteed to be zero) + auto reset_fluxes = tl.AddTask(none, ResetFluxes, base.get()); + + // Calculate the diffusive fluxes for Y0 (here still "base" as nothing has been + // updated yet) so that we can store the result as MY0 and reuse later + // (in every subsetp). + auto hydro_diff_fluxes = + tl.AddTask(reset_fluxes, CalcDiffFluxes, hydro_pkg.get(), base.get()); + + auto send_flx = + tl.AddTask(hydro_diff_fluxes, parthenon::LoadAndSendFluxCorrections, base); + auto recv_flx = + tl.AddTask(start_flxcor_recv, parthenon::ReceiveFluxCorrections, base); + auto set_flx = + tl.AddTask(recv_flx | hydro_diff_fluxes, parthenon::SetFluxCorrections, base); + + auto &Y0 = pmesh->mesh_data.GetOrAdd("u1", i); + auto &MY0 = pmesh->mesh_data.GetOrAdd("MY0", i); + auto &Yjm2 = pmesh->mesh_data.GetOrAdd("Yjm2", i); + + auto init_MY0 = tl.AddTask(set_flx, parthenon::Update::FluxDivergence>, + base.get(), MY0.get()); + + // Initialize Y0 and Y1 and the recursion relation starting with j = 2 needs data from + // the two preceeding stages. + auto rkl2_step_first = tl.AddTask(init_MY0, RKL2StepFirst, Y0.get(), base.get(), + Yjm2.get(), MY0.get(), s_rkl, tau); + + // Update ghost cells of Y1 (as MY1 is calculated for each Y_j). + // Y1 stored in "base", see rkl2_step_first task. + // Update ghost cells (local and non local), prolongate and apply bound cond. + // TODO(someone) experiment with split (local/nonlocal) comms with respect to + // performance for various tests (static, amr, block sizes) and then decide on the + // best impl. Go with default call (split local/nonlocal) for now. + // TODO(pgrete) optimize (in parthenon) to only send subset of updated vars + auto bounds_exchange = parthenon::AddBoundaryExchangeTasks( + rkl2_step_first | start_bnd, tl, base, pmesh->multilevel); + + tl.AddTask(bounds_exchange, parthenon::Update::FillDerived>, + base.get()); + } + + // Compute coefficients. Meyer+2012 eq. (16) + Real b_j = 1. / 3.; + Real b_jm1 = 1. / 3.; + Real b_jm2 = 1. / 3.; + Real w1 = 4. / (static_cast(s_rkl) * static_cast(s_rkl) + + static_cast(s_rkl) - 2.); + Real mu_j, nu_j, j, mu_tilde_j, gamma_tilde_j; + + // RKL loop + for (int jj = 2; jj <= s_rkl; jj++) { + j = static_cast(jj); + b_j = (j * j + j - 2.0) / (2 * j * (j + 1.0)); + mu_j = (2.0 * j - 1.0) / j * b_j / b_jm1; + nu_j = -(j - 1.0) / j * b_j / b_jm2; + mu_tilde_j = mu_j * w1; + gamma_tilde_j = -(1.0 - b_jm1) * mu_tilde_j; // -a_jm1*mu_tilde_j + + TaskRegion ®ion_calc_fluxes_step_other = ptask_coll->AddRegion(num_partitions); + for (int i = 0; i < num_partitions; i++) { + auto &tl = region_calc_fluxes_step_other[i]; + auto &base = pmesh->mesh_data.GetOrAdd("base", i); + + // Only need boundaries for base as it's the only "active" container exchanging + // data/fluxes with neighbors. All other containers are passive (i.e., data is only + // used but not exchanged). + const auto any = parthenon::BoundaryType::any; + auto start_bnd = tl.AddTask(none, parthenon::StartReceiveBoundBufs, base); + auto start_flxcor_recv = + tl.AddTask(none, parthenon::StartReceiveFluxCorrections, base); + + // Reset flux arrays (not guaranteed to be zero) + auto reset_fluxes = tl.AddTask(none, ResetFluxes, base.get()); + + // Calculate the diffusive fluxes for Yjm1 (here u1) + auto hydro_diff_fluxes = + tl.AddTask(reset_fluxes, CalcDiffFluxes, hydro_pkg.get(), base.get()); + + auto send_flx = + tl.AddTask(hydro_diff_fluxes, parthenon::LoadAndSendFluxCorrections, base); + auto recv_flx = + tl.AddTask(start_flxcor_recv, parthenon::ReceiveFluxCorrections, base); + auto set_flx = + tl.AddTask(recv_flx | hydro_diff_fluxes, parthenon::SetFluxCorrections, base); + + auto &Y0 = pmesh->mesh_data.GetOrAdd("u1", i); + auto &MY0 = pmesh->mesh_data.GetOrAdd("MY0", i); + auto &Yjm2 = pmesh->mesh_data.GetOrAdd("Yjm2", i); + + auto rkl2_step_other = + tl.AddTask(set_flx, RKL2StepOther, Y0.get(), base.get(), Yjm2.get(), MY0.get(), + mu_j, nu_j, mu_tilde_j, gamma_tilde_j, tau); + + // update ghost cells of base (currently storing Yj) + // Update ghost cells (local and non local), prolongate and apply bound cond. + // TODO(someone) experiment with split (local/nonlocal) comms with respect to + // performance for various tests (static, amr, block sizes) and then decide on the + // best impl. Go with default call (split local/nonlocal) for now. + // TODO(pgrete) optimize (in parthenon) to only send subset of updated vars + auto bounds_exchange = parthenon::AddBoundaryExchangeTasks( + rkl2_step_other | start_bnd, tl, base, pmesh->multilevel); + + tl.AddTask(bounds_exchange, parthenon::Update::FillDerived>, + base.get()); + } + + b_jm2 = b_jm1; + b_jm1 = b_j; + } +} + // See the advection.hpp declaration for a description of how this function gets called. TaskCollection HydroDriver::MakeTaskCollection(BlockList_t &blocks, int stage) { TaskCollection tc; @@ -232,6 +537,12 @@ TaskCollection HydroDriver::MakeTaskCollection(BlockList_t &blocks, int stage) { // First add split sources before the main time integration if (stage == 1) { + // If any tasks modify the conserved variables before this place, then + // the STS tasks should be updated to not assume prim and cons are in sync. + const auto &diffint = hydro_pkg->Param("diffint"); + if (diffint == DiffInt::rkl2) { + AddSTSTasks(&tc, pmesh, blocks, 0.5 * tm.dt); + } TaskRegion &strang_init_region = tc.AddRegion(num_partitions); for (int i = 0; i < num_partitions; i++) { auto &tl = strang_init_region[i]; @@ -277,7 +588,11 @@ TaskCollection HydroDriver::MakeTaskCollection(BlockList_t &blocks, int stage) { auto &tl = single_tasklist_per_pack_region[i]; auto &mu0 = pmesh->mesh_data.GetOrAdd("base", i); auto &mu1 = pmesh->mesh_data.GetOrAdd("u1", i); - tl.AddTask(none, parthenon::StartReceiveFluxCorrections, mu0); + + const auto any = parthenon::BoundaryType::any; + auto start_bnd = tl.AddTask(none, parthenon::StartReceiveBoundBufs, mu0); + auto start_flxcor_recv = + tl.AddTask(none, parthenon::StartReceiveFluxCorrections, mu0); const auto flux_str = (stage == 1) ? "flux_first_stage" : "flux_other_stage"; FluxFun_t *calc_flux_fun = hydro_pkg->Param(flux_str); @@ -298,9 +613,9 @@ TaskCollection HydroDriver::MakeTaskCollection(BlockList_t &blocks, int stage) { auto send_flx = tl.AddTask(first_order_flux_correct, parthenon::LoadAndSendFluxCorrections, mu0); - auto recv_flx = - tl.AddTask(first_order_flux_correct, parthenon::ReceiveFluxCorrections, mu0); - auto set_flx = tl.AddTask(recv_flx, parthenon::SetFluxCorrections, mu0); + auto recv_flx = tl.AddTask(start_flxcor_recv, parthenon::ReceiveFluxCorrections, mu0); + auto set_flx = tl.AddTask(recv_flx | first_order_flux_correct, + parthenon::SetFluxCorrections, mu0); // compute the divergence of fluxes of conserved variables auto update = tl.AddTask( @@ -332,29 +647,14 @@ TaskCollection HydroDriver::MakeTaskCollection(BlockList_t &blocks, int stage) { tl.AddTask(source_split_strang_final, AddSplitSourcesFirstOrder, mu0.get(), tm); } - // Update ghost cells (local and non local) + // Update ghost cells (local and non local), prolongate and apply bound cond. // TODO(someone) experiment with split (local/nonlocal) comms with respect to // performance for various tests (static, amr, block sizes) and then decide on the // best impl. Go with default call (split local/nonlocal) for now. - parthenon::AddBoundaryExchangeTasks(source_split_first_order, tl, mu0, + parthenon::AddBoundaryExchangeTasks(source_split_first_order | start_bnd, tl, mu0, pmesh->multilevel); } - TaskRegion &async_region_3 = tc.AddRegion(num_task_lists_executed_independently); - for (int i = 0; i < blocks.size(); i++) { - auto &tl = async_region_3[i]; - auto &u0 = blocks[i]->meshblock_data.Get("base"); - auto prolongBound = none; - // Currently taken care of by AddBoundaryExchangeTasks above. - // Needs to be reintroduced once we reintroduce split (local/nonlocal) communication. - // if (pmesh->multilevel) { - // prolongBound = tl.AddTask(none, parthenon::ProlongateBoundaries, u0); - //} - - // set physical boundaries - auto set_bc = tl.AddTask(prolongBound, parthenon::ApplyBoundaryConditions, u0); - } - // Single task in single (serial) region to reset global vars used in reductions in the // first stage. if (stage == integrator->nstages && hydro_pkg->Param("calc_c_h")) { @@ -376,10 +676,21 @@ TaskCollection HydroDriver::MakeTaskCollection(BlockList_t &blocks, int stage) { auto &mu0 = pmesh->mesh_data.GetOrAdd("base", i); auto fill_derived = tl.AddTask(none, parthenon::Update::FillDerived>, mu0.get()); + } + const auto &diffint = hydro_pkg->Param("diffint"); + // If any tasks modify the conserved variables before this place and after FillDerived, + // then the STS tasks should be updated to not assume prim and cons are in sync. + if (diffint == DiffInt::rkl2 && stage == integrator->nstages) { + AddSTSTasks(&tc, pmesh, blocks, 0.5 * tm.dt); + } - if (stage == integrator->nstages) { - auto new_dt = tl.AddTask( - fill_derived, parthenon::Update::EstimateTimestep>, mu0.get()); + if (stage == integrator->nstages) { + TaskRegion &tr = tc.AddRegion(num_partitions); + for (int i = 0; i < num_partitions; i++) { + auto &tl = tr[i]; + auto &mu0 = pmesh->mesh_data.GetOrAdd("base", i); + auto new_dt = tl.AddTask(none, parthenon::Update::EstimateTimestep>, + mu0.get()); } } diff --git a/src/main.cpp b/src/main.cpp index 87d82021..93f984bb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -44,6 +44,7 @@ int main(int argc, char *argv[]) { // Redefine defaults pman.app_input->ProcessPackages = Hydro::ProcessPackages; + pman.app_input->PreStepMeshUserWorkInLoop = Hydro::PreStepMeshUserWorkInLoop; const auto problem = pman.pinput->GetOrAddString("job", "problem_id", "unset"); if (problem == "linear_wave") { diff --git a/src/main.hpp b/src/main.hpp index bbcd0786..033118ad 100644 --- a/src/main.hpp +++ b/src/main.hpp @@ -35,7 +35,9 @@ enum class Reconstruction { undefined, dc, plm, ppm, wenoz, weno3, limo3 }; enum class Integrator { undefined, rk1, rk2, vl2, rk3 }; enum class Fluid { undefined, euler, glmmhd }; enum class Cooling { none, tabular }; -enum class Conduction { none, spitzer, thermal_diff }; +enum class Conduction { none, isotropic, anisotropic }; +enum class ConductionCoeff { none, fixed, spitzer }; +enum class DiffInt { none, unsplit, rkl2 }; enum class Hst { idx, ekin, emag, divb }; diff --git a/src/pgen/cloud.cpp b/src/pgen/cloud.cpp index b496dd2d..db53990a 100644 --- a/src/pgen/cloud.cpp +++ b/src/pgen/cloud.cpp @@ -32,6 +32,7 @@ using namespace parthenon::driver::prelude; Real rho_wind, mom_wind, rhoe_wind, r_cloud, rho_cloud; Real Bx = 0.0; Real By = 0.0; +Real Bz = 0.0; //======================================================================================== //! \fn void InitUserMeshData(Mesh *mesh, ParameterInput *pin) @@ -77,9 +78,13 @@ void InitUserMeshData(Mesh *mesh, ParameterInput *pin) { By = std::sqrt(2.0 * pressure / plasma_beta); } else if (mag_field_angle_str == "transverse") { Bx = std::sqrt(2.0 * pressure / plasma_beta); + } else if (mag_field_angle_str == "oblique") { + const auto B = std::sqrt(2.0 * pressure / plasma_beta); + Bx = B / std::sqrt(5.0); + Bz = 2 * Bx; } else { PARTHENON_FAIL("Unsupported problem/cloud/mag_field_angle. Please use either " - "'aligned' or 'transverse'."); + "'aligned', 'transverse', or 'oblique'."); } } @@ -152,7 +157,7 @@ void ProblemGenerator(MeshBlock *pmb, ParameterInput *pin) { const auto nscalars = hydro_pkg->Param("nscalars"); const bool mhd_enabled = hydro_pkg->Param("fluid") == Fluid::glmmhd; - if (((Bx != 0.0) || (By != 0.0)) && !mhd_enabled) { + if (((Bx != 0.0) || (By != 0.0) || (Bz != 0.0)) && !mhd_enabled) { PARTHENON_FAIL("Requested to initialize magnetic fields by `cloud/plasma_beta > 0`, " "but `hydro/fluid` is not supporting MHD."); } @@ -195,7 +200,8 @@ void ProblemGenerator(MeshBlock *pmb, ParameterInput *pin) { if (mhd_enabled) { u(IB1, k, j, i) = Bx; u(IB2, k, j, i) = By; - u(IEN, k, j, i) += 0.5 * (Bx * Bx + By * By); + u(IB3, k, j, i) = Bz; + u(IEN, k, j, i) += 0.5 * (Bx * Bx + By * By + Bz * Bz); } // Init passive scalars @@ -222,6 +228,7 @@ void InflowWindX2(std::shared_ptr> &mbd, bool coarse) { const auto rhoe_wind_ = rhoe_wind; const auto Bx_ = Bx; const auto By_ = By; + const auto Bz_ = Bz; pmb->par_for_bndry( "InflowWindX2", nb, IndexDomain::inner_x2, parthenon::TopologicalElement::CC, coarse, KOKKOS_LAMBDA(const int, const int &k, const int &j, const int &i) { @@ -236,6 +243,10 @@ void InflowWindX2(std::shared_ptr> &mbd, bool coarse) { cons(IB2, k, j, i) = By_; cons(IEN, k, j, i) += 0.5 * By_ * By_; } + if (Bz_ != 0.0) { + cons(IB3, k, j, i) = Bz_; + cons(IEN, k, j, i) += 0.5 * Bz_ * Bz_; + } }); } diff --git a/src/pgen/diffusion.cpp b/src/pgen/diffusion.cpp index 85ac913a..24ae60f2 100644 --- a/src/pgen/diffusion.cpp +++ b/src/pgen/diffusion.cpp @@ -1,6 +1,6 @@ // AthenaPK - a performance portable block structured AMR MHD code -// Copyright (c) 2021, Athena Parthenon Collaboration. All rights reserved. +// Copyright (c) 2021-2023, Athena Parthenon Collaboration. All rights reserved. // Licensed under the 3-Clause License (the "LICENSE") // Parthenon headers @@ -27,7 +27,15 @@ void ProblemGenerator(MeshBlock *pmb, ParameterInput *pin) { const auto By = pin->GetOrAddReal("problem/diffusion", "By", 0.0); const auto iprob = pin->GetInteger("problem/diffusion", "iprob"); - const auto sigma = pin->GetOrAddReal("problem/diffusion", "sigma", 0.1); + Real t0 = 0.5; + Real diff_coeff = 0.0; + Real amp = 1e-6; + // Get parameters for Gaussian profile + if (iprob == 10) { + diff_coeff = pin->GetReal("diffusion", "thermal_diff_coeff_code"); + t0 = pin->GetOrAddReal("problem/diffusion", "t0", t0); + amp = pin->GetOrAddReal("problem/diffusion", "amp", amp); + } auto &coords = pmb->coords; @@ -64,7 +72,15 @@ void ProblemGenerator(MeshBlock *pmb, ParameterInput *pin) { } else if (iprob == 10) { u(IB1, k, j, i) = Bx; u(IB2, k, j, i) = By; - eint = 1 + std::exp(-SQR(coords.Xc<1>(i) / sigma) / 2.0); + // Adjust for anisotropic thermal conduction. + // If there's no conduction for the setup (because the field is perp.) + // treat as 1 (also in analysis) to prevent division by 0. + // Note, this is very constructed and needs to be updated/adjusted for isotropic + // conduction, other directions, and Bfield configs with |B| != 1 + Real eff_diff_coeff = Bx == 0.0 ? diff_coeff : diff_coeff * Bx * Bx; + eint = 1 + amp / std::sqrt(4. * M_PI * eff_diff_coeff * t0) * + std::exp(-(std::pow(coords.Xc<1>(i), 2.)) / + (4. * eff_diff_coeff * t0)); // Ring diffusion in x1-x2 plane } else if (iprob == 20) { const auto x = coords.Xc<1>(i); diff --git a/src/units.hpp b/src/units.hpp index a089e632..3290e87e 100644 --- a/src/units.hpp +++ b/src/units.hpp @@ -30,6 +30,7 @@ class Units { static constexpr parthenon::Real dyne_cm2_cgs = 1.0; // dyne/cm^2 static constexpr parthenon::Real msun_cgs = 1.98841586e+33; // g static constexpr parthenon::Real atomic_mass_unit_cgs = 1.660538921e-24; // g + static constexpr parthenon::Real electron_mass_cgs = 9.1093837015e-28; // g static constexpr parthenon::Real g_cm3_cgs = 1.0; // gcm**3 static constexpr parthenon::Real erg_cgs = 1; // erg static constexpr parthenon::Real gauss_cgs = 1; // gauss @@ -124,6 +125,7 @@ class Units { parthenon::Real atomic_mass_unit() const { return atomic_mass_unit_cgs / code_mass_cgs(); } + parthenon::Real electron_mass() const { return electron_mass_cgs / code_mass_cgs(); } parthenon::Real mh() const { return mh_cgs / code_mass_cgs(); } parthenon::Real erg() const { return erg_cgs / code_energy_cgs(); } parthenon::Real gauss() const { return gauss_cgs / code_magnetic_cgs(); } diff --git a/tst/regression/CMakeLists.txt b/tst/regression/CMakeLists.txt index 3461a817..c43b4de5 100644 --- a/tst/regression/CMakeLists.txt +++ b/tst/regression/CMakeLists.txt @@ -45,6 +45,9 @@ setup_test_both("aniso_therm_cond_ring_conv" "--driver ${PROJECT_BINARY_DIR}/bin setup_test_both("aniso_therm_cond_ring_multid" "--driver ${PROJECT_BINARY_DIR}/bin/athenaPK \ --driver_input ${PROJECT_SOURCE_DIR}/inputs/diffusion.in --num_steps 4" "convergence") + +setup_test_both("aniso_therm_cond_gauss_conv" "--driver ${PROJECT_BINARY_DIR}/bin/athenaPK \ + --driver_input ${PROJECT_SOURCE_DIR}/inputs/diffusion.in --num_steps 24" "convergence") setup_test_both("field_loop" "--driver ${PROJECT_BINARY_DIR}/bin/athenaPK \ --driver_input ${PROJECT_SOURCE_DIR}/inputs/field_loop.in --num_steps 12" "convergence") diff --git a/tst/regression/test_suites/aniso_therm_cond_gauss_conv/__init__.py b/tst/regression/test_suites/aniso_therm_cond_gauss_conv/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tst/regression/test_suites/aniso_therm_cond_gauss_conv/aniso_therm_cond_gauss_conv.py b/tst/regression/test_suites/aniso_therm_cond_gauss_conv/aniso_therm_cond_gauss_conv.py new file mode 100644 index 00000000..9f002723 --- /dev/null +++ b/tst/regression/test_suites/aniso_therm_cond_gauss_conv/aniso_therm_cond_gauss_conv.py @@ -0,0 +1,221 @@ +# ======================================================================================== +# AthenaPK - a performance portable block structured AMR MHD code +# Copyright (c) 2020-2021, Athena Parthenon Collaboration. All rights reserved. +# Licensed under the 3-clause BSD License, see LICENSE file for details +# ======================================================================================== +# (C) (or copyright) 2020. Triad National Security, LLC. All rights reserved. +# +# This program was produced under U.S. Government contract 89233218CNA000001 for Los +# Alamos National Laboratory (LANL), which is operated by Triad National Security, LLC +# for the U.S. Department of Energy/National Nuclear Security Administration. All rights +# in the program are reserved by Triad National Security, LLC, and the U.S. Department +# of Energy/National Nuclear Security Administration. The Government is granted for +# itself and others acting on its behalf a nonexclusive, paid-up, irrevocable worldwide +# license in this material to reproduce, prepare derivative works, distribute copies to +# the public, perform publicly and display publicly, and to permit others to do so. +# ======================================================================================== + +# Modules +import math +import numpy as np +import matplotlib + +matplotlib.use("agg") +import matplotlib.pylab as plt +import sys +import os +import itertools +import utils.test_case +from scipy.optimize import curve_fit + +# To prevent littering up imported folders with .pyc files or __pycache_ folder +sys.dont_write_bytecode = True + +int_cfgs = ["unsplit", "rkl2"] +res_cfgs = [128, 256, 512] +field_cfgs = ["none", "aligned", "angle", "perp"] +tlim = 2.0 + +all_cfgs = list(itertools.product(res_cfgs, field_cfgs, int_cfgs)) + + +def get_outname(all_cfg): + res, field_cfg, int_cfg = all_cfg + return f"{res}_{field_cfg}_{int_cfg}" + + +def get_B(field_cfg): + if field_cfg == "aligned": + Bx = 1.0 + By = 0.0 + elif field_cfg == "perp": + Bx = 0.0 + By = 1.0 + elif field_cfg == "angle": + Bx = 1 / np.sqrt(2) + By = 1 / np.sqrt(2) + # isotropic case + elif field_cfg == "none": + Bx = 0.0 + By = 0.0 + else: + raise "Unknown field_cfg: %s" % field_cfg + + return Bx, By + + +class TestCase(utils.test_case.TestCaseAbs): + def Prepare(self, parameters, step): + assert parameters.num_ranks <= 4, "Use <= 4 ranks for diffusion test." + + res, field_cfg, int_cfg = all_cfgs[step - 1] + + Bx, By = get_B(field_cfg) + + outname = get_outname(all_cfgs[step - 1]) + + if field_cfg == "none": + conduction = "isotropic" + else: + conduction = "anisotropic" + + parameters.driver_cmd_line_args = [ + "parthenon/mesh/nx1=%d" % res, + "parthenon/meshblock/nx1=64", + "parthenon/mesh/x1min=-6.0", + "parthenon/mesh/x1max=6.0", + "parthenon/mesh/nx2=32", + "parthenon/meshblock/nx2=32", + "parthenon/mesh/x2min=-1.0", + "parthenon/mesh/x2max=1.0", + "parthenon/mesh/nx3=1", + "parthenon/meshblock/nx3=1", + "parthenon/time/integrator=%s" + % ("rk2" if (int_cfg == "unsplit") else "rk1"), + "problem/diffusion/Bx=%f" % Bx, + "problem/diffusion/By=%f" % By, + "problem/diffusion/iprob=10", + "parthenon/output0/id=%s" % outname, + "hydro/gamma=2.0", + "parthenon/time/tlim=%f" % tlim, + "diffusion/conduction=%s" % conduction, + "diffusion/thermal_diff_coeff_code=0.25", + "diffusion/integrator=%s" % int_cfg, + ] + + return parameters + + def Analyse(self, parameters): + sys.path.insert( + 1, + parameters.parthenon_path + + "/scripts/python/packages/parthenon_tools/parthenon_tools", + ) + + try: + import phdf + except ModuleNotFoundError: + print("Couldn't find module to read Parthenon hdf5 files.") + return False + + tests_passed = True + + def get_ref(x, Bx, field_cfg): + eff_diff_coeff = 0.25 if Bx == 0.0 else 0.25 * Bx * Bx + tlim_ = 0.0 if field_cfg == "perp" else tlim + return 1.0 + 1e-6 / ( + np.sqrt(4 * np.pi * eff_diff_coeff * (0.5 + tlim_)) + / np.exp(-(x**2) / (4.0 * eff_diff_coeff * (0.5 + tlim_))) + ) + + num_rows = len(res_cfgs) + num_cols = len(int_cfgs) + fig, p = plt.subplots(num_rows + 1, 2, sharey="row", sharex="row") + + l1_err = np.zeros((len(field_cfgs), len(int_cfgs), len(res_cfgs))) + for step in range(len(all_cfgs)): + outname = get_outname(all_cfgs[step]) + data_filename = f"{parameters.output_path}/parthenon.{outname}.final.phdf" + data_file = phdf.phdf(data_filename) + prim = data_file.Get("prim") + zz, yy, xx = data_file.GetVolumeLocations() + mask = yy == yy[0] + temp = prim[4][mask] + x = xx[mask] + res, field_cfg, int_cfg = all_cfgs[step] + row = res_cfgs.index(res) + col = int_cfgs.index(int_cfg) + + Bx, By = get_B(field_cfg) + temp_ref = get_ref(x, Bx, field_cfg) + l1 = np.average(np.abs(temp - temp_ref)) + l1_err[ + field_cfgs.index(field_cfg), + int_cfgs.index(int_cfg), + res_cfgs.index(res), + ] = l1 + p[row, col].plot(x, temp, label=f"{field_cfg} N={res} L$_1$={l1:.2g}") + + # Plot convergence + for i, field_cfg in enumerate(field_cfgs): + for j, int_cfg in enumerate(int_cfgs): + p[0, j].set_title(f"Integrator: {int_cfg}") + if field_cfg == "perp": + continue + + p[-1, j].plot( + res_cfgs, + l1_err[i, j, :], + label=f"{field_cfg} data", + ) + + # Simple convergence estimator + conv_model = lambda log_n, log_a, conv_rate: conv_rate * log_n + log_a + popt, pconv = curve_fit( + conv_model, np.log(res_cfgs), np.log(l1_err[i, j, :]) + ) + conv_a, conv_measured = popt + # Note that the RKL2 convergence on the plots is currently significantly better + # than expected (<-3) though the L1 errors themself are larger than the unsplit + # integrator (as expected). + # For a more reasonable test (which would take longer), reduce the RKL2 ratio to, + # say, 200 and extend the resolution grid to 1024 (as the first data point at N=128 + # is comparatively worse than at N>128). + if conv_measured > -1.98: + print( + f"!!!\nConvergence for {field_cfg} test with {int_cfg} integrator " + f"is worse ({conv_measured}) than expected (-1.98).\n!!!" + ) + tests_passed = False + p[-1, j].plot( + res_cfgs, + np.exp(conv_a) * res_cfgs**conv_measured, + ":", + lw=0.75, + label=f"{field_cfg} Measured conv: {conv_measured:.2f}", + ) + + p[-1, 0].set_xscale("log") + p[-1, 0].set_yscale("log") + p[-1, 0].legend(fontsize=6) + p[-1, 1].legend(fontsize=6) + + # Plot reference lines + x = np.linspace(-6, 6, 400) + for field_cfg in field_cfgs: + Bx, By = get_B(field_cfg) + for i in range(num_rows): + for j in range(num_cols): + y = get_ref(x, Bx, field_cfg) + p[i, j].plot(x, y, "-", lw=0.5, color="black", alpha=0.8) + p[i, j].grid() + p[i, j].legend(fontsize=6) + + fig.tight_layout() + fig.savefig( + os.path.join(parameters.output_path, "cond.png"), + bbox_inches="tight", + dpi=300, + ) + + return tests_passed diff --git a/tst/regression/test_suites/aniso_therm_cond_ring_conv/README.md b/tst/regression/test_suites/aniso_therm_cond_ring_conv/README.md index bfd8226d..8222148a 100644 --- a/tst/regression/test_suites/aniso_therm_cond_ring_conv/README.md +++ b/tst/regression/test_suites/aniso_therm_cond_ring_conv/README.md @@ -2,5 +2,5 @@ Executes 2D ring diffusion problem following Sharma & Hammett (2007) and calculates convergence rate. Errors are calculated based on comparison to steady state solution. -Convergence for this problem is not great, but matches other numbers reported in literate, e.g., Balsara, Tilley & Howk MNRAS (2008) doi:10.1111/j.1365-2966.2008.13085.x . +Convergence for this problem is not great, but matches other numbers reported in literature, e.g., Balsara, Tilley & Howk MNRAS (2008) doi:10.1111/j.1365-2966.2008.13085.x . Also the minium temperature is checked to ensure that limiting is working (i.e., the temperature is nowhere below the initial background temperature). From 72e2f4c384e00a8c681bca85b5df23d5ebb7d44f Mon Sep 17 00:00:00 2001 From: Ben Wibking Date: Thu, 22 Aug 2024 15:09:03 -0400 Subject: [PATCH 05/21] add dev container configuration --- .devcontainer/Dockerfile | 23 ++++++++++++++++++++++ .devcontainer/devcontainer.json | 35 +++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/devcontainer.json diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 00000000..b3f15860 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,23 @@ +FROM mcr.microsoft.com/devcontainers/cpp:ubuntu-24.04 + +RUN apt-get --yes -qq update \ + && apt-get --yes -qq upgrade \ + && apt-get --yes -qq install build-essential \ + git cmake clangd gcc g++ \ + python3-dev python3-numpy python3-matplotlib python3-pip \ + sphinx-doc python3-sphinx-rtd-theme python3-sphinxcontrib.bibtex python3-sphinx-copybutton \ + libopenmpi-dev \ + libhdf5-mpi-dev \ + && apt-get --yes -qq clean \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /home/ubuntu +USER ubuntu + +# install esbonio for Sphinx VSCode support (no Ubuntu package for this) +RUN pip install esbonio --break-system-packages + +# workaround Python babel bug +ENV TZ=UTC + +CMD [ "/bin/bash" ] \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..74cf0d3f --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,35 @@ +// devcontainer.json + { + "name": "athenapk-dev", + // (NOTE: using the cloud image is temporarily disabled, since it doesn't exist yet) + // "image": "ghcr.io/parthenon-hpc-lab/athenapk:main", + "build": { + // Path is relative to the devcontainer.json file. + "dockerfile": "Dockerfile" + }, + "hostRequirements": { + "cpus": 4 + }, + "customizations": { + "vscode": { + "settings": {}, + "extensions": [ + // disabled, since it interferes with clangd + "-ms-vscode.cpptools", + "llvm-vs-code-extensions.vscode-clangd", + "github.vscode-pull-request-github", + "ms-python.python", + "ms-toolsai.jupyter", + "ms-vscode.live-server", + "ms-azuretools.vscode-docker", + "swyddfa.esbonio", + "tomoki1207.pdf" // this extension does not work on codespaces + ] + } + }, + "remoteUser": "ubuntu", + // we need to manually checkout the submodules, + // but VSCode may try to configure CMake before they are fully checked-out. + // workaround TBD + "postCreateCommand": "git submodule update --init" + } From c7d74dcc0532997791cde23ed1dc8ccfa846cba2 Mon Sep 17 00:00:00 2001 From: Ben Wibking Date: Thu, 22 Aug 2024 20:32:42 +0000 Subject: [PATCH 06/21] add python packages --- .devcontainer/Dockerfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index b3f15860..a4763b08 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -4,7 +4,7 @@ RUN apt-get --yes -qq update \ && apt-get --yes -qq upgrade \ && apt-get --yes -qq install build-essential \ git cmake clangd gcc g++ \ - python3-dev python3-numpy python3-matplotlib python3-pip \ + python3-dev python3-numpy python3-matplotlib python3-pip python3-h5py \ sphinx-doc python3-sphinx-rtd-theme python3-sphinxcontrib.bibtex python3-sphinx-copybutton \ libopenmpi-dev \ libhdf5-mpi-dev \ @@ -17,6 +17,9 @@ USER ubuntu # install esbonio for Sphinx VSCode support (no Ubuntu package for this) RUN pip install esbonio --break-system-packages +# install unyt +RUN pip install unyt --break-system-packages + # workaround Python babel bug ENV TZ=UTC From 08a291294e03c9435f02d58488ac54d0d8e1686a Mon Sep 17 00:00:00 2001 From: Ben Wibking Date: Fri, 23 Aug 2024 09:36:00 -0400 Subject: [PATCH 07/21] use pre-built CI image --- .devcontainer/devcontainer.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 74cf0d3f..844f49da 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,12 +1,12 @@ // devcontainer.json { "name": "athenapk-dev", - // (NOTE: using the cloud image is temporarily disabled, since it doesn't exist yet) - // "image": "ghcr.io/parthenon-hpc-lab/athenapk:main", - "build": { - // Path is relative to the devcontainer.json file. - "dockerfile": "Dockerfile" - }, + "image": "ghcr.io/parthenon-hpc-lab/cuda11.6-mpi-hdf5-ascent", + // disable Dockerfile for now + //"build": { + // // Path is relative to the devcontainer.json file. + // "dockerfile": "Dockerfile" + //}, "hostRequirements": { "cpus": 4 }, From 589b510c92f84b9e30222c9e266969fa4e32cd2b Mon Sep 17 00:00:00 2001 From: Ben Wibking Date: Fri, 23 Aug 2024 09:38:07 -0400 Subject: [PATCH 08/21] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 47b1e93d..877ed247 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ ### Fixed (not changing behavior/API/variables/...) ### Infrastructure +- [[PR 112]](https://github.com/parthenon-hpc-lab/athenapk/pull/112) Add dev container configuration - [[PR 105]](https://github.com/parthenon-hpc-lab/athenapk/pull/105) Bump Parthenon to latest develop (2024-03-13) - [[PR 84]](https://github.com/parthenon-hpc-lab/athenapk/pull/84) Added `CHANGELOG.md` From 4bf55f0829f77d65e23d8a85cca03da1208cd657 Mon Sep 17 00:00:00 2001 From: Ben Wibking Date: Fri, 23 Aug 2024 09:43:36 -0400 Subject: [PATCH 09/21] Update development.md --- docs/development.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/development.md b/docs/development.md index 8133ef6b..dcb1885d 100644 --- a/docs/development.md +++ b/docs/development.md @@ -7,3 +7,9 @@ All pull requests are checked automatically if the code is properly formatted. The build target `format-athenapk` calls both formatters and automatically format all changes, i.e., before committing changes simply call `make format-athenapk` (or similar). Alternatively, leave a comment with `@par-hermes format` in the open pull request to format the code directly on GitHub. + +## Dev container + +You can open a [GitHub Codespace](https://docs.github.com/en/codespaces) or use VSCode to automatically open local Docker container using the CUDA CI container image. + +If you have the [VSCode Dev Container extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) installed, on opening this repository in VSCode, it will automatically prompt to ask if you want to re-open this repository in a container. From 39d041e8e04ad2642d781c0c5e2b5722fb8eabd9 Mon Sep 17 00:00:00 2001 From: Ben Wibking Date: Fri, 23 Aug 2024 13:53:54 +0000 Subject: [PATCH 10/21] run as root inside the container? --- .devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 844f49da..8cc942bf 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -27,7 +27,7 @@ ] } }, - "remoteUser": "ubuntu", + //"remoteUser": "ubuntu", // we need to manually checkout the submodules, // but VSCode may try to configure CMake before they are fully checked-out. // workaround TBD From e1dc45afcba1ae488e2d704c8a3e1a4029ae71c9 Mon Sep 17 00:00:00 2001 From: Ben Wibking Date: Fri, 23 Aug 2024 14:12:41 +0000 Subject: [PATCH 11/21] add hdf5-parallel path to PATH --- .devcontainer/devcontainer.json | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 8cc942bf..af983463 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -14,7 +14,6 @@ "vscode": { "settings": {}, "extensions": [ - // disabled, since it interferes with clangd "-ms-vscode.cpptools", "llvm-vs-code-extensions.vscode-clangd", "github.vscode-pull-request-github", @@ -23,10 +22,14 @@ "ms-vscode.live-server", "ms-azuretools.vscode-docker", "swyddfa.esbonio", - "tomoki1207.pdf" // this extension does not work on codespaces - ] + "tomoki1207.pdf", + "ms-vscode.cmake-tools" + ] } }, + "remoteEnv": { + "PATH": "${containerEnv:PATH}:/usr/local/hdf5/parallel/bin" + }, //"remoteUser": "ubuntu", // we need to manually checkout the submodules, // but VSCode may try to configure CMake before they are fully checked-out. From c0d9031bddfafde373481768702c54accb9cdb30 Mon Sep 17 00:00:00 2001 From: Ben Wibking Date: Fri, 23 Aug 2024 14:20:30 +0000 Subject: [PATCH 12/21] set MCA param to avoid libcuda warning --- .devcontainer/devcontainer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index af983463..c5080293 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -28,7 +28,8 @@ } }, "remoteEnv": { - "PATH": "${containerEnv:PATH}:/usr/local/hdf5/parallel/bin" + "PATH": "${containerEnv:PATH}:/usr/local/hdf5/parallel/bin", + "OMPI_MCA_opal_warn_on_missing_libcuda": "0" }, //"remoteUser": "ubuntu", // we need to manually checkout the submodules, From 53c5b6cf40b9db854c7143ee2daf54464cbc83b1 Mon Sep 17 00:00:00 2001 From: Ben Wibking Date: Fri, 23 Aug 2024 14:23:04 +0000 Subject: [PATCH 13/21] remove Dockerfile --- .devcontainer/Dockerfile | 26 -------------------------- 1 file changed, 26 deletions(-) delete mode 100644 .devcontainer/Dockerfile diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile deleted file mode 100644 index a4763b08..00000000 --- a/.devcontainer/Dockerfile +++ /dev/null @@ -1,26 +0,0 @@ -FROM mcr.microsoft.com/devcontainers/cpp:ubuntu-24.04 - -RUN apt-get --yes -qq update \ - && apt-get --yes -qq upgrade \ - && apt-get --yes -qq install build-essential \ - git cmake clangd gcc g++ \ - python3-dev python3-numpy python3-matplotlib python3-pip python3-h5py \ - sphinx-doc python3-sphinx-rtd-theme python3-sphinxcontrib.bibtex python3-sphinx-copybutton \ - libopenmpi-dev \ - libhdf5-mpi-dev \ - && apt-get --yes -qq clean \ - && rm -rf /var/lib/apt/lists/* - -WORKDIR /home/ubuntu -USER ubuntu - -# install esbonio for Sphinx VSCode support (no Ubuntu package for this) -RUN pip install esbonio --break-system-packages - -# install unyt -RUN pip install unyt --break-system-packages - -# workaround Python babel bug -ENV TZ=UTC - -CMD [ "/bin/bash" ] \ No newline at end of file From 76d9e95c39859be257940ca6c58b5d3dffb8df28 Mon Sep 17 00:00:00 2001 From: Ben Wibking Date: Fri, 23 Aug 2024 16:28:29 +0000 Subject: [PATCH 14/21] add Live Share extension --- .devcontainer/devcontainer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index c5080293..9341352d 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -23,7 +23,8 @@ "ms-azuretools.vscode-docker", "swyddfa.esbonio", "tomoki1207.pdf", - "ms-vscode.cmake-tools" + "ms-vscode.cmake-tools", + "ms-vsliveshare.vsliveshare" ] } }, From 47eb79b79f211a7a3d137ca4a0e20ccff6956b60 Mon Sep 17 00:00:00 2001 From: Philipp Grete Date: Thu, 29 Aug 2024 13:33:18 +0200 Subject: [PATCH 15/21] Remove SD cooling table due to unclear origin/derivation --- .../cooling_tables/sutherland_dopita.cooling | 782 ------------------ 1 file changed, 782 deletions(-) delete mode 100644 inputs/cooling_tables/sutherland_dopita.cooling diff --git a/inputs/cooling_tables/sutherland_dopita.cooling b/inputs/cooling_tables/sutherland_dopita.cooling deleted file mode 100644 index 5e329103..00000000 --- a/inputs/cooling_tables/sutherland_dopita.cooling +++ /dev/null @@ -1,782 +0,0 @@ -# Cooling table for solar metallicity, 1/3 solar metallicity -# (adapted from PLUTO code by Deovrat Prasad) -# temperature log(K), cooling rate/ne^3 (erg cm^3/s) -# This is the cooling table based on Sutherland & Dopita (1993), ApJ, 88, 253 -# logT 1/3 solar 1 solar -3.0064233e+00 -2.4478679e+01 -2.4024876e+01 -3.0154017e+00 -2.4475474e+01 -2.4022199e+01 -3.0244036e+00 -2.4472293e+01 -2.4019538e+01 -3.0333835e+00 -2.4469109e+01 -2.4016884e+01 -3.0424180e+00 -2.4465936e+01 -2.4014241e+01 -3.0513841e+00 -2.4462760e+01 -2.4011606e+01 -3.0603956e+00 -2.4459595e+01 -2.4008978e+01 -3.0694091e+00 -2.4456416e+01 -2.4006361e+01 -3.0783843e+00 -2.4453248e+01 -2.4003747e+01 -3.0873909e+00 -2.4450078e+01 -2.4001139e+01 -3.0963885e+00 -2.4446918e+01 -2.3998526e+01 -3.1053739e+00 -2.4443746e+01 -2.3995937e+01 -3.1143774e+00 -2.4440572e+01 -2.3993363e+01 -3.1233616e+00 -2.4437398e+01 -2.3990762e+01 -3.1323878e+00 -2.4434223e+01 -2.3988176e+01 -3.1413557e+00 -2.4431036e+01 -2.3985563e+01 -3.1503573e+00 -2.4427861e+01 -2.3983008e+01 -3.1593566e+00 -2.4424662e+01 -2.3980427e+01 -3.1683501e+00 -2.4421464e+01 -2.3977819e+01 -3.1773633e+00 -2.4418266e+01 -2.3975227e+01 -3.1863629e+00 -2.4415036e+01 -2.3972610e+01 -3.1953461e+00 -2.4411818e+01 -2.3970008e+01 -3.2043642e+00 -2.4408568e+01 -2.3967381e+01 -3.2133584e+00 -2.4405320e+01 -2.3964770e+01 -3.2223522e+00 -2.4402053e+01 -2.3962135e+01 -3.2313421e+00 -2.4398766e+01 -2.3959516e+01 -3.2403495e+00 -2.4395472e+01 -2.3956834e+01 -3.2493451e+00 -2.4392395e+01 -2.3954403e+01 -3.2583259e+00 -2.4388999e+01 -2.3951636e+01 -3.2673360e+00 -2.4385662e+01 -2.3948963e+01 -3.2763239e+00 -2.4382266e+01 -2.3946192e+01 -3.2853322e+00 -2.4378876e+01 -2.3943476e+01 -3.2943339e+00 -2.4375439e+01 -2.3940664e+01 -3.3033257e+00 -2.4371989e+01 -2.3937869e+01 -3.3123255e+00 -2.4368516e+01 -2.3935056e+01 -3.3213084e+00 -2.4365009e+01 -2.3932185e+01 -3.3303123e+00 -2.4361481e+01 -2.3929297e+01 -3.3393123e+00 -2.4357921e+01 -2.3926355e+01 -3.3483049e+00 -2.4354332e+01 -2.3923396e+01 -3.3573058e+00 -2.4350714e+01 -2.3920385e+01 -3.3663109e+00 -2.4347038e+01 -2.3917286e+01 -3.3752977e+00 -2.4343308e+01 -2.3914174e+01 -3.3842996e+00 -2.4339533e+01 -2.3910978e+01 -3.3932944e+00 -2.4335697e+01 -2.3907771e+01 -3.4022958e+00 -2.4331810e+01 -2.3904447e+01 -3.4112998e+00 -2.4327856e+01 -2.3901114e+01 -3.4202859e+00 -2.4323846e+01 -2.3897669e+01 -3.4292838e+00 -2.4319764e+01 -2.3894183e+01 -3.4382891e+00 -2.4315621e+01 -2.3890590e+01 -3.4472821e+00 -2.4311402e+01 -2.3886926e+01 -3.4562749e+00 -2.4307100e+01 -2.3883193e+01 -3.4652787e+00 -2.4302727e+01 -2.3879327e+01 -3.4742746e+00 -2.4298268e+01 -2.3875398e+01 -3.4832734e+00 -2.4293726e+01 -2.3871375e+01 -3.4922714e+00 -2.4289088e+01 -2.3867228e+01 -3.5012647e+00 -2.4284364e+01 -2.3862963e+01 -3.5102634e+00 -2.4279535e+01 -2.3858582e+01 -3.5192634e+00 -2.4274595e+01 -2.3854089e+01 -3.5282609e+00 -2.4269557e+01 -2.3849458e+01 -3.5372523e+00 -2.4264401e+01 -2.3844694e+01 -3.5462465e+00 -2.4259124e+01 -2.3839802e+01 -3.5552517e+00 -2.4253732e+01 -2.3834756e+01 -3.5642517e+00 -2.4248221e+01 -2.3829533e+01 -3.5732430e+00 -2.4242574e+01 -2.3824169e+01 -3.5822452e+00 -2.4236774e+01 -2.3818642e+01 -3.5912427e+00 -2.4230837e+01 -2.3812902e+01 -3.6002321e+00 -2.4224746e+01 -2.3807015e+01 -3.6092315e+00 -2.4218503e+01 -2.3800931e+01 -3.6182260e+00 -2.4212100e+01 -2.3794633e+01 -3.6272327e+00 -2.4205533e+01 -2.3788132e+01 -3.6362270e+00 -2.4198795e+01 -2.3781438e+01 -3.6452257e+00 -2.4190723e+01 -2.3773117e+01 -3.6542247e+00 -2.4183447e+01 -2.3765787e+01 -3.6632202e+00 -2.4175972e+01 -2.3758180e+01 -3.6722180e+00 -2.4168277e+01 -2.3750313e+01 -3.6812141e+00 -2.4160359e+01 -2.3742153e+01 -3.6902049e+00 -2.4152205e+01 -2.3733745e+01 -3.6992045e+00 -2.4143815e+01 -2.3725034e+01 -3.7081999e+00 -2.4135175e+01 -2.3716021e+01 -3.7172043e+00 -2.4126273e+01 -2.3706682e+01 -3.7261973e+00 -2.4117100e+01 -2.3697042e+01 -3.7351995e+00 -2.4107638e+01 -2.3687040e+01 -3.7441912e+00 -2.4097872e+01 -2.3676686e+01 -3.7531922e+00 -2.4087778e+01 -2.3665949e+01 -3.7621907e+00 -2.4077342e+01 -2.3654803e+01 -3.7711831e+00 -2.4066538e+01 -2.3643248e+01 -3.7801804e+00 -2.4055340e+01 -2.3631248e+01 -3.7891787e+00 -2.4043711e+01 -2.3618777e+01 -3.7981809e+00 -2.4031629e+01 -2.3605794e+01 -3.8071764e+00 -2.4019047e+01 -2.3592286e+01 -3.8161750e+00 -2.4005943e+01 -2.3578248e+01 -3.8251729e+00 -2.3992252e+01 -2.3563631e+01 -3.8341663e+00 -2.3977984e+01 -2.3548428e+01 -3.8431642e+00 -2.3963012e+01 -2.3532614e+01 -3.8521627e+00 -2.3947421e+01 -2.3516284e+01 -3.8611579e+00 -2.3930924e+01 -2.3499160e+01 -3.8701580e+00 -2.3913533e+01 -2.3481302e+01 -3.8791532e+00 -2.3895103e+01 -2.3462697e+01 -3.8881514e+00 -2.3875561e+01 -2.3443275e+01 -3.8971486e+00 -2.3854773e+01 -2.3423014e+01 -3.9061464e+00 -2.3832535e+01 -2.3401844e+01 -3.9151412e+00 -2.3808773e+01 -2.3379729e+01 -3.9241397e+00 -2.3783254e+01 -2.3356616e+01 -3.9331379e+00 -2.3755896e+01 -2.3332482e+01 -3.9421371e+00 -2.3726466e+01 -2.3307285e+01 -3.9511334e+00 -2.3694864e+01 -2.3280984e+01 -3.9601282e+00 -2.3660946e+01 -2.3253560e+01 -3.9691269e+00 -2.3626886e+01 -2.3227869e+01 -3.9781257e+00 -2.3587976e+01 -2.3198123e+01 -3.9871208e+00 -2.3546269e+01 -2.3166898e+01 -3.9961175e+00 -2.3501855e+01 -2.3134280e+01 -4.0051376e+00 -2.3455015e+01 -2.3100163e+01 -4.0141003e+00 -2.3405099e+01 -2.3064503e+01 -4.0231289e+00 -2.3352686e+01 -2.3027274e+01 -4.0320947e+00 -2.3297880e+01 -2.2988430e+01 -4.0411162e+00 -2.3240884e+01 -2.2947999e+01 -4.0501090e+00 -2.3181926e+01 -2.2905878e+01 -4.0591088e+00 -2.3121266e+01 -2.2862203e+01 -4.0681116e+00 -2.3059200e+01 -2.2816987e+01 -4.0771134e+00 -2.2996066e+01 -2.2770446e+01 -4.0861106e+00 -2.2932111e+01 -2.2722437e+01 -4.0950996e+00 -2.2867676e+01 -2.2673234e+01 -4.1040772e+00 -2.2803078e+01 -2.2623022e+01 -4.1130739e+00 -2.2738642e+01 -2.2572076e+01 -4.1220848e+00 -2.2674649e+01 -2.2520338e+01 -4.1310730e+00 -2.2611686e+01 -2.2468726e+01 -4.1400679e+00 -2.2550013e+01 -2.2417221e+01 -4.1490651e+00 -2.2490233e+01 -2.2366521e+01 -4.1580608e+00 -2.2432797e+01 -2.2317025e+01 -4.1670809e+00 -2.2378325e+01 -2.2269347e+01 -4.1760623e+00 -2.2327505e+01 -2.2224026e+01 -4.1850603e+00 -2.2281067e+01 -2.2182091e+01 -4.1940701e+00 -2.2239615e+01 -2.2144202e+01 -4.2030601e+00 -2.2167274e+01 -2.2083372e+01 -4.2120544e+00 -2.2127989e+01 -2.2046956e+01 -4.2210489e+00 -2.2094112e+01 -2.2015099e+01 -4.2300400e+00 -2.2065896e+01 -2.1988134e+01 -4.2390491e+00 -2.2043452e+01 -2.1966134e+01 -4.2480469e+00 -2.2026484e+01 -2.1948616e+01 -4.2570543e+00 -2.2015104e+01 -2.1936291e+01 -4.2660434e+00 -2.2008663e+01 -2.1928228e+01 -4.2750348e+00 -2.2006595e+01 -2.1923906e+01 -4.2840245e+00 -2.2008278e+01 -2.1922741e+01 -4.2930309e+00 -2.2013094e+01 -2.1924088e+01 -4.3020277e+00 -2.2020433e+01 -2.1927383e+01 -4.3110330e+00 -2.2029751e+01 -2.1932111e+01 -4.3200216e+00 -2.2040544e+01 -2.1937719e+01 -4.3290316e+00 -2.2052380e+01 -2.1943820e+01 -4.3380180e+00 -2.2064886e+01 -2.1950085e+01 -4.3470176e+00 -2.2077737e+01 -2.1956206e+01 -4.3560067e+00 -2.2090658e+01 -2.1961976e+01 -4.3650197e+00 -2.2103413e+01 -2.1967140e+01 -4.3740147e+00 -2.2115805e+01 -2.1971591e+01 -4.3830070e+00 -2.2127646e+01 -2.1975145e+01 -4.3920107e+00 -2.2138812e+01 -2.1977819e+01 -4.4010040e+00 -2.2149188e+01 -2.1979473e+01 -4.4100007e+00 -2.2158641e+01 -2.1980053e+01 -4.4189969e+00 -2.2167095e+01 -2.1979556e+01 -4.4279889e+00 -2.2174515e+01 -2.1977984e+01 -4.4369891e+00 -2.2180693e+01 -2.1974981e+01 -4.4459932e+00 -2.2185926e+01 -2.1971225e+01 -4.4549820e+00 -2.2190265e+01 -2.1966616e+01 -4.4639825e+00 -2.2193298e+01 -2.1961141e+01 -4.4729757e+00 -2.2194723e+01 -2.1954325e+01 -4.4819726e+00 -2.2195200e+01 -2.1946614e+01 -4.4909693e+00 -2.2195186e+01 -2.1938246e+01 -4.4999756e+00 -2.2194812e+01 -2.1929408e+01 -4.5089739e+00 -2.2193698e+01 -2.1919987e+01 -4.5179608e+00 -2.2192025e+01 -2.1910024e+01 -4.5269593e+00 -2.2190427e+01 -2.1899871e+01 -4.5359647e+00 -2.2188217e+01 -2.1889208e+01 -4.5449605e+00 -2.2185593e+01 -2.1878210e+01 -4.5539558e+00 -2.2182494e+01 -2.1866749e+01 -4.5629587e+00 -2.2179615e+01 -2.1855332e+01 -4.5719533e+00 -2.2175451e+01 -2.1843178e+01 -4.5809478e+00 -2.2171585e+01 -2.1831120e+01 -4.5899496e+00 -2.2166929e+01 -2.1818614e+01 -4.5989436e+00 -2.2161132e+01 -2.1805541e+01 -4.6079373e+00 -2.2155510e+01 -2.1792527e+01 -4.6169374e+00 -2.2148925e+01 -2.1778977e+01 -4.6259295e+00 -2.2141120e+01 -2.1764876e+01 -4.6349305e+00 -2.2133217e+01 -2.1750655e+01 -4.6439262e+00 -2.2123996e+01 -2.1735914e+01 -4.6529229e+00 -2.2114147e+01 -2.1720858e+01 -4.6619262e+00 -2.2103518e+01 -2.1705468e+01 -4.6709228e+00 -2.2092030e+01 -2.1689732e+01 -4.6799182e+00 -2.2079835e+01 -2.1673849e+01 -4.6889179e+00 -2.2066619e+01 -2.1657459e+01 -4.6979090e+00 -2.2052522e+01 -2.1640753e+01 -4.7069140e+00 -2.2034963e+01 -2.1622767e+01 -4.7159115e+00 -2.2018172e+01 -2.1605128e+01 -4.7249064e+00 -2.2001183e+01 -2.1587472e+01 -4.7339031e+00 -2.1983301e+01 -2.1569538e+01 -4.7428979e+00 -2.1964530e+01 -2.1551340e+01 -4.7518947e+00 -2.1944966e+01 -2.1532940e+01 -4.7608972e+00 -2.1924599e+01 -2.1514293e+01 -4.7698940e+00 -2.1903368e+01 -2.1495407e+01 -4.7788889e+00 -2.1881636e+01 -2.1476423e+01 -4.7878854e+00 -2.1859461e+01 -2.1457336e+01 -4.7968864e+00 -2.1836928e+01 -2.1438231e+01 -4.8058813e+00 -2.1814005e+01 -2.1419440e+01 -4.8148799e+00 -2.1791021e+01 -2.1400455e+01 -4.8238783e+00 -2.1768097e+01 -2.1381638e+01 -4.8328728e+00 -2.1745404e+01 -2.1363071e+01 -4.8418723e+00 -2.1723492e+01 -2.1345025e+01 -4.8508667e+00 -2.1702480e+01 -2.1327560e+01 -4.8598645e+00 -2.1682564e+01 -2.1310789e+01 -4.8688618e+00 -2.1664301e+01 -2.1294975e+01 -4.8778607e+00 -2.1646892e+01 -2.1279708e+01 -4.8868572e+00 -2.1630933e+01 -2.1265296e+01 -4.8958533e+00 -2.1616400e+01 -2.1251711e+01 -4.9048507e+00 -2.1603260e+01 -2.1238922e+01 -4.9138509e+00 -2.1591573e+01 -2.1226923e+01 -4.9228448e+00 -2.1581053e+01 -2.1215682e+01 -4.9318442e+00 -2.1571703e+01 -2.1205205e+01 -4.9408401e+00 -2.1563456e+01 -2.1195499e+01 -4.9498387e+00 -2.1556236e+01 -2.1186613e+01 -4.9588361e+00 -2.1550013e+01 -2.1178585e+01 -4.9678334e+00 -2.1544759e+01 -2.1171495e+01 -4.9768312e+00 -2.1540487e+01 -2.1165427e+01 -4.9858305e+00 -2.1537153e+01 -2.1160434e+01 -4.9948273e+00 -2.1534781e+01 -2.1156593e+01 -5.0038051e+00 -2.1533607e+01 -2.1154226e+01 -5.0128372e+00 -2.1533088e+01 -2.1152717e+01 -5.0218093e+00 -2.1534558e+01 -2.1152748e+01 -5.0308020e+00 -2.1535898e+01 -2.1153484e+01 -5.0398106e+00 -2.1537452e+01 -2.1154747e+01 -5.0487913e+00 -2.1539343e+01 -2.1156512e+01 -5.0578182e+00 -2.1541241e+01 -2.1158515e+01 -5.0668103e+00 -2.1543163e+01 -2.1160491e+01 -5.0758024e+00 -2.1544820e+01 -2.1162191e+01 -5.0847907e+00 -2.1546070e+01 -2.1163423e+01 -5.0938068e+00 -2.1546789e+01 -2.1164031e+01 -5.1028109e+00 -2.1546911e+01 -2.1163929e+01 -5.1118000e+00 -2.1546422e+01 -2.1163075e+01 -5.1208042e+00 -2.1545308e+01 -2.1161472e+01 -5.1297865e+00 -2.1543619e+01 -2.1159167e+01 -5.1387762e+00 -2.1541407e+01 -2.1156232e+01 -5.1477690e+00 -2.1538757e+01 -2.1152761e+01 -5.1567914e+00 -2.1535734e+01 -2.1148840e+01 -5.1657783e+00 -2.1532436e+01 -2.1144596e+01 -5.1747864e+00 -2.1528958e+01 -2.1140123e+01 -5.1837822e+00 -2.1525361e+01 -2.1135530e+01 -5.1927625e+00 -2.1521765e+01 -2.1130933e+01 -5.2017521e+00 -2.1518214e+01 -2.1126412e+01 -5.2107732e+00 -2.1514804e+01 -2.1122059e+01 -5.2197678e+00 -2.1511576e+01 -2.1117937e+01 -5.2287596e+00 -2.1508582e+01 -2.1114091e+01 -5.2377448e+00 -2.1505818e+01 -2.1110536e+01 -5.2467447e+00 -2.1503306e+01 -2.1107266e+01 -5.2557548e+00 -2.1501001e+01 -2.1104241e+01 -5.2647470e+00 -2.1498872e+01 -2.1101412e+01 -5.2737418e+00 -2.1496863e+01 -2.1098705e+01 -5.2827354e+00 -2.1498982e+01 -2.1097671e+01 -5.2917461e+00 -2.1496809e+01 -2.1094911e+01 -5.3007259e+00 -2.1494606e+01 -2.1092116e+01 -5.3097366e+00 -2.1492414e+01 -2.1089296e+01 -5.3187310e+00 -2.1490273e+01 -2.1086483e+01 -5.3277267e+00 -2.1488237e+01 -2.1083751e+01 -5.3367198e+00 -2.1486370e+01 -2.1081205e+01 -5.3457265e+00 -2.1484802e+01 -2.1078969e+01 -5.3547229e+00 -2.1483663e+01 -2.1077223e+01 -5.3637248e+00 -2.1483108e+01 -2.1076160e+01 -5.3727095e+00 -2.1483332e+01 -2.1076016e+01 -5.3817106e+00 -2.1484550e+01 -2.1077057e+01 -5.3907055e+00 -2.1486982e+01 -2.1079558e+01 -5.3997083e+00 -2.1490878e+01 -2.1083825e+01 -5.4086978e+00 -2.1496482e+01 -2.1090145e+01 -5.4177041e+00 -2.1503970e+01 -2.1098787e+01 -5.4267064e+00 -2.1513499e+01 -2.1109954e+01 -5.4357011e+00 -2.1525158e+01 -2.1123759e+01 -5.4447004e+00 -2.1538907e+01 -2.1140219e+01 -5.4536852e+00 -2.1554614e+01 -2.1159198e+01 -5.4626824e+00 -2.1572011e+01 -2.1180423e+01 -5.4716877e+00 -2.1590743e+01 -2.1203502e+01 -5.4806823e+00 -2.1610409e+01 -2.1227935e+01 -5.4896773e+00 -2.1630580e+01 -2.1253187e+01 -5.4986826e+00 -2.1650781e+01 -2.1278692e+01 -5.5076805e+00 -2.1670643e+01 -2.1303932e+01 -5.5166676e+00 -2.1689838e+01 -2.1328438e+01 -5.5256666e+00 -2.1708121e+01 -2.1351845e+01 -5.5346733e+00 -2.1725311e+01 -2.1373855e+01 -5.5436708e+00 -2.1741315e+01 -2.1394286e+01 -5.5526682e+00 -2.1756218e+01 -2.1413087e+01 -5.5616618e+00 -2.1769628e+01 -2.1429994e+01 -5.5706597e+00 -2.1782095e+01 -2.1445293e+01 -5.5796579e+00 -2.1793147e+01 -2.1458745e+01 -5.5886526e+00 -2.1803382e+01 -2.1470685e+01 -5.5976513e+00 -2.1812479e+01 -2.1481013e+01 -5.6066500e+00 -2.1820879e+01 -2.1490018e+01 -5.6156450e+00 -2.1828303e+01 -2.1497641e+01 -5.6246430e+00 -2.1835053e+01 -2.1504151e+01 -5.6336401e+00 -2.1841065e+01 -2.1509592e+01 -5.6426327e+00 -2.1846551e+01 -2.1514165e+01 -5.6516365e+00 -2.1851613e+01 -2.1518013e+01 -5.6606284e+00 -2.1856298e+01 -2.1521289e+01 -5.6696237e+00 -2.1860751e+01 -2.1524155e+01 -5.6786276e+00 -2.1865090e+01 -2.1526747e+01 -5.6876181e+00 -2.1869377e+01 -2.1529251e+01 -5.6966185e+00 -2.1873739e+01 -2.1531830e+01 -5.7056157e+00 -2.1879294e+01 -2.1535108e+01 -5.7146147e+00 -2.1885389e+01 -2.1538862e+01 -5.7236116e+00 -2.1891841e+01 -2.1543179e+01 -5.7326109e+00 -2.1898769e+01 -2.1548214e+01 -5.7416085e+00 -2.1906333e+01 -2.1554085e+01 -5.7506010e+00 -2.1914531e+01 -2.1560888e+01 -5.7595999e+00 -2.1923396e+01 -2.1568652e+01 -5.7686011e+00 -2.1932929e+01 -2.1577312e+01 -5.7775935e+00 -2.1943019e+01 -2.1586751e+01 -5.7865953e+00 -2.1953544e+01 -2.1596742e+01 -5.7955881e+00 -2.1964250e+01 -2.1607004e+01 -5.8045892e+00 -2.1974899e+01 -2.1617191e+01 -5.8135877e+00 -2.1985311e+01 -2.1627033e+01 -5.8225799e+00 -2.1995249e+01 -2.1636256e+01 -5.8315819e+00 -2.2004571e+01 -2.1644625e+01 -5.8405765e+00 -2.2013197e+01 -2.1652007e+01 -5.8495730e+00 -2.2021062e+01 -2.1658368e+01 -5.8585733e+00 -2.2028172e+01 -2.1663700e+01 -5.8675677e+00 -2.2034573e+01 -2.1668107e+01 -5.8765642e+00 -2.2040324e+01 -2.1671661e+01 -5.8855647e+00 -2.2045526e+01 -2.1674525e+01 -5.8945597e+00 -2.2050278e+01 -2.1676851e+01 -5.9035566e+00 -2.2054689e+01 -2.1678754e+01 -5.9125568e+00 -2.2058861e+01 -2.1680436e+01 -5.9215512e+00 -2.2062909e+01 -2.1681999e+01 -5.9305517e+00 -2.2066923e+01 -2.1683589e+01 -5.9395492e+00 -2.2071005e+01 -2.1685332e+01 -5.9485450e+00 -2.2075230e+01 -2.1687336e+01 -5.9575450e+00 -2.2079673e+01 -2.1689689e+01 -5.9665406e+00 -2.2084379e+01 -2.1692440e+01 -5.9755375e+00 -2.2089386e+01 -2.1695617e+01 -5.9845363e+00 -2.2094701e+01 -2.1699252e+01 -5.9935332e+00 -2.2100305e+01 -2.1703313e+01 -6.0025116e+00 -2.2106177e+01 -2.1707744e+01 -6.0115282e+00 -2.2112265e+01 -2.1712489e+01 -6.0205270e+00 -2.2118518e+01 -2.1717469e+01 -6.0295055e+00 -2.2124158e+01 -2.1722368e+01 -6.0385009e+00 -2.2131009e+01 -2.1727787e+01 -6.0475085e+00 -2.2137773e+01 -2.1733228e+01 -6.0565237e+00 -2.2144463e+01 -2.1738666e+01 -6.0655050e+00 -2.2151054e+01 -2.1744028e+01 -6.0745239e+00 -2.2157541e+01 -2.1749336e+01 -6.0835026e+00 -2.2163936e+01 -2.1754586e+01 -6.0925101e+00 -2.2170253e+01 -2.1759825e+01 -6.1015065e+00 -2.2176513e+01 -2.1765027e+01 -6.1104887e+00 -2.2182745e+01 -2.1770267e+01 -6.1194868e+00 -2.2188995e+01 -2.1775571e+01 -6.1284962e+00 -2.2195309e+01 -2.1781018e+01 -6.1374807e+00 -2.2201736e+01 -2.1786668e+01 -6.1465001e+00 -2.2208344e+01 -2.1792554e+01 -6.1554879e+00 -2.2215190e+01 -2.1798794e+01 -6.1644718e+00 -2.2222334e+01 -2.1805458e+01 -6.1734776e+00 -2.2229848e+01 -2.1812592e+01 -6.1824717e+00 -2.2237802e+01 -2.1820305e+01 -6.1914790e+00 -2.2246241e+01 -2.1828654e+01 -6.2004674e+00 -2.2255230e+01 -2.1837704e+01 -6.2094614e+00 -2.2264824e+01 -2.1847498e+01 -6.2184567e+00 -2.2275061e+01 -2.1858143e+01 -6.2274753e+00 -2.2285972e+01 -2.1869666e+01 -6.2364617e+00 -2.2297595e+01 -2.1882099e+01 -6.2454633e+00 -2.2309955e+01 -2.1895479e+01 -6.2544514e+00 -2.2323050e+01 -2.1909777e+01 -6.2634467e+00 -2.2336884e+01 -2.1925110e+01 -6.2724450e+00 -2.2351425e+01 -2.1941346e+01 -6.2814425e+00 -2.2366622e+01 -2.1958489e+01 -6.2904353e+00 -2.2382413e+01 -2.1976459e+01 -6.2994419e+00 -2.2398712e+01 -2.1995163e+01 -6.3084363e+00 -2.2415409e+01 -2.2014520e+01 -6.3174365e+00 -2.2432409e+01 -2.2034361e+01 -6.3264383e+00 -2.2449576e+01 -2.2054571e+01 -6.3354378e+00 -2.2466813e+01 -2.2075023e+01 -6.3444316e+00 -2.2484020e+01 -2.2095609e+01 -6.3534353e+00 -2.2501097e+01 -2.2116219e+01 -6.3624259e+00 -2.2518070e+01 -2.2136820e+01 -6.3714189e+00 -2.2534573e+01 -2.2157197e+01 -6.3804102e+00 -2.2551186e+01 -2.2177551e+01 -6.3894142e+00 -2.2567223e+01 -2.2197548e+01 -6.3984088e+00 -2.2582944e+01 -2.2217226e+01 -6.4074079e+00 -2.2598117e+01 -2.2236467e+01 -6.4164075e+00 -2.2612806e+01 -2.2255191e+01 -6.4254038e+00 -2.2626922e+01 -2.2273322e+01 -6.4344092e+00 -2.2640430e+01 -2.2290798e+01 -6.4434038e+00 -2.2653315e+01 -2.2307567e+01 -6.4523998e+00 -2.2665566e+01 -2.2323608e+01 -6.4613935e+00 -2.2677161e+01 -2.2338898e+01 -6.4703958e+00 -2.2688077e+01 -2.2353390e+01 -6.4793881e+00 -2.2698406e+01 -2.2367168e+01 -6.4883815e+00 -2.2708121e+01 -2.2380218e+01 -6.4973858e+00 -2.2717242e+01 -2.2392524e+01 -6.5063833e+00 -2.2725796e+01 -2.2404129e+01 -6.5153837e+00 -2.2733792e+01 -2.2415047e+01 -6.5243831e+00 -2.2741291e+01 -2.2425309e+01 -6.5333780e+00 -2.2748240e+01 -2.2434884e+01 -6.5423772e+00 -2.2754685e+01 -2.2443806e+01 -6.5513646e+00 -2.2760625e+01 -2.2452102e+01 -6.5603610e+00 -2.2766091e+01 -2.2459733e+01 -6.5693622e+00 -2.2770958e+01 -2.2466686e+01 -6.5783641e+00 -2.2775622e+01 -2.2473170e+01 -6.5873629e+00 -2.2779604e+01 -2.2478940e+01 -6.5963551e+00 -2.2783412e+01 -2.2484232e+01 -6.6053482e+00 -2.2786535e+01 -2.2488839e+01 -6.6143487e+00 -2.2789521e+01 -2.2493049e+01 -6.6233527e+00 -2.2791908e+01 -2.2496632e+01 -6.6323459e+00 -2.2794173e+01 -2.2499805e+01 -6.6413452e+00 -2.2795826e+01 -2.2502448e+01 -6.6503367e+00 -2.2797430e+01 -2.2504789e+01 -6.6593361e+00 -2.2798521e+01 -2.2506626e+01 -6.6683300e+00 -2.2799560e+01 -2.2508190e+01 -6.6773332e+00 -2.2800135e+01 -2.2509311e+01 -6.6863323e+00 -2.2800656e+01 -2.2510224e+01 -6.6953240e+00 -2.2800739e+01 -2.2510717e+01 -6.7043221e+00 -2.2800848e+01 -2.2511055e+01 -6.7133225e+00 -2.2800547e+01 -2.2511055e+01 -6.7223212e+00 -2.2800245e+01 -2.2510900e+01 -6.7313147e+00 -2.2799587e+01 -2.2510463e+01 -6.7403153e+00 -2.2798958e+01 -2.2509901e+01 -6.7493111e+00 -2.2798057e+01 -2.2509143e+01 -6.7583062e+00 -2.2797212e+01 -2.2508372e+01 -6.7673043e+00 -2.2796097e+01 -2.2507407e+01 -6.7763016e+00 -2.2795039e+01 -2.2506430e+01 -6.7853014e+00 -2.2793795e+01 -2.2505345e+01 -6.7942998e+00 -2.2792635e+01 -2.2504289e+01 -6.8032932e+00 -2.2791290e+01 -2.2503167e+01 -6.8122915e+00 -2.2790083e+01 -2.2502158e+01 -6.8212908e+00 -2.2788719e+01 -2.2501097e+01 -6.8302871e+00 -2.2787546e+01 -2.2500230e+01 -6.8392832e+00 -2.2786217e+01 -2.2499297e+01 -6.8482815e+00 -2.2785024e+01 -2.2498544e+01 -6.8572782e+00 -2.2783755e+01 -2.2497819e+01 -6.8662755e+00 -2.2782648e+01 -2.2497259e+01 -6.8752755e+00 -2.2781464e+01 -2.2496754e+01 -6.8842685e+00 -2.2780442e+01 -2.2496454e+01 -6.8932678e+00 -2.2779343e+01 -2.2496209e+01 -6.9022640e+00 -2.2778429e+01 -2.2496168e+01 -6.9112642e+00 -2.2777466e+01 -2.2496209e+01 -6.9202590e+00 -2.2776660e+01 -2.2496468e+01 -6.9292554e+00 -2.2775830e+01 -2.2496795e+01 -6.9382545e+00 -2.2775105e+01 -2.2497341e+01 -6.9472523e+00 -2.2774536e+01 -2.2498092e+01 -6.9562501e+00 -2.2773942e+01 -2.2498982e+01 -6.9652488e+00 -2.2773503e+01 -2.2500107e+01 -6.9742445e+00 -2.2773220e+01 -2.2501496e+01 -6.9832428e+00 -2.2772936e+01 -2.2503070e+01 -6.9922397e+00 -2.2772833e+01 -2.2504955e+01 -7.0012576e+00 -2.2772911e+01 -2.2507128e+01 -7.0102151e+00 -2.2773065e+01 -2.2509578e+01 -7.0192410e+00 -2.2773400e+01 -2.2512381e+01 -7.0282458e+00 -2.2773942e+01 -2.2515586e+01 -7.0372272e+00 -2.2774613e+01 -2.2519117e+01 -7.0462219e+00 -2.2775467e+01 -2.2523024e+01 -7.0552254e+00 -2.2776504e+01 -2.2527331e+01 -7.0642333e+00 -2.2777700e+01 -2.2532022e+01 -7.0732050e+00 -2.2779056e+01 -2.2537093e+01 -7.0822107e+00 -2.2780546e+01 -2.2542527e+01 -7.0912096e+00 -2.2782200e+01 -2.2548352e+01 -7.1001982e+00 -2.2783940e+01 -2.2554458e+01 -7.1092072e+00 -2.2785739e+01 -2.2560825e+01 -7.1181986e+00 -2.2787653e+01 -2.2567480e+01 -7.1272020e+00 -2.2789521e+01 -2.2574254e+01 -7.1361813e+00 -2.2791397e+01 -2.2581169e+01 -7.1451964e+00 -2.2793255e+01 -2.2588162e+01 -7.1541804e+00 -2.2795012e+01 -2.2595115e+01 -7.1631912e+00 -2.2796695e+01 -2.2602043e+01 -7.1721941e+00 -2.2798193e+01 -2.2608835e+01 -7.1811859e+00 -2.2799587e+01 -2.2615503e+01 -7.1901916e+00 -2.2800821e+01 -2.2621929e+01 -7.1991790e+00 -2.2801838e+01 -2.2628120e+01 -7.2081725e+00 -2.2802664e+01 -2.2634044e+01 -7.2171680e+00 -2.2803299e+01 -2.2639653e+01 -7.2261615e+00 -2.2803713e+01 -2.2644932e+01 -7.2351748e+00 -2.2803934e+01 -2.2649868e+01 -7.2441534e+00 -2.2803934e+01 -2.2654430e+01 -7.2531683e+00 -2.2803741e+01 -2.2658684e+01 -7.2621662e+00 -2.2803354e+01 -2.2662581e+01 -7.2711676e+00 -2.2802775e+01 -2.2666150e+01 -7.2801457e+00 -2.2802031e+01 -2.2669404e+01 -7.2891428e+00 -2.2800986e+01 -2.2672008e+01 -7.2981542e+00 -2.2799861e+01 -2.2674566e+01 -7.3071536e+00 -2.2798603e+01 -2.2676830e+01 -7.3161382e+00 -2.2796885e+01 -2.2678029e+01 -7.3251461e+00 -2.2795283e+01 -2.2679604e+01 -7.3341319e+00 -2.2793552e+01 -2.2680915e+01 -7.3431328e+00 -2.2791693e+01 -2.2681958e+01 -7.3521246e+00 -2.2789708e+01 -2.2682752e+01 -7.3611232e+00 -2.2787626e+01 -2.2683317e+01 -7.3701243e+00 -2.2785421e+01 -2.2683631e+01 -7.3791241e+00 -2.2783096e+01 -2.2683757e+01 -7.3881190e+00 -2.2780704e+01 -2.2683652e+01 -7.3971228e+00 -2.2778221e+01 -2.2683380e+01 -7.4061142e+00 -2.2775622e+01 -2.2682898e+01 -7.4151070e+00 -2.2772936e+01 -2.2682166e+01 -7.4241136e+00 -2.2770190e+01 -2.2681332e+01 -7.4331135e+00 -2.2767385e+01 -2.2680353e+01 -7.4421033e+00 -2.2764497e+01 -2.2679210e+01 -7.4511107e+00 -2.2761552e+01 -2.2677925e+01 -7.4601007e+00 -2.2758553e+01 -2.2676500e+01 -7.4691000e+00 -2.2755451e+01 -2.2674957e+01 -7.4780901e+00 -2.2752346e+01 -2.2673275e+01 -7.4870959e+00 -2.2749165e+01 -2.2671478e+01 -7.4960851e+00 -2.2745960e+01 -2.2669566e+01 -7.5050821e+00 -2.2742681e+01 -2.2667562e+01 -7.5140827e+00 -2.2739356e+01 -2.2665446e+01 -7.5230828e+00 -2.2736009e+01 -2.2663220e+01 -7.5320789e+00 -2.2732594e+01 -2.2660926e+01 -7.5410798e+00 -2.2729181e+01 -2.2658526e+01 -7.5500815e+00 -2.2725680e+01 -2.2656060e+01 -7.5590683e+00 -2.2722207e+01 -2.2653510e+01 -7.5680726e+00 -2.2718648e+01 -2.2650878e+01 -7.5770665e+00 -2.2715096e+01 -2.2648165e+01 -7.5860694e+00 -2.2711482e+01 -2.2645411e+01 -7.5950661e+00 -2.2707855e+01 -2.2642580e+01 -7.6040640e+00 -2.2704191e+01 -2.2639691e+01 -7.6130592e+00 -2.2700536e+01 -2.2636745e+01 -7.6220585e+00 -2.2696804e+01 -2.2633745e+01 -7.6310479e+00 -2.2693103e+01 -2.2630691e+01 -7.6400539e+00 -2.2689349e+01 -2.2627604e+01 -7.6490426e+00 -2.2685585e+01 -2.2624464e+01 -7.6580400e+00 -2.2681791e+01 -2.2621275e+01 -7.6670418e+00 -2.2678008e+01 -2.2618037e+01 -7.6760348e+00 -2.2674156e+01 -2.2614769e+01 -7.6850338e+00 -2.2670338e+01 -2.2611473e+01 -7.6940345e+00 -2.2666472e+01 -2.2608130e+01 -7.7030333e+00 -2.2662621e+01 -2.2604778e+01 -7.7120264e+00 -2.2658724e+01 -2.2601366e+01 -7.7210270e+00 -2.2654842e+01 -2.2597962e+01 -7.7300228e+00 -2.2650936e+01 -2.2594500e+01 -7.7390182e+00 -2.2647027e+01 -2.2591048e+01 -7.7480174e+00 -2.2643095e+01 -2.2587556e+01 -7.7570162e+00 -2.2639179e+01 -2.2584059e+01 -7.7660111e+00 -2.2635224e+01 -2.2580523e+01 -7.7750130e+00 -2.2631267e+01 -2.2576984e+01 -7.7840036e+00 -2.2627309e+01 -2.2573424e+01 -7.7930007e+00 -2.2623350e+01 -2.2569877e+01 -7.8020002e+00 -2.2619373e+01 -2.2566294e+01 -7.8109982e+00 -2.2615396e+01 -2.2562709e+01 -7.8199977e+00 -2.2611402e+01 -2.2559107e+01 -7.8289948e+00 -2.2607426e+01 -2.2555502e+01 -7.8379922e+00 -2.2603417e+01 -2.2551881e+01 -7.8469862e+00 -2.2599427e+01 -2.2548275e+01 -7.8559853e+00 -2.2595423e+01 -2.2544637e+01 -7.8649855e+00 -2.2591421e+01 -2.2541015e+01 -7.8739829e+00 -2.2587388e+01 -2.2537362e+01 -7.8829797e+00 -2.2583376e+01 -2.2533726e+01 -7.8919777e+00 -2.2579351e+01 -2.2530075e+01 -7.9009731e+00 -2.2575347e+01 -2.2526425e+01 -7.9099677e+00 -2.2571315e+01 -2.2522777e+01 -7.9189682e+00 -2.2567287e+01 -2.2519117e+01 -7.9279654e+00 -2.2563249e+01 -2.2515444e+01 -7.9369609e+00 -2.2559217e+01 -2.2511788e+01 -7.9459607e+00 -2.2555159e+01 -2.2508120e+01 -7.9549561e+00 -2.2551124e+01 -2.2504456e+01 -7.9639530e+00 -2.2547079e+01 -2.2500780e+01 -7.9729523e+00 -2.2543027e+01 -2.2497109e+01 -7.9819499e+00 -2.2538967e+01 -2.2493427e+01 -7.9909468e+00 -2.2534930e+01 -2.2489737e+01 -7.9999435e+00 -2.2530856e+01 -2.2486050e+01 -8.0089407e+00 -2.2526805e+01 -2.2482356e+01 -8.0179511e+00 -2.2522734e+01 -2.2478653e+01 -8.0269416e+00 -2.2518658e+01 -2.2474955e+01 -8.0359498e+00 -2.2514577e+01 -2.2471238e+01 -8.0449315e+00 -2.2510506e+01 -2.2467526e+01 -8.0539232e+00 -2.2506416e+01 -2.2463795e+01 -8.0629203e+00 -2.2502324e+01 -2.2460071e+01 -8.0719188e+00 -2.2498243e+01 -2.2456329e+01 -8.0809150e+00 -2.2494145e+01 -2.2452582e+01 -8.0899051e+00 -2.2490045e+01 -2.2448831e+01 -8.0989205e+00 -2.2485931e+01 -2.2445063e+01 -8.1079219e+00 -2.2481828e+01 -2.2441291e+01 -8.1169065e+00 -2.2477712e+01 -2.2437517e+01 -8.1259040e+00 -2.2473583e+01 -2.2433716e+01 -8.1349099e+00 -2.2469467e+01 -2.2429924e+01 -8.1438888e+00 -2.2465327e+01 -2.2426108e+01 -8.1528996e+00 -2.2461188e+01 -2.2422290e+01 -8.1619068e+00 -2.2457050e+01 -2.2418460e+01 -8.1709068e+00 -2.2452902e+01 -2.2414618e+01 -8.1798963e+00 -2.2448745e+01 -2.2410766e+01 -8.1889004e+00 -2.2444579e+01 -2.2406902e+01 -8.1978868e+00 -2.2440417e+01 -2.2403029e+01 -8.2068798e+00 -2.2436246e+01 -2.2399136e+01 -8.2158754e+00 -2.2432068e+01 -2.2395245e+01 -8.2248696e+00 -2.2427884e+01 -2.2391335e+01 -8.2338841e+00 -2.2423693e+01 -2.2387407e+01 -8.2428643e+00 -2.2419497e+01 -2.2383482e+01 -8.2518571e+00 -2.2415296e+01 -2.2379531e+01 -8.2608581e+00 -2.2411090e+01 -2.2375574e+01 -8.2698630e+00 -2.2406869e+01 -2.2371611e+01 -8.2788679e+00 -2.2402645e+01 -2.2367624e+01 -8.2878689e+00 -2.2398418e+01 -2.2363632e+01 -8.2968626e+00 -2.2394189e+01 -2.2359628e+01 -8.3058456e+00 -2.2389947e+01 -2.2355621e+01 -8.3148570e+00 -2.2385704e+01 -2.2351591e+01 -8.3238500e+00 -2.2381450e+01 -2.2347551e+01 -8.3328423e+00 -2.2377196e+01 -2.2343499e+01 -8.3418498e+00 -2.2372931e+01 -2.2339438e+01 -8.3508486e+00 -2.2368658e+01 -2.2335367e+01 -8.3598355e+00 -2.2364386e+01 -2.2331288e+01 -8.3688259e+00 -2.2360105e+01 -2.2327191e+01 -8.3778342e+00 -2.2355808e+01 -2.2323078e+01 -8.3868377e+00 -2.2351513e+01 -2.2318967e+01 -8.3958329e+00 -2.2347212e+01 -2.2314832e+01 -8.4048166e+00 -2.2342906e+01 -2.2310700e+01 -8.4138193e+00 -2.2338585e+01 -2.2306546e+01 -8.4228196e+00 -2.2334269e+01 -2.2302387e+01 -8.4318139e+00 -2.2329940e+01 -2.2298208e+01 -8.4408147e+00 -2.2325607e+01 -2.2294025e+01 -8.4498177e+00 -2.2321263e+01 -2.2289832e+01 -8.4588040e+00 -2.2316917e+01 -2.2285628e+01 -8.4678004e+00 -2.2312560e+01 -2.2281415e+01 -8.4768027e+00 -2.2308203e+01 -2.2277185e+01 -8.4858066e+00 -2.2303836e+01 -2.2272955e+01 -8.4947944e+00 -2.2299461e+01 -2.2268709e+01 -8.5037907e+00 -2.2295078e+01 -2.2264449e+01 -8.5127911e+00 -2.2290688e+01 -2.2260182e+01 -8.5217916e+00 -2.2286291e+01 -2.2255903e+01 -8.5307886e+00 -2.2281889e+01 -2.2251618e+01 -8.5397784e+00 -2.2277481e+01 -2.2247314e+01 -8.5487824e+00 -2.2273061e+01 -2.2243007e+01 -8.5577838e+00 -2.2268637e+01 -2.2238689e+01 -8.5667791e+00 -2.2264202e+01 -2.2234361e+01 -8.5757765e+00 -2.2259764e+01 -2.2230017e+01 -8.5847721e+00 -2.2255316e+01 -2.2225673e+01 -8.5937733e+00 -2.2250859e+01 -2.2221313e+01 -8.6027651e+00 -2.2246394e+01 -2.2216933e+01 -8.6117658e+00 -2.2241929e+01 -2.2212554e+01 -8.6207605e+00 -2.2237449e+01 -2.2208169e+01 -8.6297561e+00 -2.2232963e+01 -2.2203766e+01 -8.6387587e+00 -2.2228464e+01 -2.2199359e+01 -8.6477545e+00 -2.2223960e+01 -2.2194934e+01 -8.6567496e+00 -2.2219445e+01 -2.2190508e+01 -8.6657498e+00 -2.2214927e+01 -2.2186059e+01 -8.6747418e+00 -2.2210391e+01 -2.2181609e+01 -8.6837403e+00 -2.2205854e+01 -2.2177139e+01 -8.6927412e+00 -2.2201301e+01 -2.2172663e+01 -8.7017406e+00 -2.2196741e+01 -2.2168175e+01 -8.7107349e+00 -2.2192167e+01 -2.2163670e+01 -8.7197289e+00 -2.2187588e+01 -2.2159160e+01 -8.7287270e+00 -2.2182997e+01 -2.2154635e+01 -8.7377252e+00 -2.2178395e+01 -2.2150096e+01 -8.7467276e+00 -2.2173783e+01 -2.2145548e+01 -8.7557224e+00 -2.2169155e+01 -2.2140988e+01 -8.7647215e+00 -2.2164519e+01 -2.2136415e+01 -8.7737133e+00 -2.2159875e+01 -2.2131826e+01 -8.7827162e+00 -2.2155212e+01 -2.2127226e+01 -8.7917117e+00 -2.2150544e+01 -2.2122617e+01 -8.8007102e+00 -2.2145858e+01 -2.2117988e+01 -8.8097078e+00 -2.2141162e+01 -2.2113351e+01 -8.8187008e+00 -2.2136451e+01 -2.2108697e+01 -8.8276987e+00 -2.2131732e+01 -2.2104025e+01 -8.8366975e+00 -2.2126993e+01 -2.2099343e+01 -8.8456932e+00 -2.2122243e+01 -2.2094647e+01 -8.8546946e+00 -2.2117475e+01 -2.2089936e+01 -8.8636916e+00 -2.2112698e+01 -2.2085207e+01 -8.8726864e+00 -2.2107900e+01 -2.2080462e+01 -8.8816870e+00 -2.2103088e+01 -2.2075705e+01 -8.8906836e+00 -2.2098258e+01 -2.2070929e+01 -8.8996783e+00 -2.2093417e+01 -2.2066133e+01 -8.9086780e+00 -2.2088555e+01 -2.2061325e+01 -8.9176735e+00 -2.2083678e+01 -2.2056496e+01 -8.9266716e+00 -2.2078782e+01 -2.2051651e+01 -8.9356685e+00 -2.2073869e+01 -2.2046787e+01 -8.9446652e+00 -2.2068934e+01 -2.2041905e+01 -8.9536631e+00 -2.2063979e+01 -2.2037006e+01 -8.9626581e+00 -2.2059011e+01 -2.2032082e+01 -8.9716562e+00 -2.2054015e+01 -2.2027140e+01 -8.9806532e+00 -2.2049003e+01 -2.2022180e+01 -8.9896545e+00 -2.2043966e+01 -2.2017195e+01 -8.9986516e+00 -2.2038911e+01 -2.2012191e+01 -9.0076624e+00 -2.2033835e+01 -2.2007159e+01 -9.0166573e+00 -2.2028729e+01 -2.2002111e+01 -9.0256335e+00 -2.2023604e+01 -2.1997057e+01 -9.0346285e+00 -2.2018453e+01 -2.1991954e+01 -9.0436373e+00 -2.2013278e+01 -2.1986826e+01 -9.0526170e+00 -2.2008079e+01 -2.1981674e+01 -9.0616409e+00 -2.2002850e+01 -2.1976501e+01 -9.0706288e+00 -2.1997575e+01 -2.1971307e+01 -9.0796153e+00 -2.1992295e+01 -2.1966054e+01 -9.0886321e+00 -2.1986994e+01 -2.1960824e+01 -9.0976043e+00 -2.1981674e+01 -2.1955539e+01 -9.1066328e+00 -2.1976295e+01 -2.1950201e+01 -9.1156105e+00 -2.1970900e+01 -2.1944889e+01 -9.1246020e+00 -2.1965452e+01 -2.1939491e+01 -9.1336028e+00 -2.1959991e+01 -2.1934084e+01 -9.1426084e+00 -2.1954481e+01 -2.1928670e+01 -9.1516150e+00 -2.1948963e+01 -2.1923178e+01 -9.1605886e+00 -2.1943400e+01 -2.1917681e+01 -9.1695863e+00 -2.1937794e+01 -2.1912148e+01 -9.1786029e+00 -2.1932148e+01 -2.1906578e+01 -9.1876053e+00 -2.1926465e+01 -2.1900976e+01 -9.1965907e+00 -2.1920746e+01 -2.1895308e+01 -9.2055833e+00 -2.1914995e+01 -2.1889612e+01 -9.2145790e+00 -2.1909213e+01 -2.1883891e+01 -9.2235738e+00 -2.1903368e+01 -2.1878145e+01 -9.2325896e+00 -2.1897498e+01 -2.1872312e+01 -9.2415714e+00 -2.1891570e+01 -2.1866493e+01 -9.2505664e+00 -2.1885589e+01 -2.1860593e+01 -9.2595700e+00 -2.1879591e+01 -2.1854648e+01 -9.2685780e+00 -2.1873544e+01 -2.1848661e+01 -9.2775634e+00 -2.1867420e+01 -2.1842634e+01 -9.2865687e+00 -2.1861255e+01 -2.1836570e+01 -9.2955671e+00 -2.1855052e+01 -2.1830443e+01 -9.3045552e+00 -2.1848814e+01 -2.1824256e+01 -9.3135509e+00 -2.1842483e+01 -2.1818042e+01 -9.3225501e+00 -2.1836123e+01 -2.1811775e+01 -9.3315488e+00 -2.1829709e+01 -2.1805430e+01 -9.3405433e+00 -2.1823243e+01 -2.1799040e+01 -9.3495495e+00 -2.1816702e+01 -2.1792608e+01 -9.3585440e+00 -2.1810117e+01 -2.1786111e+01 -9.3675423e+00 -2.1803465e+01 -2.1779578e+01 -9.3765405e+00 -2.1796777e+01 -2.1772962e+01 -9.3855348e+00 -2.1790003e+01 -2.1766293e+01 -9.3945392e+00 -2.1783148e+01 -2.1759551e+01 -9.4035323e+00 -2.1776270e+01 -2.1752763e+01 -9.4125277e+00 -2.1769296e+01 -2.1745887e+01 -9.4215217e+00 -2.1762255e+01 -2.1738975e+01 -9.4305265e+00 -2.1755179e+01 -2.1731984e+01 -9.4395222e+00 -2.1747997e+01 -2.1724919e+01 -9.4485208e+00 -2.1740765e+01 -2.1717809e+01 -9.4575186e+00 -2.1733439e+01 -2.1710612e+01 -9.4665117e+00 -2.1726073e+01 -2.1703335e+01 -9.4755114e+00 -2.1718603e+01 -2.1695984e+01 -9.4845134e+00 -2.1711080e+01 -2.1688585e+01 -9.4934999e+00 -2.1703466e+01 -2.1681081e+01 -9.5024954e+00 -2.1695768e+01 -2.1673521e+01 -9.5114957e+00 -2.1687992e+01 -2.1665868e+01 -9.5204966e+00 -2.1680145e+01 -2.1658150e+01 -9.5294945e+00 -2.1672212e+01 -2.1650353e+01 -9.5384858e+00 -2.1664201e+01 -2.1642465e+01 -9.5474916e+00 -2.1656099e+01 -2.1634493e+01 -9.5564834e+00 -2.1647914e+01 -2.1626444e+01 -9.5654818e+00 -2.1639634e+01 -2.1618307e+01 -9.5744827e+00 -2.1631267e+01 -2.1610090e+01 -9.5834822e+00 -2.1622821e+01 -2.1601782e+01 -9.5924766e+00 -2.1614287e+01 -2.1593375e+01 -9.6014733e+00 -2.1605653e+01 -2.1584893e+01 -9.6104685e+00 -2.1596931e+01 -2.1576312e+01 -9.6194690e+00 -2.1588111e+01 -2.1567640e+01 -9.6284605e+00 -2.1579186e+01 -2.1558871e+01 -9.6374597e+00 -2.1570183e+01 -2.1550013e+01 -9.6464625e+00 -2.1561078e+01 -2.1541060e+01 -9.6554554e+00 -2.1551881e+01 -2.1532007e+01 -9.6644539e+00 -2.1542572e+01 -2.1522864e+01 -9.6734541e+00 -2.1533177e+01 -2.1513612e+01 -9.6824520e+00 -2.1523676e+01 -2.1504275e+01 -9.6914440e+00 -2.1514066e+01 -2.1494823e+01 -9.7004441e+00 -2.1504372e+01 -2.1485280e+01 -9.7094396e+00 -2.1494565e+01 -2.1475643e+01 -9.7184353e+00 -2.1484656e+01 -2.1465898e+01 -9.7274355e+00 -2.1474644e+01 -2.1456044e+01 -9.7364363e+00 -2.1464529e+01 -2.1446093e+01 -9.7454340e+00 -2.1454309e+01 -2.1436045e+01 -9.7544248e+00 -2.1443987e+01 -2.1425876e+01 -9.7634280e+00 -2.1433563e+01 -2.1415612e+01 -9.7724244e+00 -2.1423026e+01 -2.1405254e+01 -9.7814179e+00 -2.1412390e+01 -2.1394770e+01 -9.7904189e+00 -2.1401636e+01 -2.1384197e+01 -9.7994164e+00 -2.1390790e+01 -2.1373506e+01 -9.8084136e+00 -2.1379822e+01 -2.1362720e+01 -9.8174067e+00 -2.1368759e+01 -2.1351816e+01 -9.8264053e+00 -2.1357585e+01 -2.1340807e+01 -9.8354052e+00 -2.1346305e+01 -2.1329698e+01 -9.8444026e+00 -2.1334916e+01 -2.1318478e+01 -9.8534001e+00 -2.1323425e+01 -2.1307153e+01 -9.8623938e+00 -2.1311829e+01 -2.1295721e+01 -9.8713919e+00 -2.1300119e+01 -2.1284180e+01 -9.8803905e+00 -2.1288311e+01 -2.1272540e+01 -9.8893858e+00 -2.1276388e+01 -2.1260784e+01 -9.8983851e+00 -2.1264369e+01 -2.1248929e+01 -9.9073845e+00 -2.1252239e+01 -2.1236969e+01 -9.9163802e+00 -2.1240007e+01 -2.1224900e+01 -9.9253791e+00 -2.1227671e+01 -2.1212724e+01 -9.9343772e+00 -2.1215233e+01 -2.1200453e+01 -9.9433708e+00 -2.1202691e+01 -2.1188070e+01 -9.9523710e+00 -2.1190050e+01 -2.1175588e+01 -9.9613689e+00 -2.1177302e+01 -2.1162999e+01 -9.9703655e+00 -2.1164455e+01 -2.1150310e+01 -9.9793617e+00 -2.1151509e+01 -2.1137523e+01 -9.9883583e+00 -2.1138466e+01 -2.1124632e+01 From 2ec6842435436f370f77bf759203d37257053c0b Mon Sep 17 00:00:00 2001 From: Philipp Grete Date: Thu, 29 Aug 2024 15:09:37 +0200 Subject: [PATCH 16/21] Update cooling tables, adjust docs --- CHANGELOG.md | 4 + .../{ => cooling}/cooling_curves_LambdaHD.png | Bin docs/cooling/cooling_curves_nHneLambda.png | Bin 0 -> 47974 bytes docs/cooling/gnat_sternberg_cie_table.txt | 224 ++++++++++++++++++ docs/{ => cooling}/plot_lambda.py | 0 docs/{ => cooling}/schure_table_2.txt | 0 docs/cooling/schure_table_4.txt | 105 ++++++++ .../sutherland_dopita_table_6.txt | 0 docs/cooling_notes.md | 3 + docs/input.md | 14 +- inputs/cloud.in | 2 +- inputs/cluster/cluster.in | 2 +- inputs/cluster/cooling.in | 2 +- inputs/cluster/my_cluster.input | 2 +- inputs/cooling_tables/schure.cooling | 110 +-------- inputs/cooling_tables/updated_schure.cooling | 111 +++++++++ 16 files changed, 465 insertions(+), 114 deletions(-) rename docs/{ => cooling}/cooling_curves_LambdaHD.png (100%) create mode 100644 docs/cooling/cooling_curves_nHneLambda.png create mode 100644 docs/cooling/gnat_sternberg_cie_table.txt rename docs/{ => cooling}/plot_lambda.py (100%) rename docs/{ => cooling}/schure_table_2.txt (100%) create mode 100644 docs/cooling/schure_table_4.txt rename docs/{ => cooling}/sutherland_dopita_table_6.txt (100%) create mode 100644 inputs/cooling_tables/updated_schure.cooling diff --git a/CHANGELOG.md b/CHANGELOG.md index 877ed247..d8511658 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - [[PR 84]](https://github.com/parthenon-hpc-lab/athenapk/pull/84) Bump Parthenon to latest develop (2024-02-15) ### Fixed (not changing behavior/API/variables/...) +- [[PR 97]](https://github.com/parthenon-hpc-lab/athenapk/pull/97) Fixed Schure cooling curve. Removed SD one. Added description of cooling function conventions. ### Infrastructure - [[PR 112]](https://github.com/parthenon-hpc-lab/athenapk/pull/112) Add dev container configuration @@ -18,6 +19,9 @@ ### Removed (removing behavior/API/varaibles/...) ### Incompatibilities (i.e. breaking changes) +- [[PR 97]](https://github.com/parthenon-hpc-lab/athenapk/pull/97) + - Removes original `schure.cooling` cooling curve as it had unknown origin. + - Added `updated_schure.cooling` curve (and associated notebook to calculate it from the paper tables). - [[PR 84]](https://github.com/parthenon-hpc-lab/athenapk/pull/84) Bump Parthenon to latest develop (2024-02-15) - Updated access to block dimension: `pmb->block_size.nx1` -> `pmb->block_size.nx(X1DIR)` (and similarly x2 and x3) - Update access to mesh size: `pmesh->mesh_size.x1max` -> `pmesh->mesh_size.xmax(X1DIR)` (and similarly x2, x3, and min) diff --git a/docs/cooling_curves_LambdaHD.png b/docs/cooling/cooling_curves_LambdaHD.png similarity index 100% rename from docs/cooling_curves_LambdaHD.png rename to docs/cooling/cooling_curves_LambdaHD.png diff --git a/docs/cooling/cooling_curves_nHneLambda.png b/docs/cooling/cooling_curves_nHneLambda.png new file mode 100644 index 0000000000000000000000000000000000000000..b37fc0fcb99c77cf5c3bd6cf5187056f6fc9a998 GIT binary patch literal 47974 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�JyB0sLeTU2aCU8u{SAyM@eo2f$g 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 Sw@nf7qk3CiDPIv8^uGY?&St{^ literal 0 HcmV?d00001 diff --git a/docs/cooling/gnat_sternberg_cie_table.txt b/docs/cooling/gnat_sternberg_cie_table.txt new file mode 100644 index 00000000..01d22595 --- /dev/null +++ b/docs/cooling/gnat_sternberg_cie_table.txt @@ -0,0 +1,224 @@ +## Downloaded from: http://wise-obs.tau.ac.il/~orlyg/cooling/CIEcool/tab13.txt +Title: Time-Dependent Ionization in Radiatively Cooling Gas +Authors: Orly Gnat and Amiel Sternberg +Table: CIE Cooling Efficiencies +================================================================================ +Byte-by-byte Description of file: datafile13.txt +-------------------------------------------------------------------------------- + Bytes Format Units Label Explanations +-------------------------------------------------------------------------------- + 1- 10 A10 K Temperature Temperature + 12- 19 A8 10-13.J.m+3.s-1 Lambda(Z=1e-3) Cooling Efficiency (erg cm^3 + s^-1) + 21- 28 A8 10-13.J.m+3.s-1 Lambda(Z=1e-2) Cooling Efficiency (erg cm^3 + s^-1) + 30- 37 A8 10-13.J.m+310-1 Lambda(Z=1e-1) Cooling Efficiency (erg cm^3 + s^-1) + 39- 46 A8 10-13.J.m+3.s-1 Lambda(Z=1) Cooling Efficiency (erg cm^3 + s^-1) + 48- 55 A8 10-13.J.m+3.s-1 Lambda(Z=2) Cooling Efficiency (erg cm^3 + s^-1) +-------------------------------------------------------------------------------- +Note (1): Our assumed Z=1 solar abundances are listed in Table 1. +-------------------------------------------------------------------------------- +1.0000e+04 4.70e-24 4.98e-24 7.78e-24 5.59e-23 3.77e-22 +1.0470e+04 7.62e-24 7.79e-24 9.55e-24 3.09e-23 6.96e-23 +1.0970e+04 1.23e-23 1.25e-23 1.39e-23 2.86e-23 4.76e-23 +1.1490e+04 1.97e-23 1.98e-23 2.11e-23 3.41e-23 4.93e-23 +1.2030e+04 3.08e-23 3.09e-23 3.22e-23 4.51e-23 5.98e-23 +1.2600e+04 4.66e-23 4.67e-23 4.81e-23 6.16e-23 7.68e-23 +1.3200e+04 6.78e-23 6.80e-23 6.93e-23 8.39e-23 1.00e-22 +1.3830e+04 9.40e-23 9.41e-23 9.58e-23 1.11e-22 1.28e-22 +1.4480e+04 1.22e-22 1.22e-22 1.24e-22 1.41e-22 1.60e-22 +1.5170e+04 1.47e-22 1.47e-22 1.49e-22 1.67e-22 1.88e-22 +1.5890e+04 1.65e-22 1.65e-22 1.67e-22 1.86e-22 2.09e-22 +1.6640e+04 1.71e-22 1.71e-22 1.73e-22 1.94e-22 2.17e-22 +1.7430e+04 1.69e-22 1.69e-22 1.71e-22 1.92e-22 2.15e-22 +1.8250e+04 1.59e-22 1.59e-22 1.61e-22 1.82e-22 2.06e-22 +1.9120e+04 1.46e-22 1.47e-22 1.49e-22 1.70e-22 1.93e-22 +2.0020e+04 1.32e-22 1.32e-22 1.34e-22 1.55e-22 1.79e-22 +2.0970e+04 1.18e-22 1.18e-22 1.21e-22 1.43e-22 1.67e-22 +2.1960e+04 1.05e-22 1.05e-22 1.08e-22 1.31e-22 1.57e-22 +2.3000e+04 9.40e-23 9.42e-23 9.67e-23 1.21e-22 1.49e-22 +2.4090e+04 8.44e-23 8.46e-23 8.72e-23 1.14e-22 1.43e-22 +2.5240e+04 7.60e-23 7.63e-23 7.91e-23 1.08e-22 1.39e-22 +2.6430e+04 6.88e-23 6.91e-23 7.21e-23 1.03e-22 1.38e-22 +2.7680e+04 6.25e-23 6.29e-23 6.63e-23 1.00e-22 1.38e-22 +2.8990e+04 5.71e-23 5.75e-23 6.13e-23 9.85e-23 1.40e-22 +3.0370e+04 5.23e-23 5.27e-23 5.67e-23 9.77e-23 1.43e-22 +3.1810e+04 4.77e-23 4.82e-23 5.27e-23 9.77e-23 1.48e-22 +3.3310e+04 4.35e-23 4.40e-23 4.91e-23 9.88e-23 1.54e-22 +3.4890e+04 3.98e-23 4.04e-23 4.58e-23 1.01e-22 1.62e-22 +3.6540e+04 3.65e-23 3.71e-23 4.32e-23 1.04e-22 1.72e-22 +3.8280e+04 3.35e-23 3.42e-23 4.09e-23 1.08e-22 1.84e-22 +4.0090e+04 3.09e-23 3.16e-23 3.92e-23 1.14e-22 1.97e-22 +4.1990e+04 2.88e-23 2.96e-23 3.79e-23 1.21e-22 2.13e-22 +4.3980e+04 2.72e-23 2.81e-23 3.72e-23 1.29e-22 2.30e-22 +4.6060e+04 2.61e-23 2.71e-23 3.72e-23 1.38e-22 2.50e-22 +4.8240e+04 2.57e-23 2.68e-23 3.79e-23 1.49e-22 2.73e-22 +5.0530e+04 2.60e-23 2.72e-23 3.95e-23 1.62e-22 2.98e-22 +5.2920e+04 2.74e-23 2.87e-23 4.21e-23 1.77e-22 3.27e-22 +5.5430e+04 3.00e-23 3.15e-23 4.62e-23 1.94e-22 3.58e-22 +5.8050e+04 3.41e-23 3.57e-23 5.18e-23 2.13e-22 3.93e-22 +6.0800e+04 3.99e-23 4.17e-23 5.92e-23 2.35e-22 4.31e-22 +6.3680e+04 4.74e-23 4.93e-23 6.83e-23 2.59e-22 4.72e-22 +6.6700e+04 5.63e-23 5.83e-23 7.89e-23 2.85e-22 5.15e-22 +6.9860e+04 6.56e-23 6.78e-23 9.00e-23 3.12e-22 5.59e-22 +7.3170e+04 7.43e-23 7.67e-23 1.00e-22 3.37e-22 6.02e-22 +7.6630e+04 8.11e-23 8.36e-23 1.09e-22 3.61e-22 6.42e-22 +8.0260e+04 8.49e-23 8.75e-23 1.14e-22 3.80e-22 6.77e-22 +8.4070e+04 8.55e-23 8.84e-23 1.16e-22 3.97e-22 7.09e-22 +8.8050e+04 8.35e-23 8.64e-23 1.16e-22 4.10e-22 7.38e-22 +9.2220e+04 7.95e-23 8.26e-23 1.13e-22 4.20e-22 7.63e-22 +9.6590e+04 7.42e-23 7.74e-23 1.09e-22 4.28e-22 7.83e-22 +1.0120e+05 6.86e-23 7.19e-23 1.05e-22 4.32e-22 7.98e-22 +1.0600e+05 6.29e-23 6.62e-23 9.94e-23 4.32e-22 8.03e-22 +1.1100e+05 5.74e-23 6.07e-23 9.39e-23 4.27e-22 7.99e-22 +1.1620e+05 5.22e-23 5.55e-23 8.86e-23 4.20e-22 7.88e-22 +1.2170e+05 4.76e-23 5.08e-23 8.35e-23 4.11e-22 7.76e-22 +1.2750e+05 4.33e-23 4.66e-23 7.89e-23 4.03e-22 7.66e-22 +1.3350e+05 3.95e-23 4.28e-23 7.52e-23 3.99e-22 7.62e-22 +1.3990e+05 3.61e-23 3.94e-23 7.21e-23 3.99e-22 7.65e-22 +1.4650e+05 3.31e-23 3.64e-23 6.96e-23 4.02e-22 7.74e-22 +1.5340e+05 3.04e-23 3.38e-23 6.77e-23 4.08e-22 7.88e-22 +1.6070e+05 2.80e-23 3.15e-23 6.62e-23 4.15e-22 8.05e-22 +1.6830e+05 2.58e-23 2.94e-23 6.49e-23 4.22e-22 8.21e-22 +1.7630e+05 2.39e-23 2.75e-23 6.39e-23 4.29e-22 8.37e-22 +1.8460e+05 2.22e-23 2.59e-23 6.29e-23 4.35e-22 8.50e-22 +1.9340e+05 2.06e-23 2.44e-23 6.21e-23 4.41e-22 8.64e-22 +2.0260e+05 1.92e-23 2.31e-23 6.15e-23 4.47e-22 8.79e-22 +2.1210e+05 1.80e-23 2.19e-23 6.11e-23 4.54e-22 8.94e-22 +2.2220e+05 1.68e-23 2.08e-23 6.06e-23 4.60e-22 9.08e-22 +2.3270e+05 1.58e-23 1.98e-23 6.00e-23 4.64e-22 9.16e-22 +2.4370e+05 1.49e-23 1.89e-23 5.90e-23 4.62e-22 9.13e-22 +2.5530e+05 1.40e-23 1.79e-23 5.73e-23 4.52e-22 8.95e-22 +2.6740e+05 1.32e-23 1.70e-23 5.46e-23 4.33e-22 8.56e-22 +2.8000e+05 1.25e-23 1.60e-23 5.10e-23 4.03e-22 7.97e-22 +2.9330e+05 1.11e-23 1.43e-23 4.62e-23 3.67e-22 7.25e-22 +3.0720e+05 1.05e-23 1.34e-23 4.21e-23 3.31e-22 6.55e-22 +3.2180e+05 9.95e-24 1.25e-23 3.86e-23 3.00e-22 5.93e-22 +3.3700e+05 9.46e-24 1.19e-23 3.58e-23 2.76e-22 5.46e-22 +3.5300e+05 9.01e-24 1.13e-23 3.37e-23 2.59e-22 5.12e-22 +3.6970e+05 8.61e-24 1.08e-23 3.23e-23 2.48e-22 4.91e-22 +3.8720e+05 8.25e-24 1.03e-23 3.12e-23 2.41e-22 4.77e-22 +4.0560e+05 7.92e-24 9.98e-24 3.06e-23 2.38e-22 4.70e-22 +4.2480e+05 7.63e-24 9.67e-24 3.01e-23 2.36e-22 4.66e-22 +4.4490e+05 7.36e-24 9.39e-24 2.97e-23 2.34e-22 4.64e-22 +4.6600e+05 7.10e-24 9.13e-24 2.93e-23 2.33e-22 4.60e-22 +4.8800e+05 6.87e-24 8.87e-24 2.89e-23 2.30e-22 4.56e-22 +5.1110e+05 6.65e-24 8.62e-24 2.83e-23 2.26e-22 4.48e-22 +5.3540e+05 6.44e-24 8.35e-24 2.75e-23 2.20e-22 4.35e-22 +5.6070e+05 6.24e-24 8.06e-24 2.63e-23 2.10e-22 4.15e-22 +5.8730e+05 6.05e-24 7.77e-24 2.50e-23 1.98e-22 3.92e-22 +6.1510e+05 5.88e-24 7.49e-24 2.36e-23 1.86e-22 3.68e-22 +6.4420e+05 5.72e-24 7.22e-24 2.22e-23 1.73e-22 3.42e-22 +6.7480e+05 5.59e-24 7.00e-24 2.12e-23 1.64e-22 3.24e-22 +7.0670e+05 5.47e-24 6.81e-24 2.02e-23 1.55e-22 3.07e-22 +7.4020e+05 5.36e-24 6.66e-24 1.97e-23 1.51e-22 2.98e-22 +7.7530e+05 5.26e-24 6.54e-24 1.93e-23 1.47e-22 2.91e-22 +8.1200e+05 5.18e-24 6.43e-24 1.90e-23 1.46e-22 2.88e-22 +8.5040e+05 5.10e-24 6.35e-24 1.88e-23 1.44e-22 2.85e-22 +8.9070e+05 5.04e-24 6.28e-24 1.87e-23 1.44e-22 2.84e-22 +9.3290e+05 4.98e-24 6.22e-24 1.86e-23 1.43e-22 2.83e-22 +9.7710e+05 4.93e-24 6.15e-24 1.83e-23 1.41e-22 2.79e-22 +1.0000e+06 4.90e-24 6.12e-24 1.83e-23 1.41e-22 2.78e-22 +1.0470e+06 4.87e-24 6.07e-24 1.80e-23 1.38e-22 2.74e-22 +1.0960e+06 4.85e-24 6.02e-24 1.77e-23 1.36e-22 2.68e-22 +1.1480e+06 4.83e-24 5.97e-24 1.74e-23 1.33e-22 2.62e-22 +1.2020e+06 4.82e-24 5.94e-24 1.72e-23 1.30e-22 2.57e-22 +1.2590e+06 4.81e-24 5.91e-24 1.70e-23 1.28e-22 2.53e-22 +1.3180e+06 4.81e-24 5.88e-24 1.66e-23 1.25e-22 2.47e-22 +1.3800e+06 4.81e-24 5.86e-24 1.64e-23 1.23e-22 2.42e-22 +1.4450e+06 4.81e-24 5.85e-24 1.62e-23 1.20e-22 2.37e-22 +1.5140e+06 4.82e-24 5.83e-24 1.59e-23 1.17e-22 2.31e-22 +1.5850e+06 4.84e-24 5.81e-24 1.55e-23 1.13e-22 2.23e-22 +1.6600e+06 4.85e-24 5.78e-24 1.51e-23 1.09e-22 2.14e-22 +1.7380e+06 4.87e-24 5.75e-24 1.46e-23 1.04e-22 2.04e-22 +1.8200e+06 4.89e-24 5.72e-24 1.41e-23 9.80e-23 1.92e-22 +1.9060e+06 4.91e-24 5.70e-24 1.35e-23 9.23e-23 1.81e-22 +1.9950e+06 4.94e-24 5.67e-24 1.30e-23 8.64e-23 1.69e-22 +2.0890e+06 4.88e-24 5.56e-24 1.23e-23 8.05e-23 1.57e-22 +2.1880e+06 4.92e-24 5.55e-24 1.18e-23 7.53e-23 1.47e-22 +2.2910e+06 4.96e-24 5.54e-24 1.14e-23 7.05e-23 1.37e-22 +2.3990e+06 5.00e-24 5.55e-24 1.10e-23 6.61e-23 1.28e-22 +2.5120e+06 5.05e-24 5.56e-24 1.07e-23 6.21e-23 1.20e-22 +2.6300e+06 5.09e-24 5.57e-24 1.03e-23 5.82e-23 1.12e-22 +2.7540e+06 5.14e-24 5.59e-24 1.00e-23 5.48e-23 1.05e-22 +2.8840e+06 5.20e-24 5.61e-24 9.75e-24 5.15e-23 9.84e-23 +3.0200e+06 5.25e-24 5.64e-24 9.51e-24 4.85e-23 9.23e-23 +3.1620e+06 5.31e-24 5.67e-24 9.29e-24 4.58e-23 8.68e-23 +3.3110e+06 5.39e-24 5.73e-24 9.13e-24 4.34e-23 8.20e-23 +3.4670e+06 5.47e-24 5.79e-24 8.99e-24 4.13e-23 7.76e-23 +3.6310e+06 5.55e-24 5.86e-24 8.91e-24 3.96e-23 7.42e-23 +3.8020e+06 5.64e-24 5.93e-24 8.84e-24 3.81e-23 7.11e-23 +3.9810e+06 5.73e-24 6.01e-24 8.79e-24 3.69e-23 6.85e-23 +4.1690e+06 5.82e-24 6.09e-24 8.77e-24 3.58e-23 6.61e-23 +4.3650e+06 5.92e-24 6.18e-24 8.76e-24 3.48e-23 6.41e-23 +4.5710e+06 6.01e-24 6.26e-24 8.77e-24 3.40e-23 6.24e-23 +4.7860e+06 6.11e-24 6.36e-24 8.79e-24 3.32e-23 6.07e-23 +5.0120e+06 6.22e-24 6.45e-24 8.81e-24 3.26e-23 5.93e-23 +5.2480e+06 6.32e-24 6.55e-24 8.85e-24 3.19e-23 5.79e-23 +5.4950e+06 6.43e-24 6.65e-24 8.89e-24 3.14e-23 5.68e-23 +5.7540e+06 6.53e-24 6.75e-24 8.94e-24 3.09e-23 5.57e-23 +6.0260e+06 6.64e-24 6.86e-24 9.00e-24 3.06e-23 5.49e-23 +6.3100e+06 6.76e-24 6.97e-24 9.08e-24 3.03e-23 5.42e-23 +6.6070e+06 6.87e-24 7.08e-24 9.15e-24 3.01e-23 5.36e-23 +6.9180e+06 6.99e-24 7.19e-24 9.24e-24 2.99e-23 5.31e-23 +7.2440e+06 7.11e-24 7.31e-24 9.35e-24 2.99e-23 5.31e-23 +7.5860e+06 7.23e-24 7.43e-24 9.45e-24 2.98e-23 5.27e-23 +7.9430e+06 7.35e-24 7.55e-24 9.56e-24 2.98e-23 5.26e-23 +8.3180e+06 7.48e-24 7.68e-24 9.66e-24 2.97e-23 5.23e-23 +8.7100e+06 7.60e-24 7.80e-24 9.77e-24 2.96e-23 5.20e-23 +9.1200e+06 7.73e-24 7.93e-24 9.87e-24 2.95e-23 5.16e-23 +9.5500e+06 7.86e-24 8.06e-24 9.98e-24 2.94e-23 5.13e-23 +1.0000e+07 8.00e-24 8.19e-24 1.01e-23 2.92e-23 5.08e-23 +1.0470e+07 8.16e-24 8.35e-24 1.02e-23 2.89e-23 5.00e-23 +1.0960e+07 8.33e-24 8.52e-24 1.03e-23 2.86e-23 4.92e-23 +1.1480e+07 8.51e-24 8.68e-24 1.04e-23 2.82e-23 4.82e-23 +1.2020e+07 8.68e-24 8.85e-24 1.05e-23 2.75e-23 4.66e-23 +1.2590e+07 8.87e-24 9.03e-24 1.06e-23 2.69e-23 4.52e-23 +1.3180e+07 9.05e-24 9.21e-24 1.07e-23 2.62e-23 4.36e-23 +1.3800e+07 9.21e-24 9.35e-24 1.08e-23 2.54e-23 4.18e-23 +1.4450e+07 9.39e-24 9.53e-24 1.09e-23 2.46e-23 4.00e-23 +1.5140e+07 9.59e-24 9.72e-24 1.10e-23 2.37e-23 3.81e-23 +1.5850e+07 9.80e-24 9.91e-24 1.11e-23 2.30e-23 3.64e-23 +1.6600e+07 9.99e-24 1.01e-23 1.12e-23 2.22e-23 3.47e-23 +1.7380e+07 1.02e-23 1.03e-23 1.13e-23 2.15e-23 3.30e-23 +1.8200e+07 1.04e-23 1.05e-23 1.14e-23 2.09e-23 3.16e-23 +1.9060e+07 1.06e-23 1.07e-23 1.16e-23 2.04e-23 3.03e-23 +1.9950e+07 1.08e-23 1.09e-23 1.17e-23 2.00e-23 2.92e-23 +2.0890e+07 1.11e-23 1.11e-23 1.19e-23 1.96e-23 2.83e-23 +2.1880e+07 1.13e-23 1.14e-23 1.21e-23 1.93e-23 2.75e-23 +2.2910e+07 1.15e-23 1.16e-23 1.22e-23 1.91e-23 2.69e-23 +2.3990e+07 1.17e-23 1.18e-23 1.24e-23 1.90e-23 2.64e-23 +2.5120e+07 1.20e-23 1.20e-23 1.26e-23 1.89e-23 2.60e-23 +2.6300e+07 1.22e-23 1.23e-23 1.28e-23 1.89e-23 2.57e-23 +2.7540e+07 1.24e-23 1.25e-23 1.31e-23 1.89e-23 2.55e-23 +2.8840e+07 1.27e-23 1.27e-23 1.33e-23 1.90e-23 2.54e-23 +3.0200e+07 1.29e-23 1.30e-23 1.35e-23 1.91e-23 2.53e-23 +3.1620e+07 1.31e-23 1.32e-23 1.37e-23 1.92e-23 2.54e-23 +3.3110e+07 1.34e-23 1.35e-23 1.40e-23 1.94e-23 2.56e-23 +3.4670e+07 1.37e-23 1.38e-23 1.43e-23 1.97e-23 2.58e-23 +3.6310e+07 1.40e-23 1.41e-23 1.46e-23 2.00e-23 2.60e-23 +3.8020e+07 1.43e-23 1.44e-23 1.49e-23 2.03e-23 2.63e-23 +3.9810e+07 1.46e-23 1.47e-23 1.52e-23 2.06e-23 2.67e-23 +4.1690e+07 1.49e-23 1.50e-23 1.55e-23 2.09e-23 2.70e-23 +4.3650e+07 1.52e-23 1.52e-23 1.58e-23 2.12e-23 2.74e-23 +4.5710e+07 1.55e-23 1.55e-23 1.61e-23 2.16e-23 2.79e-23 +4.7860e+07 1.58e-23 1.58e-23 1.64e-23 2.20e-23 2.83e-23 +5.0120e+07 1.61e-23 1.61e-23 1.67e-23 2.24e-23 2.88e-23 +5.2480e+07 1.64e-23 1.64e-23 1.70e-23 2.27e-23 2.91e-23 +5.4950e+07 1.66e-23 1.67e-23 1.73e-23 2.31e-23 2.96e-23 +5.7540e+07 1.69e-23 1.70e-23 1.75e-23 2.34e-23 3.00e-23 +6.0260e+07 1.72e-23 1.72e-23 1.78e-23 2.38e-23 3.05e-23 +6.3100e+07 1.74e-23 1.75e-23 1.81e-23 2.41e-23 3.08e-23 +6.6070e+07 1.77e-23 1.78e-23 1.83e-23 2.44e-23 3.12e-23 +6.9180e+07 1.79e-23 1.80e-23 1.86e-23 2.47e-23 3.15e-23 +7.2440e+07 1.82e-23 1.82e-23 1.88e-23 2.50e-23 3.19e-23 +7.5860e+07 1.84e-23 1.85e-23 1.91e-23 2.52e-23 3.21e-23 +7.9430e+07 1.86e-23 1.87e-23 1.93e-23 2.55e-23 3.24e-23 +8.3180e+07 1.88e-23 1.89e-23 1.95e-23 2.56e-23 3.25e-23 +8.7100e+07 1.91e-23 1.91e-23 1.97e-23 2.58e-23 3.26e-23 +9.1200e+07 1.92e-23 1.93e-23 1.99e-23 2.59e-23 3.27e-23 +9.5500e+07 1.94e-23 1.95e-23 2.00e-23 2.60e-23 3.26e-23 +1.0000e+08 1.96e-23 1.96e-23 2.02e-23 2.61e-23 3.27e-23 diff --git a/docs/plot_lambda.py b/docs/cooling/plot_lambda.py similarity index 100% rename from docs/plot_lambda.py rename to docs/cooling/plot_lambda.py diff --git a/docs/schure_table_2.txt b/docs/cooling/schure_table_2.txt similarity index 100% rename from docs/schure_table_2.txt rename to docs/cooling/schure_table_2.txt diff --git a/docs/cooling/schure_table_4.txt b/docs/cooling/schure_table_4.txt new file mode 100644 index 00000000..e3c41418 --- /dev/null +++ b/docs/cooling/schure_table_4.txt @@ -0,0 +1,105 @@ +# Table 4 from Schure 2009 https://doi.org/10.1051/0004-6361/200912495 +# Copied directly from https://www.aanda.org/articles/aa/full_html/2009/47/aa12495-09/table4.html +# First column is Temperature (log K) +# Other columns are Cooling rates (in log cm^3 erg/s ?) +T H He C N O Ne Na Mg Al Si S Ar Ca Fe Ni +4.20 -21.34 -25.79 -23.63 -24.86 -24.94 -26.60 -29.35 -27.47 -24.51 -23.93 -26.58 -28.18 -28.59 -27.37 -28.96 +4.24 -21.37 -25.25 -23.39 -24.63 -24.55 -26.16 -29.35 -27.34 -24.31 -23.60 -26.33 -28.01 -28.56 -27.23 -28.92 +4.28 -21.47 -24.76 -23.16 -24.41 -24.18 -25.77 -29.35 -27.26 -24.13 -23.30 -26.09 -27.95 -28.55 -27.12 -28.86 +4.32 -21.59 -24.31 -22.95 -24.18 -23.84 -25.45 -29.33 -27.24 -23.97 -23.00 -25.85 -27.93 -28.55 -27.06 -28.80 +4.36 -21.71 -23.91 -22.75 -23.95 -23.54 -25.22 -29.23 -27.25 -23.83 -22.74 -25.59 -27.93 -28.55 -27.04 -28.77 +4.40 -21.83 -23.58 -22.56 -23.73 -23.27 -25.00 -28.98 -27.27 -23.71 -22.52 -25.34 -27.95 -28.56 -27.04 -28.75 +4.44 -21.94 -23.34 -22.37 -23.52 -23.02 -25.05 -28.58 -27.28 -23.61 -22.33 -25.11 -27.96 -28.56 -27.04 -28.72 +4.48 -22.05 -23.22 -22.18 -23.32 -22.79 -25.10 -28.12 -27.30 -23.53 -22.17 -24.90 -27.97 -28.57 -27.03 -28.67 +4.52 -22.15 -23.22 -22.00 -23.12 -22.59 -25.03 -27.66 -27.31 -23.49 -22.04 -24.71 -27.98 -28.56 -27.01 -28.57 +4.56 -22.25 -23.26 -21.82 -22.94 -22.40 -24.83 -27.24 -27.30 -23.51 -21.93 -24.53 -27.99 -28.47 -26.97 -28.44 +4.60 -22.34 -23.29 -21.66 -22.75 -22.23 -24.58 -26.85 -27.23 -23.62 -21.83 -24.34 -28.00 -28.14 -26.89 -28.31 +4.64 -22.42 -23.23 -21.51 -22.57 -22.07 -24.32 -26.50 -27.02 -23.81 -21.76 -24.15 -28.01 -27.61 -26.82 -28.22 +4.68 -22.51 -23.06 -21.39 -22.41 -21.93 -24.08 -26.18 -26.68 -24.05 -21.70 -23.94 -28.01 -27.09 -26.76 -28.14 +4.72 -22.59 -22.80 -21.28 -22.27 -21.80 -23.85 -25.89 -26.28 -24.30 -21.65 -23.72 -28.01 -26.64 -26.71 -28.06 +4.76 -22.67 -22.53 -21.20 -22.14 -21.68 -23.66 -25.64 -25.87 -24.54 -21.63 -23.50 -28.00 -26.25 -26.66 -27.99 +4.80 -22.74 -22.27 -21.13 -22.03 -21.58 -23.48 -25.46 -25.49 -24.78 -21.65 -23.29 -27.98 -25.91 -26.61 -27.91 +4.84 -22.81 -22.07 -21.08 -21.95 -21.48 -23.33 -25.32 -25.14 -24.99 -21.75 -23.09 -27.96 -25.60 -26.54 -27.84 +4.88 -22.88 -21.96 -21.05 -21.87 -21.39 -23.19 -25.22 -24.82 -25.19 -21.96 -22.93 -27.92 -25.33 -26.45 -27.76 +4.92 -22.95 -21.93 -21.04 -21.81 -21.31 -23.05 -25.13 -24.53 -25.38 -22.28 -22.79 -27.85 -25.09 -26.33 -27.70 +4.96 -23.01 -21.97 -21.06 -21.76 -21.23 -22.93 -25.06 -24.27 -25.55 -22.63 -22.67 -27.65 -24.88 -26.19 -27.63 +5.00 -23.07 -22.05 -21.15 -21.71 -21.16 -22.80 -24.97 -24.04 -25.70 -22.97 -22.58 -27.24 -24.70 -26.03 -27.58 +5.04 -23.13 -22.14 -21.32 -21.66 -21.09 -22.67 -24.88 -23.85 -25.84 -23.28 -22.50 -26.72 -24.54 -25.89 -27.52 +5.08 -23.18 -22.24 -21.56 -21.63 -21.03 -22.55 -24.78 -23.70 -25.96 -23.55 -22.44 -26.20 -24.42 -25.78 -27.47 +5.12 -23.23 -22.34 -21.85 -21.60 -20.97 -22.44 -24.67 -23.58 -26.07 -23.78 -22.39 -25.73 -24.32 -25.68 -27.43 +5.16 -23.27 -22.43 -22.13 -21.60 -20.93 -22.34 -24.56 -23.49 -26.18 -23.96 -22.36 -25.32 -24.25 -25.59 -27.40 +5.20 -23.32 -22.52 -22.40 -21.64 -20.89 -22.25 -24.46 -23.41 -26.30 -24.06 -22.37 -24.97 -24.20 -25.42 -27.36 +5.24 -23.35 -22.61 -22.65 -21.74 -20.85 -22.18 -24.35 -23.34 -26.35 -24.08 -22.46 -24.68 -24.18 -25.09 -27.33 +5.28 -23.39 -22.69 -22.87 -21.94 -20.82 -22.12 -24.25 -23.26 -26.22 -24.01 -22.66 -24.43 -24.17 -24.64 -27.30 +5.32 -23.42 -22.77 -23.07 -22.21 -20.80 -22.06 -24.15 -23.16 -25.91 -23.89 -22.94 -24.23 -24.17 -24.18 -27.26 +5.36 -23.45 -22.85 -23.26 -22.51 -20.80 -22.01 -24.07 -23.07 -25.55 -23.76 -23.24 -24.06 -24.17 -23.76 -27.20 +5.40 -23.47 -22.92 -23.43 -22.79 -20.84 -21.97 -24.00 -22.97 -25.21 -23.65 -23.51 -23.93 -24.14 -23.40 -27.14 +5.44 -23.49 -22.98 -23.58 -23.05 -20.94 -21.93 -23.93 -22.88 -24.91 -23.56 -23.74 -23.84 -24.09 -23.10 -27.05 +5.48 -23.51 -23.05 -23.73 -23.29 -21.14 -21.89 -23.88 -22.79 -24.66 -23.49 -23.91 -23.78 -24.03 -22.86 -26.97 +5.52 -23.53 -23.11 -23.86 -23.49 -21.41 -21.86 -23.84 -22.72 -24.46 -23.43 -24.00 -23.78 -23.98 -22.67 -26.88 +5.56 -23.54 -23.17 -23.98 -23.68 -21.69 -21.84 -23.80 -22.66 -24.30 -23.38 -24.00 -23.89 -23.94 -22.51 -26.78 +5.60 -23.56 -23.22 -24.07 -23.85 -21.96 -21.81 -23.78 -22.62 -24.17 -23.32 -23.94 -24.09 -23.91 -22.39 -26.64 +5.64 -23.57 -23.27 -24.13 -24.00 -22.20 -21.79 -23.76 -22.58 -24.07 -23.28 -23.85 -24.30 -23.87 -22.30 -26.45 +5.68 -23.57 -23.32 -24.14 -24.14 -22.42 -21.79 -23.76 -22.55 -23.99 -23.23 -23.75 -24.47 -23.81 -22.23 -26.19 +5.72 -23.58 -23.36 -24.10 -24.26 -22.61 -21.83 -23.76 -22.53 -23.93 -23.20 -23.65 -24.57 -23.74 -22.17 -25.89 +5.76 -23.58 -23.40 -24.02 -24.36 -22.77 -21.94 -23.78 -22.51 -23.88 -23.19 -23.58 -24.59 -23.72 -22.12 -25.60 +5.80 -23.58 -23.44 -23.91 -24.43 -22.92 -22.14 -23.82 -22.49 -23.86 -23.18 -23.53 -24.54 -23.83 -22.08 -25.33 +5.84 -23.58 -23.47 -23.81 -24.47 -23.06 -22.38 -23.88 -22.47 -23.85 -23.16 -23.50 -24.46 -24.05 -22.05 -25.08 +5.88 -23.58 -23.51 -23.71 -24.46 -23.17 -22.63 -23.99 -22.45 -23.86 -23.11 -23.48 -24.37 -24.29 -22.03 -24.86 +5.92 -23.58 -23.53 -23.63 -24.41 -23.27 -22.86 -24.17 -22.45 -23.89 -23.04 -23.46 -24.29 -24.45 -22.02 -24.66 +5.96 -23.58 -23.56 -23.56 -24.32 -23.33 -23.07 -24.39 -22.48 -23.94 -22.96 -23.44 -24.22 -24.52 -22.01 -24.48 +6.00 -23.57 -23.58 -23.52 -24.23 -23.37 -23.26 -24.61 -22.57 -24.00 -22.88 -23.42 -24.17 -24.51 -22.01 -24.32 +6.04 -23.57 -23.60 -23.49 -24.14 -23.36 -23.42 -24.82 -22.74 -24.05 -22.82 -23.38 -24.15 -24.46 -22.01 -24.17 +6.08 -23.56 -23.62 -23.50 -24.05 -23.33 -23.56 -25.01 -22.95 -24.11 -22.77 -23.35 -24.14 -24.40 -22.02 -24.04 +6.12 -23.55 -23.64 -23.53 -23.98 -23.26 -23.68 -25.18 -23.17 -24.19 -22.74 -23.32 -24.15 -24.33 -22.02 -23.92 +6.16 -23.54 -23.65 -23.58 -23.93 -23.19 -23.79 -25.33 -23.37 -24.31 -22.73 -23.30 -24.17 -24.28 -22.03 -23.82 +6.20 -23.53 -23.66 -23.64 -23.90 -23.11 -23.86 -25.47 -23.56 -24.47 -22.77 -23.29 -24.20 -24.25 -22.05 -23.74 +6.24 -23.52 -23.67 -23.71 -23.89 -23.04 -23.91 -25.59 -23.72 -24.64 -22.87 -23.29 -24.24 -24.24 -22.09 -23.67 +6.28 -23.51 -23.68 -23.79 -23.91 -22.98 -23.94 -25.68 -23.86 -24.81 -23.02 -23.29 -24.28 -24.23 -22.17 -23.63 +6.32 -23.50 -23.68 -23.86 -23.95 -22.93 -23.93 -25.75 -23.98 -24.96 -23.19 -23.29 -24.31 -24.23 -22.29 -23.61 +6.36 -23.49 -23.68 -23.93 -24.01 -22.91 -23.90 -25.78 -24.08 -25.11 -23.36 -23.32 -24.32 -24.22 -22.44 -23.63 +6.40 -23.47 -23.69 -24.00 -24.07 -22.91 -23.86 -25.78 -24.16 -25.23 -23.52 -23.39 -24.32 -24.19 -22.58 -23.72 +6.44 -23.46 -23.69 -24.06 -24.14 -22.94 -23.80 -25.76 -24.22 -25.33 -23.67 -23.50 -24.31 -24.16 -22.69 -23.87 +6.48 -23.45 -23.68 -24.12 -24.21 -22.98 -23.75 -25.71 -24.25 -25.41 -23.79 -23.63 -24.31 -24.14 -22.76 -23.98 +6.52 -23.43 -23.68 -24.18 -24.28 -23.04 -23.70 -25.65 -24.26 -25.47 -23.90 -23.76 -24.35 -24.12 -22.80 -24.04 +6.56 -23.42 -23.68 -24.23 -24.34 -23.10 -23.66 -25.58 -24.24 -25.49 -23.98 -23.89 -24.43 -24.12 -22.81 -24.05 +6.60 -23.40 -23.67 -24.28 -24.41 -23.17 -23.64 -25.52 -24.22 -25.49 -24.05 -24.00 -24.55 -24.14 -22.80 -24.05 +6.64 -23.39 -23.67 -24.32 -24.46 -23.23 -23.63 -25.47 -24.18 -25.46 -24.09 -24.10 -24.68 -24.20 -22.78 -24.04 +6.68 -23.37 -23.66 -24.36 -24.52 -23.30 -23.64 -25.42 -24.14 -25.42 -24.12 -24.19 -24.81 -24.29 -22.74 -24.02 +6.72 -23.36 -23.65 -24.40 -24.57 -23.36 -23.66 -25.39 -24.10 -25.37 -24.13 -24.26 -24.91 -24.41 -22.71 -24.02 +6.76 -23.34 -23.64 -24.44 -24.61 -23.41 -23.70 -25.38 -24.07 -25.31 -24.12 -24.31 -25.00 -24.55 -22.68 -24.03 +6.80 -23.33 -23.64 -24.47 -24.66 -23.47 -23.75 -25.39 -24.05 -25.26 -24.10 -24.34 -25.06 -24.67 -22.65 -24.06 +6.84 -23.31 -23.63 -24.50 -24.70 -23.52 -23.80 -25.41 -24.03 -25.21 -24.07 -24.36 -25.11 -24.79 -22.64 -24.10 +6.88 -23.29 -23.61 -24.53 -24.73 -23.56 -23.86 -25.44 -24.04 -25.17 -24.05 -24.37 -25.14 -24.89 -22.64 -24.15 +6.92 -23.28 -23.60 -24.55 -24.77 -23.61 -23.92 -25.48 -24.05 -25.15 -24.02 -24.36 -25.15 -24.97 -22.65 -24.20 +6.96 -23.26 -23.59 -24.57 -24.80 -23.65 -23.97 -25.53 -24.08 -25.14 -24.00 -24.35 -25.15 -25.04 -22.67 -24.25 +7.00 -23.24 -23.58 -24.59 -24.82 -23.68 -24.02 -25.58 -24.12 -25.14 -23.98 -24.33 -25.13 -25.09 -22.70 -24.29 +7.04 -23.23 -23.57 -24.61 -24.85 -23.72 -24.07 -25.63 -24.16 -25.15 -23.98 -24.30 -25.11 -25.12 -22.74 -24.32 +7.08 -23.21 -23.55 -24.62 -24.87 -23.75 -24.12 -25.68 -24.21 -25.18 -23.98 -24.28 -25.07 -25.14 -22.79 -24.35 +7.12 -23.19 -23.54 -24.63 -24.89 -23.77 -24.16 -25.73 -24.26 -25.22 -24.00 -24.26 -25.04 -25.15 -22.86 -24.39 +7.16 -23.17 -23.52 -24.64 -24.91 -23.80 -24.20 -25.77 -24.30 -25.26 -24.02 -24.25 -25.00 -25.15 -22.94 -24.45 +7.20 -23.16 -23.51 -24.65 -24.92 -23.82 -24.23 -25.81 -24.35 -25.30 -24.06 -24.24 -24.96 -25.13 -23.03 -24.51 +7.24 -23.14 -23.50 -24.66 -24.94 -23.84 -24.27 -25.85 -24.40 -25.34 -24.09 -24.24 -24.93 -25.11 -23.13 -24.58 +7.28 -23.12 -23.48 -24.66 -24.95 -23.86 -24.30 -25.89 -24.44 -25.39 -24.13 -24.25 -24.90 -25.09 -23.21 -24.64 +7.32 -23.10 -23.46 -24.67 -24.96 -23.87 -24.32 -25.92 -24.47 -25.43 -24.18 -24.27 -24.88 -25.07 -23.29 -24.70 +7.36 -23.08 -23.45 -24.67 -24.97 -23.88 -24.35 -25.95 -24.51 -25.47 -24.22 -24.30 -24.87 -25.05 -23.36 -24.75 +7.40 -23.07 -23.43 -24.67 -24.97 -23.90 -24.37 -25.97 -24.54 -25.50 -24.26 -24.33 -24.86 -25.03 -23.42 -24.80 +7.44 -23.05 -23.42 -24.67 -24.98 -23.90 -24.39 -26.00 -24.57 -25.54 -24.29 -24.36 -24.87 -25.01 -23.46 -24.84 +7.48 -23.03 -23.40 -24.67 -24.98 -23.91 -24.41 -26.02 -24.60 -25.57 -24.33 -24.40 -24.88 -25.00 -23.49 -24.87 +7.52 -23.01 -23.38 -24.66 -24.98 -23.92 -24.42 -26.04 -24.62 -25.60 -24.36 -24.43 -24.90 -25.00 -23.52 -24.90 +7.56 -22.99 -23.37 -24.66 -24.98 -23.92 -24.44 -26.05 -24.64 -25.62 -24.39 -24.47 -24.92 -25.00 -23.53 -24.92 +7.60 -22.97 -23.35 -24.65 -24.98 -23.92 -24.45 -26.07 -24.66 -25.65 -24.42 -24.50 -24.95 -25.01 -23.54 -24.93 +7.64 -22.95 -23.33 -24.65 -24.97 -23.93 -24.45 -26.08 -24.68 -25.67 -24.45 -24.53 -24.98 -25.02 -23.54 -24.94 +7.68 -22.94 -23.32 -24.64 -24.97 -23.92 -24.46 -26.09 -24.70 -25.68 -24.47 -24.56 -25.01 -25.04 -23.54 -24.94 +7.72 -22.92 -23.30 -24.63 -24.97 -23.92 -24.47 -26.10 -24.71 -25.70 -24.49 -24.59 -25.03 -25.06 -23.54 -24.94 +7.76 -22.90 -23.28 -24.62 -24.96 -23.92 -24.47 -26.10 -24.72 -25.71 -24.51 -24.61 -25.06 -25.08 -23.53 -24.93 +7.80 -22.88 -23.26 -24.61 -24.95 -23.92 -24.47 -26.11 -24.73 -25.72 -24.52 -24.64 -25.09 -25.10 -23.53 -24.93 +7.84 -22.86 -23.25 -24.60 -24.95 -23.91 -24.47 -26.11 -24.73 -25.73 -24.53 -24.66 -25.11 -25.12 -23.53 -24.92 +7.88 -22.84 -23.23 -24.59 -24.94 -23.91 -24.47 -26.11 -24.74 -25.74 -24.55 -24.67 -25.13 -25.15 -23.52 -24.91 +7.92 -22.82 -23.21 -24.58 -24.93 -23.90 -24.47 -26.12 -24.74 -25.75 -24.56 -24.69 -25.15 -25.17 -23.52 -24.90 +7.96 -22.80 -23.19 -24.57 -24.92 -23.89 -24.47 -26.11 -24.75 -25.75 -24.56 -24.70 -25.17 -25.19 -23.53 -24.89 +8.00 -22.78 -23.17 -24.56 -24.91 -23.88 -24.46 -26.11 -24.75 -25.76 -24.57 -24.71 -25.19 -25.21 -23.53 -24.89 +8.04 -22.76 -23.16 -24.54 -24.90 -23.87 -24.46 -26.11 -24.75 -25.76 -24.57 -24.72 -25.20 -25.22 -23.54 -24.89 +8.08 -22.74 -23.14 -24.53 -24.88 -23.86 -24.45 -26.10 -24.74 -25.76 -24.57 -24.73 -25.21 -25.24 -23.55 -24.89 +8.12 -22.72 -23.12 -24.52 -24.87 -23.85 -24.45 -26.10 -24.74 -25.75 -24.58 -24.73 -25.22 -25.25 -23.56 -24.89 +8.16 -22.70 -23.10 -24.50 -24.86 -23.84 -24.44 -26.09 -24.74 -25.75 -24.58 -24.74 -25.23 -25.27 -23.57 -24.89 diff --git a/docs/sutherland_dopita_table_6.txt b/docs/cooling/sutherland_dopita_table_6.txt similarity index 100% rename from docs/sutherland_dopita_table_6.txt rename to docs/cooling/sutherland_dopita_table_6.txt diff --git a/docs/cooling_notes.md b/docs/cooling_notes.md index 4365be1e..34fb1866 100644 --- a/docs/cooling_notes.md +++ b/docs/cooling_notes.md @@ -53,6 +53,9 @@ This convention is adopted by Schure et al. (2009) in their definition of $\Lamb This convention is adopted by Gnat and Sternberg (2007) in their definition of $\Lambda$. +The following image illustrates a comparison between different cooling curves in this notation: +![nHne cooling](./cooling/cooling_curves_nHneLambda.png) + ## $n_H^2 \Lambda$ convention In this convention, the volumetric cooling rate is given by diff --git a/docs/input.md b/docs/input.md index 11dae8c5..6d3734d4 100644 --- a/docs/input.md +++ b/docs/input.md @@ -220,11 +220,11 @@ A possible block might look like: ``` -enable_cooling = tabular # To disable, set to `none` -table_filename = schure.cooling # Path to the cooling table (in a text file) -log_temp_col = 0 # Column in the file that contains the log10 temperatures -log_lambda_col = 1 # Column in the file that contains the cooling rates -lambda_units_cgs = 1 # Conversion factor of the cooling rate relative to CGS units +enable_cooling = tabular # To disable, set to `none` +table_filename = updated_schure.cooling # Path to the cooling table (in a text file) +log_temp_col = 0 # Column in the file that contains the log10 temperatures +log_lambda_col = 1 # Column in the file that contains the cooling rates +lambda_units_cgs = 1 # Conversion factor of the cooling rate relative to CGS units integrator = townsend # Other possible options are `rk12` and `rk45` for error bound subcycling #max_iter = 100 # Max number of iteration for subcycling. Unsued for Townsend integrator @@ -237,3 +237,7 @@ d_log_temp_tol = 1e-8 # Tolerance in cooling table between subseque - Cooling is turned off once the temperature reaches the lower end of the cooling table. Within the cooling function, gas does not cool past the cooling table. - If the global temperature floor `` is higher than the lower end of the cooling table, then the global temperature floor takes precedence. - The pressure floor if present is not considered in the cooling function, only the temperature floor `` + +Finally, a more comprehensive descriptions of various conventions used for cooling +functions (and the chosen implementation in AthenaPK) can be found in [Cooling Notes](cooling_notes.md) +and a notebook comparing various cooling tables (and their conversion) in [cooling/cooling.ipynb](cooling/cooling.ipynb). diff --git a/inputs/cloud.in b/inputs/cloud.in index 05f71e25..7df63436 100644 --- a/inputs/cloud.in +++ b/inputs/cloud.in @@ -62,7 +62,7 @@ He_mass_fraction = 0.24 enable_cooling = none # turn on with "tabular" -table_filename = schure.cooling +table_filename = updated_schure.cooling log_temp_col = 0 log_lambda_col = 1 lambda_units_cgs = 1 diff --git a/inputs/cluster/cluster.in b/inputs/cluster/cluster.in index e3192524..d1355347 100644 --- a/inputs/cluster/cluster.in +++ b/inputs/cluster/cluster.in @@ -86,7 +86,7 @@ code_time_cgs = 3.15576e+16 # 1 Gyr in s enable_cooling=tabular -table_filename=schure.cooling +table_filename=updated_schure.cooling log_temp_col=0 log_lambda_col=1 lambda_units_cgs=1.0 diff --git a/inputs/cluster/cooling.in b/inputs/cluster/cooling.in index 63f8dd20..a8719157 100644 --- a/inputs/cluster/cooling.in +++ b/inputs/cluster/cooling.in @@ -70,7 +70,7 @@ code_time_cgs = 3.15576e+16 # 1 Gyr in s enable_cooling = tabular -table_filename = schure.cooling +table_filename = updated_schure.cooling log_temp_col = 0 log_lambda_col = 1 lambda_units_cgs = 1 #erg cm^3/s in cgs, as used in schure.cooling diff --git a/inputs/cluster/my_cluster.input b/inputs/cluster/my_cluster.input index 3823f7b8..bbf8e1e4 100644 --- a/inputs/cluster/my_cluster.input +++ b/inputs/cluster/my_cluster.input @@ -90,7 +90,7 @@ code_time_cgs = 3.15576e+16 enable_cooling = tabular -table_filename = schure.cooling +table_filename = updated_schure.cooling log_temp_col = 0 # Column to read temperature in cooling table log_lambda_col = 1 # Column to read lambda in cooling table lambda_units_cgs = 1 diff --git a/inputs/cooling_tables/schure.cooling b/inputs/cooling_tables/schure.cooling index e5c054f8..2237d75c 100644 --- a/inputs/cooling_tables/schure.cooling +++ b/inputs/cooling_tables/schure.cooling @@ -1,105 +1,5 @@ -# Cooling table for solar metallicity, 1/2 solar metallicity -# (from Chris Loken, computed with Sarazin & White's analytic expression) -# temperature if log(K), cooling rate/ne^3 (erg cm^3/s) -# This is the new cooling table based on http://arxiv.org/pdf/0909.5204v2 -# logT solar 1/2 solar - 4.20000 -21.3361 -21.3381 - 4.24000 -21.3623 -21.3661 - 4.28000 -21.4525 -21.4612 - 4.32000 -21.5498 -21.5694 - 4.36000 -21.6238 -21.6648 - 4.40000 -21.6623 -21.7381 - 4.44000 -21.6497 -21.7711 - 4.48000 -21.5969 -21.7669 - 4.52000 -21.5159 -21.7263 - 4.56000 -21.4141 -21.6560 - 4.60000 -21.3034 -21.5662 - 4.64000 -21.1928 -21.4688 - 4.68000 -21.0938 -21.3785 - 4.72000 -20.9973 -21.2874 - 4.76000 -20.9196 -21.2130 - 4.80000 -20.8532 -21.1486 - 4.84000 -20.8050 -21.1018 - 4.88000 -20.7735 -21.0712 - 4.92000 -20.7536 -21.0519 - 4.96000 -20.7428 -21.0415 - 5.00000 -20.7578 -21.0567 - 5.04000 -20.7825 -21.0815 - 5.08000 -20.8021 -21.1013 - 5.12000 -20.7965 -21.0960 - 5.16000 -20.7859 -21.0855 - 5.20000 -20.7703 -21.0701 - 5.24000 -20.7561 -21.0560 - 5.28000 -20.7514 -21.0515 - 5.32000 -20.7483 -21.0484 - 5.36000 -20.7553 -21.0554 - 5.40000 -20.7929 -21.0930 - 5.44000 -20.8794 -21.1793 - 5.48000 -21.0405 -21.3401 - 5.52000 -21.2276 -21.5265 - 5.56000 -21.3727 -21.6707 - 5.60000 -21.4552 -21.7528 - 5.64000 -21.4913 -21.7888 - 5.68000 -21.5107 -21.8080 - 5.72000 -21.5354 -21.8325 - 5.76000 -21.5837 -21.8803 - 5.80000 -21.6534 -21.9493 - 5.84000 -21.7090 -22.0042 - 5.88000 -21.7409 -22.0357 - 5.92000 -21.7592 -22.0537 - 5.96000 -21.7695 -22.0638 - 6.00000 -21.7877 -22.0817 - 6.04000 -21.8087 -22.1023 - 6.08000 -21.8306 -22.1236 - 6.12000 -21.8386 -22.1312 - 6.16000 -21.8493 -22.1416 - 6.20000 -21.8690 -22.1607 - 6.24000 -21.9062 -22.1968 - 6.28000 -21.9708 -22.2595 - 6.32000 -22.0543 -22.3400 - 6.36000 -22.1497 -22.4313 - 6.40000 -22.2354 -22.5118 - 6.44000 -22.3090 -22.5804 - 6.48000 -22.3616 -22.6286 - 6.52000 -22.4015 -22.6636 - 6.56000 -22.4254 -22.6846 - 6.60000 -22.4390 -22.6950 - 6.64000 -22.4443 -22.6987 - 6.68000 -22.4375 -22.6905 - 6.72000 -22.4323 -22.6848 - 6.76000 -22.4230 -22.6744 - 6.80000 -22.4147 -22.6659 - 6.84000 -22.4131 -22.6623 - 6.88000 -22.4162 -22.6627 - 6.92000 -22.4265 -22.6706 - 6.96000 -22.4402 -22.6800 - 7.00000 -22.4580 -22.6927 - 7.04000 -22.4830 -22.7125 - 7.08000 -22.5087 -22.7310 - 7.12000 -22.5429 -22.7557 - 7.16000 -22.5776 -22.7798 - 7.20000 -22.6155 -22.8075 - 7.24000 -22.6490 -22.8285 - 7.28000 -22.6689 -22.8384 - 7.32000 -22.6842 -22.8441 - 7.36000 -22.6952 -22.8463 - 7.40000 -22.7039 -22.8495 - 7.44000 -22.7033 -22.8429 - 7.48000 -22.6988 -22.8336 - 7.52000 -22.6925 -22.8228 - 7.56000 -22.6843 -22.8108 - 7.60000 -22.6731 -22.7967 - 7.64000 -22.6606 -22.7816 - 7.68000 -22.6540 -22.7738 - 7.72000 -22.6402 -22.7579 - 7.76000 -22.6245 -22.7408 - 7.80000 -22.6099 -22.7243 - 7.84000 -22.5967 -22.7087 - 7.88000 -22.5805 -22.6911 - 7.92000 -22.5646 -22.6738 - 7.96000 -22.5496 -22.6570 - 8.00000 -22.5332 -22.6393 - 8.04000 -22.5199 -22.6236 - 8.08000 -22.5040 -22.6062 - 8.12000 -22.4881 -22.5888 - 8.16000 -22.4718 -22.5711 +# The original cooling curve in this file was from unknown origin/using unknown conventions +# and has thus been removed. +# This file is kept empty to make runs crash loud that assume/use this table. +# The updated_schure.cooling table contains Lambda for 1, 0.5 and 0.3 solar +# metallicity calculated with the notebook in docs/cooling/cooling.ipynb diff --git a/inputs/cooling_tables/updated_schure.cooling b/inputs/cooling_tables/updated_schure.cooling new file mode 100644 index 00000000..3eecb9f0 --- /dev/null +++ b/inputs/cooling_tables/updated_schure.cooling @@ -0,0 +1,111 @@ +# Cooling rates generated from Schure 2009 (doi.org/10.1051/0004-6361/200912495) +# containing temperatures in the first column (in log10 K) and collisional ionisation +# equilibrium (CIE) cooling rates (in log10 erg cm^3/s) for Z=1 solar metalicity, Z=0.5, +# and Z=0.3 across the columns. Cooling rates are in the convention Lambda_hd from eq. 1, +# where the proton ratio n_e/n_H is taken from table 2. +# Lambda_N is computed from eq. 3. The cooling rate Lambda_N(X_i,T) from eq. 3 is contained +# in table 4. n_i/n_i(solar) is taken to be 1.0 for all elements for Z=1 while for Z=0.5 +# and Z=0.5 n_i/n_i(solar) is set to 1 for H and He and set to 0.5 and 0.3 respectively for +# all other elements. Made by Forrest Glines (forrestglines@gmail.com) +# ----------------------------------------------------------------------------------------- +# log10 T [K] Z=1 log10 Lambda_N [erg cm^3/s] Z=0.5 log10 Lambda_N [erg cm^3/s] Z=0.3 log10 Lambda_N [erg cm^3/s] +4.20 -21.6087 -21.6106 -21.6114 +4.24 -21.4779 -21.4817 -21.4833 +4.28 -21.5009 -21.5094 -21.5129 +4.32 -21.5702 -21.5894 -21.5974 +4.36 -21.6311 -21.6708 -21.6878 +4.40 -21.6603 -21.7330 -21.7659 +4.44 -21.6373 -21.7528 -21.8092 +4.48 -21.5738 -21.7361 -21.8230 +4.52 -21.4838 -21.6873 -21.8059 +4.56 -21.3771 -21.6136 -21.7621 +4.60 -21.2642 -21.5229 -21.6941 +4.64 -21.1525 -21.4248 -21.6111 +4.68 -21.0529 -21.3330 -21.5286 +4.72 -20.9557 -21.2392 -21.4387 +4.76 -20.8769 -21.1599 -21.3589 +4.80 -20.8078 -21.0871 -21.2816 +4.84 -20.7546 -21.0286 -21.2168 +4.88 -20.7154 -20.9858 -21.1700 +4.92 -20.6877 -20.9582 -21.1423 +4.96 -20.6713 -20.9451 -21.1331 +5.00 -20.6828 -20.9602 -21.1525 +5.04 -20.7056 -20.9861 -21.1820 +5.08 -20.7242 -21.0079 -21.2077 +5.12 -20.7180 -21.0052 -21.2093 +5.16 -20.7069 -20.9968 -21.2043 +5.20 -20.6912 -20.9834 -21.1937 +5.24 -20.6768 -20.9707 -21.1832 +5.28 -20.6720 -20.9670 -21.1811 +5.32 -20.6687 -20.9647 -21.1799 +5.36 -20.6755 -20.9722 -21.1883 +5.40 -20.7130 -21.0099 -21.2263 +5.44 -20.7993 -21.0958 -21.3118 +5.48 -20.9603 -21.2556 -21.4700 +5.52 -21.1472 -21.4404 -21.6521 +5.56 -21.2921 -21.5834 -21.7926 +5.60 -21.3746 -21.6649 -21.8728 +5.64 -21.4107 -21.7010 -21.9090 +5.68 -21.4301 -21.7207 -21.9290 +5.72 -21.4547 -21.7454 -21.9539 +5.76 -21.5029 -21.7931 -22.0008 +5.80 -21.5726 -21.8615 -22.0678 +5.84 -21.6281 -21.9160 -22.1209 +5.88 -21.6600 -21.9476 -22.1521 +5.92 -21.6782 -21.9656 -22.1698 +5.96 -21.6885 -21.9760 -22.1804 +6.00 -21.7067 -21.9938 -22.1977 +6.04 -21.7277 -22.0144 -22.2178 +6.08 -21.7494 -22.0355 -22.2383 +6.12 -21.7574 -22.0433 -22.2459 +6.16 -21.7680 -22.0536 -22.2557 +6.20 -21.7877 -22.0725 -22.2736 +6.24 -21.8248 -22.1082 -22.3075 +6.28 -21.8893 -22.1698 -22.3657 +6.32 -21.9727 -22.2486 -22.4391 +6.36 -22.0680 -22.3375 -22.5207 +6.40 -22.1536 -22.4159 -22.5909 +6.44 -22.2272 -22.4820 -22.6490 +6.48 -22.2797 -22.5278 -22.6878 +6.52 -22.3195 -22.5612 -22.7148 +6.56 -22.3434 -22.5811 -22.7308 +6.60 -22.3570 -22.5905 -22.7361 +6.64 -22.3622 -22.5940 -22.7379 +6.68 -22.3553 -22.5857 -22.7283 +6.72 -22.3501 -22.5797 -22.7216 +6.76 -22.3409 -22.5694 -22.7102 +6.80 -22.3324 -22.5612 -22.7023 +6.84 -22.3309 -22.5573 -22.6962 +6.88 -22.3340 -22.5566 -22.6921 +6.92 -22.3443 -22.5635 -22.6959 +6.96 -22.3580 -22.5718 -22.6994 +7.00 -22.3758 -22.5831 -22.7050 +7.04 -22.4007 -22.6010 -22.7170 +7.08 -22.4264 -22.6169 -22.7249 +7.12 -22.4606 -22.6391 -22.7378 +7.16 -22.4953 -22.6596 -22.7480 +7.20 -22.5331 -22.6840 -22.7629 +7.24 -22.5666 -22.7021 -22.7710 +7.28 -22.5865 -22.7090 -22.7697 +7.32 -22.6018 -22.7121 -22.7655 +7.36 -22.6128 -22.7129 -22.7605 +7.40 -22.6215 -22.7135 -22.7565 +7.44 -22.6209 -22.7065 -22.7461 +7.48 -22.6164 -22.6959 -22.7323 +7.52 -22.6101 -22.6840 -22.7176 +7.56 -22.6019 -22.6722 -22.7039 +7.60 -22.5907 -22.6574 -22.6873 +7.64 -22.5782 -22.6418 -22.6700 +7.68 -22.5715 -22.6337 -22.6613 +7.72 -22.5577 -22.6173 -22.6436 +7.76 -22.5421 -22.5998 -22.6251 +7.80 -22.5275 -22.5828 -22.6071 +7.84 -22.5143 -22.5679 -22.5914 +7.88 -22.4980 -22.5500 -22.5727 +7.92 -22.4822 -22.5324 -22.5542 +7.96 -22.4671 -22.5152 -22.5360 +8.00 -22.4508 -22.4972 -22.5172 +8.04 -22.4375 -22.4822 -22.5014 +8.08 -22.4215 -22.4644 -22.4828 +8.12 -22.4056 -22.4467 -22.4642 +8.16 -22.3893 -22.4287 -22.4455 From cc3b6bab9fda98c27f291a87fc09610784f07f0d Mon Sep 17 00:00:00 2001 From: Philipp Grete Date: Thu, 29 Aug 2024 15:12:40 +0200 Subject: [PATCH 17/21] Fix format --- docs/cooling/plot_lambda.py | 40 ++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/docs/cooling/plot_lambda.py b/docs/cooling/plot_lambda.py index 95baad1c..b82d6a93 100644 --- a/docs/cooling/plot_lambda.py +++ b/docs/cooling/plot_lambda.py @@ -6,9 +6,11 @@ ## Sutherland and Dopita (1993) [NOTE: n_i n_e convention for Lambda_N, where n_t == n_i in their notation] # Columns: Log(T), n_e, n_H, n_t, log(\Lambda_net), log(\Lambda_N) - sd_LogT, sd_ne, sd_nH, sd_nt, sd_logLambdaNet, sd_logLambdaN = np.loadtxt("sutherland_dopita_table_6.txt", unpack=True) + sd_LogT, sd_ne, sd_nH, sd_nt, sd_logLambdaNet, sd_logLambdaN = np.loadtxt( + "sutherland_dopita_table_6.txt", unpack=True + ) # convert to Lambda_hd: - sd_LambdaN = 10.**sd_logLambdaN + sd_LambdaN = 10.0**sd_logLambdaN sd_LambdaHD = (sd_ne * sd_nt * sd_LambdaN) / sd_nH**2 # convert to nH ne Lambda(T): sd_nHneLambda = (sd_ne * sd_nt * sd_LambdaN) / (sd_nH * sd_ne) @@ -16,21 +18,29 @@ ## Schure et al. (2009) [NOTE: n_H n_e convention for Lambda_N; n_H^2 convention for Lambda_hd] # Columns: log T (K), log Λ_N (erg s^−1 cm^3), log Λ_hd (erg s^−1 cm^3), n_e/n_H # BEWARE: This Lambda_N is NOT the same as the Sutherland and Dopita Lambda_N! - s_LogT, s_logLambdaN, s_logLambdaHD, s_ne_over_nH = np.loadtxt("schure_table_2.txt", unpack=True) - s_LambdaHD = 10.**s_logLambdaHD + s_LogT, s_logLambdaN, s_logLambdaHD, s_ne_over_nH = np.loadtxt( + "schure_table_2.txt", unpack=True + ) + s_LambdaHD = 10.0**s_logLambdaHD ## Gnat and Sternberg (2007) [NOTE: n_H n_e convention for Lambda] # Columns: Temperature Lambda(Z=1e-3) Lambda(Z=1e-2) Lambda(Z=1e-1) Lambda(Z=1) Lambda(Z=2) - gs_T, gs_LambdaZem3, gs_LambdaZem2, gs_LambdaZem1, gs_LambdaZ1, gs_LambdaZ2 = np.loadtxt("gnat_sternberg_cie_table.txt", unpack=True, skiprows=23) + gs_T, gs_LambdaZem3, gs_LambdaZem2, gs_LambdaZem1, gs_LambdaZ1, gs_LambdaZ2 = ( + np.loadtxt("gnat_sternberg_cie_table.txt", unpack=True, skiprows=23) + ) # NOTE: There is not enough information in this table alone to compute n_e! # (The electron fraction must be computed from datafile2a.txt) # plot nH^2-normalized Lambda(T) plt.figure() - plt.plot(sd_LogT, sd_LambdaHD, label = r"Sutherland & Dopita $\Lambda_{hd}$ for $Z_{\odot}$") - plt.plot(s_LogT, s_LambdaHD, label = r"Schure et al. $\Lambda_{hd}$ for $Z_{\odot}$") + plt.plot( + sd_LogT, + sd_LambdaHD, + label=r"Sutherland & Dopita $\Lambda_{hd}$ for $Z_{\odot}$", + ) + plt.plot(s_LogT, s_LambdaHD, label=r"Schure et al. $\Lambda_{hd}$ for $Z_{\odot}$") # (Gnat & Sternberg cannot be converted to this convention without the electron fraction, which is missing.) - plt.yscale('log') + plt.yscale("log") plt.ylim(1e-23, 3e-21) plt.xlabel(r"$\log T$ (K)") plt.ylabel(r"$\Lambda(T)$ [$n_H^2$ convention]") @@ -40,10 +50,16 @@ # plot nH ne-normalized Lambda(T) plt.figure() - plt.plot(sd_LogT, sd_nHneLambda, label = r"Sutherland & Dopita $\Lambda$ for $Z_{\odot}$") - plt.plot(s_LogT, 10.**s_logLambdaN, label = r"Schure et al. $\Lambda$ for $Z_{\odot}$") - plt.plot(np.log10(gs_T), gs_LambdaZ1, label = r"Gnat & Sternberg $\Lambda$ for $Z_{\odot}$") - plt.yscale('log') + plt.plot( + sd_LogT, sd_nHneLambda, label=r"Sutherland & Dopita $\Lambda$ for $Z_{\odot}$" + ) + plt.plot( + s_LogT, 10.0**s_logLambdaN, label=r"Schure et al. $\Lambda$ for $Z_{\odot}$" + ) + plt.plot( + np.log10(gs_T), gs_LambdaZ1, label=r"Gnat & Sternberg $\Lambda$ for $Z_{\odot}$" + ) + plt.yscale("log") plt.ylim(1e-23, 3e-21) plt.xlabel(r"$\log T$ (K)") plt.ylabel(r"$\Lambda(T)$ [$n_H n_e$ convention]") From 85895c41ef23b9ba83481472a14e9dba2c893b46 Mon Sep 17 00:00:00 2001 From: Philipp Grete Date: Fri, 30 Aug 2024 10:19:26 +0200 Subject: [PATCH 18/21] Add promised notebook --- docs/cooling/cooling.ipynb | 318 +++++++++++++++++++++++++++++++++++++ 1 file changed, 318 insertions(+) create mode 100644 docs/cooling/cooling.ipynb diff --git a/docs/cooling/cooling.ipynb b/docs/cooling/cooling.ipynb new file mode 100644 index 00000000..435a8a43 --- /dev/null +++ b/docs/cooling/cooling.ipynb @@ -0,0 +1,318 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "33ca3da4-e1e2-4dff-bf33-88072e57508e", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import unyt\n", + "\n", + "import scipy as sp\n", + "import scipy.interpolate\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import matplotlib as mpl" + ] + }, + { + "cell_type": "markdown", + "id": "eadb3f5c-e2aa-44b9-8828-555cac0c8c42", + "metadata": {}, + "source": [ + "## Load data from [Schure 2009](https://doi.org/10.1051/0004-6361/200912495) Tables 2 and 4" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6e9bfaf9-9e06-48bf-933d-b3e201e4c5f5", + "metadata": {}, + "outputs": [], + "source": [ + "elemental_rates_data = np.genfromtxt(\"schure_table_4.txt\",\n", + " skip_header=4,\n", + " dtype=float, delimiter='\\t', names=True) \n", + "elements = elemental_rates_data.dtype.names[1:]\n", + "\n", + "log_temperature = elemental_rates_data[\"T\"]\n", + "\n", + "cooling_rates = unyt.unyt_array(np.empty( (log_temperature.size,len(elements)) ),\"cm**3*erg/s\")\n", + "\n", + "for j,element in enumerate(elements):\n", + " cooling_rates[:,j] = unyt.unyt_array(10**elemental_rates_data[element],\"cm**3*erg/s\")\n", + "\n", + "\n", + "schure_table2_data = np.loadtxt(\"schure_table_2.txt\")" + ] + }, + { + "cell_type": "markdown", + "id": "0dda7ed5-24d0-4ab5-a703-7baa71d1e1b8", + "metadata": {}, + "source": [ + "## Compute Cooling rates ($\\Lambda_N$) from Schure Table 4 and eq. 3" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dd992955-c664-4dc5-9a40-0c25ebafdc88", + "metadata": {}, + "outputs": [], + "source": [ + "z1_log_cr = np.log10( cooling_rates.sum(axis=1) )\n", + "\n", + "def compute_cr(n_over_n_sun):\n", + " return (cooling_rates*n_over_n_sun).sum(axis=1)\n", + "\n", + "z05_log_cr = np.log10( compute_cr(np.array( [1,1.0] + [1./2.,]*(len(elements)-2) ) ))\n", + "z03_log_cr = np.log10( compute_cr(np.array( [1,1] + [0.3,]*(len(elements)-2) ) ))" + ] + }, + { + "cell_type": "markdown", + "id": "59b73548-47cf-438d-bc8b-41a691b7f5e8", + "metadata": {}, + "source": [ + "## Compute $\\Lambda_{hd}$ from $n_e/n_H$ in Table 2 and eq. 1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "17526d49-46cd-41ce-b12f-f682de1cdba3", + "metadata": {}, + "outputs": [], + "source": [ + "#ne_over_nh = sp.interpolate.CubicSpline(schure_table2_data[:,0],schure_table2_data[:,3])\n", + "\n", + "start = np.where(schure_table2_data[:,0] == log_temperature[0])[0][0]\n", + "end = np.where(schure_table2_data[:,0] == log_temperature[-1])[0][0]\n", + "ne_over_nh = schure_table2_data[start:end+1,3]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "12c2e08a-721a-4535-87b6-8d0688627d5d", + "metadata": {}, + "outputs": [], + "source": [ + "log_x_hd = np.log10(ne_over_nh)\n", + "schure_data = np.vstack((log_temperature,log_x_hd+z1_log_cr,log_x_hd+z05_log_cr,log_x_hd+z03_log_cr))" + ] + }, + { + "cell_type": "markdown", + "id": "abb949f6-e0eb-43d6-80db-9242e6b11ded", + "metadata": {}, + "source": [ + "## Save the schure data with a thorough note" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9783bc26-4023-41f4-b7ad-f5dbbab8fc7d", + "metadata": {}, + "outputs": [], + "source": [ + "header=\"\"\"Cooling rates generated from Schure 2009 (doi.org/10.1051/0004-6361/200912495)\n", + "containing temperatures in the first column (in log10 K) and collisional ionisation\n", + "equilibrium (CIE) cooling rates (in log10 erg cm^3/s) for Z=1 solar metalicity, Z=0.5,\n", + "and Z=0.3 across the columns. Cooling rates are in the convention Lambda_hd from eq. 1,\n", + "where the proton ratio n_e/n_H is taken from table 2.\n", + "Lambda_N is computed from eq. 3. The cooling rate Lambda_N(X_i,T) from eq. 3 is contained\n", + "in table 4. n_i/n_i(solar) is taken to be 1.0 for all elements for Z=1 while for Z=0.5\n", + "and Z=0.5 n_i/n_i(solar) is set to 1 for H and He and set to 0.5 and 0.3 respectively for\n", + "all other elements. Made by Forrest Glines (forrestglines@gmail.com)\n", + "-----------------------------------------------------------------------------------------\n", + "log10 T [K] Z=1 log10 Lambda_N [erg cm^3/s] Z=0.5 log10 Lambda_N [erg cm^3/s] Z=0.3 log10 Lambda_N [erg cm^3/s]\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b82b388b-b1db-42c0-b491-ec0acf998dd3", + "metadata": {}, + "outputs": [], + "source": [ + "np.savetxt(\"updated_schure.cooling\",schure_data.T,header=header,fmt=(\"%1.2f\",\"%2.4f\",\"%2.4f\",\"%2.4f\"))" + ] + }, + { + "cell_type": "markdown", + "id": "6c7c385d-21ed-42e5-ba60-8ae76cea7185", + "metadata": {}, + "source": [ + "## Load other cooling tables (See [Sutherland and Dopita 1993](https://ui.adsabs.harvard.edu/link_gateway/1993ApJS...88..253S/doi:10.1086/191823) )" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9177f991-65fc-46a9-a8e1-8c121da5f68f", + "metadata": {}, + "outputs": [], + "source": [ + "enzo_schure_data = np.loadtxt(\"enzo_schure.cooling\") #Schure cooling table with enzo roots\n", + "#gnat_sternberg_data = np.loadtxt(\"gnat-sternberg.cooling\")\n", + "#sutherland_dopita_data = np.loadtxt(\"cooling_data/sutherland_dopita.cooling\") #SD table with PLUTO roots\n", + "sutherland_dopita_table6_data = np.loadtxt(\"sutherland_dopita_table_6.txt\")" + ] + }, + { + "cell_type": "markdown", + "id": "702382fd-8067-4a7f-bb85-45838f236ff1", + "metadata": {}, + "source": [ + "## Make some plots" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ef31148e-36d4-4ff7-b950-712e84224f12", + "metadata": {}, + "outputs": [], + "source": [ + "fig,ax = plt.subplots()\n", + "\n", + "ax.plot(log_temperature,z1_log_cr,label=\"$\\\\Lambda_N$ Schure $Z_\\\\odot$\")\n", + "ax.plot(log_temperature,z05_log_cr,label=\"$\\\\Lambda_N$ Schure $0.5 Z_\\\\odot$\")\n", + "ax.plot(log_temperature,z03_log_cr,label=\"$\\\\Lambda_N$ Schure $0.3 Z_\\\\odot$\")\n", + "\n", + "\n", + "ax.plot(log_temperature,log_x_hd+z1_log_cr,label=\"$\\\\Lambda_{hd}$ Schure $Z_\\\\odot$\",linestyle=\"--\")\n", + "ax.plot(log_temperature,log_x_hd+z05_log_cr,label=\"$\\\\Lambda_{hd}$ Schure $0.5 Z_\\\\odot$\",linestyle=\"--\")\n", + "ax.plot(log_temperature,log_x_hd+z03_log_cr,label=\"$\\\\Lambda_{hd}$ Schure $0.3 Z_\\\\odot$\",linestyle=\"--\")\n", + "\n", + "#ax.plot(enzo_schure_data[:,0],enzo_schure_data[:,1],label=\"Legacy Schure $Z_\\\\odot$\",linestyle=\"--\")\n", + "#ax.plot(enzo_schure_data[:,0],enzo_schure_data[:,2],label=\"Legacy Schure $0.5 Z_\\\\odot$\",linestyle=\"--\")\n", + "#ax.plot(schure_table2_data[:,0],schure_table2_data[:,1],label=\"Schure Table 2 $Z=1$\",linestyle=\"--\")\n", + "\n", + "#ax.plot(gnat_sternberg_data[:,0],gnat_sternberg_data[:,4],label=\"GS $Z=1$\",linestyle=\":\")\n", + "#ax.plot(sutherland_dopita_data[:,0],sutherland_dopita_data[:,2],label=\"SD $Z=1$\",linestyle=\"-\")\n", + "#ax.plot(sutherland_dopita_data[:,0],sutherland_dopita_data[:,1],label=\"SD $Z=1/3$\",linestyle=\":\")\n", + "\n", + "#ax.plot(sutherland_dopita_table6_data[:,0],sutherland_dopita_table6_data[:,5],label=\"SD Table 6 $Z=1$\",linestyle=\"--\")\n", + "\n", + "ax.legend(ncols=2)\n", + "\n", + "#ax.set_xlim(log_temperature.min(),log_temperature.max())\n", + "\n", + "ax.set_xlim(3.8,8.2)\n", + "ax.set_ylim(-23,-20)\n", + "#ax.set_ylim(-26,-20)\n", + "\n", + "ax.set_ylabel(\"Cooling Rate -- $ \\\\log \\\\Lambda$ [ cm${}^{3}$ erg/s ]\")\n", + "ax.set_xlabel(\"Temperature -- $ \\\\log T$ [ K ]\")\n", + "\n", + "ax.grid()\n", + "\n", + "plt.show()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0261a25f-2c1a-49b7-987e-3c5bf1deedf5", + "metadata": {}, + "outputs": [], + "source": [ + "fig,ax = plt.subplots()\n", + "\n", + "ax.plot(log_temperature,log_x_hd+z1_log_cr,label=\"My $\\\\Lambda_{hd}$\",linestyle=\"-\")\n", + "ax.plot(log_temperature,schure_table2_data[start:end+1,2],label=\"Schure Table 2 $\\\\Lambda_{hd}$\",linestyle=\":\")\n", + "\n", + "ax.plot(log_temperature,z1_log_cr,label=\"My $\\\\Lambda_{N}$\",linestyle=\"-\")\n", + "ax.plot(log_temperature,enzo_schure_data[:,1],label=\"Enzo $\\\\Lambda_{N}$\",linestyle=\"--\")\n", + "ax.plot(log_temperature,schure_table2_data[start:end+1,2],label=\"Schure Table 1 $\\\\Lambda_{N}$\",linestyle=\":\")\n", + "\n", + "ax.legend()\n", + "\n", + "#ax.set_xlim(log_temperature.min(),log_temperature.max())\n", + "\n", + "ax.set_xlim(3.8,8.2)\n", + "ax.set_ylim(-23,-20)\n", + "#ax.set_ylim(-26,-20)\n", + "\n", + "ax.set_ylabel(\"Cooling Rate -- $ \\\\log \\\\Lambda$ [ cm${}^{3}$ erg/s ]\")\n", + "ax.set_xlabel(\"Temperature -- $ \\\\log T$ [ K ]\")\n", + "\n", + "ax.grid()\n", + "\n", + "plt.show()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "693b185a-a4c4-4602-b841-b43bfa909601", + "metadata": {}, + "outputs": [], + "source": [ + "fig,ax = plt.subplots()\n", + "\n", + "ax.plot(log_temperature,\n", + " (10**(log_x_hd+z1_log_cr) - 10**schure_table2_data[start:end+1,2])/10**(log_x_hd+z1_log_cr),\n", + " label=\"$\\\\Lambda_{hd}$: Mine - Schure Table 2\",linestyle=\"-\")\n", + "\n", + "ax.plot(log_temperature,\n", + " (10**(z1_log_cr) - 10**schure_table2_data[start:end+1,1])/10**(z1_log_cr),\n", + " label=\"$\\\\Lambda_{N}$: Mine - Schure Table 2\",linestyle=\"--\")\n", + "ax.plot(log_temperature,\n", + " (10**(z1_log_cr) - 10**enzo_schure_data[:,1])/10**(z1_log_cr),\n", + " label=\"$\\\\Lambda_{N}$: Mine - Enzo\",linestyle=\"-\")\n", + "\n", + "\n", + "ax.legend()\n", + "\n", + "#ax.set_xlim(log_temperature.min(),log_temperature.max())\n", + "\n", + "ax.set_xlim(3.8,8.2)\n", + "#ax.set_ylim(-23,-20)\n", + "#ax.set_ylim(-26,-20)\n", + "\n", + "ax.set_ylabel(\"Relative difference in $\\\\Lambda$\")\n", + "ax.set_xlabel(\"Temperature -- $ \\\\log T$ [ K ]\")\n", + "\n", + "ax.grid()\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fb9b70d5-32e4-43db-9fcd-f1c7c481b5a4", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From a8cbd3a5aee6f29962fdacac0b0887dedc04c085 Mon Sep 17 00:00:00 2001 From: Philipp Grete Date: Fri, 30 Aug 2024 15:45:23 +0200 Subject: [PATCH 19/21] Use single metallicity cooling tables --- CHANGELOG.md | 6 +- docs/cooling/cooling.ipynb | 63 +++++- docs/cooling/plot_lambda.py | 9 +- docs/input.md | 12 +- inputs/cloud.in | 4 +- inputs/cluster/cluster.in | 4 +- inputs/cluster/cooling.in | 4 +- inputs/cooling_tables/gnat-sternberg.cooling | 208 ----------------- .../gnat-sternberg.cooling_0.001Z | 209 ++++++++++++++++++ .../gnat-sternberg.cooling_0.01Z | 209 ++++++++++++++++++ .../gnat-sternberg.cooling_0.1Z | 209 ++++++++++++++++++ .../cooling_tables/gnat-sternberg.cooling_1Z | 209 ++++++++++++++++++ .../cooling_tables/gnat-sternberg.cooling_2Z | 209 ++++++++++++++++++ inputs/cooling_tables/schure.cooling_0.3Z | 111 ++++++++++ inputs/cooling_tables/schure.cooling_0.5Z | 111 ++++++++++ inputs/cooling_tables/schure.cooling_1.0Z | 111 ++++++++++ inputs/cooling_tables/updated_schure.cooling | 111 ---------- src/hydro/srcterms/tabular_cooling.cpp | 23 +- .../cluster_tabular_cooling.py | 2 - 19 files changed, 1473 insertions(+), 351 deletions(-) delete mode 100644 inputs/cooling_tables/gnat-sternberg.cooling create mode 100644 inputs/cooling_tables/gnat-sternberg.cooling_0.001Z create mode 100644 inputs/cooling_tables/gnat-sternberg.cooling_0.01Z create mode 100644 inputs/cooling_tables/gnat-sternberg.cooling_0.1Z create mode 100644 inputs/cooling_tables/gnat-sternberg.cooling_1Z create mode 100644 inputs/cooling_tables/gnat-sternberg.cooling_2Z create mode 100644 inputs/cooling_tables/schure.cooling_0.3Z create mode 100644 inputs/cooling_tables/schure.cooling_0.5Z create mode 100644 inputs/cooling_tables/schure.cooling_1.0Z delete mode 100644 inputs/cooling_tables/updated_schure.cooling diff --git a/CHANGELOG.md b/CHANGELOG.md index d8511658..17e1877b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,10 +6,10 @@ - [[PR 1]](https://github.com/parthenon-hpc-lab/athenapk/pull/1) Add isotropic thermal conduction and RKL2 supertimestepping ### Changed (changing behavior/API/variables/...) +- [[PR 97]](https://github.com/parthenon-hpc-lab/athenapk/pull/97) Fixed Schure cooling curve. Removed SD one. Added description of cooling function conventions. - [[PR 84]](https://github.com/parthenon-hpc-lab/athenapk/pull/84) Bump Parthenon to latest develop (2024-02-15) ### Fixed (not changing behavior/API/variables/...) -- [[PR 97]](https://github.com/parthenon-hpc-lab/athenapk/pull/97) Fixed Schure cooling curve. Removed SD one. Added description of cooling function conventions. ### Infrastructure - [[PR 112]](https://github.com/parthenon-hpc-lab/athenapk/pull/112) Add dev container configuration @@ -21,7 +21,9 @@ ### Incompatibilities (i.e. breaking changes) - [[PR 97]](https://github.com/parthenon-hpc-lab/athenapk/pull/97) - Removes original `schure.cooling` cooling curve as it had unknown origin. - - Added `updated_schure.cooling` curve (and associated notebook to calculate it from the paper tables). + - To avoid confusion, only cooling table for a single solar metallicity are supported + from now on (i.e., the parameters to specify temperature and lambda columns have been removed). + - Added `schure.cooling_#Z` curves (and associated notebook to calculate it from the paper tables). - [[PR 84]](https://github.com/parthenon-hpc-lab/athenapk/pull/84) Bump Parthenon to latest develop (2024-02-15) - Updated access to block dimension: `pmb->block_size.nx1` -> `pmb->block_size.nx(X1DIR)` (and similarly x2 and x3) - Update access to mesh size: `pmesh->mesh_size.x1max` -> `pmesh->mesh_size.xmax(X1DIR)` (and similarly x2, x3, and min) diff --git a/docs/cooling/cooling.ipynb b/docs/cooling/cooling.ipynb index 435a8a43..31b183b7 100644 --- a/docs/cooling/cooling.ipynb +++ b/docs/cooling/cooling.ipynb @@ -122,15 +122,14 @@ "source": [ "header=\"\"\"Cooling rates generated from Schure 2009 (doi.org/10.1051/0004-6361/200912495)\n", "containing temperatures in the first column (in log10 K) and collisional ionisation\n", - "equilibrium (CIE) cooling rates (in log10 erg cm^3/s) for Z=1 solar metalicity, Z=0.5,\n", - "and Z=0.3 across the columns. Cooling rates are in the convention Lambda_hd from eq. 1,\n", + "equilibrium (CIE) cooling rates (in log10 erg cm^3/s).\n", + "Cooling rates are in the convention Lambda_hd from eq. 1,\n", "where the proton ratio n_e/n_H is taken from table 2.\n", "Lambda_N is computed from eq. 3. The cooling rate Lambda_N(X_i,T) from eq. 3 is contained\n", "in table 4. n_i/n_i(solar) is taken to be 1.0 for all elements for Z=1 while for Z=0.5\n", - "and Z=0.5 n_i/n_i(solar) is set to 1 for H and He and set to 0.5 and 0.3 respectively for\n", + "and Z=0.3 n_i/n_i(solar) is set to 1 for H and He and set to 0.5 and 0.3 respectively for\n", "all other elements. Made by Forrest Glines (forrestglines@gmail.com)\n", - "-----------------------------------------------------------------------------------------\n", - "log10 T [K] Z=1 log10 Lambda_N [erg cm^3/s] Z=0.5 log10 Lambda_N [erg cm^3/s] Z=0.3 log10 Lambda_N [erg cm^3/s]\"\"\"" + "-----------------------------------------------------------------------------------------\\n\"\"\"" ] }, { @@ -140,7 +139,59 @@ "metadata": {}, "outputs": [], "source": [ - "np.savetxt(\"updated_schure.cooling\",schure_data.T,header=header,fmt=(\"%1.2f\",\"%2.4f\",\"%2.4f\",\"%2.4f\"))" + "for i, z in enumerate([1.0, 0.5, 0.3]):\n", + " np.savetxt(f\"schure.cooling_{z:.1f}Z\",\n", + " schure_data.T[:,[0, i + 1]],\n", + " header=header + f\"log10 T [K] Z={z:.1f} log10 Lambda_N [erg cm^3/s]\",\n", + " fmt=(\"%1.2f\",\"%2.4f\"))" + ] + }, + { + "cell_type": "markdown", + "id": "ebd552ea-937d-4d26-9517-cffaf98dbeb4", + "metadata": {}, + "source": [ + "### Process Gnat Sternberg Cooling Table" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1a9b0fd3-a27e-46eb-b356-4d46e53bcc55", + "metadata": {}, + "outputs": [], + "source": [ + "gnat_sternberg_data = np.loadtxt(\"gnat_sternberg_cie_table.txt\", skiprows=23)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fdf5d5db-a0eb-43e7-9283-29339d1d6d5a", + "metadata": {}, + "outputs": [], + "source": [ + "header=\"\"\"Adapted from: http://wise-obs.tau.ac.il/~orlyg/cooling/CIEcool/tab13.txt\n", + "Title: Time-Dependent Ionization in Radiatively Cooling Gas \n", + "Authors: Orly Gnat and Amiel Sternberg\n", + "Table: CIE Cooling Efficiencies\n", + "-----------------------------------------------------------------------------------------\n", + "Our assumed Z=1 solar abundances are listed in Table 1.\n", + "-----------------------------------------------------------------------------------------\\n\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0abce35b-6775-4c43-b6a8-2ed0cd6f0e1c", + "metadata": {}, + "outputs": [], + "source": [ + "for i, z in enumerate([1e-3, 1e-2, 1e-1, 1, 2]):\n", + " np.savetxt(f\"gnat-sternberg.cooling_{z:.1g}Z\",\n", + " np.log10(gnat_sternberg_data[:,[0, i + 1]]),\n", + " header=header + f\"log10 T [K] Z={z:.1g} log10 Lambda_N [erg cm^3/s]\",\n", + " fmt=(\"%1.2f\",\"%2.4f\"))" ] }, { diff --git a/docs/cooling/plot_lambda.py b/docs/cooling/plot_lambda.py index b82d6a93..1f9f6b74 100644 --- a/docs/cooling/plot_lambda.py +++ b/docs/cooling/plot_lambda.py @@ -25,7 +25,14 @@ ## Gnat and Sternberg (2007) [NOTE: n_H n_e convention for Lambda] # Columns: Temperature Lambda(Z=1e-3) Lambda(Z=1e-2) Lambda(Z=1e-1) Lambda(Z=1) Lambda(Z=2) - gs_T, gs_LambdaZem3, gs_LambdaZem2, gs_LambdaZem1, gs_LambdaZ1, gs_LambdaZ2 = ( + ( + gs_T, + gs_LambdaZem3, + gs_LambdaZem2, + gs_LambdaZem1, + gs_LambdaZ1, + gs_LambdaZ2 + ) = ( np.loadtxt("gnat_sternberg_cie_table.txt", unpack=True, skiprows=23) ) # NOTE: There is not enough information in this table alone to compute n_e! diff --git a/docs/input.md b/docs/input.md index 6d3734d4..c51aa8e7 100644 --- a/docs/input.md +++ b/docs/input.md @@ -216,15 +216,17 @@ than any other timestep constraint (e.g., the hyperbolic one). ### Cooling Tabular cooling (e.g., for optically thin cooling) is enabled through the `cooling` block in the input file. +The tabulated table itself is a text file containing (apart from comments) only two columns (two floating +point numbers per line with the first one being the log10 temperature and the second one the +log10 cooling rate scaled to a source function with $S_{cool} = n_H^2 \Lambda(T)$). + A possible block might look like: ``` -enable_cooling = tabular # To disable, set to `none` -table_filename = updated_schure.cooling # Path to the cooling table (in a text file) -log_temp_col = 0 # Column in the file that contains the log10 temperatures -log_lambda_col = 1 # Column in the file that contains the cooling rates -lambda_units_cgs = 1 # Conversion factor of the cooling rate relative to CGS units +enable_cooling = tabular # To disable, set to `none` +table_filename = schure.cooling_1.0Z # Path to the cooling table (in a text file) +lambda_units_cgs = 1 # Conversion factor of the cooling rate relative to CGS units integrator = townsend # Other possible options are `rk12` and `rk45` for error bound subcycling #max_iter = 100 # Max number of iteration for subcycling. Unsued for Townsend integrator diff --git a/inputs/cloud.in b/inputs/cloud.in index 7df63436..002febd0 100644 --- a/inputs/cloud.in +++ b/inputs/cloud.in @@ -62,9 +62,7 @@ He_mass_fraction = 0.24 enable_cooling = none # turn on with "tabular" -table_filename = updated_schure.cooling -log_temp_col = 0 -log_lambda_col = 1 +table_filename = schure.cooling_1.0Z lambda_units_cgs = 1 integrator = rk12 diff --git a/inputs/cluster/cluster.in b/inputs/cluster/cluster.in index d1355347..62d15ac1 100644 --- a/inputs/cluster/cluster.in +++ b/inputs/cluster/cluster.in @@ -86,9 +86,7 @@ code_time_cgs = 3.15576e+16 # 1 Gyr in s enable_cooling=tabular -table_filename=updated_schure.cooling -log_temp_col=0 -log_lambda_col=1 +table_filename=schure.cooling_1.0Z lambda_units_cgs=1.0 integrator=rk45 diff --git a/inputs/cluster/cooling.in b/inputs/cluster/cooling.in index a8719157..0aeb783b 100644 --- a/inputs/cluster/cooling.in +++ b/inputs/cluster/cooling.in @@ -70,9 +70,7 @@ code_time_cgs = 3.15576e+16 # 1 Gyr in s enable_cooling = tabular -table_filename = updated_schure.cooling -log_temp_col = 0 -log_lambda_col = 1 +table_filename = schure.cooling_1.0Z lambda_units_cgs = 1 #erg cm^3/s in cgs, as used in schure.cooling integrator = rk12 diff --git a/inputs/cooling_tables/gnat-sternberg.cooling b/inputs/cooling_tables/gnat-sternberg.cooling deleted file mode 100644 index bd1233a2..00000000 --- a/inputs/cooling_tables/gnat-sternberg.cooling +++ /dev/null @@ -1,208 +0,0 @@ -# Title: Time-Dependent Ionization in Radiatively Cooling Gas -# Authors: Orly Gnat and Amiel Sternberg -# Table: CIE Cooling Efficiencies -# Converted (i.e., log10) from http://wise-obs.tau.ac.il/~orlyg/cooling/CIEcool/tab13.txt -# -# cooling rates log10(Lambda) in (erg cm^3/s) for various metallicities -# logT Z=1e-3 Z=1e-2 Z=1e-1 Z=1 Z=2 -4.0000 -23.3279 -23.3028 -23.1090 -22.2526 -21.4237 -4.0199 -23.1180 -23.1085 -23.0200 -22.5100 -22.1574 -4.0402 -22.9101 -22.9031 -22.8570 -22.5436 -22.3224 -4.0603 -22.7055 -22.7033 -22.6757 -22.4672 -22.3072 -4.0803 -22.5114 -22.5100 -22.4921 -22.3458 -22.2233 -4.1004 -22.3316 -22.3307 -22.3179 -22.2104 -22.1146 -4.1206 -22.1688 -22.1675 -22.1593 -22.0762 -22.0000 -4.1408 -22.0269 -22.0264 -22.0186 -21.9547 -21.8928 -4.1608 -21.9136 -21.9136 -21.9066 -21.8508 -21.7959 -4.1810 -21.8327 -21.8327 -21.8268 -21.7773 -21.7258 -4.2011 -21.7825 -21.7825 -21.7773 -21.7305 -21.6799 -4.2212 -21.7670 -21.7670 -21.7620 -21.7122 -21.6635 -4.2413 -21.7721 -21.7721 -21.7670 -21.7167 -21.6676 -4.2613 -21.7986 -21.7986 -21.7932 -21.7399 -21.6861 -4.2815 -21.8356 -21.8327 -21.8268 -21.7696 -21.7144 -4.3015 -21.8794 -21.8794 -21.8729 -21.8097 -21.7471 -4.3216 -21.9281 -21.9281 -21.9172 -21.8447 -21.7773 -4.3416 -21.9788 -21.9788 -21.9666 -21.8827 -21.8041 -4.3617 -22.0269 -22.0259 -22.0146 -21.9172 -21.8268 -4.3818 -22.0737 -22.0726 -22.0595 -21.9431 -21.8447 -4.4021 -22.1192 -22.1175 -22.1018 -21.9666 -21.8570 -4.4221 -22.1624 -22.1605 -22.1421 -21.9872 -21.8601 -4.4422 -22.2041 -22.2013 -22.1785 -22.0000 -21.8601 -4.4622 -22.2434 -22.2403 -22.2125 -22.0066 -21.8539 -4.4824 -22.2815 -22.2782 -22.2464 -22.0101 -21.8447 -4.5026 -22.3215 -22.3170 -22.2782 -22.0101 -21.8297 -4.5226 -22.3615 -22.3565 -22.3089 -22.0052 -21.8125 -4.5427 -22.4001 -22.3936 -22.3391 -21.9957 -21.7905 -4.5628 -22.4377 -22.4306 -22.3645 -21.9830 -21.7645 -4.5830 -22.4750 -22.4660 -22.3883 -21.9666 -21.7352 -4.6030 -22.5100 -22.5003 -22.4067 -21.9431 -21.7055 -4.6231 -22.5406 -22.5287 -22.4214 -21.9172 -21.6716 -4.6433 -22.5654 -22.5513 -22.4295 -21.8894 -21.6383 -4.6633 -22.5834 -22.5670 -22.4295 -21.8601 -21.6021 -4.6834 -22.5901 -22.5719 -22.4214 -21.8268 -21.5638 -4.7035 -22.5850 -22.5654 -22.4034 -21.7905 -21.5258 -4.7236 -22.5622 -22.5421 -22.3757 -21.7520 -21.4855 -4.7437 -22.5229 -22.5017 -22.3354 -21.7122 -21.4461 -4.7638 -22.4672 -22.4473 -22.2857 -21.6716 -21.4056 -4.7839 -22.3990 -22.3799 -22.2277 -21.6289 -21.3655 -4.8040 -22.3242 -22.3072 -22.1656 -21.5867 -21.3261 -4.8241 -22.2495 -22.2343 -22.1029 -21.5452 -21.2882 -4.8442 -22.1831 -22.1688 -22.0458 -21.5058 -21.2526 -4.8643 -22.1290 -22.1152 -22.0000 -21.4724 -21.2204 -4.8844 -22.0910 -22.0778 -21.9626 -21.4425 -21.1925 -4.9045 -22.0711 -22.0580 -21.9431 -21.4202 -21.1694 -4.9246 -22.0680 -22.0535 -21.9355 -21.4012 -21.1494 -4.9447 -22.0783 -22.0635 -21.9355 -21.3872 -21.1319 -4.9648 -22.0996 -22.0830 -21.9469 -21.3768 -21.1175 -4.9849 -22.1296 -22.1113 -21.9626 -21.3686 -21.1062 -5.0052 -22.1637 -22.1433 -21.9788 -21.3645 -21.0980 -5.0253 -22.2013 -22.1791 -22.0026 -21.3645 -21.0953 -5.0453 -22.2411 -22.2168 -22.0273 -21.3696 -21.0975 -5.0652 -22.2823 -22.2557 -22.0526 -21.3768 -21.1035 -5.0853 -22.3224 -22.2941 -22.0783 -21.3862 -21.1101 -5.1055 -22.3635 -22.3316 -22.1029 -21.3947 -21.1158 -5.1255 -22.4034 -22.3686 -22.1238 -21.3990 -21.1180 -5.1458 -22.4425 -22.4045 -22.1421 -21.3990 -21.1163 -5.1658 -22.4802 -22.4389 -22.1574 -21.3958 -21.1113 -5.1858 -22.5171 -22.4711 -22.1694 -21.3893 -21.1035 -5.2060 -22.5528 -22.5017 -22.1791 -21.3820 -21.0942 -5.2261 -22.5884 -22.5317 -22.1878 -21.3747 -21.0857 -5.2463 -22.6216 -22.5607 -22.1945 -21.3675 -21.0773 -5.2662 -22.6536 -22.5867 -22.2013 -21.3615 -21.0706 -5.2865 -22.6861 -22.6126 -22.2069 -21.3556 -21.0635 -5.3066 -22.7167 -22.6364 -22.2111 -21.3497 -21.0560 -5.3265 -22.7447 -22.6596 -22.2140 -21.3429 -21.0487 -5.3467 -22.7747 -22.6819 -22.2175 -21.3372 -21.0419 -5.3668 -22.8013 -22.7033 -22.2218 -21.3335 -21.0381 -5.3869 -22.8268 -22.7235 -22.2291 -21.3354 -21.0395 -5.4071 -22.8539 -22.7471 -22.2418 -21.3449 -21.0482 -5.4272 -22.8794 -22.7696 -22.2628 -21.3635 -21.0675 -5.4472 -22.9031 -22.7959 -22.2924 -21.3947 -21.0985 -5.4673 -22.9547 -22.8447 -22.3354 -21.4353 -21.1397 -5.4874 -22.9788 -22.8729 -22.3757 -21.4802 -21.1838 -5.5076 -23.0022 -22.9031 -22.4134 -21.5229 -21.2269 -5.5276 -23.0241 -22.9245 -22.4461 -21.5591 -21.2628 -5.5478 -23.0453 -22.9469 -22.4724 -21.5867 -21.2907 -5.5678 -23.0650 -22.9666 -22.4908 -21.6055 -21.3089 -5.5879 -23.0835 -22.9872 -22.5058 -21.6180 -21.3215 -5.6081 -23.1013 -23.0009 -22.5143 -21.6234 -21.3279 -5.6282 -23.1175 -23.0146 -22.5214 -21.6271 -21.3316 -5.6483 -23.1331 -23.0273 -22.5272 -21.6308 -21.3335 -5.6684 -23.1487 -23.0395 -22.5331 -21.6326 -21.3372 -5.6884 -23.1630 -23.0521 -22.5391 -21.6383 -21.3410 -5.7085 -23.1772 -23.0645 -22.5482 -21.6459 -21.3487 -5.7287 -23.1911 -23.0783 -22.5607 -21.6576 -21.3615 -5.7487 -23.2048 -23.0937 -22.5800 -21.6778 -21.3820 -5.7689 -23.2182 -23.1096 -22.6021 -21.7033 -21.4067 -5.7889 -23.2306 -23.1255 -22.6271 -21.7305 -21.4342 -5.8090 -23.2426 -23.1415 -22.6536 -21.7620 -21.4660 -5.8292 -23.2526 -23.1549 -22.6737 -21.7852 -21.4895 -5.8492 -23.2620 -23.1669 -22.6946 -21.8097 -21.5129 -5.8693 -23.2708 -23.1765 -22.7055 -21.8210 -21.5258 -5.8895 -23.2790 -23.1844 -22.7144 -21.8327 -21.5361 -5.9096 -23.2857 -23.1918 -22.7212 -21.8356 -21.5406 -5.9296 -23.2924 -23.1972 -22.7258 -21.8416 -21.5452 -5.9497 -23.2976 -23.2020 -22.7282 -21.8416 -21.5467 -5.9698 -23.3028 -23.2062 -22.7305 -21.8447 -21.5482 -5.9899 -23.3072 -23.2111 -22.7375 -21.8508 -21.5544 -6.0000 -23.3098 -23.2132 -22.7375 -21.8508 -21.5560 -6.0199 -23.3125 -23.2168 -22.7447 -21.8601 -21.5622 -6.0398 -23.3143 -23.2204 -22.7520 -21.8665 -21.5719 -6.0599 -23.3161 -23.2240 -22.7595 -21.8761 -21.5817 -6.0799 -23.3170 -23.2262 -22.7645 -21.8861 -21.5901 -6.1000 -23.3179 -23.2284 -22.7696 -21.8928 -21.5969 -6.1199 -23.3179 -23.2306 -22.7799 -21.9031 -21.6073 -6.1399 -23.3179 -23.2321 -22.7852 -21.9101 -21.6162 -6.1599 -23.3179 -23.2328 -22.7905 -21.9208 -21.6253 -6.1801 -23.3170 -23.2343 -22.7986 -21.9318 -21.6364 -6.2000 -23.3152 -23.2358 -22.8097 -21.9469 -21.6517 -6.2201 -23.3143 -23.2381 -22.8210 -21.9626 -21.6696 -6.2400 -23.3125 -23.2403 -22.8356 -21.9830 -21.6904 -6.2601 -23.3107 -23.2426 -22.8508 -22.0088 -21.7167 -6.2801 -23.3089 -23.2441 -22.8697 -22.0348 -21.7423 -6.2999 -23.3063 -23.2464 -22.8861 -22.0635 -21.7721 -6.3199 -23.3116 -23.2549 -22.9101 -22.0942 -21.8041 -6.3400 -23.3080 -23.2557 -22.9281 -22.1232 -21.8327 -6.3600 -23.3045 -23.2565 -22.9431 -22.1518 -21.8633 -6.3800 -23.3010 -23.2557 -22.9586 -22.1798 -21.8928 -6.4000 -23.2967 -23.2549 -22.9706 -22.2069 -21.9208 -6.4200 -23.2933 -23.2541 -22.9872 -22.2351 -21.9508 -6.4400 -23.2890 -23.2526 -23.0000 -22.2612 -21.9788 -6.4600 -23.2840 -23.2510 -23.0110 -22.2882 -22.0070 -6.4800 -23.2798 -23.2487 -23.0218 -22.3143 -22.0348 -6.5000 -23.2749 -23.2464 -23.0320 -22.3391 -22.0615 -6.5200 -23.2684 -23.2418 -23.0395 -22.3625 -22.0862 -6.5400 -23.2620 -23.2373 -23.0462 -22.3840 -22.1101 -6.5600 -23.2557 -23.2321 -23.0501 -22.4023 -22.1296 -6.5800 -23.2487 -23.2269 -23.0535 -22.4191 -22.1481 -6.6000 -23.2418 -23.2211 -23.0560 -22.4330 -22.1643 -6.6200 -23.2351 -23.2154 -23.0570 -22.4461 -22.1798 -6.6400 -23.2277 -23.2090 -23.0575 -22.4584 -22.1931 -6.6600 -23.2211 -23.2034 -23.0570 -22.4685 -22.2048 -6.6800 -23.2140 -23.1965 -23.0560 -22.4789 -22.2168 -6.7000 -23.2062 -23.1904 -23.0550 -22.4868 -22.2269 -6.7200 -23.1993 -23.1838 -23.0531 -22.4962 -22.2373 -6.7400 -23.1918 -23.1772 -23.0511 -22.5031 -22.2457 -6.7600 -23.1851 -23.1707 -23.0487 -22.5100 -22.2541 -6.7800 -23.1778 -23.1637 -23.0458 -22.5143 -22.2604 -6.8000 -23.1701 -23.1568 -23.0419 -22.5186 -22.2660 -6.8200 -23.1630 -23.1500 -23.0386 -22.5214 -22.2708 -6.8400 -23.1555 -23.1433 -23.0343 -22.5243 -22.2749 -6.8600 -23.1481 -23.1361 -23.0292 -22.5243 -22.2749 -6.8800 -23.1409 -23.1290 -23.0246 -22.5258 -22.2782 -6.9000 -23.1337 -23.1221 -23.0195 -22.5258 -22.2790 -6.9200 -23.1261 -23.1146 -23.0150 -22.5272 -22.2815 -6.9400 -23.1192 -23.1079 -23.0101 -22.5287 -22.2840 -6.9600 -23.1118 -23.1007 -23.0057 -22.5302 -22.2874 -6.9800 -23.1046 -23.0937 -23.0009 -22.5317 -22.2899 -7.0000 -23.0969 -23.0867 -22.9957 -22.5346 -22.2941 -7.0199 -23.0883 -23.0783 -22.9914 -22.5391 -22.3010 -7.0398 -23.0794 -23.0696 -22.9872 -22.5436 -22.3080 -7.0599 -23.0701 -23.0615 -22.9830 -22.5498 -22.3170 -7.0799 -23.0615 -23.0531 -22.9788 -22.5607 -22.3316 -7.1000 -23.0521 -23.0443 -22.9747 -22.5702 -22.3449 -7.1199 -23.0434 -23.0357 -22.9706 -22.5817 -22.3605 -7.1399 -23.0357 -23.0292 -22.9666 -22.5952 -22.3788 -7.1599 -23.0273 -23.0209 -22.9626 -22.6091 -22.3979 -7.1801 -23.0182 -23.0123 -22.9586 -22.6253 -22.4191 -7.2000 -23.0088 -23.0039 -22.9547 -22.6383 -22.4389 -7.2201 -23.0004 -22.9957 -22.9508 -22.6536 -22.4597 -7.2400 -22.9914 -22.9872 -22.9469 -22.6676 -22.4815 -7.2601 -22.9830 -22.9788 -22.9431 -22.6799 -22.5003 -7.2801 -22.9747 -22.9706 -22.9355 -22.6904 -22.5186 -7.2999 -22.9666 -22.9626 -22.9318 -22.6990 -22.5346 -7.3199 -22.9547 -22.9547 -22.9245 -22.7077 -22.5482 -7.3400 -22.9469 -22.9431 -22.9172 -22.7144 -22.5607 -7.3600 -22.9393 -22.9355 -22.9136 -22.7190 -22.5702 -7.3800 -22.9318 -22.9281 -22.9066 -22.7212 -22.5784 -7.4000 -22.9208 -22.9208 -22.8996 -22.7235 -22.5850 -7.4200 -22.9136 -22.9101 -22.8928 -22.7235 -22.5901 -7.4400 -22.9066 -22.9031 -22.8827 -22.7235 -22.5935 -7.4600 -22.8962 -22.8962 -22.8761 -22.7212 -22.5952 -7.4800 -22.8894 -22.8861 -22.8697 -22.7190 -22.5969 -7.5000 -22.8827 -22.8794 -22.8633 -22.7167 -22.5952 -7.5200 -22.8729 -22.8697 -22.8539 -22.7122 -22.5918 -7.5400 -22.8633 -22.8601 -22.8447 -22.7055 -22.5884 -7.5600 -22.8539 -22.8508 -22.8356 -22.6990 -22.5850 -7.5800 -22.8447 -22.8416 -22.8268 -22.6925 -22.5800 -7.6000 -22.8356 -22.8327 -22.8182 -22.6861 -22.5735 -7.6200 -22.8268 -22.8239 -22.8097 -22.6799 -22.5686 -7.6400 -22.8182 -22.8182 -22.8013 -22.6737 -22.5622 -7.6600 -22.8097 -22.8097 -22.7932 -22.6655 -22.5544 -7.6800 -22.8013 -22.8013 -22.7852 -22.6576 -22.5482 -7.7000 -22.7932 -22.7932 -22.7773 -22.6498 -22.5406 -7.7200 -22.7852 -22.7852 -22.7696 -22.6440 -22.5361 -7.7400 -22.7799 -22.7773 -22.7620 -22.6364 -22.5287 -7.7600 -22.7721 -22.7696 -22.7570 -22.6308 -22.5229 -7.7800 -22.7645 -22.7645 -22.7496 -22.6234 -22.5157 -7.8000 -22.7595 -22.7570 -22.7423 -22.6180 -22.5114 -7.8200 -22.7520 -22.7496 -22.7375 -22.6126 -22.5058 -7.8400 -22.7471 -22.7447 -22.7305 -22.6073 -22.5017 -7.8600 -22.7399 -22.7399 -22.7258 -22.6021 -22.4962 -7.8800 -22.7352 -22.7328 -22.7190 -22.5986 -22.4935 -7.9000 -22.7305 -22.7282 -22.7144 -22.5935 -22.4895 -7.9200 -22.7258 -22.7235 -22.7100 -22.5918 -22.4881 -7.9400 -22.7190 -22.7190 -22.7055 -22.5884 -22.4868 -7.9600 -22.7167 -22.7144 -22.7011 -22.5867 -22.4855 -7.9800 -22.7122 -22.7100 -22.6990 -22.5850 -22.4868 -8.0000 -22.7077 -22.7077 -22.6946 -22.5834 -22.4855 diff --git a/inputs/cooling_tables/gnat-sternberg.cooling_0.001Z b/inputs/cooling_tables/gnat-sternberg.cooling_0.001Z new file mode 100644 index 00000000..13fb61d1 --- /dev/null +++ b/inputs/cooling_tables/gnat-sternberg.cooling_0.001Z @@ -0,0 +1,209 @@ +# Adapted from: http://wise-obs.tau.ac.il/~orlyg/cooling/CIEcool/tab13.txt +# Title: Time-Dependent Ionization in Radiatively Cooling Gas +# Authors: Orly Gnat and Amiel Sternberg +# Table: CIE Cooling Efficiencies +# ----------------------------------------------------------------------------------------- +# Our assumed Z=1 solar abundances are listed in Table 1. +# ----------------------------------------------------------------------------------------- +# log10 T [K] Z=0.001 log10 Lambda_N [erg cm^3/s] +4.00 -23.3279 +4.02 -23.1180 +4.04 -22.9101 +4.06 -22.7055 +4.08 -22.5114 +4.10 -22.3316 +4.12 -22.1688 +4.14 -22.0269 +4.16 -21.9136 +4.18 -21.8327 +4.20 -21.7825 +4.22 -21.7670 +4.24 -21.7721 +4.26 -21.7986 +4.28 -21.8356 +4.30 -21.8794 +4.32 -21.9281 +4.34 -21.9788 +4.36 -22.0269 +4.38 -22.0737 +4.40 -22.1192 +4.42 -22.1624 +4.44 -22.2041 +4.46 -22.2434 +4.48 -22.2815 +4.50 -22.3215 +4.52 -22.3615 +4.54 -22.4001 +4.56 -22.4377 +4.58 -22.4750 +4.60 -22.5100 +4.62 -22.5406 +4.64 -22.5654 +4.66 -22.5834 +4.68 -22.5901 +4.70 -22.5850 +4.72 -22.5622 +4.74 -22.5229 +4.76 -22.4672 +4.78 -22.3990 +4.80 -22.3242 +4.82 -22.2495 +4.84 -22.1831 +4.86 -22.1290 +4.88 -22.0910 +4.90 -22.0711 +4.92 -22.0680 +4.94 -22.0783 +4.96 -22.0996 +4.98 -22.1296 +5.01 -22.1637 +5.03 -22.2013 +5.05 -22.2411 +5.07 -22.2823 +5.09 -22.3224 +5.11 -22.3635 +5.13 -22.4034 +5.15 -22.4425 +5.17 -22.4802 +5.19 -22.5171 +5.21 -22.5528 +5.23 -22.5884 +5.25 -22.6216 +5.27 -22.6536 +5.29 -22.6861 +5.31 -22.7167 +5.33 -22.7447 +5.35 -22.7747 +5.37 -22.8013 +5.39 -22.8268 +5.41 -22.8539 +5.43 -22.8794 +5.45 -22.9031 +5.47 -22.9547 +5.49 -22.9788 +5.51 -23.0022 +5.53 -23.0241 +5.55 -23.0453 +5.57 -23.0650 +5.59 -23.0835 +5.61 -23.1013 +5.63 -23.1175 +5.65 -23.1331 +5.67 -23.1487 +5.69 -23.1630 +5.71 -23.1772 +5.73 -23.1911 +5.75 -23.2048 +5.77 -23.2182 +5.79 -23.2306 +5.81 -23.2426 +5.83 -23.2526 +5.85 -23.2620 +5.87 -23.2708 +5.89 -23.2790 +5.91 -23.2857 +5.93 -23.2924 +5.95 -23.2976 +5.97 -23.3028 +5.99 -23.3072 +6.00 -23.3098 +6.02 -23.3125 +6.04 -23.3143 +6.06 -23.3161 +6.08 -23.3170 +6.10 -23.3179 +6.12 -23.3179 +6.14 -23.3179 +6.16 -23.3179 +6.18 -23.3170 +6.20 -23.3152 +6.22 -23.3143 +6.24 -23.3125 +6.26 -23.3107 +6.28 -23.3089 +6.30 -23.3063 +6.32 -23.3116 +6.34 -23.3080 +6.36 -23.3045 +6.38 -23.3010 +6.40 -23.2967 +6.42 -23.2933 +6.44 -23.2890 +6.46 -23.2840 +6.48 -23.2798 +6.50 -23.2749 +6.52 -23.2684 +6.54 -23.2620 +6.56 -23.2557 +6.58 -23.2487 +6.60 -23.2418 +6.62 -23.2351 +6.64 -23.2277 +6.66 -23.2211 +6.68 -23.2140 +6.70 -23.2062 +6.72 -23.1993 +6.74 -23.1918 +6.76 -23.1851 +6.78 -23.1778 +6.80 -23.1701 +6.82 -23.1630 +6.84 -23.1555 +6.86 -23.1481 +6.88 -23.1409 +6.90 -23.1337 +6.92 -23.1261 +6.94 -23.1192 +6.96 -23.1118 +6.98 -23.1046 +7.00 -23.0969 +7.02 -23.0883 +7.04 -23.0794 +7.06 -23.0701 +7.08 -23.0615 +7.10 -23.0521 +7.12 -23.0434 +7.14 -23.0357 +7.16 -23.0273 +7.18 -23.0182 +7.20 -23.0088 +7.22 -23.0004 +7.24 -22.9914 +7.26 -22.9830 +7.28 -22.9747 +7.30 -22.9666 +7.32 -22.9547 +7.34 -22.9469 +7.36 -22.9393 +7.38 -22.9318 +7.40 -22.9208 +7.42 -22.9136 +7.44 -22.9066 +7.46 -22.8962 +7.48 -22.8894 +7.50 -22.8827 +7.52 -22.8729 +7.54 -22.8633 +7.56 -22.8539 +7.58 -22.8447 +7.60 -22.8356 +7.62 -22.8268 +7.64 -22.8182 +7.66 -22.8097 +7.68 -22.8013 +7.70 -22.7932 +7.72 -22.7852 +7.74 -22.7799 +7.76 -22.7721 +7.78 -22.7645 +7.80 -22.7595 +7.82 -22.7520 +7.84 -22.7471 +7.86 -22.7399 +7.88 -22.7352 +7.90 -22.7305 +7.92 -22.7258 +7.94 -22.7190 +7.96 -22.7167 +7.98 -22.7122 +8.00 -22.7077 diff --git a/inputs/cooling_tables/gnat-sternberg.cooling_0.01Z b/inputs/cooling_tables/gnat-sternberg.cooling_0.01Z new file mode 100644 index 00000000..ca4cf0c4 --- /dev/null +++ b/inputs/cooling_tables/gnat-sternberg.cooling_0.01Z @@ -0,0 +1,209 @@ +# Adapted from: http://wise-obs.tau.ac.il/~orlyg/cooling/CIEcool/tab13.txt +# Title: Time-Dependent Ionization in Radiatively Cooling Gas +# Authors: Orly Gnat and Amiel Sternberg +# Table: CIE Cooling Efficiencies +# ----------------------------------------------------------------------------------------- +# Our assumed Z=1 solar abundances are listed in Table 1. +# ----------------------------------------------------------------------------------------- +# log10 T [K] Z=0.01 log10 Lambda_N [erg cm^3/s] +4.00 -23.3028 +4.02 -23.1085 +4.04 -22.9031 +4.06 -22.7033 +4.08 -22.5100 +4.10 -22.3307 +4.12 -22.1675 +4.14 -22.0264 +4.16 -21.9136 +4.18 -21.8327 +4.20 -21.7825 +4.22 -21.7670 +4.24 -21.7721 +4.26 -21.7986 +4.28 -21.8327 +4.30 -21.8794 +4.32 -21.9281 +4.34 -21.9788 +4.36 -22.0259 +4.38 -22.0726 +4.40 -22.1175 +4.42 -22.1605 +4.44 -22.2013 +4.46 -22.2403 +4.48 -22.2782 +4.50 -22.3170 +4.52 -22.3565 +4.54 -22.3936 +4.56 -22.4306 +4.58 -22.4660 +4.60 -22.5003 +4.62 -22.5287 +4.64 -22.5513 +4.66 -22.5670 +4.68 -22.5719 +4.70 -22.5654 +4.72 -22.5421 +4.74 -22.5017 +4.76 -22.4473 +4.78 -22.3799 +4.80 -22.3072 +4.82 -22.2343 +4.84 -22.1688 +4.86 -22.1152 +4.88 -22.0778 +4.90 -22.0580 +4.92 -22.0535 +4.94 -22.0635 +4.96 -22.0830 +4.98 -22.1113 +5.01 -22.1433 +5.03 -22.1791 +5.05 -22.2168 +5.07 -22.2557 +5.09 -22.2941 +5.11 -22.3316 +5.13 -22.3686 +5.15 -22.4045 +5.17 -22.4389 +5.19 -22.4711 +5.21 -22.5017 +5.23 -22.5317 +5.25 -22.5607 +5.27 -22.5867 +5.29 -22.6126 +5.31 -22.6364 +5.33 -22.6596 +5.35 -22.6819 +5.37 -22.7033 +5.39 -22.7235 +5.41 -22.7471 +5.43 -22.7696 +5.45 -22.7959 +5.47 -22.8447 +5.49 -22.8729 +5.51 -22.9031 +5.53 -22.9245 +5.55 -22.9469 +5.57 -22.9666 +5.59 -22.9872 +5.61 -23.0009 +5.63 -23.0146 +5.65 -23.0273 +5.67 -23.0395 +5.69 -23.0521 +5.71 -23.0645 +5.73 -23.0783 +5.75 -23.0937 +5.77 -23.1096 +5.79 -23.1255 +5.81 -23.1415 +5.83 -23.1549 +5.85 -23.1669 +5.87 -23.1765 +5.89 -23.1844 +5.91 -23.1918 +5.93 -23.1972 +5.95 -23.2020 +5.97 -23.2062 +5.99 -23.2111 +6.00 -23.2132 +6.02 -23.2168 +6.04 -23.2204 +6.06 -23.2240 +6.08 -23.2262 +6.10 -23.2284 +6.12 -23.2306 +6.14 -23.2321 +6.16 -23.2328 +6.18 -23.2343 +6.20 -23.2358 +6.22 -23.2381 +6.24 -23.2403 +6.26 -23.2426 +6.28 -23.2441 +6.30 -23.2464 +6.32 -23.2549 +6.34 -23.2557 +6.36 -23.2565 +6.38 -23.2557 +6.40 -23.2549 +6.42 -23.2541 +6.44 -23.2526 +6.46 -23.2510 +6.48 -23.2487 +6.50 -23.2464 +6.52 -23.2418 +6.54 -23.2373 +6.56 -23.2321 +6.58 -23.2269 +6.60 -23.2211 +6.62 -23.2154 +6.64 -23.2090 +6.66 -23.2034 +6.68 -23.1965 +6.70 -23.1904 +6.72 -23.1838 +6.74 -23.1772 +6.76 -23.1707 +6.78 -23.1637 +6.80 -23.1568 +6.82 -23.1500 +6.84 -23.1433 +6.86 -23.1361 +6.88 -23.1290 +6.90 -23.1221 +6.92 -23.1146 +6.94 -23.1079 +6.96 -23.1007 +6.98 -23.0937 +7.00 -23.0867 +7.02 -23.0783 +7.04 -23.0696 +7.06 -23.0615 +7.08 -23.0531 +7.10 -23.0443 +7.12 -23.0357 +7.14 -23.0292 +7.16 -23.0209 +7.18 -23.0123 +7.20 -23.0039 +7.22 -22.9957 +7.24 -22.9872 +7.26 -22.9788 +7.28 -22.9706 +7.30 -22.9626 +7.32 -22.9547 +7.34 -22.9431 +7.36 -22.9355 +7.38 -22.9281 +7.40 -22.9208 +7.42 -22.9101 +7.44 -22.9031 +7.46 -22.8962 +7.48 -22.8861 +7.50 -22.8794 +7.52 -22.8697 +7.54 -22.8601 +7.56 -22.8508 +7.58 -22.8416 +7.60 -22.8327 +7.62 -22.8239 +7.64 -22.8182 +7.66 -22.8097 +7.68 -22.8013 +7.70 -22.7932 +7.72 -22.7852 +7.74 -22.7773 +7.76 -22.7696 +7.78 -22.7645 +7.80 -22.7570 +7.82 -22.7496 +7.84 -22.7447 +7.86 -22.7399 +7.88 -22.7328 +7.90 -22.7282 +7.92 -22.7235 +7.94 -22.7190 +7.96 -22.7144 +7.98 -22.7100 +8.00 -22.7077 diff --git a/inputs/cooling_tables/gnat-sternberg.cooling_0.1Z b/inputs/cooling_tables/gnat-sternberg.cooling_0.1Z new file mode 100644 index 00000000..53f1ceb3 --- /dev/null +++ b/inputs/cooling_tables/gnat-sternberg.cooling_0.1Z @@ -0,0 +1,209 @@ +# Adapted from: http://wise-obs.tau.ac.il/~orlyg/cooling/CIEcool/tab13.txt +# Title: Time-Dependent Ionization in Radiatively Cooling Gas +# Authors: Orly Gnat and Amiel Sternberg +# Table: CIE Cooling Efficiencies +# ----------------------------------------------------------------------------------------- +# Our assumed Z=1 solar abundances are listed in Table 1. +# ----------------------------------------------------------------------------------------- +# log10 T [K] Z=0.1 log10 Lambda_N [erg cm^3/s] +4.00 -23.1090 +4.02 -23.0200 +4.04 -22.8570 +4.06 -22.6757 +4.08 -22.4921 +4.10 -22.3179 +4.12 -22.1593 +4.14 -22.0186 +4.16 -21.9066 +4.18 -21.8268 +4.20 -21.7773 +4.22 -21.7620 +4.24 -21.7670 +4.26 -21.7932 +4.28 -21.8268 +4.30 -21.8729 +4.32 -21.9172 +4.34 -21.9666 +4.36 -22.0146 +4.38 -22.0595 +4.40 -22.1018 +4.42 -22.1421 +4.44 -22.1785 +4.46 -22.2125 +4.48 -22.2464 +4.50 -22.2782 +4.52 -22.3089 +4.54 -22.3391 +4.56 -22.3645 +4.58 -22.3883 +4.60 -22.4067 +4.62 -22.4214 +4.64 -22.4295 +4.66 -22.4295 +4.68 -22.4214 +4.70 -22.4034 +4.72 -22.3757 +4.74 -22.3354 +4.76 -22.2857 +4.78 -22.2277 +4.80 -22.1656 +4.82 -22.1029 +4.84 -22.0458 +4.86 -22.0000 +4.88 -21.9626 +4.90 -21.9431 +4.92 -21.9355 +4.94 -21.9355 +4.96 -21.9469 +4.98 -21.9626 +5.01 -21.9788 +5.03 -22.0026 +5.05 -22.0273 +5.07 -22.0526 +5.09 -22.0783 +5.11 -22.1029 +5.13 -22.1238 +5.15 -22.1421 +5.17 -22.1574 +5.19 -22.1694 +5.21 -22.1791 +5.23 -22.1878 +5.25 -22.1945 +5.27 -22.2013 +5.29 -22.2069 +5.31 -22.2111 +5.33 -22.2140 +5.35 -22.2175 +5.37 -22.2218 +5.39 -22.2291 +5.41 -22.2418 +5.43 -22.2628 +5.45 -22.2924 +5.47 -22.3354 +5.49 -22.3757 +5.51 -22.4134 +5.53 -22.4461 +5.55 -22.4724 +5.57 -22.4908 +5.59 -22.5058 +5.61 -22.5143 +5.63 -22.5214 +5.65 -22.5272 +5.67 -22.5331 +5.69 -22.5391 +5.71 -22.5482 +5.73 -22.5607 +5.75 -22.5800 +5.77 -22.6021 +5.79 -22.6271 +5.81 -22.6536 +5.83 -22.6737 +5.85 -22.6946 +5.87 -22.7055 +5.89 -22.7144 +5.91 -22.7212 +5.93 -22.7258 +5.95 -22.7282 +5.97 -22.7305 +5.99 -22.7375 +6.00 -22.7375 +6.02 -22.7447 +6.04 -22.7520 +6.06 -22.7595 +6.08 -22.7645 +6.10 -22.7696 +6.12 -22.7799 +6.14 -22.7852 +6.16 -22.7905 +6.18 -22.7986 +6.20 -22.8097 +6.22 -22.8210 +6.24 -22.8356 +6.26 -22.8508 +6.28 -22.8697 +6.30 -22.8861 +6.32 -22.9101 +6.34 -22.9281 +6.36 -22.9431 +6.38 -22.9586 +6.40 -22.9706 +6.42 -22.9872 +6.44 -23.0000 +6.46 -23.0110 +6.48 -23.0218 +6.50 -23.0320 +6.52 -23.0395 +6.54 -23.0462 +6.56 -23.0501 +6.58 -23.0535 +6.60 -23.0560 +6.62 -23.0570 +6.64 -23.0575 +6.66 -23.0570 +6.68 -23.0560 +6.70 -23.0550 +6.72 -23.0531 +6.74 -23.0511 +6.76 -23.0487 +6.78 -23.0458 +6.80 -23.0419 +6.82 -23.0386 +6.84 -23.0343 +6.86 -23.0292 +6.88 -23.0246 +6.90 -23.0195 +6.92 -23.0150 +6.94 -23.0101 +6.96 -23.0057 +6.98 -23.0009 +7.00 -22.9957 +7.02 -22.9914 +7.04 -22.9872 +7.06 -22.9830 +7.08 -22.9788 +7.10 -22.9747 +7.12 -22.9706 +7.14 -22.9666 +7.16 -22.9626 +7.18 -22.9586 +7.20 -22.9547 +7.22 -22.9508 +7.24 -22.9469 +7.26 -22.9431 +7.28 -22.9355 +7.30 -22.9318 +7.32 -22.9245 +7.34 -22.9172 +7.36 -22.9136 +7.38 -22.9066 +7.40 -22.8996 +7.42 -22.8928 +7.44 -22.8827 +7.46 -22.8761 +7.48 -22.8697 +7.50 -22.8633 +7.52 -22.8539 +7.54 -22.8447 +7.56 -22.8356 +7.58 -22.8268 +7.60 -22.8182 +7.62 -22.8097 +7.64 -22.8013 +7.66 -22.7932 +7.68 -22.7852 +7.70 -22.7773 +7.72 -22.7696 +7.74 -22.7620 +7.76 -22.7570 +7.78 -22.7496 +7.80 -22.7423 +7.82 -22.7375 +7.84 -22.7305 +7.86 -22.7258 +7.88 -22.7190 +7.90 -22.7144 +7.92 -22.7100 +7.94 -22.7055 +7.96 -22.7011 +7.98 -22.6990 +8.00 -22.6946 diff --git a/inputs/cooling_tables/gnat-sternberg.cooling_1Z b/inputs/cooling_tables/gnat-sternberg.cooling_1Z new file mode 100644 index 00000000..9fdcaf94 --- /dev/null +++ b/inputs/cooling_tables/gnat-sternberg.cooling_1Z @@ -0,0 +1,209 @@ +# Adapted from: http://wise-obs.tau.ac.il/~orlyg/cooling/CIEcool/tab13.txt +# Title: Time-Dependent Ionization in Radiatively Cooling Gas +# Authors: Orly Gnat and Amiel Sternberg +# Table: CIE Cooling Efficiencies +# ----------------------------------------------------------------------------------------- +# Our assumed Z=1 solar abundances are listed in Table 1. +# ----------------------------------------------------------------------------------------- +# log10 T [K] Z=1 log10 Lambda_N [erg cm^3/s] +4.00 -22.2526 +4.02 -22.5100 +4.04 -22.5436 +4.06 -22.4672 +4.08 -22.3458 +4.10 -22.2104 +4.12 -22.0762 +4.14 -21.9547 +4.16 -21.8508 +4.18 -21.7773 +4.20 -21.7305 +4.22 -21.7122 +4.24 -21.7167 +4.26 -21.7399 +4.28 -21.7696 +4.30 -21.8097 +4.32 -21.8447 +4.34 -21.8827 +4.36 -21.9172 +4.38 -21.9431 +4.40 -21.9666 +4.42 -21.9872 +4.44 -22.0000 +4.46 -22.0066 +4.48 -22.0101 +4.50 -22.0101 +4.52 -22.0052 +4.54 -21.9957 +4.56 -21.9830 +4.58 -21.9666 +4.60 -21.9431 +4.62 -21.9172 +4.64 -21.8894 +4.66 -21.8601 +4.68 -21.8268 +4.70 -21.7905 +4.72 -21.7520 +4.74 -21.7122 +4.76 -21.6716 +4.78 -21.6289 +4.80 -21.5867 +4.82 -21.5452 +4.84 -21.5058 +4.86 -21.4724 +4.88 -21.4425 +4.90 -21.4202 +4.92 -21.4012 +4.94 -21.3872 +4.96 -21.3768 +4.98 -21.3686 +5.01 -21.3645 +5.03 -21.3645 +5.05 -21.3696 +5.07 -21.3768 +5.09 -21.3862 +5.11 -21.3947 +5.13 -21.3990 +5.15 -21.3990 +5.17 -21.3958 +5.19 -21.3893 +5.21 -21.3820 +5.23 -21.3747 +5.25 -21.3675 +5.27 -21.3615 +5.29 -21.3556 +5.31 -21.3497 +5.33 -21.3429 +5.35 -21.3372 +5.37 -21.3335 +5.39 -21.3354 +5.41 -21.3449 +5.43 -21.3635 +5.45 -21.3947 +5.47 -21.4353 +5.49 -21.4802 +5.51 -21.5229 +5.53 -21.5591 +5.55 -21.5867 +5.57 -21.6055 +5.59 -21.6180 +5.61 -21.6234 +5.63 -21.6271 +5.65 -21.6308 +5.67 -21.6326 +5.69 -21.6383 +5.71 -21.6459 +5.73 -21.6576 +5.75 -21.6778 +5.77 -21.7033 +5.79 -21.7305 +5.81 -21.7620 +5.83 -21.7852 +5.85 -21.8097 +5.87 -21.8210 +5.89 -21.8327 +5.91 -21.8356 +5.93 -21.8416 +5.95 -21.8416 +5.97 -21.8447 +5.99 -21.8508 +6.00 -21.8508 +6.02 -21.8601 +6.04 -21.8665 +6.06 -21.8761 +6.08 -21.8861 +6.10 -21.8928 +6.12 -21.9031 +6.14 -21.9101 +6.16 -21.9208 +6.18 -21.9318 +6.20 -21.9469 +6.22 -21.9626 +6.24 -21.9830 +6.26 -22.0088 +6.28 -22.0348 +6.30 -22.0635 +6.32 -22.0942 +6.34 -22.1232 +6.36 -22.1518 +6.38 -22.1798 +6.40 -22.2069 +6.42 -22.2351 +6.44 -22.2612 +6.46 -22.2882 +6.48 -22.3143 +6.50 -22.3391 +6.52 -22.3625 +6.54 -22.3840 +6.56 -22.4023 +6.58 -22.4191 +6.60 -22.4330 +6.62 -22.4461 +6.64 -22.4584 +6.66 -22.4685 +6.68 -22.4789 +6.70 -22.4868 +6.72 -22.4962 +6.74 -22.5031 +6.76 -22.5100 +6.78 -22.5143 +6.80 -22.5186 +6.82 -22.5214 +6.84 -22.5243 +6.86 -22.5243 +6.88 -22.5258 +6.90 -22.5258 +6.92 -22.5272 +6.94 -22.5287 +6.96 -22.5302 +6.98 -22.5317 +7.00 -22.5346 +7.02 -22.5391 +7.04 -22.5436 +7.06 -22.5498 +7.08 -22.5607 +7.10 -22.5702 +7.12 -22.5817 +7.14 -22.5952 +7.16 -22.6091 +7.18 -22.6253 +7.20 -22.6383 +7.22 -22.6536 +7.24 -22.6676 +7.26 -22.6799 +7.28 -22.6904 +7.30 -22.6990 +7.32 -22.7077 +7.34 -22.7144 +7.36 -22.7190 +7.38 -22.7212 +7.40 -22.7235 +7.42 -22.7235 +7.44 -22.7235 +7.46 -22.7212 +7.48 -22.7190 +7.50 -22.7167 +7.52 -22.7122 +7.54 -22.7055 +7.56 -22.6990 +7.58 -22.6925 +7.60 -22.6861 +7.62 -22.6799 +7.64 -22.6737 +7.66 -22.6655 +7.68 -22.6576 +7.70 -22.6498 +7.72 -22.6440 +7.74 -22.6364 +7.76 -22.6308 +7.78 -22.6234 +7.80 -22.6180 +7.82 -22.6126 +7.84 -22.6073 +7.86 -22.6021 +7.88 -22.5986 +7.90 -22.5935 +7.92 -22.5918 +7.94 -22.5884 +7.96 -22.5867 +7.98 -22.5850 +8.00 -22.5834 diff --git a/inputs/cooling_tables/gnat-sternberg.cooling_2Z b/inputs/cooling_tables/gnat-sternberg.cooling_2Z new file mode 100644 index 00000000..87995a09 --- /dev/null +++ b/inputs/cooling_tables/gnat-sternberg.cooling_2Z @@ -0,0 +1,209 @@ +# Adapted from: http://wise-obs.tau.ac.il/~orlyg/cooling/CIEcool/tab13.txt +# Title: Time-Dependent Ionization in Radiatively Cooling Gas +# Authors: Orly Gnat and Amiel Sternberg +# Table: CIE Cooling Efficiencies +# ----------------------------------------------------------------------------------------- +# Our assumed Z=1 solar abundances are listed in Table 1. +# ----------------------------------------------------------------------------------------- +# log10 T [K] Z=2 log10 Lambda_N [erg cm^3/s] +4.00 -21.4237 +4.02 -22.1574 +4.04 -22.3224 +4.06 -22.3072 +4.08 -22.2233 +4.10 -22.1146 +4.12 -22.0000 +4.14 -21.8928 +4.16 -21.7959 +4.18 -21.7258 +4.20 -21.6799 +4.22 -21.6635 +4.24 -21.6676 +4.26 -21.6861 +4.28 -21.7144 +4.30 -21.7471 +4.32 -21.7773 +4.34 -21.8041 +4.36 -21.8268 +4.38 -21.8447 +4.40 -21.8570 +4.42 -21.8601 +4.44 -21.8601 +4.46 -21.8539 +4.48 -21.8447 +4.50 -21.8297 +4.52 -21.8125 +4.54 -21.7905 +4.56 -21.7645 +4.58 -21.7352 +4.60 -21.7055 +4.62 -21.6716 +4.64 -21.6383 +4.66 -21.6021 +4.68 -21.5638 +4.70 -21.5258 +4.72 -21.4855 +4.74 -21.4461 +4.76 -21.4056 +4.78 -21.3655 +4.80 -21.3261 +4.82 -21.2882 +4.84 -21.2526 +4.86 -21.2204 +4.88 -21.1925 +4.90 -21.1694 +4.92 -21.1494 +4.94 -21.1319 +4.96 -21.1175 +4.98 -21.1062 +5.01 -21.0980 +5.03 -21.0953 +5.05 -21.0975 +5.07 -21.1035 +5.09 -21.1101 +5.11 -21.1158 +5.13 -21.1180 +5.15 -21.1163 +5.17 -21.1113 +5.19 -21.1035 +5.21 -21.0942 +5.23 -21.0857 +5.25 -21.0773 +5.27 -21.0706 +5.29 -21.0635 +5.31 -21.0560 +5.33 -21.0487 +5.35 -21.0419 +5.37 -21.0381 +5.39 -21.0395 +5.41 -21.0482 +5.43 -21.0675 +5.45 -21.0985 +5.47 -21.1397 +5.49 -21.1838 +5.51 -21.2269 +5.53 -21.2628 +5.55 -21.2907 +5.57 -21.3089 +5.59 -21.3215 +5.61 -21.3279 +5.63 -21.3316 +5.65 -21.3335 +5.67 -21.3372 +5.69 -21.3410 +5.71 -21.3487 +5.73 -21.3615 +5.75 -21.3820 +5.77 -21.4067 +5.79 -21.4342 +5.81 -21.4660 +5.83 -21.4895 +5.85 -21.5129 +5.87 -21.5258 +5.89 -21.5361 +5.91 -21.5406 +5.93 -21.5452 +5.95 -21.5467 +5.97 -21.5482 +5.99 -21.5544 +6.00 -21.5560 +6.02 -21.5622 +6.04 -21.5719 +6.06 -21.5817 +6.08 -21.5901 +6.10 -21.5969 +6.12 -21.6073 +6.14 -21.6162 +6.16 -21.6253 +6.18 -21.6364 +6.20 -21.6517 +6.22 -21.6696 +6.24 -21.6904 +6.26 -21.7167 +6.28 -21.7423 +6.30 -21.7721 +6.32 -21.8041 +6.34 -21.8327 +6.36 -21.8633 +6.38 -21.8928 +6.40 -21.9208 +6.42 -21.9508 +6.44 -21.9788 +6.46 -22.0070 +6.48 -22.0348 +6.50 -22.0615 +6.52 -22.0862 +6.54 -22.1101 +6.56 -22.1296 +6.58 -22.1481 +6.60 -22.1643 +6.62 -22.1798 +6.64 -22.1931 +6.66 -22.2048 +6.68 -22.2168 +6.70 -22.2269 +6.72 -22.2373 +6.74 -22.2457 +6.76 -22.2541 +6.78 -22.2604 +6.80 -22.2660 +6.82 -22.2708 +6.84 -22.2749 +6.86 -22.2749 +6.88 -22.2782 +6.90 -22.2790 +6.92 -22.2815 +6.94 -22.2840 +6.96 -22.2874 +6.98 -22.2899 +7.00 -22.2941 +7.02 -22.3010 +7.04 -22.3080 +7.06 -22.3170 +7.08 -22.3316 +7.10 -22.3449 +7.12 -22.3605 +7.14 -22.3788 +7.16 -22.3979 +7.18 -22.4191 +7.20 -22.4389 +7.22 -22.4597 +7.24 -22.4815 +7.26 -22.5003 +7.28 -22.5186 +7.30 -22.5346 +7.32 -22.5482 +7.34 -22.5607 +7.36 -22.5702 +7.38 -22.5784 +7.40 -22.5850 +7.42 -22.5901 +7.44 -22.5935 +7.46 -22.5952 +7.48 -22.5969 +7.50 -22.5952 +7.52 -22.5918 +7.54 -22.5884 +7.56 -22.5850 +7.58 -22.5800 +7.60 -22.5735 +7.62 -22.5686 +7.64 -22.5622 +7.66 -22.5544 +7.68 -22.5482 +7.70 -22.5406 +7.72 -22.5361 +7.74 -22.5287 +7.76 -22.5229 +7.78 -22.5157 +7.80 -22.5114 +7.82 -22.5058 +7.84 -22.5017 +7.86 -22.4962 +7.88 -22.4935 +7.90 -22.4895 +7.92 -22.4881 +7.94 -22.4868 +7.96 -22.4855 +7.98 -22.4868 +8.00 -22.4855 diff --git a/inputs/cooling_tables/schure.cooling_0.3Z b/inputs/cooling_tables/schure.cooling_0.3Z new file mode 100644 index 00000000..a3e8cfc6 --- /dev/null +++ b/inputs/cooling_tables/schure.cooling_0.3Z @@ -0,0 +1,111 @@ +# Cooling rates generated from Schure 2009 (doi.org/10.1051/0004-6361/200912495) +# containing temperatures in the first column (in log10 K) and collisional ionisation +# equilibrium (CIE) cooling rates (in log10 erg cm^3/s). +# Cooling rates are in the convention Lambda_hd from eq. 1, +# where the proton ratio n_e/n_H is taken from table 2. +# Lambda_N is computed from eq. 3. The cooling rate Lambda_N(X_i,T) from eq. 3 is contained +# in table 4. n_i/n_i(solar) is taken to be 1.0 for all elements for Z=1 while for Z=0.5 +# and Z=0.3 n_i/n_i(solar) is set to 1 for H and He and set to 0.5 and 0.3 respectively for +# all other elements. Made by Forrest Glines (forrestglines@gmail.com) +# ----------------------------------------------------------------------------------------- +# log10 T [K] Z=0.3 log10 Lambda_N [erg cm^3/s] +4.20 -21.6114 +4.24 -21.4833 +4.28 -21.5129 +4.32 -21.5974 +4.36 -21.6878 +4.40 -21.7659 +4.44 -21.8092 +4.48 -21.8230 +4.52 -21.8059 +4.56 -21.7621 +4.60 -21.6941 +4.64 -21.6111 +4.68 -21.5286 +4.72 -21.4387 +4.76 -21.3589 +4.80 -21.2816 +4.84 -21.2168 +4.88 -21.1700 +4.92 -21.1423 +4.96 -21.1331 +5.00 -21.1525 +5.04 -21.1820 +5.08 -21.2077 +5.12 -21.2093 +5.16 -21.2043 +5.20 -21.1937 +5.24 -21.1832 +5.28 -21.1811 +5.32 -21.1799 +5.36 -21.1883 +5.40 -21.2263 +5.44 -21.3118 +5.48 -21.4700 +5.52 -21.6521 +5.56 -21.7926 +5.60 -21.8728 +5.64 -21.9090 +5.68 -21.9290 +5.72 -21.9539 +5.76 -22.0008 +5.80 -22.0678 +5.84 -22.1209 +5.88 -22.1521 +5.92 -22.1698 +5.96 -22.1804 +6.00 -22.1977 +6.04 -22.2178 +6.08 -22.2383 +6.12 -22.2459 +6.16 -22.2557 +6.20 -22.2736 +6.24 -22.3075 +6.28 -22.3657 +6.32 -22.4391 +6.36 -22.5207 +6.40 -22.5909 +6.44 -22.6490 +6.48 -22.6878 +6.52 -22.7148 +6.56 -22.7308 +6.60 -22.7361 +6.64 -22.7379 +6.68 -22.7283 +6.72 -22.7216 +6.76 -22.7102 +6.80 -22.7023 +6.84 -22.6962 +6.88 -22.6921 +6.92 -22.6959 +6.96 -22.6994 +7.00 -22.7050 +7.04 -22.7170 +7.08 -22.7249 +7.12 -22.7378 +7.16 -22.7480 +7.20 -22.7629 +7.24 -22.7710 +7.28 -22.7697 +7.32 -22.7655 +7.36 -22.7605 +7.40 -22.7565 +7.44 -22.7461 +7.48 -22.7323 +7.52 -22.7176 +7.56 -22.7039 +7.60 -22.6873 +7.64 -22.6700 +7.68 -22.6613 +7.72 -22.6436 +7.76 -22.6251 +7.80 -22.6071 +7.84 -22.5914 +7.88 -22.5727 +7.92 -22.5542 +7.96 -22.5360 +8.00 -22.5172 +8.04 -22.5014 +8.08 -22.4828 +8.12 -22.4642 +8.16 -22.4455 diff --git a/inputs/cooling_tables/schure.cooling_0.5Z b/inputs/cooling_tables/schure.cooling_0.5Z new file mode 100644 index 00000000..8f23fbce --- /dev/null +++ b/inputs/cooling_tables/schure.cooling_0.5Z @@ -0,0 +1,111 @@ +# Cooling rates generated from Schure 2009 (doi.org/10.1051/0004-6361/200912495) +# containing temperatures in the first column (in log10 K) and collisional ionisation +# equilibrium (CIE) cooling rates (in log10 erg cm^3/s). +# Cooling rates are in the convention Lambda_hd from eq. 1, +# where the proton ratio n_e/n_H is taken from table 2. +# Lambda_N is computed from eq. 3. The cooling rate Lambda_N(X_i,T) from eq. 3 is contained +# in table 4. n_i/n_i(solar) is taken to be 1.0 for all elements for Z=1 while for Z=0.5 +# and Z=0.3 n_i/n_i(solar) is set to 1 for H and He and set to 0.5 and 0.3 respectively for +# all other elements. Made by Forrest Glines (forrestglines@gmail.com) +# ----------------------------------------------------------------------------------------- +# log10 T [K] Z=0.5 log10 Lambda_N [erg cm^3/s] +4.20 -21.6106 +4.24 -21.4817 +4.28 -21.5094 +4.32 -21.5894 +4.36 -21.6708 +4.40 -21.7330 +4.44 -21.7528 +4.48 -21.7361 +4.52 -21.6873 +4.56 -21.6136 +4.60 -21.5229 +4.64 -21.4248 +4.68 -21.3330 +4.72 -21.2392 +4.76 -21.1599 +4.80 -21.0871 +4.84 -21.0286 +4.88 -20.9858 +4.92 -20.9582 +4.96 -20.9451 +5.00 -20.9602 +5.04 -20.9861 +5.08 -21.0079 +5.12 -21.0052 +5.16 -20.9968 +5.20 -20.9834 +5.24 -20.9707 +5.28 -20.9670 +5.32 -20.9647 +5.36 -20.9722 +5.40 -21.0099 +5.44 -21.0958 +5.48 -21.2556 +5.52 -21.4404 +5.56 -21.5834 +5.60 -21.6649 +5.64 -21.7010 +5.68 -21.7207 +5.72 -21.7454 +5.76 -21.7931 +5.80 -21.8615 +5.84 -21.9160 +5.88 -21.9476 +5.92 -21.9656 +5.96 -21.9760 +6.00 -21.9938 +6.04 -22.0144 +6.08 -22.0355 +6.12 -22.0433 +6.16 -22.0536 +6.20 -22.0725 +6.24 -22.1082 +6.28 -22.1698 +6.32 -22.2486 +6.36 -22.3375 +6.40 -22.4159 +6.44 -22.4820 +6.48 -22.5278 +6.52 -22.5612 +6.56 -22.5811 +6.60 -22.5905 +6.64 -22.5940 +6.68 -22.5857 +6.72 -22.5797 +6.76 -22.5694 +6.80 -22.5612 +6.84 -22.5573 +6.88 -22.5566 +6.92 -22.5635 +6.96 -22.5718 +7.00 -22.5831 +7.04 -22.6010 +7.08 -22.6169 +7.12 -22.6391 +7.16 -22.6596 +7.20 -22.6840 +7.24 -22.7021 +7.28 -22.7090 +7.32 -22.7121 +7.36 -22.7129 +7.40 -22.7135 +7.44 -22.7065 +7.48 -22.6959 +7.52 -22.6840 +7.56 -22.6722 +7.60 -22.6574 +7.64 -22.6418 +7.68 -22.6337 +7.72 -22.6173 +7.76 -22.5998 +7.80 -22.5828 +7.84 -22.5679 +7.88 -22.5500 +7.92 -22.5324 +7.96 -22.5152 +8.00 -22.4972 +8.04 -22.4822 +8.08 -22.4644 +8.12 -22.4467 +8.16 -22.4287 diff --git a/inputs/cooling_tables/schure.cooling_1.0Z b/inputs/cooling_tables/schure.cooling_1.0Z new file mode 100644 index 00000000..93aac5e5 --- /dev/null +++ b/inputs/cooling_tables/schure.cooling_1.0Z @@ -0,0 +1,111 @@ +# Cooling rates generated from Schure 2009 (doi.org/10.1051/0004-6361/200912495) +# containing temperatures in the first column (in log10 K) and collisional ionisation +# equilibrium (CIE) cooling rates (in log10 erg cm^3/s). +# Cooling rates are in the convention Lambda_hd from eq. 1, +# where the proton ratio n_e/n_H is taken from table 2. +# Lambda_N is computed from eq. 3. The cooling rate Lambda_N(X_i,T) from eq. 3 is contained +# in table 4. n_i/n_i(solar) is taken to be 1.0 for all elements for Z=1 while for Z=0.5 +# and Z=0.3 n_i/n_i(solar) is set to 1 for H and He and set to 0.5 and 0.3 respectively for +# all other elements. Made by Forrest Glines (forrestglines@gmail.com) +# ----------------------------------------------------------------------------------------- +# log10 T [K] Z=1.0 log10 Lambda_N [erg cm^3/s] +4.20 -21.6087 +4.24 -21.4779 +4.28 -21.5009 +4.32 -21.5702 +4.36 -21.6311 +4.40 -21.6603 +4.44 -21.6373 +4.48 -21.5738 +4.52 -21.4838 +4.56 -21.3771 +4.60 -21.2642 +4.64 -21.1525 +4.68 -21.0529 +4.72 -20.9557 +4.76 -20.8769 +4.80 -20.8078 +4.84 -20.7546 +4.88 -20.7154 +4.92 -20.6877 +4.96 -20.6713 +5.00 -20.6828 +5.04 -20.7056 +5.08 -20.7242 +5.12 -20.7180 +5.16 -20.7069 +5.20 -20.6912 +5.24 -20.6768 +5.28 -20.6720 +5.32 -20.6687 +5.36 -20.6755 +5.40 -20.7130 +5.44 -20.7993 +5.48 -20.9603 +5.52 -21.1472 +5.56 -21.2921 +5.60 -21.3746 +5.64 -21.4107 +5.68 -21.4301 +5.72 -21.4547 +5.76 -21.5029 +5.80 -21.5726 +5.84 -21.6281 +5.88 -21.6600 +5.92 -21.6782 +5.96 -21.6885 +6.00 -21.7067 +6.04 -21.7277 +6.08 -21.7494 +6.12 -21.7574 +6.16 -21.7680 +6.20 -21.7877 +6.24 -21.8248 +6.28 -21.8893 +6.32 -21.9727 +6.36 -22.0680 +6.40 -22.1536 +6.44 -22.2272 +6.48 -22.2797 +6.52 -22.3195 +6.56 -22.3434 +6.60 -22.3570 +6.64 -22.3622 +6.68 -22.3553 +6.72 -22.3501 +6.76 -22.3409 +6.80 -22.3324 +6.84 -22.3309 +6.88 -22.3340 +6.92 -22.3443 +6.96 -22.3580 +7.00 -22.3758 +7.04 -22.4007 +7.08 -22.4264 +7.12 -22.4606 +7.16 -22.4953 +7.20 -22.5331 +7.24 -22.5666 +7.28 -22.5865 +7.32 -22.6018 +7.36 -22.6128 +7.40 -22.6215 +7.44 -22.6209 +7.48 -22.6164 +7.52 -22.6101 +7.56 -22.6019 +7.60 -22.5907 +7.64 -22.5782 +7.68 -22.5715 +7.72 -22.5577 +7.76 -22.5421 +7.80 -22.5275 +7.84 -22.5143 +7.88 -22.4980 +7.92 -22.4822 +7.96 -22.4671 +8.00 -22.4508 +8.04 -22.4375 +8.08 -22.4215 +8.12 -22.4056 +8.16 -22.3893 diff --git a/inputs/cooling_tables/updated_schure.cooling b/inputs/cooling_tables/updated_schure.cooling deleted file mode 100644 index 3eecb9f0..00000000 --- a/inputs/cooling_tables/updated_schure.cooling +++ /dev/null @@ -1,111 +0,0 @@ -# Cooling rates generated from Schure 2009 (doi.org/10.1051/0004-6361/200912495) -# containing temperatures in the first column (in log10 K) and collisional ionisation -# equilibrium (CIE) cooling rates (in log10 erg cm^3/s) for Z=1 solar metalicity, Z=0.5, -# and Z=0.3 across the columns. Cooling rates are in the convention Lambda_hd from eq. 1, -# where the proton ratio n_e/n_H is taken from table 2. -# Lambda_N is computed from eq. 3. The cooling rate Lambda_N(X_i,T) from eq. 3 is contained -# in table 4. n_i/n_i(solar) is taken to be 1.0 for all elements for Z=1 while for Z=0.5 -# and Z=0.5 n_i/n_i(solar) is set to 1 for H and He and set to 0.5 and 0.3 respectively for -# all other elements. Made by Forrest Glines (forrestglines@gmail.com) -# ----------------------------------------------------------------------------------------- -# log10 T [K] Z=1 log10 Lambda_N [erg cm^3/s] Z=0.5 log10 Lambda_N [erg cm^3/s] Z=0.3 log10 Lambda_N [erg cm^3/s] -4.20 -21.6087 -21.6106 -21.6114 -4.24 -21.4779 -21.4817 -21.4833 -4.28 -21.5009 -21.5094 -21.5129 -4.32 -21.5702 -21.5894 -21.5974 -4.36 -21.6311 -21.6708 -21.6878 -4.40 -21.6603 -21.7330 -21.7659 -4.44 -21.6373 -21.7528 -21.8092 -4.48 -21.5738 -21.7361 -21.8230 -4.52 -21.4838 -21.6873 -21.8059 -4.56 -21.3771 -21.6136 -21.7621 -4.60 -21.2642 -21.5229 -21.6941 -4.64 -21.1525 -21.4248 -21.6111 -4.68 -21.0529 -21.3330 -21.5286 -4.72 -20.9557 -21.2392 -21.4387 -4.76 -20.8769 -21.1599 -21.3589 -4.80 -20.8078 -21.0871 -21.2816 -4.84 -20.7546 -21.0286 -21.2168 -4.88 -20.7154 -20.9858 -21.1700 -4.92 -20.6877 -20.9582 -21.1423 -4.96 -20.6713 -20.9451 -21.1331 -5.00 -20.6828 -20.9602 -21.1525 -5.04 -20.7056 -20.9861 -21.1820 -5.08 -20.7242 -21.0079 -21.2077 -5.12 -20.7180 -21.0052 -21.2093 -5.16 -20.7069 -20.9968 -21.2043 -5.20 -20.6912 -20.9834 -21.1937 -5.24 -20.6768 -20.9707 -21.1832 -5.28 -20.6720 -20.9670 -21.1811 -5.32 -20.6687 -20.9647 -21.1799 -5.36 -20.6755 -20.9722 -21.1883 -5.40 -20.7130 -21.0099 -21.2263 -5.44 -20.7993 -21.0958 -21.3118 -5.48 -20.9603 -21.2556 -21.4700 -5.52 -21.1472 -21.4404 -21.6521 -5.56 -21.2921 -21.5834 -21.7926 -5.60 -21.3746 -21.6649 -21.8728 -5.64 -21.4107 -21.7010 -21.9090 -5.68 -21.4301 -21.7207 -21.9290 -5.72 -21.4547 -21.7454 -21.9539 -5.76 -21.5029 -21.7931 -22.0008 -5.80 -21.5726 -21.8615 -22.0678 -5.84 -21.6281 -21.9160 -22.1209 -5.88 -21.6600 -21.9476 -22.1521 -5.92 -21.6782 -21.9656 -22.1698 -5.96 -21.6885 -21.9760 -22.1804 -6.00 -21.7067 -21.9938 -22.1977 -6.04 -21.7277 -22.0144 -22.2178 -6.08 -21.7494 -22.0355 -22.2383 -6.12 -21.7574 -22.0433 -22.2459 -6.16 -21.7680 -22.0536 -22.2557 -6.20 -21.7877 -22.0725 -22.2736 -6.24 -21.8248 -22.1082 -22.3075 -6.28 -21.8893 -22.1698 -22.3657 -6.32 -21.9727 -22.2486 -22.4391 -6.36 -22.0680 -22.3375 -22.5207 -6.40 -22.1536 -22.4159 -22.5909 -6.44 -22.2272 -22.4820 -22.6490 -6.48 -22.2797 -22.5278 -22.6878 -6.52 -22.3195 -22.5612 -22.7148 -6.56 -22.3434 -22.5811 -22.7308 -6.60 -22.3570 -22.5905 -22.7361 -6.64 -22.3622 -22.5940 -22.7379 -6.68 -22.3553 -22.5857 -22.7283 -6.72 -22.3501 -22.5797 -22.7216 -6.76 -22.3409 -22.5694 -22.7102 -6.80 -22.3324 -22.5612 -22.7023 -6.84 -22.3309 -22.5573 -22.6962 -6.88 -22.3340 -22.5566 -22.6921 -6.92 -22.3443 -22.5635 -22.6959 -6.96 -22.3580 -22.5718 -22.6994 -7.00 -22.3758 -22.5831 -22.7050 -7.04 -22.4007 -22.6010 -22.7170 -7.08 -22.4264 -22.6169 -22.7249 -7.12 -22.4606 -22.6391 -22.7378 -7.16 -22.4953 -22.6596 -22.7480 -7.20 -22.5331 -22.6840 -22.7629 -7.24 -22.5666 -22.7021 -22.7710 -7.28 -22.5865 -22.7090 -22.7697 -7.32 -22.6018 -22.7121 -22.7655 -7.36 -22.6128 -22.7129 -22.7605 -7.40 -22.6215 -22.7135 -22.7565 -7.44 -22.6209 -22.7065 -22.7461 -7.48 -22.6164 -22.6959 -22.7323 -7.52 -22.6101 -22.6840 -22.7176 -7.56 -22.6019 -22.6722 -22.7039 -7.60 -22.5907 -22.6574 -22.6873 -7.64 -22.5782 -22.6418 -22.6700 -7.68 -22.5715 -22.6337 -22.6613 -7.72 -22.5577 -22.6173 -22.6436 -7.76 -22.5421 -22.5998 -22.6251 -7.80 -22.5275 -22.5828 -22.6071 -7.84 -22.5143 -22.5679 -22.5914 -7.88 -22.4980 -22.5500 -22.5727 -7.92 -22.4822 -22.5324 -22.5542 -7.96 -22.4671 -22.5152 -22.5360 -8.00 -22.4508 -22.4972 -22.5172 -8.04 -22.4375 -22.4822 -22.5014 -8.08 -22.4215 -22.4644 -22.4828 -8.12 -22.4056 -22.4467 -22.4642 -8.16 -22.3893 -22.4287 -22.4455 diff --git a/src/hydro/srcterms/tabular_cooling.cpp b/src/hydro/srcterms/tabular_cooling.cpp index 9164f4cc..7143029b 100644 --- a/src/hydro/srcterms/tabular_cooling.cpp +++ b/src/hydro/srcterms/tabular_cooling.cpp @@ -33,8 +33,17 @@ TabularCooling::TabularCooling(ParameterInput *pin, const std::string table_filename = pin->GetString("cooling", "table_filename"); - const int log_temp_col = pin->GetOrAddInteger("cooling", "log_temp_col", 0); - const int log_lambda_col = pin->GetOrAddInteger("cooling", "log_lambda_col", 1); + // It should be fine to just issue a warning here. + // If an original cooling table with two columns was used, the behavior is the same. + // If not, then the test below on the number of columns in the file will fail. + if (Globals::my_rank == 0 && (pin->DoesParameterExist("cooling", "log_temp_col") || + pin->DoesParameterExist("cooling", "log_lambda_col"))) { + PARTHENON_WARN("\"cooling/log_temp_col\" or \"cooling/log_lambda_col\" found in" + "the parameter input.\n" + "These have been deprecated and only cooling tables for a single " + "metallicity containing the log10 temperature and log10 lambdas are " + "supported.\n"); + } const Real lambda_units_cgs = pin->GetReal("cooling", "lambda_units_cgs"); // Convert erg cm^3/s to code units @@ -109,16 +118,16 @@ TabularCooling::TabularCooling(ParameterInput *pin, std::vector line_data{std::istream_iterator{iss}, std::istream_iterator{}}; // Check size - if (line_data.empty() || line_data.size() <= std::max(log_temp_col, log_lambda_col)) { + if (line_data.empty() || line_data.size() != 2) { msg << "### FATAL ERROR in function [TabularCooling::TabularCooling]" << std::endl - << "Index " << std::max(log_temp_col, log_lambda_col) << " out of range on \"" - << line << "\"" << std::endl; + << "Expected exactly two columns per line but got: \"" << line << "\"" + << std::endl; PARTHENON_FAIL(msg); } try { - const Real log_temp = std::stod(line_data[log_temp_col]); - const Real log_lambda = std::stod(line_data[log_lambda_col]); + const Real log_temp = std::stod(line_data[0]); + const Real log_lambda = std::stod(line_data[1]); // Add to growing list log_temps.push_back(log_temp); diff --git a/tst/regression/test_suites/cluster_tabular_cooling/cluster_tabular_cooling.py b/tst/regression/test_suites/cluster_tabular_cooling/cluster_tabular_cooling.py index e04cdc60..1b4b0077 100644 --- a/tst/regression/test_suites/cluster_tabular_cooling/cluster_tabular_cooling.py +++ b/tst/regression/test_suites/cluster_tabular_cooling/cluster_tabular_cooling.py @@ -170,8 +170,6 @@ def Prepare(self, parameters, step): f"problem/cluster/uniform_gas/uz={self.uniform_gas_uz.in_units('code_length*code_time**-1').v}", f"problem/cluster/uniform_gas/pres={self.uniform_gas_pres.in_units('code_mass*code_length**-1*code_time**-2').v}", f"cooling/table_filename={table_filename}", - f"cooling/log_temp_col=0", - f"cooling/log_lambda_col=1", f"cooling/lambda_units_cgs=1", f"cooling/integrator={integrator}", f"cooling/cfl={cooling_cfl}", From 342352b512ed872e39201e77e2574fd71777a7b9 Mon Sep 17 00:00:00 2001 From: Philipp Grete Date: Fri, 30 Aug 2024 15:48:28 +0200 Subject: [PATCH 20/21] silly inconsistencies in black formatting... --- docs/cooling/plot_lambda.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/cooling/plot_lambda.py b/docs/cooling/plot_lambda.py index 1f9f6b74..ccb9b5bc 100644 --- a/docs/cooling/plot_lambda.py +++ b/docs/cooling/plot_lambda.py @@ -31,10 +31,8 @@ gs_LambdaZem2, gs_LambdaZem1, gs_LambdaZ1, - gs_LambdaZ2 - ) = ( - np.loadtxt("gnat_sternberg_cie_table.txt", unpack=True, skiprows=23) - ) + gs_LambdaZ2, + ) = np.loadtxt("gnat_sternberg_cie_table.txt", unpack=True, skiprows=23) # NOTE: There is not enough information in this table alone to compute n_e! # (The electron fraction must be computed from datafile2a.txt) From 7a50cca13132738b6cd590de1ada2f3463c73b6c Mon Sep 17 00:00:00 2001 From: Philipp Grete Date: Mon, 9 Sep 2024 11:36:39 +0200 Subject: [PATCH 21/21] Bump Parthenon and Kokkos (#114) * bump Parthenon * Bump Parth to include restart ghost fix * update parthenon to openpmd branch * Bump Kokkos 4.4.0 and Parthenon 24.08 * Fix history filename * Update interface (cleanup and workaround) * cpp-py-formatter * Fix typo * Fix unit handling in hse test * Bump CI image to be used * Chagne CI machine * And back to the old machine * Limit timestep * Fix logical location * Back to good old CI container (with slightly updated python modules) * adjust container resources * Disable CUDA IPC in CI container --------- Co-authored-by: Ben Wibking Co-authored-by: par-hermes --- .github/workflows/ci.yml | 9 +++-- CHANGELOG.md | 8 ++++ external/Kokkos | 2 +- external/parthenon | 2 +- src/pgen/cloud.cpp | 3 +- src/pgen/cluster.cpp | 3 +- src/pgen/pgen.hpp | 6 ++- src/pgen/turbulence.cpp | 3 +- src/utils/few_modes_ft.cpp | 12 +++--- .../aniso_therm_cond_gauss_conv.py | 13 ++++++- .../aniso_therm_cond_ring_conv.py | 11 ++++-- .../aniso_therm_cond_ring_multid.py | 10 +++-- .../test_suites/cluster_hse/cluster_hse.py | 38 ++++++++----------- .../cluster_tabular_cooling.py | 30 ++++++--------- .../test_suites/field_loop/field_loop.py | 6 +-- .../riemann_hydro/riemann_hydro.py | 12 +++--- .../test_suites/turbulence/turbulence.py | 8 ++-- 17 files changed, 99 insertions(+), 77 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 05049ba7..1d8fbe03 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,6 +14,9 @@ env: CMAKE_BUILD_PARALLEL_LEVEL: 8 # num threads for build MACHINE_CFG: external/parthenon/cmake/machinecfg/CI.cmake OMPI_MCA_mpi_common_cuda_event_max: 1000 + # disable CUDA IPC within container entirely as it's causing issue for + # unknown reasons, see https://github.com/parthenon-hpc-lab/athenapk/pull/114 + OMPI_MCA_btl_smcuda_use_cuda_ipc: 0 jobs: regression: @@ -22,9 +25,9 @@ jobs: parallel: ['serial', 'mpi'] runs-on: [self-hosted, A100] container: - image: ghcr.io/parthenon-hpc-lab/cuda11.6-mpi-hdf5-ascent + image: ghcr.io/parthenon-hpc-lab/cuda11.6-noascent # map to local user id on CI machine to allow writing to build cache - options: --user 1001 + options: --user 1001 --cap-add CAP_SYS_PTRACE --shm-size="8g" --ulimit memlock=134217728 steps: - uses: actions/checkout@v3 with: @@ -56,6 +59,6 @@ jobs: build/tst/regression/outputs/aniso_therm_cond_gauss_conv/cond.png build/tst/regression/outputs/field_loop/field_loop.png build/tst/regression/outputs/riemann_hydro/shock_tube.png - build/tst/regression/outputs/turbulence/parthenon.hst + build/tst/regression/outputs/turbulence/parthenon.out1.hst retention-days: 3 diff --git a/CHANGELOG.md b/CHANGELOG.md index 17e1877b..e5957e43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ ### Fixed (not changing behavior/API/variables/...) ### Infrastructure +- [[PR 114]](https://github.com/parthenon-hpc-lab/athenapk/pull/114) Bump Parthenon 24.08 and Kokkos to 4.4.00 - [[PR 112]](https://github.com/parthenon-hpc-lab/athenapk/pull/112) Add dev container configuration - [[PR 105]](https://github.com/parthenon-hpc-lab/athenapk/pull/105) Bump Parthenon to latest develop (2024-03-13) - [[PR 84]](https://github.com/parthenon-hpc-lab/athenapk/pull/84) Added `CHANGELOG.md` @@ -19,6 +20,13 @@ ### Removed (removing behavior/API/varaibles/...) ### Incompatibilities (i.e. breaking changes) +- [[PR 114]](https://github.com/parthenon-hpc-lab/athenapk/pull/114) Bump Parthenon 24.08 and Kokkos to 4.4.00 + - Changed signature of `UserWorkBeforeOutput` to include `SimTime` as last paramter + - Fixes bitwise idential restarts for AMR simulations (the derefinement counter is now included) + - Order of operations in flux-correction has changed (expect round-off error differences to previous results for AMR sims) + - History outputs now carry the output block number, i.e., a file previously called parthenon.hst might now be called parthenon.out1.hst + - History outputs now contain two additional columns (cycle number and meshblock counts), which changes/shifts the column indices (hint: use the column headers to parse the contents and do not rely on fixed indices as they may also vary between different pgen due to custom/pgen-dependent content in the history file) + - Given the introduction of a forest of tree (rather than a single tree), the logical locations are each meshblock (`pmb->loc`) are now local to the tree and not global any more. To recover the original global index use `auto loc = pmb->pmy_mesh->Forest().GetLegacyTreeLocation(pmb->loc);` - [[PR 97]](https://github.com/parthenon-hpc-lab/athenapk/pull/97) - Removes original `schure.cooling` cooling curve as it had unknown origin. - To avoid confusion, only cooling table for a single solar metallicity are supported diff --git a/external/Kokkos b/external/Kokkos index 62d2b6c8..08ceff92 160000 --- a/external/Kokkos +++ b/external/Kokkos @@ -1 +1 @@ -Subproject commit 62d2b6c879b74b6ae7bd06eb3e5e80139c4708e6 +Subproject commit 08ceff92bcf3a828844480bc1e6137eb74028517 diff --git a/external/parthenon b/external/parthenon index a66670bb..ec61c9cb 160000 --- a/external/parthenon +++ b/external/parthenon @@ -1 +1 @@ -Subproject commit a66670bbc767fe03ef48a33794c6cd288ee517ed +Subproject commit ec61c9cb102d6a67a4dd03e7d7fa4e10c82c1032 diff --git a/src/pgen/cloud.cpp b/src/pgen/cloud.cpp index db53990a..890f52dc 100644 --- a/src/pgen/cloud.cpp +++ b/src/pgen/cloud.cpp @@ -229,9 +229,10 @@ void InflowWindX2(std::shared_ptr> &mbd, bool coarse) { const auto Bx_ = Bx; const auto By_ = By; const auto Bz_ = Bz; + const bool fine = false; pmb->par_for_bndry( "InflowWindX2", nb, IndexDomain::inner_x2, parthenon::TopologicalElement::CC, - coarse, KOKKOS_LAMBDA(const int, const int &k, const int &j, const int &i) { + coarse, fine, KOKKOS_LAMBDA(const int &, const int &k, const int &j, const int &i) { cons(IDN, k, j, i) = rho_wind_; cons(IM2, k, j, i) = mom_wind_; cons(IEN, k, j, i) = rhoe_wind_ + 0.5 * mom_wind_ * mom_wind_ / rho_wind_; diff --git a/src/pgen/cluster.cpp b/src/pgen/cluster.cpp index 1e73d8b5..ecc19336 100644 --- a/src/pgen/cluster.cpp +++ b/src/pgen/cluster.cpp @@ -812,7 +812,8 @@ void ProblemGenerator(Mesh *pmesh, ParameterInput *pin, MeshData *md) { } } -void UserWorkBeforeOutput(MeshBlock *pmb, ParameterInput *pin) { +void UserWorkBeforeOutput(MeshBlock *pmb, ParameterInput *pin, + const parthenon::SimTime & /*tm*/) { // get hydro auto pkg = pmb->packages.Get("Hydro"); const Real gam = pin->GetReal("hydro", "gamma"); diff --git a/src/pgen/pgen.hpp b/src/pgen/pgen.hpp index 182d8497..b3e55aad 100644 --- a/src/pgen/pgen.hpp +++ b/src/pgen/pgen.hpp @@ -99,7 +99,8 @@ using namespace parthenon::driver::prelude; void ProblemInitPackageData(ParameterInput *pin, parthenon::StateDescriptor *pkg); void InitUserMeshData(ParameterInput *pin); void ProblemGenerator(Mesh *pmesh, ParameterInput *pin, MeshData *md); -void UserWorkBeforeOutput(MeshBlock *pmb, ParameterInput *pin); +void UserWorkBeforeOutput(MeshBlock *pmb, ParameterInput *pin, + const parthenon::SimTime &tm); void ClusterUnsplitSrcTerm(MeshData *md, const parthenon::SimTime &tm, const Real beta_dt); void ClusterSplitSrcTerm(MeshData *md, const parthenon::SimTime &tm, @@ -120,7 +121,8 @@ void ProblemGenerator(Mesh *pm, parthenon::ParameterInput *pin, MeshData * void ProblemInitPackageData(ParameterInput *pin, parthenon::StateDescriptor *pkg); void Driving(MeshData *md, const parthenon::SimTime &tm, const Real dt); void SetPhases(MeshBlock *pmb, ParameterInput *pin); -void UserWorkBeforeOutput(MeshBlock *pmb, ParameterInput *pin); +void UserWorkBeforeOutput(MeshBlock *pmb, ParameterInput *pin, + const parthenon::SimTime &tm); void Cleanup(); } // namespace turbulence diff --git a/src/pgen/turbulence.cpp b/src/pgen/turbulence.cpp index 2c9ff9a7..b137a9ad 100644 --- a/src/pgen/turbulence.cpp +++ b/src/pgen/turbulence.cpp @@ -450,7 +450,8 @@ void Driving(MeshData *md, const parthenon::SimTime &tm, const Real dt) { Perturb(md, dt); } -void UserWorkBeforeOutput(MeshBlock *pmb, ParameterInput *pin) { +void UserWorkBeforeOutput(MeshBlock *pmb, ParameterInput *pin, + const parthenon::SimTime & /*tm*/) { auto hydro_pkg = pmb->packages.Get("Hydro"); // Store (common) acceleration field in spectral space diff --git a/src/utils/few_modes_ft.cpp b/src/utils/few_modes_ft.cpp index e42edde2..5d22d042 100644 --- a/src/utils/few_modes_ft.cpp +++ b/src/utils/few_modes_ft.cpp @@ -9,18 +9,15 @@ // C++ headers #include -#include // Parthenon headers #include "basic_types.hpp" #include "config.hpp" #include "globals.hpp" #include "kokkos_abstraction.hpp" -#include "mesh/domain.hpp" #include "mesh/meshblock_pack.hpp" // AthenaPK headers -#include "../main.hpp" #include "few_modes_ft.hpp" #include "utils/error_checking.hpp" @@ -130,9 +127,12 @@ void FewModesFT::SetPhases(MeshBlock *pmb, ParameterInput *pin) { const auto nx2 = pmb->block_size.nx(X2DIR); const auto nx3 = pmb->block_size.nx(X3DIR); - const auto gis = pmb->loc.lx1() * pmb->block_size.nx(X1DIR); - const auto gjs = pmb->loc.lx2() * pmb->block_size.nx(X2DIR); - const auto gks = pmb->loc.lx3() * pmb->block_size.nx(X3DIR); + // Need to use legacy locations (which are global) because locations now are local + // to the tree, which results in inconsistencies for meshes with multiple trees. + const auto loc = pmb->pmy_mesh->Forest().GetLegacyTreeLocation(pmb->loc); + const auto gis = loc.lx1() * pmb->block_size.nx(X1DIR); + const auto gjs = loc.lx2() * pmb->block_size.nx(X2DIR); + const auto gks = loc.lx3() * pmb->block_size.nx(X3DIR); // make local ref to capure in lambda const auto num_modes = num_modes_; diff --git a/tst/regression/test_suites/aniso_therm_cond_gauss_conv/aniso_therm_cond_gauss_conv.py b/tst/regression/test_suites/aniso_therm_cond_gauss_conv/aniso_therm_cond_gauss_conv.py index 9f002723..fb2a187b 100644 --- a/tst/regression/test_suites/aniso_therm_cond_gauss_conv/aniso_therm_cond_gauss_conv.py +++ b/tst/regression/test_suites/aniso_therm_cond_gauss_conv/aniso_therm_cond_gauss_conv.py @@ -98,6 +98,10 @@ def Prepare(self, parameters, step): "parthenon/output0/id=%s" % outname, "hydro/gamma=2.0", "parthenon/time/tlim=%f" % tlim, + # Work around for RKL2 integrator (that, by default, does not limit the + # timestep, which in newer versions of Parthenon results in triggering + # a fail-safe given the default init value of numeric_limits max. + "parthenon/time/dt_ceil=%f" % tlim, "diffusion/conduction=%s" % conduction, "diffusion/thermal_diff_coeff_code=0.25", "diffusion/integrator=%s" % int_cfg, @@ -137,10 +141,15 @@ def get_ref(x, Bx, field_cfg): outname = get_outname(all_cfgs[step]) data_filename = f"{parameters.output_path}/parthenon.{outname}.final.phdf" data_file = phdf.phdf(data_filename) - prim = data_file.Get("prim") zz, yy, xx = data_file.GetVolumeLocations() mask = yy == yy[0] - temp = prim[4][mask] + # Flatten=true (default) is currently (Sep 24) broken so we manually flatten + components = data_file.GetComponents( + data_file.Info["ComponentNames"], flatten=False + ) + temp = components["prim_pressure"].ravel()[ + mask + ] # because of gamma = 2.0 and rho = 1 -> p = e = T x = xx[mask] res, field_cfg, int_cfg = all_cfgs[step] row = res_cfgs.index(res) diff --git a/tst/regression/test_suites/aniso_therm_cond_ring_conv/aniso_therm_cond_ring_conv.py b/tst/regression/test_suites/aniso_therm_cond_ring_conv/aniso_therm_cond_ring_conv.py index db2ae4e4..ba13129e 100644 --- a/tst/regression/test_suites/aniso_therm_cond_ring_conv/aniso_therm_cond_ring_conv.py +++ b/tst/regression/test_suites/aniso_therm_cond_ring_conv/aniso_therm_cond_ring_conv.py @@ -35,7 +35,6 @@ class TestCase(utils.test_case.TestCaseAbs): def Prepare(self, parameters, step): - assert parameters.num_ranks <= 4, "Use <= 4 ranks for diffusion test." res = res_cfgs[step - 1] @@ -78,8 +77,14 @@ def Analyse(self, parameters): for res in res_cfgs: data_filename = f"{parameters.output_path}/parthenon.{res}.final.phdf" data_file = phdf.phdf(data_filename) - prim = data_file.Get("prim") - T = prim[4] # because of gamma = 2.0 and rho = 1 -> p = e = T + # Flatten=true (default) is currently (Sep 24) broken so we manually flatten + components = data_file.GetComponents( + data_file.Info["ComponentNames"], flatten=False + ) + T = components[ + "prim_pressure" + ].ravel() # because of gamma = 2.0 and rho = 1 -> p = e = T + zz, yy, xx = data_file.GetVolumeLocations() r = np.sqrt(xx**2 + yy**2) diff --git a/tst/regression/test_suites/aniso_therm_cond_ring_multid/aniso_therm_cond_ring_multid.py b/tst/regression/test_suites/aniso_therm_cond_ring_multid/aniso_therm_cond_ring_multid.py index bf1e0416..3f933507 100644 --- a/tst/regression/test_suites/aniso_therm_cond_ring_multid/aniso_therm_cond_ring_multid.py +++ b/tst/regression/test_suites/aniso_therm_cond_ring_multid/aniso_therm_cond_ring_multid.py @@ -35,7 +35,6 @@ class TestCase(utils.test_case.TestCaseAbs): def Prepare(self, parameters, step): - assert parameters.num_ranks <= 4, "Use <= 4 ranks for diffusion test." # 2D reference case again @@ -110,8 +109,13 @@ def Analyse(self, parameters): for step in range(1, 5): data_filename = f"{parameters.output_path}/parthenon.{step}.final.phdf" data_file = phdf.phdf(data_filename) - prim = data_file.Get("prim") - T = prim[4] # because of gamma = 2.0 and rho = 1 -> p = e = T + # Flatten=true (default) is currently (Sep 24) broken so we manually flatten + components = data_file.GetComponents( + data_file.Info["ComponentNames"], flatten=False + ) + T = components[ + "prim_pressure" + ].ravel() # because of gamma = 2.0 and rho = 1 -> p = e = T zz, yy, xx = data_file.GetVolumeLocations() if step == 1 or step == 2: r = np.sqrt(xx**2 + yy**2) diff --git a/tst/regression/test_suites/cluster_hse/cluster_hse.py b/tst/regression/test_suites/cluster_hse/cluster_hse.py index 0f567e4f..9c8ec012 100644 --- a/tst/regression/test_suites/cluster_hse/cluster_hse.py +++ b/tst/regression/test_suites/cluster_hse/cluster_hse.py @@ -211,21 +211,15 @@ def AnalyseInitPert(self, parameters): # flatten array as prim var are also flattended cell_vol = cell_vol.ravel() - prim = data_file.Get("prim") - - # FIXME: For now this is hard coded - a component mapping should be done by phdf - prim_col_dict = { - "velocity_1": 1, - "velocity_2": 2, - "velocity_3": 3, - "magnetic_field_1": 5, - "magnetic_field_2": 6, - "magnetic_field_3": 7, - } - - vx = prim[prim_col_dict["velocity_1"]] - vy = prim[prim_col_dict["velocity_2"]] - vz = prim[prim_col_dict["velocity_3"]] + # Flatten=true (default) is currently (Sep 24) broken so we manually flatten + components = data_file.GetComponents( + data_file.Info["ComponentNames"], flatten=False + ) + rho = components["prim_density"].ravel() + vx = components["prim_velocity_1"].ravel() + vy = components["prim_velocity_2"].ravel() + vz = components["prim_velocity_3"].ravel() + pres = components["prim_pressure"].ravel() # volume weighted rms velocity rms_v = np.sqrt( @@ -243,9 +237,9 @@ def AnalyseInitPert(self, parameters): f"Expected {self.sigma_v.in_units('code_velocity')} but got {rms_v}\n" ) - bx = prim[prim_col_dict["magnetic_field_1"]] - by = prim[prim_col_dict["magnetic_field_2"]] - bz = prim[prim_col_dict["magnetic_field_3"]] + bx = components["prim_magnetic_field_1"].ravel() + by = components["prim_magnetic_field_2"].ravel() + bz = components["prim_magnetic_field_3"].ravel() # volume weighted rms magnetic field rms_b = np.sqrt( @@ -394,11 +388,11 @@ def rk4(f, y0, T): # Prepare two array of R leading inwards and outwards from the virial radius, to integrate R_in = unyt.unyt_array( - np.hstack((R[R < self.R_fix], self.R_fix.in_units("code_length"))), + np.hstack((R[R < self.R_fix].v, self.R_fix.in_units("code_length").v)), "code_length", ) R_out = unyt.unyt_array( - np.hstack((self.R_fix.in_units("code_length"), R[R > self.R_fix])), + np.hstack((self.R_fix.in_units("code_length").v, R[R > self.R_fix].v)), "code_length", ) @@ -412,7 +406,7 @@ def rk4(f, y0, T): # Put the two pieces of P together P = unyt.unyt_array( np.hstack( - (P_in[:-1].in_units("dyne/cm**2"), P_out[1:].in_units("dyne/cm**2")) + (P_in[:-1].in_units("dyne/cm**2").v, P_out[1:].in_units("dyne/cm**2").v) ), "dyne/cm**2", ) @@ -537,7 +531,7 @@ def rk4(f, y0, T): # Compare the initial output to the analytic model def analytic_gold(Z, Y, X, analytic_var): - r = np.sqrt(X**2 + Y**2 + Z**2) + r = unyt.unyt_array(np.sqrt(X**2 + Y**2 + Z**2), "code_length") analytic_interp = unyt.unyt_array( np.interp(r, analytic_R, analytic_var), analytic_var.units ) diff --git a/tst/regression/test_suites/cluster_tabular_cooling/cluster_tabular_cooling.py b/tst/regression/test_suites/cluster_tabular_cooling/cluster_tabular_cooling.py index 1b4b0077..77a8cfeb 100644 --- a/tst/regression/test_suites/cluster_tabular_cooling/cluster_tabular_cooling.py +++ b/tst/regression/test_suites/cluster_tabular_cooling/cluster_tabular_cooling.py @@ -310,19 +310,16 @@ def zero_corrected_linf_err(gold, test): analyze_status = False data_file = phdf.phdf(data_filename) - prim = data_file.Get("prim") - - # FIXME: TODO(forrestglines) For now this is hard coded - a component mapping should be done by phdf - prim_col_dict = { - "density": 0, - "pressure": 4, - } + # Flatten=true (default) is currently (Sep 24) broken so we manually flatten + components = data_file.GetComponents( + data_file.Info["ComponentNames"], flatten=False + ) rho = unyt.unyt_array( - prim[prim_col_dict["density"], :], "code_mass*code_length**-3" + components["prim_density"].ravel(), "code_mass*code_length**-3" ) pres = unyt.unyt_array( - prim[prim_col_dict["pressure"], :], + components["prim_pressure"].ravel(), "code_mass*code_length**-1*code_time**-2", ) @@ -364,19 +361,16 @@ def zero_corrected_linf_err(gold, test): analyze_status = False data_file = phdf.phdf(data_filename) - prim = data_file.Get("prim") - - # FIXME: TODO(forrestglines) For now this is hard coded - a component mapping should be done by phdf - prim_col_dict = { - "density": 0, - "pressure": 4, - } + # Flatten=true (default) is currently (Sep 24) broken so we manually flatten + components = data_file.GetComponents( + data_file.Info["ComponentNames"], flatten=False + ) rho = unyt.unyt_array( - prim[prim_col_dict["density"]], "code_mass*code_length**-3" + components["prim_density"].ravel(), "code_mass*code_length**-3" ) pres = unyt.unyt_array( - prim[prim_col_dict["pressure"]], + components["prim_pressure"].ravel(), "code_mass*code_length**-1*code_time**-2", ) diff --git a/tst/regression/test_suites/field_loop/field_loop.py b/tst/regression/test_suites/field_loop/field_loop.py index b752f535..07e032b0 100644 --- a/tst/regression/test_suites/field_loop/field_loop.py +++ b/tst/regression/test_suites/field_loop/field_loop.py @@ -135,13 +135,13 @@ def Analyse(self, parameters): for step in range(len(all_cfgs)): outname = get_outname(all_cfgs[step]) - data_filename = f"{parameters.output_path}/{outname}.hst" + data_filename = f"{parameters.output_path}/{outname}.out1.hst" data = np.genfromtxt(data_filename) res, method = all_cfgs[step] row = method_cfgs.index(method) - p[row, 0].plot(data[:, 0], data[:, 8] / data[0, 8], label=outname) - p[row, 1].plot(data[:, 0], data[:, 10], label=outname) + p[row, 0].plot(data[:, 0], data[:, 10] / data[0, 10], label=outname) + p[row, 1].plot(data[:, 0], data[:, 12], label=outname) p[0, 0].set_title("Emag(t)/Emag(0)") p[0, 1].set_title("rel DivB") diff --git a/tst/regression/test_suites/riemann_hydro/riemann_hydro.py b/tst/regression/test_suites/riemann_hydro/riemann_hydro.py index 9d0fc1f4..1a926371 100644 --- a/tst/regression/test_suites/riemann_hydro/riemann_hydro.py +++ b/tst/regression/test_suites/riemann_hydro/riemann_hydro.py @@ -58,7 +58,6 @@ class TestCase(utils.test_case.TestCaseAbs): def Prepare(self, parameters, step): - method, init_cond = all_cfgs[step - 1] nx1 = method["nx1"] @@ -126,10 +125,13 @@ def Analyse(self, parameters): data_filename = f"{parameters.output_path}/parthenon.{step + 1}.final.phdf" data_file = phdf.phdf(data_filename) - prim = data_file.Get("prim") - rho = prim[0] - vx = prim[1] - pres = prim[4] + # Flatten=true (default) is currently (Sep 24) broken so we manually flatten + components = data_file.GetComponents( + data_file.Info["ComponentNames"], flatten=False + ) + rho = components["prim_density"].ravel() + vx = components["prim_velocity_1"].ravel() + pres = components["prim_pressure"].ravel() zz, yy, xx = data_file.GetVolumeLocations() label = ( diff --git a/tst/regression/test_suites/turbulence/turbulence.py b/tst/regression/test_suites/turbulence/turbulence.py index eddbd38e..c5a492a1 100644 --- a/tst/regression/test_suites/turbulence/turbulence.py +++ b/tst/regression/test_suites/turbulence/turbulence.py @@ -22,7 +22,6 @@ class TestCase(utils.test_case.TestCaseAbs): def Prepare(self, parameters, step): - parameters.driver_cmd_line_args = [ "parthenon/output2/dt=-1", "parthenon/output3/dt=-1", @@ -31,7 +30,6 @@ def Prepare(self, parameters, step): return parameters def Analyse(self, parameters): - sys.path.insert( 1, parameters.parthenon_path @@ -40,17 +38,17 @@ def Analyse(self, parameters): success = True - data_filename = f"{parameters.output_path}/parthenon.hst" + data_filename = f"{parameters.output_path}/parthenon.out1.hst" data = np.genfromtxt(data_filename) # Check Ms if not (data[-1, -3] > 0.45 and data[-1, -3] < 0.50): - print("ERROR: Mismatch in Ms") + print(f"ERROR: Mismatch in Ms={data[-1, -3]}") success = False # Check Ma if not (data[-1, -2] > 12.8 and data[-1, -2] < 13.6): - print("ERROR: Mismatch in Ma") + print(f"ERROR: Mismatch in Ma={data[-1, -2]}") success = False return success