Skip to content
Snippets Groups Projects
Commit a25d70c9 authored by Loic Hausammann's avatar Loic Hausammann
Browse files

Cooling almost correctly done and clean

parent 18fbc424
No related branches found
No related tags found
1 merge request!7Change clone to fetch
This commit is part of merge request !7. Comments created here will be created in the context of that merge request.
Readme.md
\ No newline at end of file
Wrapper Libcooling
======= ==========
.. automodule:: pyswiftsim.wrapper .. automodule:: pyswiftsim.libcooling
:members: :members:
:undoc-members: :undoc-members:
:private-members: :private-members:
......
File moved
...@@ -82,7 +82,7 @@ pygments_style = None ...@@ -82,7 +82,7 @@ pygments_style = None
# The theme to use for HTML and HTML Help pages. See the documentation for # The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes. # a list of builtin themes.
# #
html_theme = 'alabaster' html_theme = 'sphinx_rtd_theme'
# Theme options are theme-specific and customize the look and feel of a theme # Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the # further. For a list of options available for each theme, see the
...@@ -199,3 +199,5 @@ todo_include_todos = True ...@@ -199,3 +199,5 @@ todo_include_todos = True
# -- Options for numpy extension ---------------------------------------------- # -- Options for numpy extension ----------------------------------------------
numpydoc_use_plots = True numpydoc_use_plots = True
numpydoc_xref_param_type = True
...@@ -6,12 +6,15 @@ ...@@ -6,12 +6,15 @@
Welcome to PySWIFTsim's documentation! Welcome to PySWIFTsim's documentation!
====================================== ======================================
PySWIFTsim is a python wrapper around the gravity and SPH solver SWIFT.
The aim is to provide a python tool that benefits from HPC code and allows to directly use some feature of SWIFT in order to either test it or analyze a simulation.
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
:caption: Contents:
pyswiftsim.rst RST/pyswiftsim.rst
wrapper.rst RST/libcooling.rst
RST/examples.rst
......
""" # ########################################################################
This file is part of PYSWIFT. # This file is part of PYSWIFT.
Copyright (c) 2018 Loic Hausammann (loic.hausammann@epfl.ch) # Copyright (c) 2018 Loic Hausammann (loic.hausammann@epfl.ch)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# ########################################################################
This program is free software: you can redistribute it and/or modify import os
it under the terms of the GNU Lesser General Public License as published import urllib.request
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Lesser General Public License def downloadCoolingTable():
along with this program. If not, see <http://www.gnu.org/licenses/>. url = "http://virgodb.cosma.dur.ac.uk/"
""" url += "swift-webstorage/CoolingTables/CloudyData_UVB=HM2012.h5"
filename = "CloudyData_UVB=HM2012.h5"
from pyswiftsim import * if not os.path.isfile(filename):
# Download the file from `url` and save it locally under `file_name`:
urllib.request.urlretrieve(url, filename)
...@@ -118,7 +118,7 @@ data_files = [] ...@@ -118,7 +118,7 @@ data_files = []
############## ##############
c_src = glob("src/*.c") c_src = glob("src/*.c")
ext_modules = Extension("pyswiftsim.wrapper", ext_modules = Extension("pyswiftsim.libcooling",
c_src, c_src,
include_dirs=include, include_dirs=include,
libraries=lib, libraries=lib,
......
...@@ -19,6 +19,48 @@ ...@@ -19,6 +19,48 @@
#include "cooling_wrapper.h" #include "cooling_wrapper.h"
#include "pyswiftsim_tools.h" #include "pyswiftsim_tools.h"
/* TODO Remove this */
struct cooling_function_data cooling;
int initialized;
/**
* @brief Set the cooling element fractions
*
* @param xp The #xpart to set
* @param frac The numpy array containing the fractions (id, element)
* @param idx The id (in frac) of the particle to set
*/
void pycooling_set_fractions(struct xpart *xp, PyArrayObject* frac, const int idx) {
#ifdef COOLING_GRACKLE
struct cooling_xpart_data *data = &xp->cooling_data;
data->metal_frac = *(float*)PyArray_GETPTR2(frac, idx, 0);
#ifdef COOLING_GRACKLE
#if COOLING_GRACKLE_MODE > 0
data->HI_frac = *(float*)PyArray_GETPTR2(frac, idx, 1);
data->HII_frac = *(float*)PyArray_GETPTR2(frac, idx, 2);
data->HeI_frac = *(float*)PyArray_GETPTR2(frac, idx, 3);
data->HeII_frac = *(float*)PyArray_GETPTR2(frac, idx, 4);
data->HeIII_frac = *(float*)PyArray_GETPTR2(frac, idx, 5);
data->e_frac = *(float*)PyArray_GETPTR2(frac, idx, 6);
#endif // COOLING_GRACKLE_MODE
#if COOLING_GRACKLE_MODE > 1
data->HM_frac = *(float*)PyArray_GETPTR2(frac, idx, 7);
data->H2I_frac = *(float*)PyArray_GETPTR2(frac, idx, 8);
data->H2II_frac = *(float*)PyArray_GETPTR2(frac, idx, 9);
#endif // COOLING_GRACKLE_MODE
#if COOLING_GRACKLE_MODE > 2
data->DI_frac = *(float*)PyArray_GETPTR2(frac, idx, 10);
data->DII_frac = *(float*)PyArray_GETPTR2(frac, idx, 11);
data->HDI_frac = *(float*)PyArray_GETPTR2(frac, idx, 12);
#endif // COOLING_GRACKLE_MODE
#endif // COOLING_GRACKLE
#else
error("Not implemented");
#endif
}
/** /**
* @brief Compute the cooling rate * @brief Compute the cooling rate
...@@ -50,19 +92,19 @@ PyObject* pycooling_rate(PyObject* self, PyObject* args) { ...@@ -50,19 +92,19 @@ PyObject* pycooling_rate(PyObject* self, PyObject* args) {
/* parse argument */ /* parse argument */
if (!PyArg_ParseTuple( if (!PyArg_ParseTuple(
args, "siOO|fO", &filename, &with_cosmo, args, "sOO|ifO", &filename, &rho, &energy,
&rho, &energy, &dt, &fractions)) &with_cosmo, &dt, &fractions))
return NULL; return NULL;
/* check numpy array */ /* check numpy array */
if (pytools_check_array(energy, 1, NPY_FLOAT, "Energy") != SUCCESS) if (pytools_check_array(energy, 1, NPY_FLOAT, "Energy") != SWIFT_SUCCESS)
return NULL; return NULL;
if (pytools_check_array(rho, 1, NPY_FLOAT, "Density") != SUCCESS) if (pytools_check_array(rho, 1, NPY_FLOAT, "Density") != SWIFT_SUCCESS)
return NULL; return NULL;
if (fractions != NULL && if (fractions != NULL &&
pytools_check_array(fractions, 2, NPY_FLOAT, "Fractions") != SUCCESS) pytools_check_array(fractions, 2, NPY_FLOAT, "Fractions") != SWIFT_SUCCESS)
return NULL; return NULL;
if (PyArray_DIM(energy, 0) != PyArray_DIM(rho, 0)) if (PyArray_DIM(energy, 0) != PyArray_DIM(rho, 0))
...@@ -75,24 +117,34 @@ PyObject* pycooling_rate(PyObject* self, PyObject* args) { ...@@ -75,24 +117,34 @@ PyObject* pycooling_rate(PyObject* self, PyObject* args) {
size_t N = PyArray_DIM(energy, 0); size_t N = PyArray_DIM(energy, 0);
/* Initialize everything */ /* Initialize parser */
struct swift_params params; struct swift_params params;
parser_read_file(filename, &params); parser_read_file(filename, &params);
/* Init unit system */
struct unit_system us; struct unit_system us;
units_init_from_params(&us, &params, "InternalUnitSystem"); units_init_from_params(&us, &params, "InternalUnitSystem");
/* Init physical constant */
struct phys_const pconst; struct phys_const pconst;
phys_const_init(&us, &params, &pconst); phys_const_init(&us, &params, &pconst);
struct cooling_function_data cooling;
/* init cooling */ /* init cooling */
cooling_init_backend(&params, &us, &pconst, &cooling); if (initialized == 0) {
// struct cooling_function_data cooling;
cooling_init_backend(&params, &us, &pconst, &cooling);
initialized = 1;
}
else if (initialized == 1) {
message("WARNING: not reinitializing the cooling, need to be fixed");
initialized = 2;
}
/* Init chemistry */
struct chemistry_global_data chemistry; struct chemistry_global_data chemistry;
chemistry_init_backend(&params, &us, &pconst, &chemistry); chemistry_init_backend(&params, &us, &pconst, &chemistry);
/* Init cosmo */
struct cosmology cosmo; struct cosmology cosmo;
if (with_cosmo) if (with_cosmo)
...@@ -100,10 +152,18 @@ PyObject* pycooling_rate(PyObject* self, PyObject* args) { ...@@ -100,10 +152,18 @@ PyObject* pycooling_rate(PyObject* self, PyObject* args) {
else else
cosmology_init_no_cosmo(&cosmo); cosmology_init_no_cosmo(&cosmo);
/* Init hydro prop */
struct hydro_props hydro_props;
hydro_props_init(&hydro_props, &pconst, &us, &params);
/* Init entropy floor */
struct entropy_floor_properties floor_props;
entropy_floor_init(&floor_props, &pconst, &us,
&hydro_props, &params);
struct part p; struct part p;
struct xpart xp; struct xpart xp;
pyswift_part_set_to_zero(&p, &xp);
hydro_first_init_part(&p, &xp); hydro_first_init_part(&p, &xp);
/* return object */ /* return object */
...@@ -115,27 +175,28 @@ PyObject* pycooling_rate(PyObject* self, PyObject* args) { ...@@ -115,27 +175,28 @@ PyObject* pycooling_rate(PyObject* self, PyObject* args) {
/* set particle data */ /* set particle data */
p.rho = *(float*) PyArray_GETPTR1(rho, i); p.rho = *(float*) PyArray_GETPTR1(rho, i);
float u = *(float*) PyArray_GETPTR1(energy, i); float u = *(float*) PyArray_GETPTR1(energy, i);
p.entropy = gas_entropy_from_internal_energy(p.rho, u); hydro_set_physical_internal_energy(&p, &xp, &cosmo, u);
if (fractions != NULL) if (fractions != NULL)
pycooling_set_fractions(&xp, fractions, i); pycooling_set_fractions(&xp, fractions, i);
else else
cooling_first_init_part(&pconst, &us, &cosmo, &cooling, &p, &xp); cooling_first_init_part(&pconst, &us, &cosmo, &cooling, &p, &xp);
chemistry_first_init_part(&pconst, &us, &cosmo, &chemistry, &p, &xp); chemistry_first_init_part(&pconst, &us, &cosmo, &chemistry, &p, &xp);
hydro_set_physical_internal_energy_dt(&p, &cosmo, 0);
/* compute cooling rate */ /* compute cooling rate */
#ifdef COOLING_GRACKLE cooling_cool_part(&pconst, &us, &cosmo, &hydro_props,
&floor_props, &cooling, &p, &xp, dt, dt);
float *tmp = PyArray_GETPTR1(rate, i); float *tmp = PyArray_GETPTR1(rate, i);
*tmp = cooling_new_energy(&pconst, &us, &cosmo, &cooling, &p, &xp, dt); *tmp = hydro_get_physical_internal_energy_dt(&p, &cosmo);
*tmp = *tmp - hydro_get_physical_internal_energy(&p, &xp, &cosmo);
*tmp /= dt;
#else
error("Not implemented");
//*tmp = cooling_rate(pconst, us, cosmo, cooling, &p, &xp);
#endif
} }
/* Cleanup */
cosmology_clean(&cosmo);
return (PyObject *) rate; return (PyObject *) rate;
} }
......
...@@ -21,6 +21,11 @@ ...@@ -21,6 +21,11 @@
#include "pyswiftsim_includes.h" #include "pyswiftsim_includes.h"
/* A few global variables */
extern struct cooling_function_data cooling;
extern int initialized;
PyObject* pycooling_rate(PyObject* self, PyObject* args); PyObject* pycooling_rate(PyObject* self, PyObject* args);
#endif // __PYSWIFTSIM_COOLING_H__ #endif // __PYSWIFTSIM_COOLING_H__
......
...@@ -22,30 +22,38 @@ ...@@ -22,30 +22,38 @@
#include <math.h> #include <math.h>
#include <numpy/arrayobject.h> #include <numpy/arrayobject.h>
/* definition of the method table */ /* definition of the method table */
static PyMethodDef wrapper_methods[] = { static PyMethodDef libcooling_methods[] = {
{"coolingRate", pycooling_rate, METH_VARARGS, {"coolingRate", pycooling_rate, METH_VARARGS,
"Compute the cooling rate.\n\n" "Compute the cooling rate.\n\n"
"Parameters\n" "Parameters\n"
"----------\n\n" "----------\n\n"
"pyconst: swift physical constant\n" "filename: str\n"
"pyus: swift unit system\n" "\t Parameter file\n"
"cooling: swift cooling structure\n" "rho: array\n"
"rho: np.array\n" "\t Mass density in internal units\n"
"\t Mass density in pyus units\n" "energy: array\n"
"energy: np.array\n" "\t Internal energy in internal units\n"
"\t Internal energy in pyus units\n"
"dt: float, optional\n" "dt: float, optional\n"
"\t Time step in pyus units\n" "\t Time step in internal units\n"
"fractions: np.array, optional\n" "with_cosmo: int, optional\n"
"\t Use cosmology?\n"
"fractions: array, optional\n"
"\t Fraction of each cooling element (including metals)\n" "\t Fraction of each cooling element (including metals)\n"
"\n"
"Returns\n" "Returns\n"
"-------\n\n" "-------\n"
"rate: np.array\n" "rate: array\n"
"\t Cooling rate\n" "\t Cooling rate\n"
"\n"
"Examples\n"
"--------\n"
">>> rho = np.array([1])\n"
">>> u = np.array([1000])\n"
">>> filename = 'params.yml'\n"
">>> rate = coolingRate(filename, rho, u)\n"
}, },
...@@ -54,12 +62,12 @@ static PyMethodDef wrapper_methods[] = { ...@@ -54,12 +62,12 @@ static PyMethodDef wrapper_methods[] = {
static struct PyModuleDef wrapper_cmodule = { static struct PyModuleDef libcooling_cmodule = {
PyModuleDef_HEAD_INIT, PyModuleDef_HEAD_INIT,
"wrapper", "libcooling",
"Wrapper around the SPH cosmological simulation code SWIFT", "Wrapper around the cooling of SWIFT",
-1, -1,
wrapper_methods, libcooling_methods,
NULL, /* m_slots */ NULL, /* m_slots */
NULL, /* m_traverse */ NULL, /* m_traverse */
NULL, /* m_clear */ NULL, /* m_clear */
...@@ -67,7 +75,7 @@ static struct PyModuleDef wrapper_cmodule = { ...@@ -67,7 +75,7 @@ static struct PyModuleDef wrapper_cmodule = {
}; };
PyMODINIT_FUNC PyInit_libpyswiftsim(void) PyMODINIT_FUNC PyInit_libcooling(void)
{ {
PyObject *m; PyObject *m;
...@@ -76,7 +84,7 @@ PyMODINIT_FUNC PyInit_libpyswiftsim(void) ...@@ -76,7 +84,7 @@ PyMODINIT_FUNC PyInit_libpyswiftsim(void)
import_array(); import_array();
Py_Initialize(); Py_Initialize();
m = PyModule_Create(&wrapper_cmodule); m = PyModule_Create(&libcooling_cmodule);
return m; return m;
} }
...@@ -35,21 +35,21 @@ int pytools_check_array(PyArrayObject *obj, int dim, int type, const char* name) ...@@ -35,21 +35,21 @@ int pytools_check_array(PyArrayObject *obj, int dim, int type, const char* name)
/* check if array */ /* check if array */
if (!PyArray_Check(obj)) if (!PyArray_Check(obj))
{ {
pyerror("Expecting a numpy array for %s", name); error("Expecting a numpy array for %s", name);
} }
/* check if required dim */ /* check if required dim */
if (PyArray_NDIM(obj) != dim) if (PyArray_NDIM(obj) != dim)
{ {
pyerror("Array should be a %i dimensional object for %s", dim, name); error("Array should be a %i dimensional object for %s", dim, name);
} }
/* check data type */ /* check data type */
if (PyArray_TYPE(obj) != type) if (PyArray_TYPE(obj) != type)
{ {
pyerror("Wrong array type for %s", name); error("Wrong array type for %s", name);
} }
return SUCCESS; return SWIFT_SUCCESS;
} }
...@@ -36,8 +36,8 @@ ...@@ -36,8 +36,8 @@
/* error code in pyswiftsim */ /* error code in pyswiftsim */
enum error_code { enum error_code {
FAIL = 0, // ensure NULL == FAIL SWIFT_FAIL,
SUCCESS, SWIFT_SUCCESS,
}; };
......
#!/bin/bash
wget http://virgodb.cosma.dur.ac.uk/swift-webstorage/CoolingTables/CloudyData_UVB=HM2012.h5
#!/usr/bin/env python3 #!/usr/bin/env python3
# ########################################################################
# This file is part of PYSWIFT.
# Copyright (c) 2018 Loic Hausammann (loic.hausammann@epfl.ch)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# ########################################################################
from pyswiftsim.wrapper import coolingRate from pyswiftsim.libcooling import coolingRate
from pyswiftsim import downloadCoolingTable
import numpy as np import numpy as np
from astropy import units, constants from astropy import units, constants
import yaml import yaml
...@@ -10,6 +28,9 @@ filename = "test_cooling.yml" ...@@ -10,6 +28,9 @@ filename = "test_cooling.yml"
# adiabatic index # adiabatic index
gamma = 5. / 3. gamma = 5. / 3.
# download cooling table
downloadCoolingTable()
# Read parameter file # Read parameter file
f = open(filename, "r") f = open(filename, "r")
data = yaml.load(f) data = yaml.load(f)
...@@ -29,29 +50,35 @@ u_t = u_l / u_v ...@@ -29,29 +50,35 @@ u_t = u_l / u_v
u_e = u_m * u_l**2 / u_t**2 u_e = u_m * u_l**2 / u_t**2
# boltzman constant # boltzman constant
k_B = constants.k_B.to("{} J / K".format(u_e)) k_B = constants.k_B.to("erg / K") * units.K / (units.erg * u_e)
k_B = float(k_B)
# proton mass # proton mass
m_p = constants.m_p.to("{} g".format(u_l)) m_p = constants.m_p.to("g") / (units.g * u_m)
m_p = float(m_p)
def internalEnergy(T): def internalEnergy(T):
u = k_B * T u = (k_B / m_p) * T
u /= (gamma - 1.) * m_p u /= (gamma - 1.)
return u return u
# generates data # generates data
# time step in Myr
dt = 1e-3
dt = float(units.Myr.to('s')) / u_t
# density in atom / cm3 # density in atom / cm3
density = np.array([1.], dtype=np.float32) density = np.array([1.], dtype=np.float32)
density *= float(constants.m_p.to("g") / units.g) / u_m density *= m_p * u_l**3
density *= u_l**3
# Temperature in K # Temperature in K
T = np.array([100], dtype=np.float32) T = np.array([1e4], dtype=np.float32)
u = internalEnergy(T) u = internalEnergy(T)
# compute the cooling rate # compute the cooling rate
rate = coolingRate(filename, density, u) with_cosmo = False
rate = coolingRate(filename, density, u, with_cosmo, dt)
# go back to cgs # go back to cgs
rate /= u_e / u_t rate /= u_e / u_t
......
# Define the system of units to use internally. # Define the system of units to use internally.
InternalUnitSystem: InternalUnitSystem:
UnitMass_in_cgs: 1000 # Grams UnitMass_in_cgs: 1.989e43 # Grams
UnitLength_in_cgs: 1 # Centimeters UnitLength_in_cgs: 3.085e21 # Centimeters
UnitVelocity_in_cgs: 1 # Centimeters per second UnitVelocity_in_cgs: 1e5 # Centimeters per second
UnitCurrent_in_cgs: 1 # Amperes UnitCurrent_in_cgs: 1 # Amperes
UnitTemp_in_cgs: 1 # Kelvin UnitTemp_in_cgs: 1 # Kelvin
...@@ -18,3 +18,8 @@ GrackleCooling: ...@@ -18,3 +18,8 @@ GrackleCooling:
OutputMode: 0 # (optional) Write in output corresponding primordial chemistry mode OutputMode: 0 # (optional) Write in output corresponding primordial chemistry mode
MaxSteps: 10000 # (optional) Max number of step when computing the initial composition MaxSteps: 10000 # (optional) Max number of step when computing the initial composition
ConvergenceLimit: 1e-2 # (optional) Convergence threshold (relative) for initial composition ConvergenceLimit: 1e-2 # (optional) Convergence threshold (relative) for initial composition
# Parameters for the hydrodynamics scheme
SPH:
resolution_eta: 1.2348 # Target smoothing length in units of the mean inter-particle separation (1.2348 == 48Ngbs with the cubic spline kernel).
CFL_condition: 0.1 # Courant-Friedrich-Levy condition for time integration.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment