From 314cf30d77439a1788004d2b2918f3a5b1eb9f03 Mon Sep 17 00:00:00 2001 From: Wolfgang Kerzendorf Date: Thu, 28 Sep 2023 15:28:23 -0400 Subject: [PATCH 01/23] restructure of geometry --- tardis/model/base.py | 141 +++++++++++-------- tardis/model/geometry/radial1d.py | 70 ++++++++- tardis/model/geometry/tests/test_radial1d.py | 40 ++++++ 3 files changed, 184 insertions(+), 67 deletions(-) create mode 100644 tardis/model/geometry/tests/test_radial1d.py diff --git a/tardis/model/base.py b/tardis/model/base.py index 4d5e94abeda..c7859a912df 100644 --- a/tardis/model/base.py +++ b/tardis/model/base.py @@ -12,7 +12,7 @@ from tardis.io.model.readers.generic_readers import ( read_uniform_abundances, ) -from tardis.model.geometry.radial1d import Radial1DGeometry +from tardis.model.geometry.radial1d import HomologousRadial1DGeometry from tardis.util.base import quantity_linspace, is_valid_nuclide_or_elem from tardis.io.model.readers.csvy import load_csvy @@ -200,7 +200,7 @@ class SimulationState(HDFWriterMixin): def __init__( self, - velocity, + geometry, density, abundance, isotope_abundance, @@ -214,18 +214,20 @@ def __init__( v_boundary_outer=None, electron_densities=None, ): + self.geometry = geometry self._v_boundary_inner = None self._v_boundary_outer = None - self._velocity = None - self.raw_velocity = velocity + #self._velocity = None + #self.raw_velocity = velocity self.v_boundary_inner = v_boundary_inner self.v_boundary_outer = v_boundary_outer + self._abundance = abundance self.time_explosion = time_explosion self._electron_densities = electron_densities - v_outer = self.velocity[1:] - v_inner = self.velocity[:-1] - if len(density) != len(self.velocity) - 1: + + if len(density) != len(self.geometry.v_inner): + density = density[ self.v_boundary_inner_index + 1 : self.v_boundary_outer_index @@ -275,12 +277,6 @@ def __init__( elemental_mass_fraction=self.abundance, atomic_mass=atomic_mass, ) - geometry = Radial1DGeometry( - r_inner=self.time_explosion * v_inner, - r_outer=self.time_explosion * v_outer, - v_inner=v_inner, - v_outer=v_outer, - ) self.model_state = ModelState( composition=composition, geometry=geometry, @@ -391,6 +387,7 @@ def t_radiative(self, value): @property def radius(self): + return None return self.time_explosion * self.velocity @property @@ -407,6 +404,7 @@ def r_middle(self): @property def velocity(self): + return None if self._velocity is None: self._velocity = self.raw_velocity[ self.v_boundary_inner_index : self.v_boundary_outer_index + 1 @@ -449,20 +447,22 @@ def volume(self): @property def no_of_shells(self): - return len(self.velocity) - 1 + return self.geometry.no_of_shells @property def no_of_raw_shells(self): - return len(self.raw_velocity) - 1 - + return self.geometry.no_of_shells + """ @property def v_boundary_inner(self): + return self.v_boundary_inner if self._v_boundary_inner is None: return self.raw_velocity[0] if self._v_boundary_inner < 0 * u.km / u.s: return self.raw_velocity[0] return self._v_boundary_inner + @v_boundary_inner.setter def v_boundary_inner(self, value): if value is not None: @@ -484,15 +484,18 @@ def v_boundary_inner(self, value): self._v_boundary_inner = value # Invalidate the cached cut-down velocity array self._velocity = None + @property def v_boundary_outer(self): + return self.v_boundary_outer + if self._v_boundary_outer is None: return self.raw_velocity[-1] if self._v_boundary_outer < 0 * u.km / u.s: return self.raw_velocity[-1] return self._v_boundary_outer - + @v_boundary_outer.setter def v_boundary_outer(self, value): if value is not None: @@ -537,7 +540,7 @@ def v_boundary_outer_index(self): self.raw_velocity, self.v_boundary_outer ) return v_outer_ind - + """ @classmethod def from_config(cls, config, atom_data=None): """ @@ -554,50 +557,18 @@ def from_config(cls, config, atom_data=None): """ time_explosion = config.supernova.time_explosion.cgs - structure = config.model.structure - electron_densities = None - temperature = None - if structure.type == "specific": - velocity = quantity_linspace( - structure.velocity.start, - structure.velocity.stop, - structure.velocity.num + 1, - ).cgs - density = parse_config_v1_density(config) - - elif structure.type == "file": - if os.path.isabs(structure.filename): - structure_fname = structure.filename - else: - structure_fname = os.path.join( - config.config_dirname, structure.filename - ) - - ( - time_0, - velocity, - density_0, - electron_densities, - temperature, - ) = read_density_file(structure_fname, structure.filetype) - density_0 = density_0.insert(0, 0) - - density = calculate_density_after_time( - density_0, time_0, time_explosion - ) - - else: - raise NotImplementedError - - # Note: This is the number of shells *without* taking in mind the - # v boundaries. - no_of_shells = len(velocity) - 1 + ( + electron_densities, + temperature, + geometry, + density + ) = parse_structure_config(config, time_explosion) if temperature is not None: t_radiative = temperature elif config.plasma.initial_t_rad > 0 * u.K: t_radiative = ( - np.ones(no_of_shells + 1) * config.plasma.initial_t_rad + np.ones(geometry.no_of_shells + 1) * config.plasma.initial_t_rad ) else: t_radiative = None @@ -616,7 +587,7 @@ def from_config(cls, config, atom_data=None): if abundances_section.type == "uniform": abundance, isotope_abundance = read_uniform_abundances( - abundances_section, no_of_shells + abundances_section, geometry.no_of_shells ) elif abundances_section.type == "file": @@ -650,7 +621,7 @@ def from_config(cls, config, atom_data=None): elemental_mass = atom_data.atom_data.mass return cls( - velocity=velocity, + geometry=geometry, density=density, abundance=abundance, isotope_abundance=isotope_abundance, @@ -660,8 +631,8 @@ def from_config(cls, config, atom_data=None): elemental_mass=elemental_mass, luminosity_requested=luminosity_requested, dilution_factor=None, - v_boundary_inner=structure.get("v_inner_boundary", None), - v_boundary_outer=structure.get("v_outer_boundary", None), + v_boundary_inner=config.model.structure.get("v_inner_boundary", None), + v_boundary_outer=config.model.structure.get("v_outer_boundary", None), electron_densities=electron_densities, ) @@ -871,3 +842,51 @@ def from_csvy(cls, config, atom_data=None): v_boundary_outer=v_boundary_outer, electron_densities=electron_densities, ) + + +def parse_structure_config(config, time_explosion, enable_homology=True): + electron_densities = None + temperature = None + structure_config = config.model.structure + if structure_config.type == "specific": + velocity = quantity_linspace( + structure_config.velocity.start, + structure_config.velocity.stop, + structure_config.velocity.num + 1, + ).cgs + density = parse_config_v1_density(config) + + elif structure_config.type == "file": + if os.path.isabs(structure_config.filename): + structure_config_fname = structure_config.filename + else: + structure_config_fname = os.path.join( + config.config_dirname, structure_config.filename + ) + + ( + time_0, + velocity, + density_0, + electron_densities, + temperature, + ) = read_density_file(structure_config_fname, structure_config.filetype) + density_0 = density_0.insert(0, 0) + + density = calculate_density_after_time( + density_0, time_0, time_explosion + ) + + else: + raise NotImplementedError + + # Note: This is the number of shells *without* taking in mind the + # v boundaries. + + geometry = HomologousRadial1DGeometry( + velocity[:-1] * time_explosion, # r_inner + velocity[1:] * time_explosion, # r_outer + velocity[:-1], # v_inner + velocity[1:], # v_outer + ) + return electron_densities, temperature, geometry, density diff --git a/tardis/model/geometry/radial1d.py b/tardis/model/geometry/radial1d.py index db0a064884a..a11f2783269 100644 --- a/tardis/model/geometry/radial1d.py +++ b/tardis/model/geometry/radial1d.py @@ -4,7 +4,7 @@ from astropy import units as u -class Radial1DGeometry: +class HomologousRadial1DGeometry: """ Holds information about model geometry for radial 1D models. @@ -21,17 +21,75 @@ class Radial1DGeometry: Volume in each shell """ - def __init__(self, r_inner, r_outer, v_inner, v_outer): - self.r_inner = r_inner - self.r_outer = r_outer - self.v_inner = v_inner - self.v_outer = v_outer + DEFAULT_VELOCITY_UNIT = u.km / u.s + DEFAULT_DISTANCE_UNIT = u.km + + def __init__( + self, + v_inner, + v_outer, + v_inner_boundary, + v_outer_boundary, + time_explosion, + ): + self.time_explosion = time_explosion + + # ensuring that the cells are continuous + assert np.allclose(v_inner[1:], v_outer[:-1]) + + self.v_inner = v_inner.to(self.DEFAULT_VELOCITY_UNIT) + self.v_outer = v_outer.to(self.DEFAULT_VELOCITY_UNIT) + + # ensuring that the boundaries are within the simulation area + assert v_inner_boundary < v_outer_boundary + assert v_inner_boundary >= self.v_inner[0] #TBD - we could just extrapolate + assert v_outer_boundary <= self.v_outer[-1] + + self.v_inner_boundary = v_inner_boundary + self.v_outer_boundary = v_outer_boundary + + @property + def v_inner_boundary_index(self): + # TODO potentially rename to v_inner_active_index?? + + # fix to ensure that we get the same index if we are on the shell + # boundary vs slightly above + + return np.max( + [ + np.searchsorted( + self.v_inner, self.v_inner_boundary, side="left" + ) + - 1, + 0 + ] + ) + + @property + def v_outer_boundary_index(self): + return np.searchsorted(self.v_outer, self.v_outer_boundary, side='right') + + @property + def r_inner(self): + return (self.v_inner * self.time_explosion).to( + self.DEFAULT_DISTANCE_UNIT + ) + + @property + def r_outer(self): + return (self.v_inner * self.time_explosion).to( + self.DEFAULT_DISTANCE_UNIT + ) @property def volume(self): """Volume in shell computed from r_outer and r_inner""" return (4.0 / 3) * np.pi * (self.r_outer**3 - self.r_inner**3) + @property + def no_of_shells(self): + return len(self.r_inner) + def to_numba(self): """ Returns a new NumbaRadial1DGeometry object diff --git a/tardis/model/geometry/tests/test_radial1d.py b/tardis/model/geometry/tests/test_radial1d.py new file mode 100644 index 00000000000..b0f39482f5c --- /dev/null +++ b/tardis/model/geometry/tests/test_radial1d.py @@ -0,0 +1,40 @@ +from astropy import units as u +import numpy as np + +from tardis.model.geometry.radial1d import HomologousRadial1DGeometry + +import pytest + + +@pytest.fixture(scope="function") +def homologous_radial1d_geometry(): + velocity = np.arange(8000, 21000, 1000) * u.km / u.s + v_inner = velocity[:-1] + v_outer = velocity[1:] + time_explosion = 5 * u.day + geometry = HomologousRadial1DGeometry( + v_inner, v_outer, v_inner[0], v_outer[-1], time_explosion + ) + return geometry + + +def test_v_indices(homologous_radial1d_geometry): + # Testing if the indices returned are correct when inner and outer + # boundary are on the innermost and outermost shell + + homologous_radial1d_geometry.v_inner_boundary = ( + homologous_radial1d_geometry.v_inner[0] + ) + homologous_radial1d_geometry.v_outer_boundary = ( + homologous_radial1d_geometry.v_outer[-1] + ) + assert homologous_radial1d_geometry.v_inner_boundary_index == 0 + assert homologous_radial1d_geometry.v_outer_boundary_index == 12 + vib_index = homologous_radial1d_geometry.v_inner_boundary_index + vob_index = homologous_radial1d_geometry.v_outer_boundary_index + assert np.all( + homologous_radial1d_geometry.v_inner[vib_index:vob_index] + == homologous_radial1d_geometry.v_inner + ) + homologous_radial1d_geometry.v_inner_boundary += 0.0001 * u.km/u.s + assert homologous_radial1d_geometry.v_inner_boundary_index == 0 From d353133d58e6297419a35aff0f6fd252cb73d3b9 Mon Sep 17 00:00:00 2001 From: Wolfgang Kerzendorf Date: Wed, 4 Oct 2023 12:17:47 -0400 Subject: [PATCH 02/23] add radial1d boundary logic --- tardis/model/geometry/radial1d.py | 26 +++++++++++--------- tardis/model/geometry/tests/test_radial1d.py | 26 +++++++++++++++++++- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/tardis/model/geometry/radial1d.py b/tardis/model/geometry/radial1d.py index a11f2783269..f229ba7c561 100644 --- a/tardis/model/geometry/radial1d.py +++ b/tardis/model/geometry/radial1d.py @@ -42,8 +42,10 @@ def __init__( # ensuring that the boundaries are within the simulation area assert v_inner_boundary < v_outer_boundary - assert v_inner_boundary >= self.v_inner[0] #TBD - we could just extrapolate - assert v_outer_boundary <= self.v_outer[-1] + assert ( + v_inner_boundary >= self.v_inner[0] + ) # TBD - we could just extrapolate + assert v_outer_boundary <= self.v_outer[-1] self.v_inner_boundary = v_inner_boundary self.v_outer_boundary = v_outer_boundary @@ -55,19 +57,21 @@ def v_inner_boundary_index(self): # fix to ensure that we get the same index if we are on the shell # boundary vs slightly above - return np.max( - [ - np.searchsorted( - self.v_inner, self.v_inner_boundary, side="left" - ) - - 1, - 0 - ] + return np.clip( + np.searchsorted(self.v_inner, self.v_inner_boundary, side="left") + - 1, + 0, + None, ) @property def v_outer_boundary_index(self): - return np.searchsorted(self.v_outer, self.v_outer_boundary, side='right') + return np.clip( + np.searchsorted(self.v_outer, self.v_outer_boundary, side="right") + + 1, + None, + len(self.v_outer), + ) @property def r_inner(self): diff --git a/tardis/model/geometry/tests/test_radial1d.py b/tardis/model/geometry/tests/test_radial1d.py index b0f39482f5c..cfb875aa5c7 100644 --- a/tardis/model/geometry/tests/test_radial1d.py +++ b/tardis/model/geometry/tests/test_radial1d.py @@ -36,5 +36,29 @@ def test_v_indices(homologous_radial1d_geometry): homologous_radial1d_geometry.v_inner[vib_index:vob_index] == homologous_radial1d_geometry.v_inner ) - homologous_radial1d_geometry.v_inner_boundary += 0.0001 * u.km/u.s + + #pivoting around the inner boundary of the simulation + + homologous_radial1d_geometry.v_inner_boundary = homologous_radial1d_geometry.v_inner[0] + 0.0001 * u.km / u.s + assert homologous_radial1d_geometry.v_inner_boundary_index == 0 + homologous_radial1d_geometry.v_inner_boundary = homologous_radial1d_geometry.v_inner[0] - 0.0001 * u.km / u.s assert homologous_radial1d_geometry.v_inner_boundary_index == 0 + + #pivoting around the first shell boundary of the simulation + homologous_radial1d_geometry.v_inner_boundary = homologous_radial1d_geometry.v_inner[1] - 0.0001 * u.km / u.s + assert homologous_radial1d_geometry.v_inner_boundary_index == 0 + homologous_radial1d_geometry.v_inner_boundary = homologous_radial1d_geometry.v_inner[1] + 0.0001 * u.km / u.s + assert homologous_radial1d_geometry.v_inner_boundary_index == 1 + + #pivoting around the outer boundary of the simulation + homologous_radial1d_geometry.v_outer_boundary = homologous_radial1d_geometry.v_outer[-1] + 0.0001 * u.km / u.s + assert homologous_radial1d_geometry.v_outer_boundary_index == 12 + homologous_radial1d_geometry.v_outer_boundary = homologous_radial1d_geometry.v_outer[-1] - 0.0001 * u.km / u.s + assert homologous_radial1d_geometry.v_outer_boundary_index == 12 + + #pivoting around the second to outer boundary of the simulation + homologous_radial1d_geometry.v_outer_boundary = homologous_radial1d_geometry.v_outer[-2] + 0.0001 * u.km / u.s + assert homologous_radial1d_geometry.v_outer_boundary_index == 12 + homologous_radial1d_geometry.v_outer_boundary = homologous_radial1d_geometry.v_outer[-2] - 0.0001 * u.km / u.s + assert homologous_radial1d_geometry.v_outer_boundary_index == 11 + From 2475551afb3d2916d0034b4deefbf9776f3b621c Mon Sep 17 00:00:00 2001 From: Wolfgang Kerzendorf Date: Wed, 4 Oct 2023 12:19:42 -0400 Subject: [PATCH 03/23] black format --- tardis/model/geometry/tests/test_radial1d.py | 41 +++++++++++++------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/tardis/model/geometry/tests/test_radial1d.py b/tardis/model/geometry/tests/test_radial1d.py index cfb875aa5c7..69e21012484 100644 --- a/tardis/model/geometry/tests/test_radial1d.py +++ b/tardis/model/geometry/tests/test_radial1d.py @@ -37,28 +37,43 @@ def test_v_indices(homologous_radial1d_geometry): == homologous_radial1d_geometry.v_inner ) - #pivoting around the inner boundary of the simulation + # pivoting around the inner boundary of the simulation - homologous_radial1d_geometry.v_inner_boundary = homologous_radial1d_geometry.v_inner[0] + 0.0001 * u.km / u.s + homologous_radial1d_geometry.v_inner_boundary = ( + homologous_radial1d_geometry.v_inner[0] + 0.0001 * u.km / u.s + ) assert homologous_radial1d_geometry.v_inner_boundary_index == 0 - homologous_radial1d_geometry.v_inner_boundary = homologous_radial1d_geometry.v_inner[0] - 0.0001 * u.km / u.s + homologous_radial1d_geometry.v_inner_boundary = ( + homologous_radial1d_geometry.v_inner[0] - 0.0001 * u.km / u.s + ) assert homologous_radial1d_geometry.v_inner_boundary_index == 0 - #pivoting around the first shell boundary of the simulation - homologous_radial1d_geometry.v_inner_boundary = homologous_radial1d_geometry.v_inner[1] - 0.0001 * u.km / u.s + # pivoting around the first shell boundary of the simulation + homologous_radial1d_geometry.v_inner_boundary = ( + homologous_radial1d_geometry.v_inner[1] - 0.0001 * u.km / u.s + ) assert homologous_radial1d_geometry.v_inner_boundary_index == 0 - homologous_radial1d_geometry.v_inner_boundary = homologous_radial1d_geometry.v_inner[1] + 0.0001 * u.km / u.s + homologous_radial1d_geometry.v_inner_boundary = ( + homologous_radial1d_geometry.v_inner[1] + 0.0001 * u.km / u.s + ) assert homologous_radial1d_geometry.v_inner_boundary_index == 1 - #pivoting around the outer boundary of the simulation - homologous_radial1d_geometry.v_outer_boundary = homologous_radial1d_geometry.v_outer[-1] + 0.0001 * u.km / u.s + # pivoting around the outer boundary of the simulation + homologous_radial1d_geometry.v_outer_boundary = ( + homologous_radial1d_geometry.v_outer[-1] + 0.0001 * u.km / u.s + ) assert homologous_radial1d_geometry.v_outer_boundary_index == 12 - homologous_radial1d_geometry.v_outer_boundary = homologous_radial1d_geometry.v_outer[-1] - 0.0001 * u.km / u.s + homologous_radial1d_geometry.v_outer_boundary = ( + homologous_radial1d_geometry.v_outer[-1] - 0.0001 * u.km / u.s + ) assert homologous_radial1d_geometry.v_outer_boundary_index == 12 - #pivoting around the second to outer boundary of the simulation - homologous_radial1d_geometry.v_outer_boundary = homologous_radial1d_geometry.v_outer[-2] + 0.0001 * u.km / u.s + # pivoting around the second to outer boundary of the simulation + homologous_radial1d_geometry.v_outer_boundary = ( + homologous_radial1d_geometry.v_outer[-2] + 0.0001 * u.km / u.s + ) assert homologous_radial1d_geometry.v_outer_boundary_index == 12 - homologous_radial1d_geometry.v_outer_boundary = homologous_radial1d_geometry.v_outer[-2] - 0.0001 * u.km / u.s + homologous_radial1d_geometry.v_outer_boundary = ( + homologous_radial1d_geometry.v_outer[-2] - 0.0001 * u.km / u.s + ) assert homologous_radial1d_geometry.v_outer_boundary_index == 11 - From e6d16975315a389552fdbd692775880cd0bfebbc Mon Sep 17 00:00:00 2001 From: Wolfgang Kerzendorf Date: Wed, 4 Oct 2023 13:41:29 -0400 Subject: [PATCH 04/23] several fixes --- tardis/model/geometry/radial1d.py | 16 ++++- tardis/model/geometry/tests/test_radial1d.py | 61 ++++++++++++++++---- 2 files changed, 64 insertions(+), 13 deletions(-) diff --git a/tardis/model/geometry/radial1d.py b/tardis/model/geometry/radial1d.py index f229ba7c561..b3a5adc628a 100644 --- a/tardis/model/geometry/radial1d.py +++ b/tardis/model/geometry/radial1d.py @@ -58,7 +58,7 @@ def v_inner_boundary_index(self): # boundary vs slightly above return np.clip( - np.searchsorted(self.v_inner, self.v_inner_boundary, side="left") + np.searchsorted(self.v_inner, self.v_inner_boundary, side="right") - 1, 0, None, @@ -67,12 +67,24 @@ def v_inner_boundary_index(self): @property def v_outer_boundary_index(self): return np.clip( - np.searchsorted(self.v_outer, self.v_outer_boundary, side="right") + np.searchsorted(self.v_outer, self.v_outer_boundary, side="left") + 1, None, len(self.v_outer), ) + @property + def v_inner_active(self): + v_inner_active = self.v_inner[self.v_inner_boundary_index :].copy() + v_inner_active[0] = self.v_inner_boundary + return v_inner_active + + @property + def v_outer_active(self): + v_outer_active = self.v_outer[: self.v_outer_boundary_index].copy() + v_outer_active[-1] = self.v_outer_boundary + return v_outer_active + @property def r_inner(self): return (self.v_inner * self.time_explosion).to( diff --git a/tardis/model/geometry/tests/test_radial1d.py b/tardis/model/geometry/tests/test_radial1d.py index 69e21012484..576b89e32ae 100644 --- a/tardis/model/geometry/tests/test_radial1d.py +++ b/tardis/model/geometry/tests/test_radial1d.py @@ -1,5 +1,6 @@ from astropy import units as u import numpy as np +import numpy.testing as npt from tardis.model.geometry.radial1d import HomologousRadial1DGeometry @@ -18,7 +19,7 @@ def homologous_radial1d_geometry(): return geometry -def test_v_indices(homologous_radial1d_geometry): +def test_vb_indices(homologous_radial1d_geometry): # Testing if the indices returned are correct when inner and outer # boundary are on the innermost and outermost shell @@ -29,51 +30,89 @@ def test_v_indices(homologous_radial1d_geometry): homologous_radial1d_geometry.v_outer[-1] ) assert homologous_radial1d_geometry.v_inner_boundary_index == 0 - assert homologous_radial1d_geometry.v_outer_boundary_index == 12 + assert homologous_radial1d_geometry.v_outer_boundary_index == len( + homologous_radial1d_geometry.v_inner + ) vib_index = homologous_radial1d_geometry.v_inner_boundary_index vob_index = homologous_radial1d_geometry.v_outer_boundary_index assert np.all( homologous_radial1d_geometry.v_inner[vib_index:vob_index] == homologous_radial1d_geometry.v_inner ) - + EPSILON_VELOCITY_SHIFT = EPSILON_VELOCITY_SHIFT # pivoting around the inner boundary of the simulation homologous_radial1d_geometry.v_inner_boundary = ( - homologous_radial1d_geometry.v_inner[0] + 0.0001 * u.km / u.s + homologous_radial1d_geometry.v_inner[0] + EPSILON_VELOCITY_SHIFT ) assert homologous_radial1d_geometry.v_inner_boundary_index == 0 homologous_radial1d_geometry.v_inner_boundary = ( - homologous_radial1d_geometry.v_inner[0] - 0.0001 * u.km / u.s + homologous_radial1d_geometry.v_inner[0] - EPSILON_VELOCITY_SHIFT ) assert homologous_radial1d_geometry.v_inner_boundary_index == 0 # pivoting around the first shell boundary of the simulation homologous_radial1d_geometry.v_inner_boundary = ( - homologous_radial1d_geometry.v_inner[1] - 0.0001 * u.km / u.s + homologous_radial1d_geometry.v_inner[1] - EPSILON_VELOCITY_SHIFT ) assert homologous_radial1d_geometry.v_inner_boundary_index == 0 homologous_radial1d_geometry.v_inner_boundary = ( - homologous_radial1d_geometry.v_inner[1] + 0.0001 * u.km / u.s + homologous_radial1d_geometry.v_inner[1] + EPSILON_VELOCITY_SHIFT ) assert homologous_radial1d_geometry.v_inner_boundary_index == 1 # pivoting around the outer boundary of the simulation homologous_radial1d_geometry.v_outer_boundary = ( - homologous_radial1d_geometry.v_outer[-1] + 0.0001 * u.km / u.s + homologous_radial1d_geometry.v_outer[-1] + EPSILON_VELOCITY_SHIFT ) assert homologous_radial1d_geometry.v_outer_boundary_index == 12 homologous_radial1d_geometry.v_outer_boundary = ( - homologous_radial1d_geometry.v_outer[-1] - 0.0001 * u.km / u.s + homologous_radial1d_geometry.v_outer[-1] - EPSILON_VELOCITY_SHIFT ) assert homologous_radial1d_geometry.v_outer_boundary_index == 12 # pivoting around the second to outer boundary of the simulation homologous_radial1d_geometry.v_outer_boundary = ( - homologous_radial1d_geometry.v_outer[-2] + 0.0001 * u.km / u.s + homologous_radial1d_geometry.v_outer[-2] + EPSILON_VELOCITY_SHIFT ) assert homologous_radial1d_geometry.v_outer_boundary_index == 12 homologous_radial1d_geometry.v_outer_boundary = ( - homologous_radial1d_geometry.v_outer[-2] - 0.0001 * u.km / u.s + homologous_radial1d_geometry.v_outer[-2] - EPSILON_VELOCITY_SHIFT ) assert homologous_radial1d_geometry.v_outer_boundary_index == 11 + + +def test_velocity_boundary(homologous_radial1d_geometry): + # Testing if the indices returned are correct when inner and outer + # boundary are on the innermost and outermost shell + + homologous_radial1d_geometry.v_inner_boundary = 7999 * u.km / u.s + npt.assert_almost_equal( + homologous_radial1d_geometry.v_inner_active[0].value, 7999 + ) + assert len(homologous_radial1d_geometry.v_inner_active) == len( + homologous_radial1d_geometry.v_inner + ) + + homologous_radial1d_geometry.v_inner_boundary = 8001 * u.km / u.s + npt.assert_almost_equal( + homologous_radial1d_geometry.v_inner_active[0].value, 8001 + ) + assert len(homologous_radial1d_geometry.v_inner_active) == len( + homologous_radial1d_geometry.v_inner + ) + + homologous_radial1d_geometry.v_inner_boundary = 9001 * u.km / u.s + npt.assert_almost_equal( + homologous_radial1d_geometry.v_inner_active[0].value, 9001 + ) + assert len(homologous_radial1d_geometry.v_inner_active) == ( + len(homologous_radial1d_geometry.v_inner) - 1 + ) + homologous_radial1d_geometry.v_inner_boundary = 9000 * u.km / u.s + npt.assert_almost_equal( + homologous_radial1d_geometry.v_inner_active[0].value, 9000 + ) + assert len(homologous_radial1d_geometry.v_inner_active) == ( + len(homologous_radial1d_geometry.v_inner) - 1 + ) From 3c53cdaf4d3cd1f3c6f45a14af358b433fb08d9d Mon Sep 17 00:00:00 2001 From: Wolfgang Kerzendorf Date: Wed, 4 Oct 2023 14:20:51 -0400 Subject: [PATCH 05/23] fix epsilon --- tardis/model/geometry/tests/test_radial1d.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tardis/model/geometry/tests/test_radial1d.py b/tardis/model/geometry/tests/test_radial1d.py index 576b89e32ae..af5ede08b04 100644 --- a/tardis/model/geometry/tests/test_radial1d.py +++ b/tardis/model/geometry/tests/test_radial1d.py @@ -39,7 +39,7 @@ def test_vb_indices(homologous_radial1d_geometry): homologous_radial1d_geometry.v_inner[vib_index:vob_index] == homologous_radial1d_geometry.v_inner ) - EPSILON_VELOCITY_SHIFT = EPSILON_VELOCITY_SHIFT + EPSILON_VELOCITY_SHIFT = 1 * u.km / u.s # pivoting around the inner boundary of the simulation homologous_radial1d_geometry.v_inner_boundary = ( From 6dce2b455cdd8123bcc1969846969d0401d16a1f Mon Sep 17 00:00:00 2001 From: Wolfgang Kerzendorf Date: Wed, 4 Oct 2023 14:39:58 -0400 Subject: [PATCH 06/23] add testing of boundaries --- tardis/model/geometry/tests/test_radial1d.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tardis/model/geometry/tests/test_radial1d.py b/tardis/model/geometry/tests/test_radial1d.py index af5ede08b04..e6c887180d0 100644 --- a/tardis/model/geometry/tests/test_radial1d.py +++ b/tardis/model/geometry/tests/test_radial1d.py @@ -83,8 +83,7 @@ def test_vb_indices(homologous_radial1d_geometry): def test_velocity_boundary(homologous_radial1d_geometry): - # Testing if the indices returned are correct when inner and outer - # boundary are on the innermost and outermost shell + # testing the active cell boundaries when setting the boundaries homologous_radial1d_geometry.v_inner_boundary = 7999 * u.km / u.s npt.assert_almost_equal( From 1fdcea8d8d235f4bc1719ec9f5a669a044538780 Mon Sep 17 00:00:00 2001 From: Wolfgang Kerzendorf Date: Wed, 4 Oct 2023 14:41:15 -0400 Subject: [PATCH 07/23] change the r_inner_active --- tardis/model/geometry/radial1d.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tardis/model/geometry/radial1d.py b/tardis/model/geometry/radial1d.py index b3a5adc628a..32b6bcc3467 100644 --- a/tardis/model/geometry/radial1d.py +++ b/tardis/model/geometry/radial1d.py @@ -91,12 +91,26 @@ def r_inner(self): self.DEFAULT_DISTANCE_UNIT ) + @property + def r_inner_active(self): + return (self.v_inner_active * self.time_explosion).to( + self.DEFAULT_DISTANCE_UNIT + ) + + @property def r_outer(self): return (self.v_inner * self.time_explosion).to( self.DEFAULT_DISTANCE_UNIT ) + @property + def r_outer_active(self): + return (self.v_outer_active * self.time_explosion).to( + self.DEFAULT_DISTANCE_UNIT + ) + + @property def volume(self): """Volume in shell computed from r_outer and r_inner""" From 56e9da57d6ce0a79fa4c4dc37441466ec9d45732 Mon Sep 17 00:00:00 2001 From: Wolfgang Kerzendorf Date: Sat, 7 Oct 2023 17:14:05 -0400 Subject: [PATCH 08/23] first integration with `from_config` working --- tardis/model/base.py | 41 +++++++++++++++++-------------- tardis/model/geometry/radial1d.py | 22 +++++++++++------ 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/tardis/model/base.py b/tardis/model/base.py index c7859a912df..635689ae6fc 100644 --- a/tardis/model/base.py +++ b/tardis/model/base.py @@ -217,8 +217,8 @@ def __init__( self.geometry = geometry self._v_boundary_inner = None self._v_boundary_outer = None - #self._velocity = None - #self.raw_velocity = velocity + # self._velocity = None + # self.raw_velocity = velocity self.v_boundary_inner = v_boundary_inner self.v_boundary_outer = v_boundary_outer @@ -227,11 +227,8 @@ def __init__( self._electron_densities = electron_densities if len(density) != len(self.geometry.v_inner): - density = density[ - self.v_boundary_inner_index - + 1 : self.v_boundary_outer_index - + 1 + self.geometry.v_inner_boundary_index : self.geometry.v_outer_boundary_index ] self.raw_abundance = self._abundance @@ -304,7 +301,7 @@ def __init__( ) t_radiative = constants.b_wien / ( lambda_wien_inner - * (1 + (self.v_middle - self.v_boundary_inner) / constants.c) + * (1 + (self.v_middle - self.geometry.v_inner_boundary) / constants.c) ) elif len(t_radiative) != self.no_of_shells: t_radiative = t_radiative[ @@ -324,9 +321,7 @@ def __init__( ) elif len(dilution_factor) != self.no_of_shells: dilution_factor = dilution_factor[ - self.v_boundary_inner_index - + 1 : self.v_boundary_outer_index - + 1 + self.geometry.v_inner_boundary_index : self.geometry.v_outer_boundary_index ] assert len(dilution_factor) == self.no_of_shells @@ -435,8 +430,9 @@ def abundance(self): self._abundance = self.raw_isotope_abundance.decay( self.time_explosion ).merge(self.raw_abundance) - abundance = self._abundance.loc[ - :, self.v_boundary_inner_index : self.v_boundary_outer_index - 1 + abundance = self._abundance.iloc[ + :, + self.geometry.v_inner_boundary_index : self.geometry.v_outer_boundary_index, ] abundance.columns = range(len(abundance.columns)) return abundance @@ -452,6 +448,7 @@ def no_of_shells(self): @property def no_of_raw_shells(self): return self.geometry.no_of_shells + """ @property def v_boundary_inner(self): @@ -541,6 +538,7 @@ def v_boundary_outer_index(self): ) return v_outer_ind """ + @classmethod def from_config(cls, config, atom_data=None): """ @@ -561,7 +559,7 @@ def from_config(cls, config, atom_data=None): electron_densities, temperature, geometry, - density + density, ) = parse_structure_config(config, time_explosion) if temperature is not None: @@ -631,8 +629,12 @@ def from_config(cls, config, atom_data=None): elemental_mass=elemental_mass, luminosity_requested=luminosity_requested, dilution_factor=None, - v_boundary_inner=config.model.structure.get("v_inner_boundary", None), - v_boundary_outer=config.model.structure.get("v_outer_boundary", None), + v_boundary_inner=config.model.structure.get( + "v_inner_boundary", None + ), + v_boundary_outer=config.model.structure.get( + "v_outer_boundary", None + ), electron_densities=electron_densities, ) @@ -884,9 +886,10 @@ def parse_structure_config(config, time_explosion, enable_homology=True): # v boundaries. geometry = HomologousRadial1DGeometry( - velocity[:-1] * time_explosion, # r_inner - velocity[1:] * time_explosion, # r_outer - velocity[:-1], # v_inner - velocity[1:], # v_outer + velocity[:-1], # r_inner + velocity[1:], # r_outer + v_inner_boundary=structure_config.get("v_inner_boundary", None), + v_outer_boundary=structure_config.get("v_outer_boundary", None), + time_explosion=time_explosion, ) return electron_densities, temperature, geometry, density diff --git a/tardis/model/geometry/radial1d.py b/tardis/model/geometry/radial1d.py index 32b6bcc3467..da7adf796a6 100644 --- a/tardis/model/geometry/radial1d.py +++ b/tardis/model/geometry/radial1d.py @@ -41,14 +41,22 @@ def __init__( self.v_outer = v_outer.to(self.DEFAULT_VELOCITY_UNIT) # ensuring that the boundaries are within the simulation area - assert v_inner_boundary < v_outer_boundary + + if v_inner_boundary is None: + self.v_inner_boundary = self.v_inner[0] + else: + self.v_inner_boundary = v_inner_boundary + + if v_outer_boundary is None: + self.v_outer_boundary = self.v_outer[-1] + else: + self.v_outer_boundary = v_outer_boundary + + assert self.v_inner_boundary < self.v_outer_boundary assert ( - v_inner_boundary >= self.v_inner[0] + self.v_inner_boundary >= self.v_inner[0] ) # TBD - we could just extrapolate - assert v_outer_boundary <= self.v_outer[-1] - - self.v_inner_boundary = v_inner_boundary - self.v_outer_boundary = v_outer_boundary + assert self.v_outer_boundary <= self.v_outer[-1] @property def v_inner_boundary_index(self): @@ -143,8 +151,6 @@ def to_numba(self): ("v_inner", float64[:]), ("v_outer", float64[:]), ] - - @jitclass(numba_geometry_spec) class NumbaRadial1DGeometry(object): def __init__(self, r_inner, r_outer, v_inner, v_outer): From f6743d74cff404e8368e507cdef1bbef2674b8c8 Mon Sep 17 00:00:00 2001 From: Wolfgang Kerzendorf Date: Sun, 8 Oct 2023 07:41:37 -0400 Subject: [PATCH 09/23] hunting down density indexing bug --- tardis/model/base.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tardis/model/base.py b/tardis/model/base.py index 635689ae6fc..1e871601d08 100644 --- a/tardis/model/base.py +++ b/tardis/model/base.py @@ -227,6 +227,7 @@ def __init__( self._electron_densities = electron_densities if len(density) != len(self.geometry.v_inner): + #finite difference vs finite volume - take the density 1 further density = density[ self.geometry.v_inner_boundary_index : self.geometry.v_outer_boundary_index ] From b55b21d8845de8ac4731e3e0d2dad642ac809c12 Mon Sep 17 00:00:00 2001 From: Wolfgang Kerzendorf Date: Sun, 8 Oct 2023 13:47:02 -0400 Subject: [PATCH 10/23] all model tests (without csvy) pass --- tardis/model/base.py | 117 +++++------------------------- tardis/model/geometry/radial1d.py | 13 +++- tardis/model/tests/test_base.py | 24 +++--- 3 files changed, 40 insertions(+), 114 deletions(-) diff --git a/tardis/model/base.py b/tardis/model/base.py index 1e871601d08..ed7c08b0965 100644 --- a/tardis/model/base.py +++ b/tardis/model/base.py @@ -119,10 +119,10 @@ def __init__(self, composition, geometry, time_explosion): def mass(self): """Mass calculated using the formula: mass_fraction * density * volume""" + + total_mass = (self.geometry.volume * self.composition.density).to(u.g) return ( - self.composition.elemental_mass_fraction - * self.composition.density - * self.geometry.volume + self.composition.elemental_mass_fraction * total_mass.value ) @property @@ -227,7 +227,6 @@ def __init__( self._electron_densities = electron_densities if len(density) != len(self.geometry.v_inner): - #finite difference vs finite volume - take the density 1 further density = density[ self.geometry.v_inner_boundary_index : self.geometry.v_outer_boundary_index ] @@ -302,7 +301,11 @@ def __init__( ) t_radiative = constants.b_wien / ( lambda_wien_inner - * (1 + (self.v_middle - self.geometry.v_inner_boundary) / constants.c) + * ( + 1 + + (self.v_middle - self.geometry.v_inner_boundary) + / constants.c + ) ) elif len(t_radiative) != self.no_of_shells: t_radiative = t_radiative[ @@ -388,11 +391,11 @@ def radius(self): @property def r_inner(self): - return self.model_state.geometry.r_inner + return self.model_state.geometry.r_inner_active @property def r_outer(self): - return self.model_state.geometry.r_outer + return self.model_state.geometry.r_outer_active @property def r_middle(self): @@ -411,11 +414,11 @@ def velocity(self): @property def v_inner(self): - return self.model_state.geometry.v_inner + return self.model_state.geometry.v_inner_active @property def v_outer(self): - return self.model_state.geometry.v_outer + return self.model_state.geometry.v_outer_active @property def v_middle(self): @@ -450,96 +453,6 @@ def no_of_shells(self): def no_of_raw_shells(self): return self.geometry.no_of_shells - """ - @property - def v_boundary_inner(self): - return self.v_boundary_inner - if self._v_boundary_inner is None: - return self.raw_velocity[0] - if self._v_boundary_inner < 0 * u.km / u.s: - return self.raw_velocity[0] - return self._v_boundary_inner - - - @v_boundary_inner.setter - def v_boundary_inner(self, value): - if value is not None: - if value > 0 * u.km / u.s: - value = u.Quantity(value, self.v_boundary_inner.unit) - if value > self.v_boundary_outer: - raise ValueError( - f"v_boundary_inner ({value}) must not be higher than " - f"v_boundary_outer ({self.v_boundary_outer})." - ) - if value > self.raw_velocity[-1]: - raise ValueError( - f"v_boundary_inner ({value}) is outside of the model range ({self.raw_velocity[-1]})." - ) - if value < self.raw_velocity[0]: - raise ValueError( - f"v_boundary_inner ({value}) is lower than the lowest shell ({self.raw_velocity[0]}) in the model." - ) - self._v_boundary_inner = value - # Invalidate the cached cut-down velocity array - self._velocity = None - - - @property - def v_boundary_outer(self): - return self.v_boundary_outer - - if self._v_boundary_outer is None: - return self.raw_velocity[-1] - if self._v_boundary_outer < 0 * u.km / u.s: - return self.raw_velocity[-1] - return self._v_boundary_outer - - @v_boundary_outer.setter - def v_boundary_outer(self, value): - if value is not None: - if value > 0 * u.km / u.s: - value = u.Quantity(value, self.v_boundary_outer.unit) - if value < self.v_boundary_inner: - raise ValueError( - f"v_boundary_outer ({value}) must not be smaller than v_boundary_inner ({self.v_boundary_inner})." - ) - if value < self.raw_velocity[0]: - raise ValueError( - f"v_boundary_outer ({value}) is outside of the model range ({self.raw_velocity[0]})." - ) - if value > self.raw_velocity[-1]: - raise ValueError( - f"v_boundary_outer ({value}) is larger than the largest shell in the model ({self.raw_velocity[-1]})." - ) - self._v_boundary_outer = value - # Invalidate the cached cut-down velocity array - self._velocity = None - - @property - def v_boundary_inner_index(self): - if self.v_boundary_inner in self.raw_velocity: - v_inner_ind = np.argwhere( - self.raw_velocity == self.v_boundary_inner - )[0][0] - else: - v_inner_ind = ( - np.searchsorted(self.raw_velocity, self.v_boundary_inner) - 1 - ) - return v_inner_ind - - @property - def v_boundary_outer_index(self): - if self.v_boundary_outer in self.raw_velocity: - v_outer_ind = np.argwhere( - self.raw_velocity == self.v_boundary_outer - )[0][0] - else: - v_outer_ind = np.searchsorted( - self.raw_velocity, self.v_boundary_outer - ) - return v_outer_ind - """ - @classmethod def from_config(cls, config, atom_data=None): """ @@ -885,7 +798,11 @@ def parse_structure_config(config, time_explosion, enable_homology=True): # Note: This is the number of shells *without* taking in mind the # v boundaries. - + if len(density) == len(velocity): + logger.warning( + "Number of density points larger than number of shells. Assuming inner point irrelevant" + ) + density = density[1:] geometry = HomologousRadial1DGeometry( velocity[:-1], # r_inner velocity[1:], # r_outer diff --git a/tardis/model/geometry/radial1d.py b/tardis/model/geometry/radial1d.py index da7adf796a6..c18bb079b3a 100644 --- a/tardis/model/geometry/radial1d.py +++ b/tardis/model/geometry/radial1d.py @@ -2,6 +2,7 @@ from numba.experimental import jitclass import numpy as np from astropy import units as u +import warnings class HomologousRadial1DGeometry: @@ -44,11 +45,17 @@ def __init__( if v_inner_boundary is None: self.v_inner_boundary = self.v_inner[0] + elif v_inner_boundary < 0: + warnings.warn("v_inner_boundary < 0, assuming default value", DeprecationWarning) + self.v_inner_boundary = self.v_inner[0] else: self.v_inner_boundary = v_inner_boundary if v_outer_boundary is None: self.v_outer_boundary = self.v_outer[-1] + elif v_outer_boundary < 0: + warnings.warn("v_outer_boundary < 0, assuming default value", DeprecationWarning) + self.v_outer_boundary = self.v_outer[-1] else: self.v_outer_boundary = v_outer_boundary @@ -83,13 +90,13 @@ def v_outer_boundary_index(self): @property def v_inner_active(self): - v_inner_active = self.v_inner[self.v_inner_boundary_index :].copy() + v_inner_active = self.v_inner[self.v_inner_boundary_index:self.v_outer_boundary_index].copy() v_inner_active[0] = self.v_inner_boundary return v_inner_active @property def v_outer_active(self): - v_outer_active = self.v_outer[: self.v_outer_boundary_index].copy() + v_outer_active = self.v_outer[self.v_inner_boundary_index:self.v_outer_boundary_index].copy() v_outer_active[-1] = self.v_outer_boundary return v_outer_active @@ -108,7 +115,7 @@ def r_inner_active(self): @property def r_outer(self): - return (self.v_inner * self.time_explosion).to( + return (self.v_outer * self.time_explosion).to( self.DEFAULT_DISTANCE_UNIT ) diff --git a/tardis/model/tests/test_base.py b/tardis/model/tests/test_base.py index f86fd982204..44f6c4393a3 100644 --- a/tardis/model/tests/test_base.py +++ b/tardis/model/tests/test_base.py @@ -59,8 +59,9 @@ def setup(self, example_model_file_dir): self.simulation_state = SimulationState.from_config(self.config) def test_velocities(self): - assert self.simulation_state.v_inner.unit == u.Unit("cm/s") - assert_almost_equal(self.simulation_state.v_inner[0].value, 1e4 * 1e5) + assert_almost_equal( + self.simulation_state.v_inner.to(u.cm / u.s).value[0], 1e4 * 1e5 + ) def test_abundances(self): oxygen_abundance = self.config.model.abundances.O @@ -78,9 +79,9 @@ def setup(self, example_model_file_dir): self.simulation_state = SimulationState.from_config(self.config) def test_velocities(self): - assert self.simulation_state.v_inner.unit == u.Unit("cm/s") assert_almost_equal( - self.simulation_state.v_inner[0].value, 1.259375e03 * 1e5 + self.simulation_state.v_inner[0].to(u.cm / u.s).value, + 1.259375e03 * 1e5, ) def test_abundances(self): @@ -102,9 +103,9 @@ def setup(self, example_model_file_dir): self.simulation_state = SimulationState.from_config(self.config) def test_velocities(self): - assert self.simulation_state.v_inner.unit == u.Unit("cm/s") assert_almost_equal( - self.simulation_state.v_inner[0].value, 1.259375e03 * 1e5 + self.simulation_state.v_inner[0].to(u.cm / u.s).value, + 1.259375e03 * 1e5, ) def test_abundances(self): @@ -116,7 +117,6 @@ def test_abundances(self): class TestModelFromArtisDensityAbundancesVSlice: @pytest.fixture(autouse=True) def setup(self, example_model_file_dir): - self.config = Configuration.from_yaml( example_model_file_dir / "tardis_configv1_artis_density_v_slice.yml" ) @@ -126,7 +126,6 @@ def setup(self, example_model_file_dir): self.simulation_state = SimulationState.from_config(self.config) def test_velocities(self): - assert self.simulation_state.v_inner.unit == u.Unit("cm/s") assert_almost_equal( self.simulation_state.v_inner[0].to(u.km / u.s).value, 9000 ) @@ -175,7 +174,9 @@ def setup(self, example_model_file_dir): self.simulation_state = SimulationState.from_config(self.config) def test_velocities(self): - assert self.simulation_state.v_inner.unit == u.Unit("cm/s") + # unclear why we are testing this + # assert self.simulation_state.v_inner.unit == u.Unit("cm/s") + assert hasattr(self.simulation_state.v_inner, "unit") assert_almost_equal( self.simulation_state.v_inner[0].to(u.km / u.s).value, 11000 ) @@ -357,8 +358,9 @@ def test_radial_1D_geometry_volume(simulation_verysimple, index, expected): geometry = simulation_verysimple.simulation_state.model_state.geometry volume = geometry.volume - assert volume.unit == u.Unit("cm3") - assert_almost_equal(volume[index].value, expected, decimal=-40) + assert_almost_equal( + volume[index].to(u.cm**3).value, expected, decimal=-40 + ) @pytest.mark.parametrize( From ed978d96f72b84105689278c10833740d76c2d57 Mon Sep 17 00:00:00 2001 From: Wolfgang Kerzendorf Date: Mon, 9 Oct 2023 13:04:30 -0400 Subject: [PATCH 11/23] more fixes --- tardis/io/tests/test_model_reader.py | 2 +- tardis/model/base.py | 14 ++--- tardis/model/geometry/radial1d.py | 52 ++++++++++++++----- .../montecarlo_numba/tests/test_vpacket.py | 6 ++- tardis/plasma/standard_plasmas.py | 41 ++++++++------- .../visualization/tools/convergence_plot.py | 10 ++-- 6 files changed, 81 insertions(+), 44 deletions(-) diff --git a/tardis/io/tests/test_model_reader.py b/tardis/io/tests/test_model_reader.py index 1d3196fe19e..5f14860a772 100644 --- a/tardis/io/tests/test_model_reader.py +++ b/tardis/io/tests/test_model_reader.py @@ -138,7 +138,7 @@ def test_model_to_dict(simulation_verysimple): model_dict, isotope_abundance = model_to_dict(model) # Check model dictionary - assert np.array_equal(model_dict["velocity_cgs"][0], model.velocity.value) + assert np.array_equal(model_dict["velocity_cgs"][0], model.velocity.cgs.value) assert model_dict["velocity_cgs"][1] == model.velocity.unit.to_string() assert np.array_equal(model_dict["abundance"], model.abundance) assert np.array_equal( diff --git a/tardis/model/base.py b/tardis/model/base.py index ed7c08b0965..62127a3174a 100644 --- a/tardis/model/base.py +++ b/tardis/model/base.py @@ -217,8 +217,6 @@ def __init__( self.geometry = geometry self._v_boundary_inner = None self._v_boundary_outer = None - # self._velocity = None - # self.raw_velocity = velocity self.v_boundary_inner = v_boundary_inner self.v_boundary_outer = v_boundary_outer @@ -226,7 +224,7 @@ def __init__( self.time_explosion = time_explosion self._electron_densities = electron_densities - if len(density) != len(self.geometry.v_inner): + if len(density) != len(self.geometry.v_inner_active): density = density[ self.geometry.v_inner_boundary_index : self.geometry.v_outer_boundary_index ] @@ -307,10 +305,11 @@ def __init__( / constants.c ) ) - elif len(t_radiative) != self.no_of_shells: + + elif len(t_radiative) == self.no_of_shells + 1: t_radiative = t_radiative[ - self.v_boundary_inner_index - + 1 : self.v_boundary_outer_index + self.geometry.v_inner_boundary_index + + 1 : self.geometry.v_outer_boundary_index + 1 ] else: @@ -403,7 +402,8 @@ def r_middle(self): @property def velocity(self): - return None + velocity = self.geometry.v_outer_active.copy() + return velocity.insert(0, self.geometry.v_inner_active[0]) if self._velocity is None: self._velocity = self.raw_velocity[ self.v_boundary_inner_index : self.v_boundary_outer_index + 1 diff --git a/tardis/model/geometry/radial1d.py b/tardis/model/geometry/radial1d.py index c18bb079b3a..479b15821a0 100644 --- a/tardis/model/geometry/radial1d.py +++ b/tardis/model/geometry/radial1d.py @@ -42,11 +42,14 @@ def __init__( self.v_outer = v_outer.to(self.DEFAULT_VELOCITY_UNIT) # ensuring that the boundaries are within the simulation area - + if v_inner_boundary is None: self.v_inner_boundary = self.v_inner[0] elif v_inner_boundary < 0: - warnings.warn("v_inner_boundary < 0, assuming default value", DeprecationWarning) + warnings.warn( + "v_inner_boundary < 0, assuming default value", + DeprecationWarning, + ) self.v_inner_boundary = self.v_inner[0] else: self.v_inner_boundary = v_inner_boundary @@ -54,16 +57,24 @@ def __init__( if v_outer_boundary is None: self.v_outer_boundary = self.v_outer[-1] elif v_outer_boundary < 0: - warnings.warn("v_outer_boundary < 0, assuming default value", DeprecationWarning) + warnings.warn( + "v_outer_boundary < 0, assuming default value", + DeprecationWarning, + ) self.v_outer_boundary = self.v_outer[-1] else: self.v_outer_boundary = v_outer_boundary - + assert self.v_inner_boundary < self.v_outer_boundary - assert ( - self.v_inner_boundary >= self.v_inner[0] - ) # TBD - we could just extrapolate - assert self.v_outer_boundary <= self.v_outer[-1] + if self.v_inner_boundary < self.v_inner[0]: + warnings.warn( + "Requesting inner boundary below inner shell. Extrapolating the inner cell" + ) + + if self.v_outer_boundary > self.v_outer[-1]: + warnings.warn( + "Requesting inner boundary below inner shell. Extrapolating the inner cell" + ) @property def v_inner_boundary_index(self): @@ -90,13 +101,17 @@ def v_outer_boundary_index(self): @property def v_inner_active(self): - v_inner_active = self.v_inner[self.v_inner_boundary_index:self.v_outer_boundary_index].copy() + v_inner_active = self.v_inner[ + self.v_inner_boundary_index : self.v_outer_boundary_index + ].copy() v_inner_active[0] = self.v_inner_boundary return v_inner_active @property def v_outer_active(self): - v_outer_active = self.v_outer[self.v_inner_boundary_index:self.v_outer_boundary_index].copy() + v_outer_active = self.v_outer[ + self.v_inner_boundary_index : self.v_outer_boundary_index + ].copy() v_outer_active[-1] = self.v_outer_boundary return v_outer_active @@ -112,7 +127,6 @@ def r_inner_active(self): self.DEFAULT_DISTANCE_UNIT ) - @property def r_outer(self): return (self.v_outer * self.time_explosion).to( @@ -125,16 +139,28 @@ def r_outer_active(self): self.DEFAULT_DISTANCE_UNIT ) - @property def volume(self): """Volume in shell computed from r_outer and r_inner""" return (4.0 / 3) * np.pi * (self.r_outer**3 - self.r_inner**3) + @property + def volume_active(self): + """Volume in shell computed from r_outer and r_inner""" + return ( + (4.0 / 3) + * np.pi + * (self.r_outer_active**3 - self.r_inner_active**3) + ) + @property def no_of_shells(self): return len(self.r_inner) + @property + def no_of_shells_active(self): + return len(self.r_inner_active) + def to_numba(self): """ Returns a new NumbaRadial1DGeometry object @@ -158,6 +184,8 @@ def to_numba(self): ("v_inner", float64[:]), ("v_outer", float64[:]), ] + + @jitclass(numba_geometry_spec) class NumbaRadial1DGeometry(object): def __init__(self, r_inner, r_outer, v_inner, v_outer): diff --git a/tardis/montecarlo/montecarlo_numba/tests/test_vpacket.py b/tardis/montecarlo/montecarlo_numba/tests/test_vpacket.py index 21ad8647d40..bee9fc4c41f 100644 --- a/tardis/montecarlo/montecarlo_numba/tests/test_vpacket.py +++ b/tardis/montecarlo/montecarlo_numba/tests/test_vpacket.py @@ -66,7 +66,8 @@ def test_trace_vpacket_within_shell( ) npt.assert_almost_equal(tau_trace_combined, 8164850.891288479) - npt.assert_almost_equal(distance_boundary, 843684056256104.1) + #changed from almost equal to allclose. Now seems to work. + npt.assert_allclose(distance_boundary, 843684056256104.1) assert delta_shell == 1 @@ -92,7 +93,8 @@ def test_trace_vpacket( ) npt.assert_almost_equal(tau_trace_combined, 8164850.891288479) - npt.assert_almost_equal(v_packet.r, 1286064000000000.0) + #change from almost_equal to allclose. Now seems to work. + npt.assert_allclose(v_packet.r, 1286064000000000.0) npt.assert_almost_equal(v_packet.nu, 4.0e15) npt.assert_almost_equal(v_packet.energy, 0.0) npt.assert_almost_equal(v_packet.mu, 0.8309726858508629) diff --git a/tardis/plasma/standard_plasmas.py b/tardis/plasma/standard_plasmas.py index 01e40fde22e..c4323830738 100644 --- a/tardis/plasma/standard_plasmas.py +++ b/tardis/plasma/standard_plasmas.py @@ -1,3 +1,4 @@ +from astropy import units as u import os import logging @@ -49,7 +50,7 @@ logger = logging.getLogger(__name__) -def assemble_plasma(config, model, atom_data=None): +def assemble_plasma(config, simulation_state, atom_data=None): """ Create a BasePlasma instance from a Configuration object and a Radial1DModel. @@ -106,7 +107,7 @@ def assemble_plasma(config, model, atom_data=None): raise atom_data.prepare_atom_data( - model.abundance.index, + simulation_state.abundance.index, line_interaction_type=config.plasma.line_interaction_type, nlte_species=nlte_species, ) @@ -135,12 +136,12 @@ def assemble_plasma(config, model, atom_data=None): ] kwargs = dict( - t_rad=model.t_radiative, - abundance=model.abundance, - density=model.density, + t_rad=simulation_state.t_radiative, + abundance=simulation_state.abundance, + density=simulation_state.density, atomic_data=atom_data, - time_explosion=model.time_explosion, - w=model.dilution_factor, + time_explosion=simulation_state.time_explosion, + w=simulation_state.dilution_factor, link_t_rad_t_electron=config.plasma.link_t_rad_t_electron, continuum_interaction_species=continuum_interaction_species, nlte_ionization_species=nlte_ionization_species, @@ -213,9 +214,9 @@ def assemble_plasma(config, model, atom_data=None): bf_heating_coeff_estimator=None, stim_recomb_cooling_coeff_estimator=None, alpha_stim_estimator=None, - volume=model.volume, - r_inner=model.r_inner, - t_inner=model.t_inner, + volume=simulation_state.volume, + r_inner=simulation_state.r_inner.to(u.cm), + t_inner=simulation_state.t_inner, ) if config.plasma.radiative_rates_type == "blackbody": plasma_modules.append(JBluesBlackBody) @@ -224,9 +225,9 @@ def assemble_plasma(config, model, atom_data=None): elif config.plasma.radiative_rates_type == "detailed": plasma_modules += detailed_j_blues_properties + detailed_j_blues_inputs kwargs.update( - r_inner=model.r_inner, - t_inner=model.t_inner, - volume=model.volume, + r_inner=simulation_state.r_inner.to(u.cm), + t_inner=simulation_state.t_inner, + volume=simulation_state.volume, j_blue_estimator=None, ) property_kwargs[JBluesDetailed] = {"w_epsilon": config.plasma.w_epsilon} @@ -278,8 +279,10 @@ def assemble_plasma(config, model, atom_data=None): else: plasma_modules += helium_lte_properties - if model._electron_densities is not None: - electron_densities = pd.Series(model._electron_densities.cgs.value) + if simulation_state._electron_densities is not None: + electron_densities = pd.Series( + simulation_state._electron_densities.cgs.value + ) if config.plasma.helium_treatment == "numerical-nlte": property_kwargs[IonNumberDensityHeNLTE] = dict( electron_densities=electron_densities @@ -289,10 +292,12 @@ def assemble_plasma(config, model, atom_data=None): electron_densities=electron_densities ) - if not model.raw_isotope_abundance.empty: + if not simulation_state.raw_isotope_abundance.empty: plasma_modules += isotope_properties - isotope_abundance = model.raw_isotope_abundance.loc[ - :, model.v_boundary_inner_index : model.v_boundary_outer_index - 1 + isotope_abundance = simulation_state.raw_isotope_abundance.loc[ + :, + simulation_state.geometry.v_inner_boundary_index : simulation_state.geometry.v_outer_boundary_index + - 1, ] kwargs.update(isotope_abundance=isotope_abundance) diff --git a/tardis/visualization/tools/convergence_plot.py b/tardis/visualization/tools/convergence_plot.py index 5417b85e2a8..16e588f5e76 100644 --- a/tardis/visualization/tools/convergence_plot.py +++ b/tardis/visualization/tools/convergence_plot.py @@ -310,10 +310,12 @@ def build(self, display_plot=True): def update_plasma_plots(self): """Update plasma convergence plots every iteration.""" # convert velocity to km/s - x = self.iterable_data["velocity"].to(u.km / u.s).value.tolist() + velocity_km_s = ( + self.iterable_data["velocity"].to(u.km / u.s).value.tolist() + ) # add luminosity data in hover data in plasma plots - customdata = len(x) * [ + customdata = len(velocity_km_s) * [ "
" + "Emitted Luminosity: " + f'{self.value_data["Emitted"][-1]:.4g}' @@ -327,7 +329,7 @@ def update_plasma_plots(self): # add a radiation temperature vs shell velocity trace to the plasma plot self.plasma_plot.add_scatter( - x=x, + x=velocity_km_s, y=self.iterable_data["t_rad"], line_color=self.plasma_colorscale[self.current_iteration - 1], row=1, @@ -341,7 +343,7 @@ def update_plasma_plots(self): # add a dilution factor vs shell velocity trace to the plasma plot self.plasma_plot.add_scatter( - x=x, + x=velocity_km_s, y=self.iterable_data["w"], line_color=self.plasma_colorscale[self.current_iteration - 1], row=1, From cae9c19e6c59bee1e7ee2e75f67f6df9806a2aab Mon Sep 17 00:00:00 2001 From: Wolfgang Kerzendorf Date: Mon, 9 Oct 2023 17:51:54 -0400 Subject: [PATCH 12/23] fix of model to simulation_state --- tardis/model/geometry/radial1d.py | 15 ++++----------- tardis/montecarlo/base.py | 24 ++++++++++++------------ 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/tardis/model/geometry/radial1d.py b/tardis/model/geometry/radial1d.py index 479b15821a0..239b3281fd0 100644 --- a/tardis/model/geometry/radial1d.py +++ b/tardis/model/geometry/radial1d.py @@ -78,11 +78,6 @@ def __init__( @property def v_inner_boundary_index(self): - # TODO potentially rename to v_inner_active_index?? - - # fix to ensure that we get the same index if we are on the shell - # boundary vs slightly above - return np.clip( np.searchsorted(self.v_inner, self.v_inner_boundary, side="right") - 1, @@ -171,10 +166,10 @@ def to_numba(self): Numba version of Radial1DGeometry with properties in cgs units """ return NumbaRadial1DGeometry( - self.r_inner.to(u.cm).value, - self.r_outer.to(u.cm).value, - self.v_inner.to(u.cm / u.s).value, - self.v_outer.to(u.cm / u.s).value, + self.r_inner_active.to(u.cm).value, + self.r_outer_active.to(u.cm).value, + self.v_inner_active.to(u.cm / u.s).value, + self.v_outer_active.to(u.cm / u.s).value, ) @@ -184,8 +179,6 @@ def to_numba(self): ("v_inner", float64[:]), ("v_outer", float64[:]), ] - - @jitclass(numba_geometry_spec) class NumbaRadial1DGeometry(object): def __init__(self, r_inner, r_outer, v_inner, v_outer): diff --git a/tardis/montecarlo/base.py b/tardis/montecarlo/base.py index 8a6976cb9c8..e3abf459305 100644 --- a/tardis/montecarlo/base.py +++ b/tardis/montecarlo/base.py @@ -191,7 +191,7 @@ def _initialize_continuum_estimator_arrays(self, gamma_shape): gamma_shape, dtype=np.int64 ) - def _initialize_geometry_arrays(self, model): + def _initialize_geometry_arrays(self, simulation_state): """ Generate the cgs like geometry arrays for the montecarlo part @@ -199,10 +199,10 @@ def _initialize_geometry_arrays(self, model): ---------- model : model.Radial1DModel """ - self.r_inner_cgs = model.r_inner.to("cm").value - self.r_outer_cgs = model.r_outer.to("cm").value - self.v_inner_cgs = model.v_inner.to("cm/s").value - self.v_outer_cgs = model.v_outer.to("cm/s").value + self.r_inner_cgs = simulation_state.r_inner.to("cm").value + self.r_outer_cgs = simulation_state.r_outer.to("cm").value + self.v_inner_cgs = simulation_state.v_inner.to("cm/s").value + self.v_outer_cgs = simulation_state.v_outer.to("cm/s").value def _initialize_packets(self, model, no_of_packets, iteration): # the iteration (passed as seed_offset) is added each time to preserve randomness @@ -302,7 +302,7 @@ def integrator(self): def run( self, - model, + simulation_state, plasma, no_of_packets, no_of_virtual_packets=0, @@ -329,8 +329,8 @@ def run( set_num_threads(self.nthreads) - self.time_of_simulation = self.calculate_time_of_simulation(model) - self.volume = model.volume + self.time_of_simulation = self.calculate_time_of_simulation(simulation_state) + self.volume = simulation_state.volume # Initializing estimator array self._initialize_estimator_arrays(plasma.tau_sobolevs.shape) @@ -342,17 +342,17 @@ def run( self._initialize_continuum_estimator_arrays(gamma_shape) - self._initialize_geometry_arrays(model) + self._initialize_geometry_arrays(simulation_state) self._initialize_packets( - model, + simulation_state, no_of_packets, iteration, ) configuration_initialize(self, no_of_virtual_packets) montecarlo_radial1d( - model, + simulation_state, plasma, iteration, no_of_packets, @@ -360,7 +360,7 @@ def run( show_progress_bars, self, ) - self._integrator = FormalIntegrator(model, plasma, self) + self._integrator = FormalIntegrator(simulation_state, plasma, self) def legacy_return(self): return ( From d829e73748fe6468c01159bce3f9958a3cda77e9 Mon Sep 17 00:00:00 2001 From: Wolfgang Kerzendorf Date: Mon, 9 Oct 2023 19:01:59 -0400 Subject: [PATCH 13/23] fix inner boundary packet error --- tardis/montecarlo/base.py | 2 +- tardis/montecarlo/montecarlo_numba/tests/test_base.py | 2 ++ tardis/montecarlo/packet_source.py | 6 +++--- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/tardis/montecarlo/base.py b/tardis/montecarlo/base.py index e3abf459305..9863f2511fd 100644 --- a/tardis/montecarlo/base.py +++ b/tardis/montecarlo/base.py @@ -220,7 +220,7 @@ def _initialize_packets(self, model, no_of_packets, iteration): no_of_packets ) - self.input_r = radii + self.input_r = radii.to(u.cm).value self.input_nu = nus self.input_mu = mus self.input_energy = energies diff --git a/tardis/montecarlo/montecarlo_numba/tests/test_base.py b/tardis/montecarlo/montecarlo_numba/tests/test_base.py index 4e069fee394..4bedaa444d8 100644 --- a/tardis/montecarlo/montecarlo_numba/tests/test_base.py +++ b/tardis/montecarlo/montecarlo_numba/tests/test_base.py @@ -33,6 +33,8 @@ def test_montecarlo_main_loop( config_montecarlo_1e5_verysimple.montecarlo.no_of_virtual_packets = 0 config_montecarlo_1e5_verysimple.montecarlo.iterations = 1 config_montecarlo_1e5_verysimple.plasma.line_interaction_type = "macroatom" + + del config_montecarlo_1e5_verysimple["config_dirname"] sim = Simulation.from_config( diff --git a/tardis/montecarlo/packet_source.py b/tardis/montecarlo/packet_source.py index 095fca194c4..f6a069dac0e 100644 --- a/tardis/montecarlo/packet_source.py +++ b/tardis/montecarlo/packet_source.py @@ -123,12 +123,12 @@ def __init__(self, radius=None, temperature=None, **kwargs): self.temperature = temperature super().__init__(**kwargs) - def set_state_from_model(self, model): + def set_state_from_model(self, simulation_state): """ Set state of packet source (correct state should be ensured before creating packets) """ - self.radius = model.r_inner[0] - self.temperature = model.t_inner.value + self.radius = simulation_state.r_inner[0] + self.temperature = simulation_state.t_inner.value def create_packets(self, no_of_packets, *args, **kwargs): if self.radius is None or self.temperature is None: From 9592a97013f5c2244ce817461d4e8d48bd41b947 Mon Sep 17 00:00:00 2001 From: Wolfgang Kerzendorf Date: Mon, 9 Oct 2023 20:32:47 -0400 Subject: [PATCH 14/23] fix some leftovers --- tardis/io/model/model_reader.py | 22 +++++------ tardis/io/tests/test_model_reader.py | 46 +++++++++++----------- tardis/model/base.py | 23 +++++------ tardis/simulation/tests/test_simulation.py | 4 ++ 4 files changed, 48 insertions(+), 47 deletions(-) diff --git a/tardis/io/model/model_reader.py b/tardis/io/model/model_reader.py index 989157b620a..d63c5790263 100644 --- a/tardis/io/model/model_reader.py +++ b/tardis/io/model/model_reader.py @@ -42,7 +42,7 @@ def transport_to_dict(transport): "input_energy": transport.input_energy, "input_mu": transport.input_mu, "input_nu": transport.input_nu, - "input_r_cgs": transport.input_r, + "input_r": transport.input_r, "j_blue_estimator": transport.j_blue_estimator, "j_estimator": transport.j_estimator, "last_interaction_in_nu": transport.last_interaction_in_nu, @@ -296,23 +296,23 @@ def model_to_dict(model): isotope_abundance : dict """ model_dict = { - "velocity_cgs": model.velocity, + "velocity_cgs": model.velocity.cgs, "abundance": model.abundance, - "time_explosion_cgs": model.time_explosion, - "t_inner_cgs": model.t_inner, - "t_radiative_cgs": model.t_radiative, + "time_explosion_cgs": model.time_explosion.cgs, + "t_inner_cgs": model.t_inner.cgs, + "t_radiative_cgs": model.t_radiative.cgs, "dilution_factor": model.dilution_factor, - "v_boundary_inner_cgs": model.v_boundary_inner, - "v_boundary_outer_cgs": model.v_boundary_outer, + "v_boundary_inner_cgs": model.v_boundary_inner.cgs, + "v_boundary_outer_cgs": model.v_boundary_outer.cgs, "w": model.w, - "t_rad_cgs": model.t_rad, - "r_inner_cgs": model.r_inner, - "density_cgs": model.density, + "t_rad_cgs": model.t_rad.cgs, + "r_inner_cgs": model.r_inner.cgs, + "density_cgs": model.density.cgs, } for key, value in model_dict.items(): if hasattr(value, "unit"): - model_dict[key] = [value.cgs.value, value.unit.to_string()] + model_dict[key] = [value.cgs.value, value.cgs.unit.to_string()] isotope_abundance = model.raw_isotope_abundance.__dict__ diff --git a/tardis/io/tests/test_model_reader.py b/tardis/io/tests/test_model_reader.py index 5f14860a772..5b8ddd93530 100644 --- a/tardis/io/tests/test_model_reader.py +++ b/tardis/io/tests/test_model_reader.py @@ -139,7 +139,7 @@ def test_model_to_dict(simulation_verysimple): # Check model dictionary assert np.array_equal(model_dict["velocity_cgs"][0], model.velocity.cgs.value) - assert model_dict["velocity_cgs"][1] == model.velocity.unit.to_string() + assert model_dict["velocity_cgs"][1] == model.velocity.cgs.unit.to_string() assert np.array_equal(model_dict["abundance"], model.abundance) assert np.array_equal( model_dict["time_explosion_cgs"][0], model.time_explosion.value @@ -148,36 +148,36 @@ def test_model_to_dict(simulation_verysimple): model_dict["time_explosion_cgs"][1] == model.time_explosion.unit.to_string() ) - assert np.array_equal(model_dict["t_inner_cgs"][0], model.t_inner.value) + assert np.array_equal(model_dict["t_inner_cgs"][0], model.t_inner.cgs.value) assert model_dict["t_inner_cgs"][1] == model.t_inner.unit.to_string() assert np.array_equal( - model_dict["t_radiative_cgs"][0], model.t_radiative.value + model_dict["t_radiative_cgs"][0], model.t_radiative.cgs.value ) assert ( model_dict["t_radiative_cgs"][1] == model.t_radiative.unit.to_string() ) assert np.array_equal(model_dict["dilution_factor"], model.dilution_factor) assert np.array_equal( - model_dict["v_boundary_inner_cgs"][0], model.v_boundary_inner.value + model_dict["v_boundary_inner_cgs"][0], model.v_boundary_inner.cgs.value ) assert ( model_dict["v_boundary_inner_cgs"][1] - == model.v_boundary_inner.unit.to_string() + == model.v_boundary_inner.cgs.unit.to_string() ) assert np.array_equal( - model_dict["v_boundary_outer_cgs"][0], model.v_boundary_outer.value + model_dict["v_boundary_outer_cgs"][0], model.v_boundary_outer.cgs.value ) assert ( model_dict["v_boundary_outer_cgs"][1] - == model.v_boundary_outer.unit.to_string() + == model.v_boundary_outer.cgs.unit.to_string() ) assert np.array_equal(model_dict["w"], model.w) - assert np.array_equal(model_dict["t_rad_cgs"][0], model.t_rad.value) - assert model_dict["t_rad_cgs"][1] == model.t_rad.unit.to_string() - assert np.array_equal(model_dict["r_inner_cgs"][0], model.r_inner.value) - assert model_dict["r_inner_cgs"][1] == model.r_inner.unit.to_string() - assert np.array_equal(model_dict["density_cgs"][0], model.density.value) - assert model_dict["density_cgs"][1] == model.density.unit.to_string() + assert np.array_equal(model_dict["t_rad_cgs"][0], model.t_rad.cgs.value) + assert model_dict["t_rad_cgs"][1] == model.t_rad.cgs.unit.to_string() + assert np.array_equal(model_dict["r_inner_cgs"][0], model.r_inner.cgs.value) + assert model_dict["r_inner_cgs"][1] == model.r_inner.cgs.unit.to_string() + assert np.array_equal(model_dict["density_cgs"][0], model.density.cgs.value) + assert model_dict["density_cgs"][1] == model.density.cgs.unit.to_string() def test_store_model_to_hdf(simulation_verysimple, tmp_path): @@ -190,26 +190,26 @@ def test_store_model_to_hdf(simulation_verysimple, tmp_path): # Check file contents with h5py.File(fname) as f: - assert np.array_equal(f["model/velocity_cgs"], model.velocity.value) + assert np.array_equal(f["model/velocity_cgs"], model.velocity.cgs.value) assert np.array_equal(f["model/abundance"], model.abundance) assert np.array_equal( - f["model/time_explosion_cgs"], model.time_explosion.value + f["model/time_explosion_cgs"], model.time_explosion.cgs.value ) - assert np.array_equal(f["model/t_inner_cgs"], model.t_inner.value) + assert np.array_equal(f["model/t_inner_cgs"], model.t_inner.cgs.value) assert np.array_equal( - f["model/t_radiative_cgs"], model.t_radiative.value + f["model/t_radiative_cgs"], model.t_radiative.cgs.value ) assert np.array_equal(f["model/dilution_factor"], model.dilution_factor) assert np.array_equal( - f["model/v_boundary_inner_cgs"], model.v_boundary_inner.value + f["model/v_boundary_inner_cgs"], model.v_boundary_inner.cgs.value ) assert np.array_equal( - f["model/v_boundary_outer_cgs"], model.v_boundary_outer.value + f["model/v_boundary_outer_cgs"], model.v_boundary_outer.cgs.value ) assert np.array_equal(f["model/w"], model.w) - assert np.array_equal(f["model/t_rad_cgs"], model.t_rad.value) - assert np.array_equal(f["model/r_inner_cgs"], model.r_inner.value) - assert np.array_equal(f["model/density_cgs"], model.density.value) + assert np.array_equal(f["model/t_rad_cgs"], model.t_rad.cgs.value) + assert np.array_equal(f["model/r_inner_cgs"], model.r_inner.cgs.value) + assert np.array_equal(f["model/density_cgs"], model.density.cgs.value) def test_transport_to_dict(simulation_verysimple): @@ -290,7 +290,7 @@ def test_store_transport_to_hdf(simulation_verysimple, tmp_path): f["transport/input_nu"], transport_data["input_nu"] ) assert np.array_equal( - f["transport/input_r_cgs"], transport_data["input_r"].value + f["transport/input_r"], transport_data["input_r"] ) assert np.array_equal( f["transport/j_blue_estimator"], transport_data["j_blue_estimator"] diff --git a/tardis/model/base.py b/tardis/model/base.py index 62127a3174a..e431ebde016 100644 --- a/tardis/model/base.py +++ b/tardis/model/base.py @@ -210,16 +210,10 @@ def __init__( luminosity_requested=None, t_radiative=None, dilution_factor=None, - v_boundary_inner=None, - v_boundary_outer=None, electron_densities=None, ): self.geometry = geometry - self._v_boundary_inner = None - self._v_boundary_outer = None - self.v_boundary_inner = v_boundary_inner - self.v_boundary_outer = v_boundary_outer - + self._abundance = abundance self.time_explosion = time_explosion self._electron_densities = electron_densities @@ -388,6 +382,15 @@ def radius(self): return None return self.time_explosion * self.velocity + + @property + def v_boundary_inner(self): + return self.geometry.v_inner_boundary + + @property + def v_boundary_outer(self): + return self.geometry.v_outer_boundary + @property def r_inner(self): return self.model_state.geometry.r_inner_active @@ -543,12 +546,6 @@ def from_config(cls, config, atom_data=None): elemental_mass=elemental_mass, luminosity_requested=luminosity_requested, dilution_factor=None, - v_boundary_inner=config.model.structure.get( - "v_inner_boundary", None - ), - v_boundary_outer=config.model.structure.get( - "v_outer_boundary", None - ), electron_densities=electron_densities, ) diff --git a/tardis/simulation/tests/test_simulation.py b/tardis/simulation/tests/test_simulation.py index d4f68ff3cc5..0c8d46dccb7 100644 --- a/tardis/simulation/tests/test_simulation.py +++ b/tardis/simulation/tests/test_simulation.py @@ -112,10 +112,14 @@ def test_plasma_estimates(simulation_one_loop, refdata, name): def test_plasma_state_iterations(simulation_one_loop, refdata, name): actual = getattr(simulation_one_loop, name) + if hasattr(actual, "value"): + actual = actual.value + try: actual = pd.Series(actual) except Exception: actual = pd.DataFrame(actual) + if type(actual) == pd.DataFrame: pdt.assert_frame_equal(actual, refdata(name), rtol=1e-5, atol=1e-8) From 4da6869a616bca5b2b9c36bbfb2d69d2c66cef15 Mon Sep 17 00:00:00 2001 From: Wolfgang Kerzendorf Date: Mon, 9 Oct 2023 23:42:24 -0400 Subject: [PATCH 15/23] final fix for csvy --- tardis/model/base.py | 81 +++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 35 deletions(-) diff --git a/tardis/model/base.py b/tardis/model/base.py index e431ebde016..fde1f770986 100644 --- a/tardis/model/base.py +++ b/tardis/model/base.py @@ -617,35 +617,7 @@ def from_csvy(cls, config, atom_data=None): electron_densities = None temperature = None - if hasattr(config, "model"): - if hasattr(config.model, "v_inner_boundary"): - v_boundary_inner = config.model.v_inner_boundary - else: - v_boundary_inner = None - - if hasattr(config.model, "v_outer_boundary"): - v_boundary_outer = config.model.v_outer_boundary - else: - v_boundary_outer = None - else: - v_boundary_inner = None - v_boundary_outer = None - - if hasattr(csvy_model_config, "velocity"): - velocity = quantity_linspace( - csvy_model_config.velocity.start, - csvy_model_config.velocity.stop, - csvy_model_config.velocity.num + 1, - ).cgs - else: - velocity_field_index = [ - field["name"] for field in csvy_model_config.datatype.fields - ].index("velocity") - velocity_unit = u.Unit( - csvy_model_config.datatype.fields[velocity_field_index]["unit"] - ) - velocity = csvy_model_data["velocity"].values * velocity_unit - velocity = velocity.to("cm/s") + geometry = parse_csvy_geometry(config, csvy_model_config, csvy_model_data, time_explosion) if hasattr(csvy_model_config, "density"): density = parse_csvy_density(csvy_model_config, time_explosion) @@ -664,7 +636,7 @@ def from_csvy(cls, config, atom_data=None): density_0, time_0, time_explosion ) - no_of_shells = len(velocity) - 1 + no_of_shells = geometry.no_of_shells # TODO -- implement t_radiative # t_radiative = None @@ -692,7 +664,7 @@ def from_csvy(cls, config, atom_data=None): ) elif config.plasma.initial_t_rad > 0 * u.K: - t_radiative = np.ones(no_of_shells) * config.plasma.initial_t_rad + t_radiative = np.ones(geometry.no_of_shells) * config.plasma.initial_t_rad else: t_radiative = None @@ -706,7 +678,7 @@ def from_csvy(cls, config, atom_data=None): if hasattr(csvy_model_config, "abundance"): abundances_section = csvy_model_config.abundance abundance, isotope_abundance = read_uniform_abundances( - abundances_section, no_of_shells + abundances_section, geometry.no_of_shells ) else: index, abundance, isotope_abundance = parse_csv_abundances( @@ -741,7 +713,7 @@ def from_csvy(cls, config, atom_data=None): elemental_mass = atom_data.atom_data.mass return cls( - velocity=velocity, + geometry=geometry, density=density, abundance=abundance, isotope_abundance=isotope_abundance, @@ -751,11 +723,50 @@ def from_csvy(cls, config, atom_data=None): elemental_mass=elemental_mass, luminosity_requested=luminosity_requested, dilution_factor=dilution_factor, - v_boundary_inner=v_boundary_inner, - v_boundary_outer=v_boundary_outer, electron_densities=electron_densities, ) +def parse_csvy_geometry(config, csvy_model_config, csvy_model_data, time_explosion): + if hasattr(config, "model"): + if hasattr(config.model, "v_inner_boundary"): + v_boundary_inner = config.model.v_inner_boundary + else: + v_boundary_inner = None + + if hasattr(config.model, "v_outer_boundary"): + v_boundary_outer = config.model.v_outer_boundary + else: + v_boundary_outer = None + else: + v_boundary_inner = None + v_boundary_outer = None + + if hasattr(csvy_model_config, "velocity"): + velocity = quantity_linspace( + csvy_model_config.velocity.start, + csvy_model_config.velocity.stop, + csvy_model_config.velocity.num + 1, + ).cgs + else: + velocity_field_index = [ + field["name"] for field in csvy_model_config.datatype.fields + ].index("velocity") + velocity_unit = u.Unit( + csvy_model_config.datatype.fields[velocity_field_index]["unit"] + ) + velocity = csvy_model_data["velocity"].values * velocity_unit + velocity = velocity.to("cm/s") + + geometry = HomologousRadial1DGeometry( + velocity[:-1], # r_inner + velocity[1:], # r_outer + v_inner_boundary=v_boundary_inner, + v_outer_boundary=v_boundary_outer, + time_explosion=time_explosion + ) + return geometry + + def parse_structure_config(config, time_explosion, enable_homology=True): electron_densities = None From f381d2e74560a293521795e983ca21c77e123556 Mon Sep 17 00:00:00 2001 From: Wolfgang Kerzendorf Date: Tue, 10 Oct 2023 00:22:17 -0400 Subject: [PATCH 16/23] blackify --- tardis/io/tests/test_model_reader.py | 8 +++--- tardis/model/base.py | 25 +++++++++++-------- tardis/model/geometry/radial1d.py | 2 ++ tardis/montecarlo/base.py | 4 ++- .../montecarlo_numba/tests/test_base.py | 1 - .../montecarlo_numba/tests/test_vpacket.py | 4 +-- tardis/simulation/tests/test_simulation.py | 1 - 7 files changed, 25 insertions(+), 20 deletions(-) diff --git a/tardis/io/tests/test_model_reader.py b/tardis/io/tests/test_model_reader.py index 5b8ddd93530..8b283b71c1e 100644 --- a/tardis/io/tests/test_model_reader.py +++ b/tardis/io/tests/test_model_reader.py @@ -138,7 +138,9 @@ def test_model_to_dict(simulation_verysimple): model_dict, isotope_abundance = model_to_dict(model) # Check model dictionary - assert np.array_equal(model_dict["velocity_cgs"][0], model.velocity.cgs.value) + assert np.array_equal( + model_dict["velocity_cgs"][0], model.velocity.cgs.value + ) assert model_dict["velocity_cgs"][1] == model.velocity.cgs.unit.to_string() assert np.array_equal(model_dict["abundance"], model.abundance) assert np.array_equal( @@ -289,9 +291,7 @@ def test_store_transport_to_hdf(simulation_verysimple, tmp_path): assert np.array_equal( f["transport/input_nu"], transport_data["input_nu"] ) - assert np.array_equal( - f["transport/input_r"], transport_data["input_r"] - ) + assert np.array_equal(f["transport/input_r"], transport_data["input_r"]) assert np.array_equal( f["transport/j_blue_estimator"], transport_data["j_blue_estimator"] ) diff --git a/tardis/model/base.py b/tardis/model/base.py index fde1f770986..9b0858f5229 100644 --- a/tardis/model/base.py +++ b/tardis/model/base.py @@ -121,9 +121,7 @@ def mass(self): mass_fraction * density * volume""" total_mass = (self.geometry.volume * self.composition.density).to(u.g) - return ( - self.composition.elemental_mass_fraction * total_mass.value - ) + return self.composition.elemental_mass_fraction * total_mass.value @property def number(self): @@ -213,7 +211,7 @@ def __init__( electron_densities=None, ): self.geometry = geometry - + self._abundance = abundance self.time_explosion = time_explosion self._electron_densities = electron_densities @@ -299,7 +297,7 @@ def __init__( / constants.c ) ) - + elif len(t_radiative) == self.no_of_shells + 1: t_radiative = t_radiative[ self.geometry.v_inner_boundary_index @@ -382,7 +380,6 @@ def radius(self): return None return self.time_explosion * self.velocity - @property def v_boundary_inner(self): return self.geometry.v_inner_boundary @@ -617,7 +614,9 @@ def from_csvy(cls, config, atom_data=None): electron_densities = None temperature = None - geometry = parse_csvy_geometry(config, csvy_model_config, csvy_model_data, time_explosion) + geometry = parse_csvy_geometry( + config, csvy_model_config, csvy_model_data, time_explosion + ) if hasattr(csvy_model_config, "density"): density = parse_csvy_density(csvy_model_config, time_explosion) @@ -664,7 +663,9 @@ def from_csvy(cls, config, atom_data=None): ) elif config.plasma.initial_t_rad > 0 * u.K: - t_radiative = np.ones(geometry.no_of_shells) * config.plasma.initial_t_rad + t_radiative = ( + np.ones(geometry.no_of_shells) * config.plasma.initial_t_rad + ) else: t_radiative = None @@ -726,7 +727,10 @@ def from_csvy(cls, config, atom_data=None): electron_densities=electron_densities, ) -def parse_csvy_geometry(config, csvy_model_config, csvy_model_data, time_explosion): + +def parse_csvy_geometry( + config, csvy_model_config, csvy_model_data, time_explosion +): if hasattr(config, "model"): if hasattr(config.model, "v_inner_boundary"): v_boundary_inner = config.model.v_inner_boundary @@ -762,10 +766,9 @@ def parse_csvy_geometry(config, csvy_model_config, csvy_model_data, time_explosi velocity[1:], # r_outer v_inner_boundary=v_boundary_inner, v_outer_boundary=v_boundary_outer, - time_explosion=time_explosion + time_explosion=time_explosion, ) return geometry - def parse_structure_config(config, time_explosion, enable_homology=True): diff --git a/tardis/model/geometry/radial1d.py b/tardis/model/geometry/radial1d.py index 239b3281fd0..eb04cf1a68f 100644 --- a/tardis/model/geometry/radial1d.py +++ b/tardis/model/geometry/radial1d.py @@ -179,6 +179,8 @@ def to_numba(self): ("v_inner", float64[:]), ("v_outer", float64[:]), ] + + @jitclass(numba_geometry_spec) class NumbaRadial1DGeometry(object): def __init__(self, r_inner, r_outer, v_inner, v_outer): diff --git a/tardis/montecarlo/base.py b/tardis/montecarlo/base.py index 9863f2511fd..b2ebc956b5a 100644 --- a/tardis/montecarlo/base.py +++ b/tardis/montecarlo/base.py @@ -329,7 +329,9 @@ def run( set_num_threads(self.nthreads) - self.time_of_simulation = self.calculate_time_of_simulation(simulation_state) + self.time_of_simulation = self.calculate_time_of_simulation( + simulation_state + ) self.volume = simulation_state.volume # Initializing estimator array diff --git a/tardis/montecarlo/montecarlo_numba/tests/test_base.py b/tardis/montecarlo/montecarlo_numba/tests/test_base.py index 4bedaa444d8..cf10aa19bd2 100644 --- a/tardis/montecarlo/montecarlo_numba/tests/test_base.py +++ b/tardis/montecarlo/montecarlo_numba/tests/test_base.py @@ -33,7 +33,6 @@ def test_montecarlo_main_loop( config_montecarlo_1e5_verysimple.montecarlo.no_of_virtual_packets = 0 config_montecarlo_1e5_verysimple.montecarlo.iterations = 1 config_montecarlo_1e5_verysimple.plasma.line_interaction_type = "macroatom" - del config_montecarlo_1e5_verysimple["config_dirname"] diff --git a/tardis/montecarlo/montecarlo_numba/tests/test_vpacket.py b/tardis/montecarlo/montecarlo_numba/tests/test_vpacket.py index bee9fc4c41f..6e156982820 100644 --- a/tardis/montecarlo/montecarlo_numba/tests/test_vpacket.py +++ b/tardis/montecarlo/montecarlo_numba/tests/test_vpacket.py @@ -66,7 +66,7 @@ def test_trace_vpacket_within_shell( ) npt.assert_almost_equal(tau_trace_combined, 8164850.891288479) - #changed from almost equal to allclose. Now seems to work. + # changed from almost equal to allclose. Now seems to work. npt.assert_allclose(distance_boundary, 843684056256104.1) assert delta_shell == 1 @@ -93,7 +93,7 @@ def test_trace_vpacket( ) npt.assert_almost_equal(tau_trace_combined, 8164850.891288479) - #change from almost_equal to allclose. Now seems to work. + # change from almost_equal to allclose. Now seems to work. npt.assert_allclose(v_packet.r, 1286064000000000.0) npt.assert_almost_equal(v_packet.nu, 4.0e15) npt.assert_almost_equal(v_packet.energy, 0.0) diff --git a/tardis/simulation/tests/test_simulation.py b/tardis/simulation/tests/test_simulation.py index 0c8d46dccb7..1a11b1add40 100644 --- a/tardis/simulation/tests/test_simulation.py +++ b/tardis/simulation/tests/test_simulation.py @@ -119,7 +119,6 @@ def test_plasma_state_iterations(simulation_one_loop, refdata, name): actual = pd.Series(actual) except Exception: actual = pd.DataFrame(actual) - if type(actual) == pd.DataFrame: pdt.assert_frame_equal(actual, refdata(name), rtol=1e-5, atol=1e-8) From e59741dab420465599074d36bbe1c22fe42e89ed Mon Sep 17 00:00:00 2001 From: Wolfgang Kerzendorf Date: Tue, 10 Oct 2023 20:10:44 -0400 Subject: [PATCH 17/23] restructure to readers and remove some leftover code --- tardis/io/model/readers/base.py | 61 +++++++++++++++++ tardis/io/model/readers/csvy.py | 47 +++++++++++++- tardis/model/base.py | 112 ++------------------------------ 3 files changed, 111 insertions(+), 109 deletions(-) diff --git a/tardis/io/model/readers/base.py b/tardis/io/model/readers/base.py index c66da4b2b03..3a9029f0604 100644 --- a/tardis/io/model/readers/base.py +++ b/tardis/io/model/readers/base.py @@ -1,3 +1,8 @@ +from tardis.io.model.parse_density_configuration import ( + calculate_density_after_time, + parse_config_v1_density, +) +import os from tardis.io.model.readers.cmfgen import ( read_cmfgen_composition, read_cmfgen_density, @@ -14,6 +19,9 @@ import pandas as pd from tardis.io.model.readers.artis import read_artis_density +from tardis.model.base import logger +from tardis.model.geometry.radial1d import HomologousRadial1DGeometry +from tardis.util.base import quantity_linspace def read_abundances_file( @@ -131,3 +139,56 @@ def read_density_file(filename, filetype): electron_densities, temperature, ) + + +def parse_structure_config(config, time_explosion, enable_homology=True): + electron_densities = None + temperature = None + structure_config = config.model.structure + if structure_config.type == "specific": + velocity = quantity_linspace( + structure_config.velocity.start, + structure_config.velocity.stop, + structure_config.velocity.num + 1, + ).cgs + density = parse_config_v1_density(config) + + elif structure_config.type == "file": + if os.path.isabs(structure_config.filename): + structure_config_fname = structure_config.filename + else: + structure_config_fname = os.path.join( + config.config_dirname, structure_config.filename + ) + + ( + time_0, + velocity, + density_0, + electron_densities, + temperature, + ) = read_density_file(structure_config_fname, structure_config.filetype) + density_0 = density_0.insert(0, 0) + + density = calculate_density_after_time( + density_0, time_0, time_explosion + ) + + else: + raise NotImplementedError + + # Note: This is the number of shells *without* taking in mind the + # v boundaries. + if len(density) == len(velocity): + logger.warning( + "Number of density points larger than number of shells. Assuming inner point irrelevant" + ) + density = density[1:] + geometry = HomologousRadial1DGeometry( + velocity[:-1], # r_inner + velocity[1:], # r_outer + v_inner_boundary=structure_config.get("v_inner_boundary", None), + v_outer_boundary=structure_config.get("v_outer_boundary", None), + time_explosion=time_explosion, + ) + return electron_densities, temperature, geometry, density diff --git a/tardis/io/model/readers/csvy.py b/tardis/io/model/readers/csvy.py index d958397137f..8c4533c86ef 100644 --- a/tardis/io/model/readers/csvy.py +++ b/tardis/io/model/readers/csvy.py @@ -1,11 +1,13 @@ import logging +from astropy import units as u import numpy as np from radioactivedecay import Nuclide from radioactivedecay.utils import Z_DICT, elem_to_Z import yaml import pandas as pd from tardis.io.util import YAMLLoader -from tardis.util.base import is_valid_nuclide_or_elem +from tardis.model.geometry.radial1d import HomologousRadial1DGeometry +from tardis.util.base import is_valid_nuclide_or_elem, quantity_linspace YAML_DELIMITER = "---" @@ -144,3 +146,46 @@ def parse_csv_abundances(csvy_data): ].tolist() return abundance.index, abundance, isotope_abundance + + +def parse_csvy_geometry( + config, csvy_model_config, csvy_model_data, time_explosion +): + if hasattr(config, "model"): + if hasattr(config.model, "v_inner_boundary"): + v_boundary_inner = config.model.v_inner_boundary + else: + v_boundary_inner = None + + if hasattr(config.model, "v_outer_boundary"): + v_boundary_outer = config.model.v_outer_boundary + else: + v_boundary_outer = None + else: + v_boundary_inner = None + v_boundary_outer = None + + if hasattr(csvy_model_config, "velocity"): + velocity = quantity_linspace( + csvy_model_config.velocity.start, + csvy_model_config.velocity.stop, + csvy_model_config.velocity.num + 1, + ).cgs + else: + velocity_field_index = [ + field["name"] for field in csvy_model_config.datatype.fields + ].index("velocity") + velocity_unit = u.Unit( + csvy_model_config.datatype.fields[velocity_field_index]["unit"] + ) + velocity = csvy_model_data["velocity"].values * velocity_unit + velocity = velocity.to("cm/s") + + geometry = HomologousRadial1DGeometry( + velocity[:-1], # r_inner + velocity[1:], # r_outer + v_inner_boundary=v_boundary_inner, + v_outer_boundary=v_boundary_outer, + time_explosion=time_explosion, + ) + return geometry diff --git a/tardis/model/base.py b/tardis/model/base.py index 9b0858f5229..fe2a974eda6 100644 --- a/tardis/model/base.py +++ b/tardis/model/base.py @@ -8,13 +8,14 @@ from tardis import constants import radioactivedecay as rd from radioactivedecay.utils import Z_DICT -from tardis.io.model.readers.base import read_abundances_file, read_density_file +from tardis.io.model.readers.base import read_abundances_file +from tardis.io.model.readers.base import parse_structure_config +from tardis.io.model.readers.csvy import parse_csvy_geometry from tardis.io.model.readers.generic_readers import ( read_uniform_abundances, ) -from tardis.model.geometry.radial1d import HomologousRadial1DGeometry -from tardis.util.base import quantity_linspace, is_valid_nuclide_or_elem +from tardis.util.base import is_valid_nuclide_or_elem from tardis.io.model.readers.csvy import load_csvy from tardis.io.model.readers.csvy import ( parse_csv_abundances, @@ -25,7 +26,6 @@ from tardis.io.decay import IsotopeAbundances from tardis.io.model.parse_density_configuration import ( - parse_config_v1_density, parse_csvy_density, calculate_density_after_time, ) @@ -377,7 +377,6 @@ def t_radiative(self, value): @property def radius(self): - return None return self.time_explosion * self.velocity @property @@ -404,13 +403,6 @@ def r_middle(self): def velocity(self): velocity = self.geometry.v_outer_active.copy() return velocity.insert(0, self.geometry.v_inner_active[0]) - if self._velocity is None: - self._velocity = self.raw_velocity[ - self.v_boundary_inner_index : self.v_boundary_outer_index + 1 - ] - self._velocity[0] = self.v_boundary_inner - self._velocity[-1] = self.v_boundary_outer - return self._velocity @property def v_inner(self): @@ -726,99 +718,3 @@ def from_csvy(cls, config, atom_data=None): dilution_factor=dilution_factor, electron_densities=electron_densities, ) - - -def parse_csvy_geometry( - config, csvy_model_config, csvy_model_data, time_explosion -): - if hasattr(config, "model"): - if hasattr(config.model, "v_inner_boundary"): - v_boundary_inner = config.model.v_inner_boundary - else: - v_boundary_inner = None - - if hasattr(config.model, "v_outer_boundary"): - v_boundary_outer = config.model.v_outer_boundary - else: - v_boundary_outer = None - else: - v_boundary_inner = None - v_boundary_outer = None - - if hasattr(csvy_model_config, "velocity"): - velocity = quantity_linspace( - csvy_model_config.velocity.start, - csvy_model_config.velocity.stop, - csvy_model_config.velocity.num + 1, - ).cgs - else: - velocity_field_index = [ - field["name"] for field in csvy_model_config.datatype.fields - ].index("velocity") - velocity_unit = u.Unit( - csvy_model_config.datatype.fields[velocity_field_index]["unit"] - ) - velocity = csvy_model_data["velocity"].values * velocity_unit - velocity = velocity.to("cm/s") - - geometry = HomologousRadial1DGeometry( - velocity[:-1], # r_inner - velocity[1:], # r_outer - v_inner_boundary=v_boundary_inner, - v_outer_boundary=v_boundary_outer, - time_explosion=time_explosion, - ) - return geometry - - -def parse_structure_config(config, time_explosion, enable_homology=True): - electron_densities = None - temperature = None - structure_config = config.model.structure - if structure_config.type == "specific": - velocity = quantity_linspace( - structure_config.velocity.start, - structure_config.velocity.stop, - structure_config.velocity.num + 1, - ).cgs - density = parse_config_v1_density(config) - - elif structure_config.type == "file": - if os.path.isabs(structure_config.filename): - structure_config_fname = structure_config.filename - else: - structure_config_fname = os.path.join( - config.config_dirname, structure_config.filename - ) - - ( - time_0, - velocity, - density_0, - electron_densities, - temperature, - ) = read_density_file(structure_config_fname, structure_config.filetype) - density_0 = density_0.insert(0, 0) - - density = calculate_density_after_time( - density_0, time_0, time_explosion - ) - - else: - raise NotImplementedError - - # Note: This is the number of shells *without* taking in mind the - # v boundaries. - if len(density) == len(velocity): - logger.warning( - "Number of density points larger than number of shells. Assuming inner point irrelevant" - ) - density = density[1:] - geometry = HomologousRadial1DGeometry( - velocity[:-1], # r_inner - velocity[1:], # r_outer - v_inner_boundary=structure_config.get("v_inner_boundary", None), - v_outer_boundary=structure_config.get("v_outer_boundary", None), - time_explosion=time_explosion, - ) - return electron_densities, temperature, geometry, density From a42dd554e1dd1bf72d03386fc9267755609aee4c Mon Sep 17 00:00:00 2001 From: Wolfgang Kerzendorf Date: Tue, 10 Oct 2023 23:09:29 -0400 Subject: [PATCH 18/23] further cleanup --- tardis/io/model/readers/base.py | 61 ------------------ tardis/io/model/readers/csvy.py | 47 +------------- tardis/model/__init__.py | 2 +- tardis/model/base.py | 18 ++++-- tardis/model/parse_input.py | 109 ++++++++++++++++++++++++++++++++ 5 files changed, 122 insertions(+), 115 deletions(-) create mode 100644 tardis/model/parse_input.py diff --git a/tardis/io/model/readers/base.py b/tardis/io/model/readers/base.py index 3a9029f0604..c66da4b2b03 100644 --- a/tardis/io/model/readers/base.py +++ b/tardis/io/model/readers/base.py @@ -1,8 +1,3 @@ -from tardis.io.model.parse_density_configuration import ( - calculate_density_after_time, - parse_config_v1_density, -) -import os from tardis.io.model.readers.cmfgen import ( read_cmfgen_composition, read_cmfgen_density, @@ -19,9 +14,6 @@ import pandas as pd from tardis.io.model.readers.artis import read_artis_density -from tardis.model.base import logger -from tardis.model.geometry.radial1d import HomologousRadial1DGeometry -from tardis.util.base import quantity_linspace def read_abundances_file( @@ -139,56 +131,3 @@ def read_density_file(filename, filetype): electron_densities, temperature, ) - - -def parse_structure_config(config, time_explosion, enable_homology=True): - electron_densities = None - temperature = None - structure_config = config.model.structure - if structure_config.type == "specific": - velocity = quantity_linspace( - structure_config.velocity.start, - structure_config.velocity.stop, - structure_config.velocity.num + 1, - ).cgs - density = parse_config_v1_density(config) - - elif structure_config.type == "file": - if os.path.isabs(structure_config.filename): - structure_config_fname = structure_config.filename - else: - structure_config_fname = os.path.join( - config.config_dirname, structure_config.filename - ) - - ( - time_0, - velocity, - density_0, - electron_densities, - temperature, - ) = read_density_file(structure_config_fname, structure_config.filetype) - density_0 = density_0.insert(0, 0) - - density = calculate_density_after_time( - density_0, time_0, time_explosion - ) - - else: - raise NotImplementedError - - # Note: This is the number of shells *without* taking in mind the - # v boundaries. - if len(density) == len(velocity): - logger.warning( - "Number of density points larger than number of shells. Assuming inner point irrelevant" - ) - density = density[1:] - geometry = HomologousRadial1DGeometry( - velocity[:-1], # r_inner - velocity[1:], # r_outer - v_inner_boundary=structure_config.get("v_inner_boundary", None), - v_outer_boundary=structure_config.get("v_outer_boundary", None), - time_explosion=time_explosion, - ) - return electron_densities, temperature, geometry, density diff --git a/tardis/io/model/readers/csvy.py b/tardis/io/model/readers/csvy.py index 8c4533c86ef..d958397137f 100644 --- a/tardis/io/model/readers/csvy.py +++ b/tardis/io/model/readers/csvy.py @@ -1,13 +1,11 @@ import logging -from astropy import units as u import numpy as np from radioactivedecay import Nuclide from radioactivedecay.utils import Z_DICT, elem_to_Z import yaml import pandas as pd from tardis.io.util import YAMLLoader -from tardis.model.geometry.radial1d import HomologousRadial1DGeometry -from tardis.util.base import is_valid_nuclide_or_elem, quantity_linspace +from tardis.util.base import is_valid_nuclide_or_elem YAML_DELIMITER = "---" @@ -146,46 +144,3 @@ def parse_csv_abundances(csvy_data): ].tolist() return abundance.index, abundance, isotope_abundance - - -def parse_csvy_geometry( - config, csvy_model_config, csvy_model_data, time_explosion -): - if hasattr(config, "model"): - if hasattr(config.model, "v_inner_boundary"): - v_boundary_inner = config.model.v_inner_boundary - else: - v_boundary_inner = None - - if hasattr(config.model, "v_outer_boundary"): - v_boundary_outer = config.model.v_outer_boundary - else: - v_boundary_outer = None - else: - v_boundary_inner = None - v_boundary_outer = None - - if hasattr(csvy_model_config, "velocity"): - velocity = quantity_linspace( - csvy_model_config.velocity.start, - csvy_model_config.velocity.stop, - csvy_model_config.velocity.num + 1, - ).cgs - else: - velocity_field_index = [ - field["name"] for field in csvy_model_config.datatype.fields - ].index("velocity") - velocity_unit = u.Unit( - csvy_model_config.datatype.fields[velocity_field_index]["unit"] - ) - velocity = csvy_model_data["velocity"].values * velocity_unit - velocity = velocity.to("cm/s") - - geometry = HomologousRadial1DGeometry( - velocity[:-1], # r_inner - velocity[1:], # r_outer - v_inner_boundary=v_boundary_inner, - v_outer_boundary=v_boundary_outer, - time_explosion=time_explosion, - ) - return geometry diff --git a/tardis/model/__init__.py b/tardis/model/__init__.py index 3399f042e29..4b7881ad71e 100644 --- a/tardis/model/__init__.py +++ b/tardis/model/__init__.py @@ -6,4 +6,4 @@ factor of the model used in the simulation. """ -from tardis.model.base import * +from tardis.model.base import SimulationState diff --git a/tardis/model/base.py b/tardis/model/base.py index fe2a974eda6..0bbc70674d2 100644 --- a/tardis/model/base.py +++ b/tardis/model/base.py @@ -8,18 +8,25 @@ from tardis import constants import radioactivedecay as rd from radioactivedecay.utils import Z_DICT +from tardis.model.parse_input import parse_csvy_geometry, parse_structure_config +from tardis.util.base import is_valid_nuclide_or_elem + + +from tardis.montecarlo.packet_source import BlackBodySimpleSource + +from tardis.radiation_field.base import MonteCarloRadiationFieldState + from tardis.io.model.readers.base import read_abundances_file -from tardis.io.model.readers.base import parse_structure_config -from tardis.io.model.readers.csvy import parse_csvy_geometry from tardis.io.model.readers.generic_readers import ( read_uniform_abundances, ) -from tardis.util.base import is_valid_nuclide_or_elem -from tardis.io.model.readers.csvy import load_csvy from tardis.io.model.readers.csvy import ( parse_csv_abundances, + load_csvy, ) + + from tardis.io.configuration.config_validator import validate_dict from tardis.io.configuration.config_reader import Configuration from tardis.io.util import HDFWriterMixin @@ -29,9 +36,6 @@ parse_csvy_density, calculate_density_after_time, ) -from tardis.montecarlo.packet_source import BlackBodySimpleSource - -from tardis.radiation_field.base import MonteCarloRadiationFieldState logger = logging.getLogger(__name__) diff --git a/tardis/model/parse_input.py b/tardis/model/parse_input.py new file mode 100644 index 00000000000..5736777978f --- /dev/null +++ b/tardis/model/parse_input.py @@ -0,0 +1,109 @@ +import logging +import os + +from astropy import units as u +from tardis.io.model.parse_density_configuration import ( + calculate_density_after_time, + parse_config_v1_density, +) +from tardis.io.model.readers.base import read_density_file +from tardis.model.geometry.radial1d import HomologousRadial1DGeometry +from tardis.util.base import quantity_linspace + +logger = logging.getLogger(__name__) + + +def parse_structure_config(config, time_explosion, enable_homology=True): + electron_densities = None + temperature = None + structure_config = config.model.structure + if structure_config.type == "specific": + velocity = quantity_linspace( + structure_config.velocity.start, + structure_config.velocity.stop, + structure_config.velocity.num + 1, + ).cgs + density = parse_config_v1_density(config) + + elif structure_config.type == "file": + if os.path.isabs(structure_config.filename): + structure_config_fname = structure_config.filename + else: + structure_config_fname = os.path.join( + config.config_dirname, structure_config.filename + ) + + ( + time_0, + velocity, + density_0, + electron_densities, + temperature, + ) = read_density_file(structure_config_fname, structure_config.filetype) + density_0 = density_0.insert(0, 0) + + density = calculate_density_after_time( + density_0, time_0, time_explosion + ) + + else: + raise NotImplementedError + + # Note: This is the number of shells *without* taking in mind the + # v boundaries. + if len(density) == len(velocity): + logger.warning( + "Number of density points larger than number of shells. Assuming inner point irrelevant" + ) + density = density[1:] + geometry = HomologousRadial1DGeometry( + velocity[:-1], # r_inner + velocity[1:], # r_outer + v_inner_boundary=structure_config.get("v_inner_boundary", None), + v_outer_boundary=structure_config.get("v_outer_boundary", None), + time_explosion=time_explosion, + ) + return electron_densities, temperature, geometry, density + + +def parse_csvy_geometry( + config, csvy_model_config, csvy_model_data, time_explosion +): + if hasattr(config, "model"): + if hasattr(config.model, "v_inner_boundary"): + v_boundary_inner = config.model.v_inner_boundary + else: + v_boundary_inner = None + + if hasattr(config.model, "v_outer_boundary"): + v_boundary_outer = config.model.v_outer_boundary + else: + v_boundary_outer = None + else: + v_boundary_inner = None + v_boundary_outer = None + + if hasattr(csvy_model_config, "velocity"): + velocity = quantity_linspace( + csvy_model_config.velocity.start, + csvy_model_config.velocity.stop, + csvy_model_config.velocity.num + 1, + ).cgs + else: + velocity_field_index = [ + field["name"] for field in csvy_model_config.datatype.fields + ].index("velocity") + velocity_unit = u.Unit( + csvy_model_config.datatype.fields[velocity_field_index]["unit"] + ) + velocity = csvy_model_data["velocity"].values * velocity_unit + velocity = velocity.to("cm/s") + + geometry = HomologousRadial1DGeometry( + velocity[:-1], # r_inner + velocity[1:], # r_outer + v_inner_boundary=v_boundary_inner, + v_outer_boundary=v_boundary_outer, + time_explosion=time_explosion, + ) + return geometry From 3288c6c2c07562ac4449c2e15bbdb90003752e46 Mon Sep 17 00:00:00 2001 From: Wolfgang Kerzendorf Date: Wed, 11 Oct 2023 16:50:50 -0400 Subject: [PATCH 19/23] first start of the restructure --- tardis/model/base.py | 47 +++++++------------------------------ tardis/model/parse_input.py | 47 ++++++++++++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 40 deletions(-) diff --git a/tardis/model/base.py b/tardis/model/base.py index 0bbc70674d2..54c1fc0ca7d 100644 --- a/tardis/model/base.py +++ b/tardis/model/base.py @@ -8,7 +8,11 @@ from tardis import constants import radioactivedecay as rd from radioactivedecay.utils import Z_DICT -from tardis.model.parse_input import parse_csvy_geometry, parse_structure_config +from tardis.model.parse_input import ( + parse_abundance_section, + parse_csvy_geometry, + parse_structure_config, +) from tardis.util.base import is_valid_nuclide_or_elem @@ -16,7 +20,6 @@ from tardis.radiation_field.base import MonteCarloRadiationFieldState -from tardis.io.model.readers.base import read_abundances_file from tardis.io.model.readers.generic_readers import ( read_uniform_abundances, ) @@ -490,43 +493,9 @@ def from_config(cls, config, atom_data=None): luminosity_requested = None t_inner = config.plasma.initial_t_inner - abundances_section = config.model.abundances - isotope_abundance = pd.DataFrame() - - if abundances_section.type == "uniform": - abundance, isotope_abundance = read_uniform_abundances( - abundances_section, geometry.no_of_shells - ) - - elif abundances_section.type == "file": - if os.path.isabs(abundances_section.filename): - abundances_fname = abundances_section.filename - else: - abundances_fname = os.path.join( - config.config_dirname, abundances_section.filename - ) - - index, abundance, isotope_abundance = read_abundances_file( - abundances_fname, abundances_section.filetype - ) - - abundance = abundance.replace(np.nan, 0.0) - abundance = abundance[abundance.sum(axis=1) > 0] - - norm_factor = abundance.sum(axis=0) + isotope_abundance.sum(axis=0) - - if np.any(np.abs(norm_factor - 1) > 1e-12): - logger.warning( - "Abundances have not been normalized to 1." " - normalizing" - ) - abundance /= norm_factor - isotope_abundance /= norm_factor - - isotope_abundance = IsotopeAbundances(isotope_abundance) - - elemental_mass = None - if atom_data is not None: - elemental_mass = atom_data.atom_data.mass + isotope_abundance, abundance, elemental_mass = parse_abundance_section( + config, atom_data, geometry + ) return cls( geometry=geometry, diff --git a/tardis/model/parse_input.py b/tardis/model/parse_input.py index 5736777978f..ce6898d4bfe 100644 --- a/tardis/model/parse_input.py +++ b/tardis/model/parse_input.py @@ -2,11 +2,15 @@ import os from astropy import units as u +from tardis.io.decay import IsotopeAbundances +import numpy as np +import pandas as pd from tardis.io.model.parse_density_configuration import ( calculate_density_after_time, parse_config_v1_density, ) -from tardis.io.model.readers.base import read_density_file +from tardis.io.model.readers.base import read_abundances_file, read_density_file +from tardis.io.model.readers.generic_readers import read_uniform_abundances from tardis.model.geometry.radial1d import HomologousRadial1DGeometry from tardis.util.base import quantity_linspace @@ -107,3 +111,44 @@ def parse_csvy_geometry( time_explosion=time_explosion, ) return geometry + + +def parse_abundance_section(config, atom_data, geometry): + abundances_section = config.model.abundances + isotope_abundance = pd.DataFrame() + + if abundances_section.type == "uniform": + abundance, isotope_abundance = read_uniform_abundances( + abundances_section, geometry.no_of_shells + ) + + elif abundances_section.type == "file": + if os.path.isabs(abundances_section.filename): + abundances_fname = abundances_section.filename + else: + abundances_fname = os.path.join( + config.config_dirname, abundances_section.filename + ) + + index, abundance, isotope_abundance = read_abundances_file( + abundances_fname, abundances_section.filetype + ) + + abundance = abundance.replace(np.nan, 0.0) + abundance = abundance[abundance.sum(axis=1) > 0] + + norm_factor = abundance.sum(axis=0) + isotope_abundance.sum(axis=0) + + if np.any(np.abs(norm_factor - 1) > 1e-12): + logger.warning( + "Abundances have not been normalized to 1." " - normalizing" + ) + abundance /= norm_factor + isotope_abundance /= norm_factor + + isotope_abundance = IsotopeAbundances(isotope_abundance) + + elemental_mass = None + if atom_data is not None: + elemental_mass = atom_data.atom_data.mass + return isotope_abundance, abundance, elemental_mass From 518a8f94670796c5a2a95b13643c8b5435f563cb Mon Sep 17 00:00:00 2001 From: Wolfgang Kerzendorf Date: Wed, 11 Oct 2023 16:51:52 -0400 Subject: [PATCH 20/23] add comment about removing quantitiness --- tardis/simulation/tests/test_simulation.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tardis/simulation/tests/test_simulation.py b/tardis/simulation/tests/test_simulation.py index 1a11b1add40..258787c612f 100644 --- a/tardis/simulation/tests/test_simulation.py +++ b/tardis/simulation/tests/test_simulation.py @@ -112,6 +112,7 @@ def test_plasma_estimates(simulation_one_loop, refdata, name): def test_plasma_state_iterations(simulation_one_loop, refdata, name): actual = getattr(simulation_one_loop, name) + # removing the quantitiness of the data as it will screw up the comparison via pandas if hasattr(actual, "value"): actual = actual.value From c78b6de0aa9ec22ed6b2bf7b95d229f971f4357c Mon Sep 17 00:00:00 2001 From: Wolfgang Kerzendorf Date: Wed, 11 Oct 2023 17:01:58 -0400 Subject: [PATCH 21/23] add velocity check --- tardis/model/geometry/radial1d.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tardis/model/geometry/radial1d.py b/tardis/model/geometry/radial1d.py index eb04cf1a68f..ada4aaad540 100644 --- a/tardis/model/geometry/radial1d.py +++ b/tardis/model/geometry/radial1d.py @@ -22,9 +22,6 @@ class HomologousRadial1DGeometry: Volume in each shell """ - DEFAULT_VELOCITY_UNIT = u.km / u.s - DEFAULT_DISTANCE_UNIT = u.km - def __init__( self, v_inner, @@ -38,8 +35,11 @@ def __init__( # ensuring that the cells are continuous assert np.allclose(v_inner[1:], v_outer[:-1]) - self.v_inner = v_inner.to(self.DEFAULT_VELOCITY_UNIT) - self.v_outer = v_outer.to(self.DEFAULT_VELOCITY_UNIT) + assert "velocity" in v_inner.unit.physical_type + assert "velocity" in v_outer.unit.physical_type + + self.v_inner = v_inner + self.v_outer = v_outer # ensuring that the boundaries are within the simulation area From 006ca9d1baa1d323d7bb8d7bbdfced35b05866de Mon Sep 17 00:00:00 2001 From: Wolfgang Kerzendorf Date: Thu, 12 Oct 2023 09:04:53 -0400 Subject: [PATCH 22/23] add new abundance functions --- tardis/model/parse_input.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tardis/model/parse_input.py b/tardis/model/parse_input.py index ce6898d4bfe..7d3f93bf0e1 100644 --- a/tardis/model/parse_input.py +++ b/tardis/model/parse_input.py @@ -151,4 +151,5 @@ def parse_abundance_section(config, atom_data, geometry): elemental_mass = None if atom_data is not None: elemental_mass = atom_data.atom_data.mass + return isotope_abundance, abundance, elemental_mass From 9c680a8f03b38d1b8f909d7dfdd3e6ab5540ad60 Mon Sep 17 00:00:00 2001 From: Wolfgang Kerzendorf Date: Thu, 12 Oct 2023 09:07:43 -0400 Subject: [PATCH 23/23] remove default units --- tardis/model/geometry/radial1d.py | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/tardis/model/geometry/radial1d.py b/tardis/model/geometry/radial1d.py index ada4aaad540..c870b817882 100644 --- a/tardis/model/geometry/radial1d.py +++ b/tardis/model/geometry/radial1d.py @@ -112,27 +112,19 @@ def v_outer_active(self): @property def r_inner(self): - return (self.v_inner * self.time_explosion).to( - self.DEFAULT_DISTANCE_UNIT - ) + return (self.v_inner * self.time_explosion).cgs @property def r_inner_active(self): - return (self.v_inner_active * self.time_explosion).to( - self.DEFAULT_DISTANCE_UNIT - ) + return (self.v_inner_active * self.time_explosion).cgs @property def r_outer(self): - return (self.v_outer * self.time_explosion).to( - self.DEFAULT_DISTANCE_UNIT - ) + return (self.v_outer * self.time_explosion).cgs @property def r_outer_active(self): - return (self.v_outer_active * self.time_explosion).to( - self.DEFAULT_DISTANCE_UNIT - ) + return (self.v_outer_active * self.time_explosion).cgs @property def volume(self):