Skip to content

Commit

Permalink
Merge branch 'main' into osf-optim
Browse files Browse the repository at this point in the history
  • Loading branch information
stefsmeets authored Oct 29, 2024
2 parents d6739fa + 66e9f42 commit 3b8a20b
Show file tree
Hide file tree
Showing 10 changed files with 79 additions and 34 deletions.
4 changes: 0 additions & 4 deletions src/proteus/atmos_clim/dummy.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,6 @@ def RunDummyAtm( dirs:dict, config:Config, T_magma:float, F_ins:float, R_int:flo
skin_d = config.atmos_clim.surface_d
skin_k = config.atmos_clim.surface_k

# Check configuration
if config.atmos_clim.rayleigh:
log.warning("Rayleigh scattering is enabled but it will be neglected")

log.info("Gamma = %.4f" % gamma)
if not (0.0 <= gamma <= 1.0):
log.warning("Gamma value is out of bounds; expect unreasonable fluxes")
Expand Down
20 changes: 16 additions & 4 deletions src/proteus/config/_atmos_clim.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
from __future__ import annotations

import logging

from attrs import define, field
from attrs.validators import ge, gt, in_, le

from ._converters import none_if_none

log = logging.getLogger('fwl.' + __name__)


def tmp_max_bigger_than_tmp_min(instance, attribute, value):
if value <= instance.tmp_minimum:
raise ValueError("'tmp_maximum' has to be bigger than 'tmp_minimum'.")


def warn_if_dummy(instance, attribute, value):
if instance.module == 'dummy':
log.warning('Rayleigh scattering is enabled but it will be neglected')


@define
class AtmosClim:
"""Atmosphere parameters, model selection.
Expand Down Expand Up @@ -47,6 +57,7 @@ class AtmosClim:
dummy: Dummy
Config parameters for dummy atmosphere module
"""

prevent_warming: bool
surface_d: float = field(validator=gt(0))
surface_k: float = field(validator=gt(0))
Expand All @@ -55,7 +66,7 @@ class AtmosClim:
surf_state: str = field(validator=in_(('mixed_layer', 'fixed', 'skin')))
surf_albedo: float = field(validator=(ge(0), le(1)))
albedo_pl: float = field(validator=(ge(0), le(1)))
rayleigh: bool
rayleigh: bool = field(validator=warn_if_dummy)
tmp_minimum: float = field(validator=gt(0))
tmp_maximum: float = field(validator=tmp_max_bigger_than_tmp_min)

Expand Down Expand Up @@ -88,13 +99,12 @@ class Agni:
chemistry: str | None
Treatment of self-consistent atmospheric chemsitry. Choices: "none", "eq", "kin".
"""

p_top: float = field(validator=gt(0))
spectral_group: str
spectral_bands: str
num_levels: int = field(validator=ge(15))
chemistry: str | None = field(
validator=in_((None, 'eq', 'kin')), converter=none_if_none
)
chemistry: str | None = field(validator=in_((None, 'eq', 'kin')), converter=none_if_none)

@property
def chemistry_int(self) -> int:
Expand All @@ -121,6 +131,7 @@ class Janus:
tropopause: str | None
Scheme for determining tropopause location. Choices: "none", "skin", "dynamic".
"""

p_top: float = field(validator=gt(0))
spectral_group: str
spectral_bands: str
Expand All @@ -140,4 +151,5 @@ class Dummy:
gamma: float
Atmosphere opacity between 0 and 1.
"""

gamma: float
4 changes: 4 additions & 0 deletions src/proteus/config/_delivery.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ class Volatiles:
CH4: float = field(default=0, validator=ge(0))
CO: float = field(default=0, validator=ge(0))

def get_pressure(self, s: str) -> float:
"""Helper method for getting the pressure for `vol` by string."""
return getattr(self, s)


@define
class Delivery:
Expand Down
24 changes: 14 additions & 10 deletions src/proteus/config/_outgas.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ class Calliope:
Attributes
----------
T_floor: float
Temperature floor applied to outgassing calculation [K].
include_H2O: bool
If True, include H2O outgassing.
include_CO2: bool
Expand All @@ -48,18 +50,20 @@ class Calliope:
If True, include CH4 outgassing.
include_CO: bool
If True, include CO outgassing.
T_floor: float
Temperature floor applied to outgassing calculation [K].
"""
include_H2O: bool
include_CO2: bool
include_N2: bool
include_S2: bool
include_SO2: bool
include_H2: bool
include_CH4: bool
include_CO: bool
T_floor: float = field(validator=validators.gt(0.0))
include_H2O: bool = False
include_CO2: bool = False
include_N2: bool = False
include_S2: bool = False
include_SO2: bool = False
include_H2: bool = False
include_CH4: bool = False
include_CO: bool = False

def is_included(self, vol: str) -> bool:
"""Helper method for getting flag if `vol` is included in outgassing."""
return getattr(self, f'include_{vol}')


@define
Expand Down
8 changes: 4 additions & 4 deletions src/proteus/outgas/calliope.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ def construct_options(dirs:dict, config:Config, hf_row:dict):

# Volatile inventory
for s in vol_list:
solvevol_inp[f'{s}_initial_bar'] = getattr(config.delivery.volatiles, s)
solvevol_inp[f'{s}_initial_bar'] = config.delivery.volatiles.get_pressure(s)

included = getattr(config.outgas.calliope, f'include_{s}')
solvevol_inp[f'{s}_included'] = 1 if included else 0
included = config.outgas.calliope.is_included(s)
solvevol_inp[f'{s}_included'] = int(included)

if (s in ["H2O","CO2","N2","S2"]) and not included:
if (s in ("H2O","CO2","N2","S2")) and not included:
UpdateStatusfile(dirs, 20)
raise RuntimeError(f"Missing required volatile {s}")

Expand Down
9 changes: 5 additions & 4 deletions src/proteus/plot/cpl_fluxes_global.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@

if TYPE_CHECKING:
from proteus import Proteus
from proteus.config import Config

log = logging.getLogger("fwl."+__name__)

def plot_fluxes_global(hf_all:pd.DataFrame, output_dir: str, options: dict, t0: float=100.0):
def plot_fluxes_global(hf_all:pd.DataFrame, output_dir: str, config: Config, t0: float=100.0):

# Get values
hf_crop = hf_all.loc[hf_all["Time"]>t0]
Expand All @@ -28,7 +29,7 @@ def plot_fluxes_global(hf_all:pd.DataFrame, output_dir: str, options: dict, t0:
log.info("Plot global fluxes")

F_net = np.array(hf_crop["F_atm"])
F_asf = np.array(hf_crop["F_ins"]) * options["asf_scalefactor"] * (1.0 - options["albedo_pl"]) * np.cos(options["zenith_angle"] * np.pi/180.0)
F_asf = np.array(hf_crop["F_ins"]) * config.orbit.s0_factor * (1.0 - config.atmos_clim.albedo_pl) * np.cos(config.orbit.zenith_angle * np.pi/180.0)
F_olr = np.array(hf_crop["F_olr"])
F_upw = np.array(hf_crop["F_olr"]) + np.array(hf_crop["F_sct"])
F_int = np.array(hf_crop["F_int"])
Expand Down Expand Up @@ -63,7 +64,7 @@ def plot_fluxes_global(hf_all:pd.DataFrame, output_dir: str, options: dict, t0:

plt.close()
plt.ioff()
fig.savefig(output_dir+"/plot_fluxes_global.%s"%options["plot_format"],
fig.savefig(output_dir+"/plot_fluxes_global.%s" % config.params.out.plot_fmt,
bbox_inches='tight', dpi=200)


Expand All @@ -75,7 +76,7 @@ def plot_fluxes_global_entry(handler: Proteus):
plot_fluxes_global(
hf_all=hf_all,
output_dir=handler.directories["output"],
options=handler.config,
config=handler.config,
)


Expand Down
13 changes: 8 additions & 5 deletions src/proteus/plot/cpl_global.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@

if TYPE_CHECKING:
from proteus import Proteus
from proteus.config import Config

log = logging.getLogger("fwl."+__name__)

def plot_global(hf_all: pd.DataFrame, output_dir: str, options: dict,
def plot_global(hf_all: pd.DataFrame, output_dir: str, config: Config,
logt: bool=True, tmin: float=1e1):

if np.amax(hf_all["Time"]) < 2:
Expand Down Expand Up @@ -51,7 +52,8 @@ def plot_global(hf_all: pd.DataFrame, output_dir: str, options: dict,
# Check vmr for presence
this_vmr = np.array(hf_all[vol+"_vmr"])
vol_present[vol] = True
if (np.amax(this_vmr) < 1.0e-20) or (options[vol+"_included"] < 1):

if (np.amax(this_vmr) < 1.0e-20) or not config.outgas.calliope.is_included(vol):
vol_present[vol] = False
continue
vol_vmr[vol] = this_vmr
Expand Down Expand Up @@ -154,9 +156,10 @@ def plot_global(hf_all: pd.DataFrame, output_dir: str, options: dict,
ax_cl.set_ylim(min(1000.0,min_temp-25) , max(3500.0,max_temp+25))

# PLOT ax_bl
ax_bl.axhline( y=options["planet_coresize"], ls='dashed', lw=lw*1.5, alpha=al, color=get_colour("core"), label=r'C-M boundary' )
ax_bl.axhline( y=config.struct.corefrac, ls='dashed', lw=lw*1.5, alpha=al, color=get_colour("core"), label=r'C-M boundary' )
ax_bl.plot( hf_all["Time"], 1.0-hf_all["RF_depth"], color=get_colour("int"), ls="solid", lw=lw, alpha=al, label=r'Rheol. front')
ax_bl.plot( hf_all["Time"], hf_all["Phi_global"], color=get_colour("atm"), linestyle=':', lw=lw, alpha=al, label=r'Melt fraction')

ax_bl.legend(loc='center left', **leg_kwargs)
ax_bl.set_ylim(0.0,1.01)

Expand Down Expand Up @@ -195,7 +198,7 @@ def plot_global(hf_all: pd.DataFrame, output_dir: str, options: dict,
else:
plt_name += "_lin"

fig.savefig(output_dir+"/%s.%s"%(plt_name,options["plot_format"]),
fig.savefig(output_dir+"/%s.%s"%(plt_name,config.params.out.plot_fmt),
bbox_inches='tight', dpi=200)


Expand All @@ -208,7 +211,7 @@ def plot_global_entry(handler: Proteus):
plot_global(
hf_all=hf_all,
output_dir=handler.directories['output'],
options=handler.config,
config=handler.config,
logt=logt,
tmin=1e1,
)
Expand Down
4 changes: 2 additions & 2 deletions src/proteus/proteus.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,8 @@ def start(self, *, resume: bool = False):
log.info("Input partial pressures:")
inc_gases = []
for s in vol_list:
pp_val = getattr(self.config.delivery.volatiles, s)
include = getattr(self.config.outgas.calliope, f'include_{s}')
pp_val = self.config.delivery.volatiles.get_pressure(s)
include = self.config.outgas.calliope.is_included(s)

log.info(
" %-6s : %-5.2f bar (included = %s)"
Expand Down
4 changes: 3 additions & 1 deletion src/proteus/star/wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,10 @@ def get_new_spectrum(t_star:float, config:Config,
match config.star.mors.tracks:
case 'spada':
star_props_hist = get_spada_synthesis_properties(stellar_track, t_star/1e6)
assert star_struct_modern
assert star_props_modern
synthetic = mors.synthesis.CalcScaledSpectrumFromProps(
star_struct_modern, star_props_modern, star_props_hist)
modern_spec=star_struct_modern, modern_dict=star_props_modern, historical_dict=star_props_hist)
fl = synthetic.fl
wl = synthetic.wl
case 'baraffe':
Expand Down
23 changes: 23 additions & 0 deletions tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from proteus import Proteus
from proteus.config import Config, read_config_object
from proteus.config._converters import none_if_none
from proteus.config._delivery import Volatiles
from proteus.config._outgas import Calliope

PATHS = chain(
(PROTEUS_ROOT / 'input').glob('*.toml'),
Expand Down Expand Up @@ -50,3 +52,24 @@ def test_proteus_init(path):
runner = Proteus(config_path=path)

assert isinstance(runner.config, Config)


def test_calliope_is_included():
conf = Calliope(
T_floor=0.1,
include_CO=False,
include_H2=True,
)
assert not conf.is_included('CO')
assert conf.is_included('H2')
with pytest.raises(AttributeError):
conf.is_included('fails')


def test_delivery_get_pressure():
conf = Volatiles(
N2 = 123.0
)
assert conf.get_pressure('N2') == 123.0
with pytest.raises(AttributeError):
conf.get_pressure('fails')

0 comments on commit 3b8a20b

Please sign in to comment.