-
Notifications
You must be signed in to change notification settings - Fork 21
Isotropic constant thermal conduction #1806
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: development
Are you sure you want to change the base?
Changes from all commits
220649b
51b0e2d
b250367
03216d7
6eb4ce5
b0ce11c
81138ab
70110ab
52b2156
e0e0169
3760284
769ad08
57285c6
d73dc40
875a5fa
3f33fb3
74d3eb8
51c7506
e571b74
d521372
993a0e2
f36ea39
a597ece
a69be2a
5a09bb0
d1ae1a1
7fe825b
759cc12
e4935ec
4e44bb9
8221a3b
79e347a
0809849
0e49460
38b9c7e
ff32a81
acca305
2ce86b5
470d960
31bf51b
9464398
a8edbec
8ecc183
cdc4f94
8acf2b3
8ce8281
edc431a
f2bfa7d
137c023
0a8a3a0
cb7b155
d263b49
fbd7c6c
685db3a
45e0e24
c01642a
fb5c552
9edbee3
9cc5d2d
787d400
cdf53e7
5130fc2
9b63609
b4ec2d6
90a7c79
f92464a
fbd2047
f1b0458
10d52e8
836f51a
d3a89fb
fb2e67b
63e5f8b
eff8394
73d21e3
a6edb77
47bb3c2
618457e
c5d0750
ca52ea7
79052f3
722bf1a
7ed8f38
74a3bc8
832ff2f
ae7834d
a413d8d
11023ec
3418911
e6f47a1
a68f83b
16635e0
02cfa08
2d38401
2e867ee
0f2a32b
92a57f7
e0ee560
04f5763
ff9cdb8
6b71f76
3ee8dfa
aff77a7
c572b38
10db8df
07d4894
a5962d0
ff17b66
53f832f
f38cb1f
75ee561
41f9e0d
3665505
40fb768
152e52f
c9a21a4
298b877
724efcc
bcacedc
e748f9d
e4ff90e
18b0a98
bfc0dc9
0acc4ae
8aefc50
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| # ***************************************************************** | ||
| # Problem size and geometry | ||
| # ***************************************************************** | ||
| geometry.prob_lo = [-1.5428e18, -1.5428e18, -1.5428e18] | ||
| geometry.prob_hi = [1.5428e18, 1.5428e18, 1.5428e18] | ||
| quokka.bc = ["foextrap", "foextrap", "foextrap"] | ||
|
|
||
| # ***************************************************************** | ||
| # VERBOSITY | ||
| # ***************************************************************** | ||
| amr.v = 1 # verbosity in Amr | ||
|
|
||
| # ***************************************************************** | ||
| # Resolution and refinement | ||
| # ***************************************************************** | ||
| amr.n_cell = [128, 128, 128] | ||
| amr.max_level = 0 # number of levels = max_level + 1 | ||
| amr.blocking_factor = 32 # grid size must be divisible by this | ||
|
|
||
| cfl = 0.3 | ||
|
|
||
| cooling.enabled = 0 | ||
| cooling.read_tables_even_if_disabled = 1 | ||
| cooling.cooling_table_type = "resampled" | ||
| cooling.hdf5_data_file = "../extern/cooling/CloudyData_UVB=HM2012_resampled.h5" | ||
|
|
||
|
|
||
| conduction.enabled = 1 | ||
| conduction.conductivity_prefactor = 0.6113916490935586e12 | ||
| conduction.flux_limiter_phi = 1 | ||
| conduction.saturation_factor = 1.2e20 | ||
| conduction.conduction_cfl = 0.1 | ||
| conduction.eos_flag = 1 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,5 @@ | ||
| module load gcc/12.2.0 | ||
| module purge | ||
| module load gcc/14.2.0 | ||
| module load cuda/12.9.0 | ||
|
|
||
| module unload openmpi | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,214 @@ | ||
| #ifndef ELECTRON_CONDUCTION_HPP_ // NOLINT | ||
| #define ELECTRON_CONDUCTION_HPP_ | ||
|
|
||
| //============================================================================== | ||
| // TwoMomentRad - a radiation transport library for patch-based AMR codes | ||
| // Copyright 2020 Benjamin Wibking. | ||
| // Released under the MIT license. See LICENSE file included in the GitHub repo. | ||
| //============================================================================== | ||
| /// \file ElectronConduction.hpp | ||
| /// \brief Explicit flux-limited electron thermal conduction update. | ||
|
|
||
| #include <array> | ||
| #include <cmath> | ||
| #include <limits> | ||
|
|
||
| #include "AMReX_Array4.H" | ||
| #include "AMReX_Geometry.H" | ||
| #include "AMReX_GpuQualifiers.H" | ||
| #include "AMReX_MultiFab.H" | ||
| #include "AMReX_REAL.H" | ||
| #include "AMReX_SPACE.H" | ||
| #include "AMReX_Vector.H" | ||
| #include "cooling/ResampledCooling.hpp" | ||
| #include "hydro/hydro_system.hpp" | ||
|
|
||
| namespace quokka::conduction | ||
| { | ||
|
|
||
| struct ElectronConductionParams { | ||
| amrex::Real conductivity_prefactor = 3.e34; // units of erg cm^-1 s^-1 K^-1 | ||
| amrex::Real flux_limiter_phi = 0.1; | ||
| amrex::Real saturation_factor = 5.0; // refer to equation 8 of Cowee & McKee 1977 | ||
| amrex::Real min_temperature = 0.0; // default value will be overwritten by tempFloor_ during initialization | ||
| int eos_flag = 1; // 1 == use quokka::EOS; 0 == use resampled cooling | ||
| }; | ||
|
|
||
| template <typename problem_t> class ElectronConduction | ||
| { | ||
| public: | ||
| static void ComputeExplicit(amrex::MultiFab &state, std::array<amrex::MultiFab, AMREX_SPACEDIM> const &state_fc, amrex::Geometry const &geom, | ||
| amrex::Real dt, ElectronConductionParams const ¶ms, const quokka::ResampledCooling::resampled_tables &tables) | ||
| { | ||
| static_assert(Physics_Traits<problem_t>::is_hydro_enabled, "Electron conduction requires hydro to be enabled."); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A check should be added here to ensure that the simulation only has a single level and is not using AMR, since it doesn't fully support AMR yet.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This check has been add to QuokkaSimulation.hpp. |
||
|
|
||
| if ((dt <= 0.0) || (params.conductivity_prefactor <= 0.0)) { | ||
| return; | ||
| } | ||
|
|
||
| if constexpr (HydroSystem<problem_t>::is_eos_isothermal()) { | ||
| amrex::ignore_unused(state_fc, geom, params); | ||
| return; | ||
| } | ||
|
|
||
| AMREX_ALWAYS_ASSERT_WITH_MESSAGE(state.nGrow() >= 1, "Electron conduction requires at least 1 ghost cell."); | ||
|
|
||
| const auto dx = geom.CellSizeArray(); | ||
| const amrex::Real flux_limiter_phi = params.flux_limiter_phi; | ||
| const amrex::Real saturation_factor = params.saturation_factor; | ||
| const amrex::Real t_min = params.min_temperature; | ||
| const amrex::Real small = std::numeric_limits<amrex::Real>::min(); | ||
|
|
||
| amrex::MultiFab temperature(state.boxArray(), state.DistributionMap(), 1, state.nGrow()); | ||
| temperature.setVal(0.0); | ||
| amrex::MultiFab conductivity(state.boxArray(), state.DistributionMap(), 1, state.nGrow()); | ||
| conductivity.setVal(0.0); | ||
| amrex::MultiFab saturated_flux(state.boxArray(), state.DistributionMap(), 1, state.nGrow()); | ||
| saturated_flux.setVal(0.0); | ||
|
BenWibking marked this conversation as resolved.
|
||
|
|
||
| auto const &state_x0 = state.const_arrays(); | ||
| auto const &state_fc_x0 = state_fc[0].const_arrays(); | ||
| #if AMREX_SPACEDIM >= 2 | ||
| auto const &state_fc_x1 = state_fc[1].const_arrays(); | ||
| #endif | ||
| #if AMREX_SPACEDIM == 3 | ||
| auto const &state_fc_x2 = state_fc[2].const_arrays(); | ||
| #endif | ||
| auto temperature_arr = temperature.arrays(); | ||
| auto conductivity_arr = conductivity.arrays(); | ||
| auto saturated_flux_arr = saturated_flux.arrays(); | ||
| amrex::IntVect ng = amrex::IntVect(AMREX_D_DECL(2, 2, 2)); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The number of ghost cells to iterate over ( Since the gradient calculation only requires 1 ghost cell, amrex::IntVect ng = amrex::IntVect(AMREX_D_DECL(1, 1, 1)); |
||
| std::optional<decltype(tables.const_tables())> tables_dev; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. src/conduction/ElectronConduction.hpp:81: Severity: high 🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage. |
||
| if (params.eos_flag == 0) { | ||
| tables_dev = tables.const_tables(); | ||
| } else if (params.eos_flag != 0 && params.eos_flag != 1) { | ||
| amrex::Abort("Invalid eos_flag value in ElectronConduction. Must be 0 (resampled cooling) or 1 (quokka::EOS)."); | ||
| } | ||
|
|
||
| amrex::ParallelFor(state, ng, [=] AMREX_GPU_DEVICE(int bx, int i, int j, int k) noexcept { | ||
| std::array<amrex::Array4<const amrex::Real>, AMREX_SPACEDIM> local_state_fc{}; | ||
| if (Physics_Traits<problem_t>::is_mhd_enabled) { | ||
| local_state_fc[0] = state_fc_x0[bx]; | ||
| #if AMREX_SPACEDIM >= 2 | ||
| local_state_fc[1] = state_fc_x1[bx]; | ||
| #endif | ||
| #if AMREX_SPACEDIM == 3 | ||
| local_state_fc[2] = state_fc_x2[bx]; | ||
| #endif | ||
| } | ||
|
|
||
| auto const &cons = state_x0[bx]; | ||
| const amrex::Real rho = cons(i, j, k, HydroSystem<problem_t>::density_index); | ||
| const amrex::Real Eint = HydroSystem<problem_t>::ComputeInternalEnergy(cons, i, j, k, &local_state_fc); | ||
| amrex::Real Tgas = NAN; | ||
| amrex::Real cs = NAN; | ||
| if (params.eos_flag == 0) { | ||
| Tgas = quokka::ResampledCooling::ComputeTgasFromEgas(rho, Eint, *tables_dev); | ||
| cs = quokka::ResampledCooling::ComputeSoundSpeedFromRhoEint(rho, Eint, *tables_dev); | ||
| } else if (params.eos_flag == 1) { | ||
| Tgas = quokka::EOS<problem_t>::ComputeTgasFromEint(rho, Eint); | ||
| amrex::Real Pgas = quokka::EOS<problem_t>::ComputePressure(rho, Eint); | ||
| cs = quokka::EOS<problem_t>::ComputeSoundSpeed(rho, Pgas); | ||
| } | ||
|
|
||
| const amrex::Real Tuse = amrex::max(Tgas, t_min); | ||
| const amrex::Real kappa = params.conductivity_prefactor; | ||
| const amrex::Real qsat = amrex::max(saturation_factor * flux_limiter_phi * rho * cs * cs * cs, small); | ||
|
|
||
| temperature_arr[bx](i, j, k) = Tuse; | ||
| conductivity_arr[bx](i, j, k) = kappa; | ||
| saturated_flux_arr[bx](i, j, k) = qsat; | ||
| }); | ||
|
|
||
| std::array<amrex::MultiFab, AMREX_SPACEDIM> heat_flux; | ||
| for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) { | ||
| amrex::BoxArray const ba_face = amrex::convert(state.boxArray(), amrex::IntVect::TheDimensionVector(idim)); | ||
| heat_flux[idim].define(ba_face, state.DistributionMap(), 1, 0); | ||
| heat_flux[idim].setVal(0.0); | ||
| } | ||
|
|
||
| auto const &temp = temperature.const_arrays(); | ||
| auto const &kappa = conductivity.const_arrays(); | ||
| auto const &qsat = saturated_flux.const_arrays(); | ||
| auto flux_x = heat_flux[0].arrays(); | ||
| amrex::ParallelFor(heat_flux[0], [=] AMREX_GPU_DEVICE(int bx, int i, int j, int k) noexcept { | ||
| const amrex::Real gradT = (temp[bx](i, j, k) - temp[bx](i - 1, j, k)) / dx[0]; | ||
| const amrex::Real kappa_face = 0.5 * (kappa[bx](i, j, k) + kappa[bx](i - 1, j, k)); | ||
| const amrex::Real q_classical = -kappa_face * gradT; | ||
| const amrex::Real q_sat_face = 0.5 * (qsat[bx](i, j, k) + qsat[bx](i - 1, j, k)); | ||
| const amrex::Real limiter = 1.0 + std::abs(q_classical) / amrex::max(q_sat_face, small); | ||
|
Comment on lines
+138
to
+139
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The flux limiter is calculated but not applied to the heat flux. While the PR notes mention a preference for classical flux for now, calculating the limiter without using it is inefficient. If the limiter is intended for future use, it should be applied to const amrex::Real limiter = 1.0 + std::abs(q_classical) / amrex::max(q_sat_face, small);
flux_x[bx](i, j, k) = q_classical / limiter;
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've re-added the limiter and set it to a large value in the input file in order to obviate its use. |
||
| flux_x[bx](i, j, k) = q_classical / limiter; | ||
| }); | ||
|
|
||
| #if AMREX_SPACEDIM >= 2 | ||
| auto flux_y = heat_flux[1].arrays(); | ||
| amrex::ParallelFor(heat_flux[1], [=] AMREX_GPU_DEVICE(int bx, int i, int j, int k) noexcept { | ||
| const amrex::Real gradT = (temp[bx](i, j, k) - temp[bx](i, j - 1, k)) / dx[1]; | ||
| const amrex::Real kappa_face = 0.5 * (kappa[bx](i, j, k) + kappa[bx](i, j - 1, k)); | ||
| const amrex::Real q_classical = -kappa_face * gradT; | ||
| const amrex::Real q_sat_face = 0.5 * (qsat[bx](i, j, k) + qsat[bx](i, j - 1, k)); | ||
| const amrex::Real limiter = 1.0 + std::abs(q_classical) / amrex::max(q_sat_face, small); | ||
| flux_y[bx](i, j, k) = q_classical / limiter; | ||
| }); | ||
| #endif | ||
|
|
||
| #if AMREX_SPACEDIM == 3 | ||
| auto flux_z = heat_flux[2].arrays(); | ||
| amrex::ParallelFor(heat_flux[2], [=] AMREX_GPU_DEVICE(int bx, int i, int j, int k) noexcept { | ||
| const amrex::Real gradT = (temp[bx](i, j, k) - temp[bx](i, j, k - 1)) / dx[2]; | ||
| const amrex::Real kappa_face = 0.5 * (kappa[bx](i, j, k) + kappa[bx](i, j, k - 1)); | ||
| const amrex::Real q_classical = -kappa_face * gradT; | ||
| const amrex::Real q_sat_face = 0.5 * (qsat[bx](i, j, k) + qsat[bx](i, j, k - 1)); | ||
| const amrex::Real limiter = 1.0 + std::abs(q_classical) / amrex::max(q_sat_face, small); | ||
| flux_z[bx](i, j, k) = q_classical / limiter; | ||
| }); | ||
| #endif | ||
|
|
||
| auto state_out = state.arrays(); | ||
| auto const &flux_x_const = heat_flux[0].const_arrays(); | ||
| #if AMREX_SPACEDIM >= 2 | ||
| auto const &flux_y_const = heat_flux[1].const_arrays(); | ||
| #endif | ||
| #if AMREX_SPACEDIM == 3 | ||
| auto const &flux_z_const = heat_flux[2].const_arrays(); | ||
| #endif | ||
|
|
||
| amrex::ParallelFor(state, [=] AMREX_GPU_DEVICE(int bx, int i, int j, int k) noexcept { | ||
| std::array<amrex::Array4<const amrex::Real>, AMREX_SPACEDIM> local_state_fc{}; | ||
| if (Physics_Traits<problem_t>::is_mhd_enabled) { | ||
| local_state_fc[0] = state_fc_x0[bx]; | ||
| #if AMREX_SPACEDIM >= 2 | ||
| local_state_fc[1] = state_fc_x1[bx]; | ||
| #endif | ||
| #if AMREX_SPACEDIM == 3 | ||
| local_state_fc[2] = state_fc_x2[bx]; | ||
| #endif | ||
| } | ||
|
|
||
| const amrex::Real rho = state_out[bx](i, j, k, HydroSystem<problem_t>::density_index); | ||
| const amrex::Real px = state_out[bx](i, j, k, HydroSystem<problem_t>::x1Momentum_index); | ||
| const amrex::Real py = state_out[bx](i, j, k, HydroSystem<problem_t>::x2Momentum_index); | ||
| const amrex::Real pz = state_out[bx](i, j, k, HydroSystem<problem_t>::x3Momentum_index); | ||
|
|
||
| const amrex::Real Ekin = 0.5 * (px * px + py * py + pz * pz) / rho; | ||
| const amrex::Real Eint_old = HydroSystem<problem_t>::ComputeInternalEnergy(state_out[bx], i, j, k, &local_state_fc); | ||
| const amrex::Real Emag = HydroSystem<problem_t>::ComputeMagneticEnergy(i, j, k, &local_state_fc); | ||
| amrex::Real div_flux = (flux_x_const[bx](i + 1, j, k) - flux_x_const[bx](i, j, k)) / dx[0]; | ||
| #if AMREX_SPACEDIM >= 2 | ||
| div_flux += (flux_y_const[bx](i, j + 1, k) - flux_y_const[bx](i, j, k)) / dx[1]; | ||
| #endif | ||
| #if AMREX_SPACEDIM == 3 | ||
| div_flux += (flux_z_const[bx](i, j, k + 1) - flux_z_const[bx](i, j, k)) / dx[2]; | ||
| #endif | ||
|
|
||
| amrex::Real Eint_new = Eint_old - dt * div_flux; | ||
|
BenWibking marked this conversation as resolved.
|
||
|
|
||
| state_out[bx](i, j, k, HydroSystem<problem_t>::energy_index) = Eint_new + Ekin + Emag; | ||
| state_out[bx](i, j, k, HydroSystem<problem_t>::internalEnergy_index) = Eint_new; | ||
|
BenWibking marked this conversation as resolved.
|
||
| }); | ||
| } | ||
| }; | ||
|
|
||
| } // namespace quokka::conduction | ||
|
|
||
| #endif // ELECTRON_CONDUCTION_HPP_ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| quokka_add_problem(JOB_NAME ThermalConduction PRIORITY 100) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you provide a reference for the value you used here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has been chosen arbitrarily since it is not being used for now. PLUTO manual suggests phi<1.