Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
b36dafa
Tolerance updated in `RegressionTest` in `test/HD/sod/testme.py`
dutta-alankar Aug 30, 2024
58de06b
[FIX] Dump datatype agnostic file xdmf IO
dutta-alankar Sep 9, 2024
c7f83dd
Merge branch 'idefix-code:master' into master
dutta-alankar Aug 28, 2025
92992da
[ADD] tabulated optically thin radiative cooling module
dutta-alankar Sep 4, 2025
1357703
[FIX] additional tags for successful `cmake` compilation
dutta-alankar Sep 4, 2025
b07f7ff
[FIX] minor typo in documentation
dutta-alankar Sep 6, 2025
70d6c40
[FIX] decrement internal energy by radiative cooling
dutta-alankar Sep 6, 2025
d4aa609
[FIX] cpplint edits
dutta-alankar Sep 6, 2025
231951b
[DOC] radiative cooling module documentation
dutta-alankar Sep 6, 2025
16a3844
[DOC] unit conversion
dutta-alankar Sep 6, 2025
6f7733f
[FIX] reverse old change
dutta-alankar Sep 6, 2025
391b273
Merge branch 'idefix-code:master' into master
dutta-alankar Jan 14, 2026
ff6dbfa
Merge branch 'master' into master
dutta-alankar Jun 17, 2026
f625997
Change energy calculation to energy per unit volume
dutta-alankar Jun 17, 2026
7bb5ef1
Usage of runtime code units in cooling
dutta-alankar Jun 18, 2026
7f8d399
documentation update
dutta-alankar Jun 18, 2026
c6040dc
Fix formatting of code block reference in radCooling.rst
dutta-alankar Jun 18, 2026
781e56d
Fix cooling to work on GPUs
dutta-alankar Jun 18, 2026
b45b6c6
Fix non-existent library linking error (librt stub)
dutta-alankar Jun 19, 2026
02cd06d
Handle output log directory creation and log file dumping
dutta-alankar Jun 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 80 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,31 @@ if(Kokkos_ENABLE_CUDA)
set(Kokkos_ENABLE_CUDA_LAMBDA ON CACHE BOOL "Idefix requires lambdas on Cuda" FORCE)
# CUDA_MALLOC_ASYNC disbaled by default in Kokkos 4.5, so not required here
#set(Kokkos_ENABLE_IMPL_CUDA_MALLOC_ASYNC OFF CACHE BOOL "Disable Async malloc to avoid bugs on PSM2" FORCE)

# On recent glibc (>= 2.34) the realtime functions were merged into libc and
# /usr/lib64/librt.a is only an empty archive stub. CMake's FindCUDAToolkit still
# resolves librt via find_library(CUDAToolkit_rt_LIBRARY rt) and attaches the
# resulting /usr/lib64/librt.a to CUDA::cudart_static_deps, which is pulled in by
# CUDA::cudart and CUDA::cuda_driver (the targets Kokkos links). The device link
# then passes that absolute archive path to nvlink, which cannot open the empty
# stub and fails with:
# nvlink fatal: Could not open input file '/usr/lib64/librt.a'
# Pre-seed the cache so FindCUDAToolkit links the shared librt (host-only, ignored
# by nvlink) instead of the static stub. We point at the shared object when it can
# be located, otherwise fall back to the "-lrt" link flag form; both avoid handing
# an absolute *.a path to nvlink, and the realtime symbols are provided by libc.
if(NOT DEFINED CUDAToolkit_rt_LIBRARY)
find_library(IDEFIX_RT_SHARED_LIBRARY
NAMES librt.so.1 librt.so
PATHS /lib64 /usr/lib64 /lib /usr/lib)
if(IDEFIX_RT_SHARED_LIBRARY)
set(CUDAToolkit_rt_LIBRARY "${IDEFIX_RT_SHARED_LIBRARY}"
CACHE FILEPATH "Shared librt used by CUDA::cudart_static_deps" FORCE)
else()
set(CUDAToolkit_rt_LIBRARY "rt"
CACHE FILEPATH "librt link flag used by CUDA::cudart_static_deps" FORCE)
endif()
endif()
endif()

# Add kokkos CMAKE files (required early since these set compiler options)
Expand Down Expand Up @@ -113,12 +138,64 @@ if(Idefix_HDF5)
PUBLIC src/output/xdmf.cpp
PUBLIC src/output/xdmf.hpp
)
find_package(HDF5 REQUIRED)
target_link_libraries(idefix "${HDF5_LIBRARIES}")
# Prefer imported targets (matches older working behavior), then fall back.
find_package(HDF5 QUIET COMPONENTS C)
if(NOT HDF5_FOUND)
find_package(HDF5 REQUIRED MODULE COMPONENTS C)
endif()

set(_idefix_hdf5_link_items "${HDF5_LIBRARIES}")
if(TARGET hdf5::hdf5)
set(_idefix_hdf5_link_items hdf5::hdf5)
elseif(TARGET HDF5::HDF5)
set(_idefix_hdf5_link_items HDF5::HDF5)
endif()

target_link_libraries(idefix ${_idefix_hdf5_link_items})
message(STATUS "Found HDF5 include directories: ${HDF5_INCLUDE_DIRS}")
target_include_directories(idefix PUBLIC "${HDF5_INCLUDE_DIRS}")
if(Idefix_MPI)
if(NOT HDF5_IS_PARALLEL)
include(CheckCSourceCompiles)

# Some CMake/HDF5 combinations do not reliably set HDF5_IS_PARALLEL.
# Combine metadata checks with a compile+link probe for MPI-IO symbols.
set(_idefix_hdf5_is_parallel FALSE)
if(HDF5_IS_PARALLEL OR HDF5_C_IS_PARALLEL)
set(_idefix_hdf5_is_parallel TRUE)
endif()

if(NOT _idefix_hdf5_is_parallel AND DEFINED HDF5_C_COMPILER_EXECUTABLE)
execute_process(
COMMAND ${HDF5_C_COMPILER_EXECUTABLE} -showconfig
OUTPUT_VARIABLE _idefix_hdf5_showconfig
ERROR_QUIET
)
if(_idefix_hdf5_showconfig MATCHES "Parallel HDF5:[ \t]*yes")
set(_idefix_hdf5_is_parallel TRUE)
endif()
endif()

set(CMAKE_REQUIRED_INCLUDES ${HDF5_INCLUDE_DIRS} ${MPI_C_INCLUDE_DIRS})
set(CMAKE_REQUIRED_LIBRARIES ${_idefix_hdf5_link_items} MPI::MPI_C)
check_c_source_compiles(
"#include <mpi.h>
#include <hdf5.h>
int main(void) {
hid_t plist = H5Pcreate(H5P_FILE_ACCESS);
H5Pset_fapl_mpio(plist, MPI_COMM_WORLD, MPI_INFO_NULL);
H5Pclose(plist);
return 0;
}"
IDEFIX_HDF5_HAS_MPI_IO
)
unset(CMAKE_REQUIRED_INCLUDES)
unset(CMAKE_REQUIRED_LIBRARIES)

if(IDEFIX_HDF5_HAS_MPI_IO)
set(_idefix_hdf5_is_parallel TRUE)
endif()

if(NOT _idefix_hdf5_is_parallel)
message(FATAL_ERROR "Parallel HDF5 required for Idefix_MPI but the found HDF5 library does not support it")
endif()
endif()
Expand Down
5 changes: 5 additions & 0 deletions doc/source/modules.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ In this section, you will find a more detailed documentation about each module t
The Braginskii module, models the anisotropic flux of heat and momentum
taking place in weakly collisional, magnetised plasma (like the intracluster medium).

:ref:`radiativeCoolingModule`
The optically thin radiative cooling module, handles the loss of internal thermal energy due to radiation in an
optically thin medium.

:ref:`gridCoarseningModule`
The grid coarsening module, that allows to derefine the grid in particular locations to speed up the computation.

Expand All @@ -42,5 +46,6 @@ In this section, you will find a more detailed documentation about each module t
modules/eos.rst
modules/selfGravity.rst
modules/braginskii.rst
modules/radCooling.rst
modules/gridCoarsening.rst
modules/pydefix.rst
58 changes: 58 additions & 0 deletions doc/source/modules/radCooling.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
.. _radiativeCoolingModule:

Radiative Cooling module
===================

Equations solved and method
---------------------------

The ``RadiativeCooling`` module implements the computation of the loss of internal thermal energy
due radiation in an optically thin medium. Physically, it solves for :math:`\dot_{e}=\mathcal{L}`,
where we have used :math:`\mathcal{L}=-n_H^2 \Lambda (T)` (where :math:`T` is the gas temperature,
:math:`n_H=\rho X_H/m_p` is the total hydrogen number density, and :math:`\Lambda(T)`) is the
radiative cooling rate computed seperately from quantum mechanical calculations
by other plasma modeling codes, for example, Cloudy (Ferland et. al, PASP 110, 749 (1998)).

This computation becomes especially relevant for multiphase gas in astrophysical environments
prevalent in the ISM, the CGM, and the ICM, for which this module has been designed.

The ``RadiativeCooling`` module implemented in *Idefix* follows the algorithm of the Townsend
to integrate the loss of internal thermal energy (Townsend, ApJS 181, 2 (2009)) at every timestep
in an operator split manner. The cooling rate is read from a table at runtime where the `first` row
is temperature (in :math:`\rm K`) and second row is :math:`\Lambda (T)` (in :math:`\rm erg cm^3 s^{-1}`).

.. note::
We assume a normalization of :math:`n_H`, the total hydrogen number density for the
of the cooling curve supplied by the rate table at runtime to *Idefix*. Different might cooling curves with
different normalisation is known to exist in literature and special attention must be given to
what is supplied to the code. Right now, this module has been tested only with the ideal gas equation of state.
We also assume the mean particle mass :math:`\mu=0.609`, i.e., constant in the current implementation (appropriate
for fully ionized plasma).
It is recommended to include conversion factors between code and physical units in ``idefix.ini`` which is in the `[Units]`
block. This is to ensure that the cooling curve supplied in physical units is correctly interpreted by the code.
A test example of a uniform advecting box is in `test/HD/CoolBox`.
Main parameters of the module
-----------------------------

The ``RadiativeCooling`` module is a submodule of the ``Hydro`` module to compute the loss of internal thermal energy (pressure)
of the gas. The parameters specific to radiative cooling are to be set in a dedicated line starting with the word
``Cooling`` in the ``[Hydro]`` block. An example is as follows succeded by a detailed explanation.

``
Cooling Tabulated cooltable.dat Townsend TcoolFloor 1.0e+04
``

+----------------------+-------------------------+----------------------------------------------------------------------------------------------+
| Entry name | Parameter type | Comment |
+======================+=========================+==============================================================================================+
| cooling mode | string | | Type of radiative cooling. Only `Tabulated` is supported right now. |
+----------------------+-------------------------+----------------------------------------------------------------------------------------------+
| table name | string | | name/location of the cooling table w.r.t. *Idefix* binary to be loaded at runtime. |
+----------------------+-------------------------+----------------------------------------------------------------------------------------------+
| integration method | string | | Integration method to calculate the internal thermal energy loss due to radiative cooling. |
| | | | Only `Townsend` supported right now. |
+----------------------+-------------------------+----------------------------------------------------------------------------------------------+
| TcoolFloor | string (optional) | | Floor temperature in K below which cooling is turned off. |
+----------------------+-------------------------+----------------------------------------------------------------------------------------------+
| temperature floor | float (optional) | | Default is 1.0e+04 |
+----------------------+-------------------------+----------------------------------------------------------------------------------------------+
6 changes: 3 additions & 3 deletions doc/source/programmingguide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ A typical loop on three indices looks like
idefix_for("LoopName",
kbeg,kend,
jbeg,jend,
ibeg,ieng,
ibeg,iend,
KOKKOS_LAMBDA (int k, int j, int i) {
myArray(k,j,i) = 0.0;
});
Expand Down Expand Up @@ -153,7 +153,7 @@ For instance, a sum over all of the elements would be done through:
idefix_reduce("Sum",
kbeg,kend,
jbeg,jend,
ibeg,ieng,
ibeg,iend,
KOKKOS_LAMBDA (int k, int j, int i, real &localSum) {
localSum += myArray(k,j,i);
},
Expand All @@ -179,7 +179,7 @@ snippet:
idefix_reduce("Minimum",
kbeg,kend,
jbeg,jend,
ibeg,ieng,
ibeg,iend,
KOKKOS_LAMBDA (int k, int j, int i, real &localMin) {
localMin = std::fmin(localMin, myArray(k,j,i));
},
Expand Down
1 change: 1 addition & 0 deletions src/fluid/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ add_subdirectory(constrainedTransport)
add_subdirectory(eos)
add_subdirectory(RiemannSolver)
add_subdirectory(tracer)
add_subdirectory(cooling)


target_sources(idefix
Expand Down
18 changes: 17 additions & 1 deletion src/fluid/addSourceTerms.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ struct Fluid_AddSourceTermsFunctor {
//*****************************************************************
// Functor constructor
//*****************************************************************
explicit Fluid_AddSourceTermsFunctor(Fluid<Phys> *hydro, real dt) {
explicit Fluid_AddSourceTermsFunctor(Fluid<Phys> *hydro, real dt):
hydroin(hydro) {
Uc = hydro->Uc;
Vc = hydro->Vc;
x1 = hydro->data->x[IDIR];
Expand All @@ -42,6 +43,13 @@ struct Fluid_AddSourceTermsFunctor {
}
// shearing box (only with fargo&cartesian)
sbS = hydro->sbS;

// Radiative cooling
coolingOn = hydro->coolingOn;
if (coolingOn) {
hydro->radCooling->CalculateCoolingSource(dt);
this->delta_eng_cool = hydro->radCooling->delta_eng;
}
}

//*****************************************************************
Expand All @@ -52,7 +60,9 @@ struct Fluid_AddSourceTermsFunctor {
IdefixArray1D<real> x1;
IdefixArray1D<real> x2;
IdefixArray3D<real> csIsoArr;
IdefixArray3D<real> delta_eng_cool;

Fluid<Phys> *hydroin;
real dt;
#if GEOMETRY == SPHERICAL
IdefixArray1D<real> sinx2;
Expand All @@ -72,6 +82,9 @@ struct Fluid_AddSourceTermsFunctor {
// shearing box (only with fargo&cartesian)
real sbS;

// Radiative cooling
bool coolingOn;

//*****************************************************************
// Functor Operator
//*****************************************************************
Expand Down Expand Up @@ -191,7 +204,10 @@ struct Fluid_AddSourceTermsFunctor {
Uc(MX2,k,j,i) += dt*Sm / rt(i);
#endif // COMPONENTS
#endif
if (coolingOn) {
Uc(ENG,k,j,i) += delta_eng_cool(k,j,i); // energy per unit volume
}
}
};


Expand Down
8 changes: 8 additions & 0 deletions src/fluid/cooling/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
target_sources(idefix
PUBLIC ${CMAKE_CURRENT_LIST_DIR}/cooling.hpp
PUBLIC ${CMAKE_CURRENT_LIST_DIR}/cooling.cpp
)

target_include_directories(idefix
PUBLIC ${CMAKE_CURRENT_LIST_DIR}
)
Loading