Source code for WallGo.config

""" Dataclasses to store the configs """

import os
import configparser
from dataclasses import dataclass, field

[docs] @dataclass class ConfigGrid: """ Holds the config of the Grid3Scales class. """ spatialGridSize: int = 40 """ Number of grid points in the spatial direction (M in 2204.13120). """ momentumGridSize: int = 11 """ Number of grid points in the momentum directions (N in 2204.13120). MUST BE ODD. """ ratioPointsWall: float = 0.5 """ Fraction of points inside the wall defined by the interval [-wallThickness+wallCenter, wallThickness+wallCenter]. Should be a number between 0 and 1. """ smoothing: float = 0.1 """ Smoothing factor of the mapping function (the larger the smoother). """
[docs] @dataclass class ConfigEOM: """ Holds the config of the EOM class. """ errTol: float = 1e-3 """ The absolute error tolerance for the wall velocity result. """ pressRelErrTol: float = 0.1 """ Relative error tolerance for the pressure. """ maxIterations: int = 20 """ Maximum number of iterations for the convergence of the pressure. """ conserveEnergyMomentum: bool = True r""" Flag to enforce conservation of energy and momentum. Normally, this should be set to True, but it can help with numerical stability to set it to False. If True, there is an ambiguity in the separation between :math:`f_{eq}` and :math:`\delta f` when the out-of-equilibrium particles form a closed system (or nearly closed). This can lead to a divergence of the iterative loop. In the end, it is better to set this to False if most of the degrees of freedom are treated as out-of-equilibrium particle. If most of the dofs are in the background fluid, setting it to True will give better results. """ wallThicknessBounds: list[float] = field(default_factory=lambda: [0.1, 100.0]) """ Lower and upper bounds on wall thickness (in units of 1/Tnucl). """ wallOffsetBounds: list[float] = field(default_factory=lambda: [-10.0, 10.0]) """ Lower and upper bounds on wall offset. """ ## The following parameters are only used for detonation solutions ## vwMaxDeton: float = 0.99 """ Maximal Velocity at which the solver will look to find a detonation solution """ nbrPointsMinDeton: int = 5 """ Minimal number of points probed to bracket the detonation roots. """ nbrPointsMaxDeton: int = 20 """ Maximal number of points probed to bracket the detonation roots. """ overshootProbDeton: float = 0.05 """ Desired probability of overshooting a root. Must be between 0 and 1. A smaller value will lead to more pressure evaluations (and thus a longer time), but is less likely to miss a root. """
[docs] @dataclass class ConfigHydrodynamics: """ Holds the config of the Hydrodynamics class. """ tmin: float = 0.01 """ Minimum temperature that is probed in Hydrodynamics (in units of Tnucl). """ tmax: float = 10.0 """ Maximum temperature that is probed in Hydrodynamics (in units of Tnucl). """ relativeTol: float = 1e-6 """ Relative tolerance used in Hydrodynamics. """ absoluteTol: float = 1e-10 """ Absolute tolerance used in Hydrodynamics. """
[docs] @dataclass class ConfigThermodynamics: """ Holds the config of the Hydrodynamics class. """ tmin: float = 0.8 """ Minimum temperature used in the phase tracing (in units of the estimate for the minimum temperature obtained in the template model). """ tmax: float = 1.2 """ Maximum temperature used in the phase tracing (in units of the estimate for the maximum temperature obtained in the template model). """ phaseTracerTol: float = 1e-6 """ Desired accuracy of the phase tracer and the resulting FreeEnergy interpolation. """ phaseTracerFirstStep: float | None = None r""" Starting step for phaseTrace. If a float, this gives the starting step size in units of the maximum step size :py:data:`dT`. If :py:data:`None` then uses the initial step size algorithm of :py:mod:`scipy.integrate.solve_ivp`. """ interpolationDegree: int = 1 """ Degree of the splines used in FreeEnergy to interpolate the potential and its derivatives. """
[docs] @dataclass class ConfigBoltzmannSolver: """ Holds the config of the BoltzmannSolver class. """ basisM: str = 'Cardinal' """ The position polynomial basis type, either 'Cardinal' or 'Chebyshev'. """ basisN: str = 'Chebyshev' """ The momentum polynomial basis type, either 'Cardinal' or 'Chebyshev'. """ collisionMultiplier: float = 1.0 """ Factor multiplying the collision term in the Boltzmann equation. Can be used for testing or for studying the solution's sensibility to the collision integrals. Don't forget to adjust meanFreePathScale accordingly if this is different from 1 (meanFreePathScale should scale like 1/collisionMultiplier). WARNING: THIS CHANGES THE COLLISION TERMS WRT TO THEIR PHYSICAL VALUE. """ truncationOption: str = 'AUTO' """ Truncation option for spectral expansions. Can be 'NONE' for no truncation, 'AUTO' to automatically detect if the spectral expansion is converging and truncate if not, or 'THIRD' which always truncates the last third. """
[docs] @dataclass class Config: """ Data class that holds all the model-independent configs. It contains objects of the data classes ConfigGrid, ConfigEOM, ConfigEffectivePotential, ConfigHydrodynamics, ConfigThermodynamics and ConfigBoltzmannSolver. It can also load the configs from an .ini file. """ configGrid: ConfigGrid = field(default_factory=lambda: ConfigGrid()) """ Holds the config of the Grid3Scales class. """ configEOM: ConfigEOM = field(default_factory=lambda: ConfigEOM()) """ Holds the config of the EOM class. """ configHydrodynamics: ConfigHydrodynamics = field( default_factory=lambda: ConfigHydrodynamics()) """ Holds the config of the Hydrodynamics class. """ configThermodynamics: ConfigThermodynamics = field( default_factory=lambda: ConfigThermodynamics()) """ Holds the config of the Thermodynamics class. """ configBoltzmannSolver: ConfigBoltzmannSolver = field( default_factory=lambda: ConfigBoltzmannSolver()) """ Holds the config of the BoltzmannSolver class. """
[docs] def loadConfigFromFile(self, filePath: str) -> None: """ Load the configs from a file. Parameters ---------- filePath : str Path of the file where the configs are. """ # Make sure that the file exists if not os.path.isfile(filePath): raise FileNotFoundError(filePath) parser = configparser.ConfigParser() parser.optionxform = str parser.read(filePath) # Read the Grid configs if 'Grid' in parser.sections(): keys = parser['Grid'].keys() if 'spatialGridSize' in keys: self.configGrid.spatialGridSize = parser.getint("Grid", "spatialGridSize") if 'momentumGridSize' in keys: self.configGrid.momentumGridSize = parser.getint("Grid", "momentumGridSize") if 'ratioPointsWall' in keys: self.configGrid.ratioPointsWall = parser.getfloat("Grid", "ratioPointsWall") if 'smoothing' in keys: self.configGrid.smoothing = parser.getfloat("Grid", "smoothing") # Read the EOM configs if 'EquationOfMotion' in parser.sections(): keys = parser['EquationOfMotion'].keys() if 'errTol' in keys: self.configEOM.errTol = parser.getfloat("EquationOfMotion", "errTol") if 'pressRelErrTol' in keys: self.configEOM.pressRelErrTol = parser.getfloat("EquationOfMotion", "pressRelErrTol") if 'maxIterations' in keys: self.configEOM.maxIterations = parser.getint("EquationOfMotion", "maxIterations") if 'conserveEnergyMomentum' in keys: self.configEOM.conserveEnergyMomentum = parser.getboolean( "EquationOfMotion", "conserveEnergyMomentum") if 'wallThicknessLowerBound' in keys: self.configEOM.wallThicknessBounds[0] = parser.getfloat( "EquationOfMotion", "wallThicknessLowerBound") if 'wallThicknessUpperBound' in keys: self.configEOM.wallThicknessBounds[1] = parser.getfloat( "EquationOfMotion", "wallThicknessUpperBound") if 'wallOffsetLowerBound' in keys: self.configEOM.wallOffsetBounds[0] = parser.getfloat( "EquationOfMotion", "wallOffsetLowerBound") if 'wallOffsetUpperBound' in keys: self.configEOM.wallOffsetBounds[1] = parser.getfloat( "EquationOfMotion", "wallOffsetUpperBound") if 'vwMaxDeton' in keys: self.configEOM.vwMaxDeton = parser.getfloat("EquationOfMotion", "vwMaxDeton") if 'nbrPointsMinDeton' in keys: self.configEOM.nbrPointsMinDeton = parser.getint("EquationOfMotion", "nbrPointsMinDeton") if 'nbrPointsMaxDeton' in keys: self.configEOM.nbrPointsMaxDeton = parser.getint("EquationOfMotion", "nbrPointsMaxDeton") if 'overshootProbDeton' in keys: self.configEOM.overshootProbDeton = parser.getfloat("EquationOfMotion", "overshootProbDeton") # Read the Hydrodynamics configs if 'Hydrodynamics' in parser.sections(): keys = parser['Hydrodynamics'].keys() if 'tmin' in keys: self.configHydrodynamics.tmin = parser.getfloat("Hydrodynamics", "tmin") if 'tmax' in keys: self.configHydrodynamics.tmax = parser.getfloat("Hydrodynamics", "tmax") if 'relativeTol' in keys: self.configHydrodynamics.relativeTol = parser.getfloat("Hydrodynamics", "relativeTol") if 'absoluteTol' in keys: self.configHydrodynamics.absoluteTol = parser.getfloat("Hydrodynamics", "absoluteTol") # Read the Thermodynamics configs if 'Thermodynamics' in parser.sections(): keys = parser['Thermodynamics'].keys() if 'tmin' in keys: self.configThermodynamics.tmin = parser.getfloat("Thermodynamics", "tmin") if 'tmax' in keys: self.configThermodynamics.tmax = parser.getfloat("Thermodynamics", "tmax") if 'phaseTracerTol' in keys: self.configThermodynamics.phaseTracerTol = parser.getfloat( "Thermodynamics", "phaseTracerTol" ) if 'phaseTracerFirstStep' in keys: # either float or None try: self.configThermodynamics.phaseTracerFirstStep = parser.getfloat( "Thermodynamics", "phaseTracerFirstStep" ) except ValueError as valErr: if str(valErr) == "could not convert string to float: 'None'": self.configThermodynamics.phaseTracerFirstStep = None else: raise if 'interpolationDegree' in keys: self.configThermodynamics.interpolationDegree = parser.getint( "Thermodynamics", "interpolationDegree" ) # Read the BoltzmannSolver configs if 'BoltzmannSolver' in parser.sections(): keys = parser['BoltzmannSolver'].keys() if 'collisionMultiplier' in keys: self.configBoltzmannSolver.collisionMultiplier = parser.getfloat("BoltzmannSolver", "collisionMultiplier") if 'basisM' in keys: self.configBoltzmannSolver.basisM = parser.get( "BoltzmannSolver", "basisM") if 'basisN' in keys: self.configBoltzmannSolver.basisN = parser.get( "BoltzmannSolver", "basisN") if 'truncationOption' in keys: self.configBoltzmannSolver.truncationOption = parser.get( "BoltzmannSolver", "truncationOption")