From 053e4001cad17d7be04b27fed41e1b62f08837b4 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 21 Oct 2024 10:32:41 +0200 Subject: [PATCH 01/13] Set up boilerplate for config docs --- docs/config.md | 37 +++++++++++++++++++++++++++++++++++++ mkdocs.yml | 7 +++++-- 2 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 docs/config.md diff --git a/docs/config.md b/docs/config.md new file mode 100644 index 00000000..638d4ba6 --- /dev/null +++ b/docs/config.md @@ -0,0 +1,37 @@ +::: proteus.config.Config + + +::: proteus.config._atmos_clim.AtmosClim + + +::: proteus.config._atmos_clim.Agni + + +::: proteus.config._atmos_clim.Janus + + +::: proteus.config._atmos_clim.Dummy + + +::: proteus.config._delivery.Delivery + + +::: proteus.config._escape.Escape + + +::: proteus.config._interior.Interior + + +::: proteus.config._orbit.Orbit + + +::: proteus.config._outgas.Outgas + + +::: proteus.config._params.Params + + +::: proteus.config._star.Star + + +::: proteus.config._struct.Struct diff --git a/mkdocs.yml b/mkdocs.yml index 30b5a3c4..39f41704 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -7,6 +7,7 @@ nav: - Home: index.md - Installation: installation.md - Usage: usage.md + - Config: config.md - Troubleshooting: troubleshooting.md - MORS: https://fwl-proteus.readthedocs.io/projects/mors/ - JANUS: https://fwl-proteus.readthedocs.io/projects/janus/ @@ -57,8 +58,10 @@ plugins: ignore_init_summary: yes show_submodules: no show_source: true - show_root_heading: false - show_root_full_path: false + show_root_heading: true + shol_root_toc_entry: true + show_docstring_attributes: true + show_root_full_path: true docstring_section_style: list members_order: alphabetical merge_init_into_class: yes From 07d5614d9ee56fbef3500ab77b8f4894a5375888 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 21 Oct 2024 10:33:02 +0200 Subject: [PATCH 02/13] Add root / atmos docstrings --- src/proteus/config/_atmos_clim.py | 75 ++++++++++++++++++++++++++++++- src/proteus/config/_config.py | 26 ++++++++++- 2 files changed, 99 insertions(+), 2 deletions(-) diff --git a/src/proteus/config/_atmos_clim.py b/src/proteus/config/_atmos_clim.py index ccd12d38..a5c09196 100644 --- a/src/proteus/config/_atmos_clim.py +++ b/src/proteus/config/_atmos_clim.py @@ -7,6 +7,21 @@ @define class Agni: + """Agni atmosphere module. + + Attributes + ---------- + p_top: float + Bar, top of atmosphere grid pressure. + spectral_group: str + Which gas opacities to include. + spectral_bands: str + Number of spectral bands? + num_levels: str + Number of atmospheric grid levels. + chemistry: str | None + Choices: None, "eq", "kin" + """ p_top: float spectral_group: str spectral_bands: str @@ -23,6 +38,23 @@ def chemistry_int(self) -> int: @define class Janus: + """Janus atmosphere module. + + Attributes + ---------- + p_top: float + Bar, top of atmosphere grid pressure. + spectral_group: str + Which gas opacities to include. + spectral_bands: str + Number of spectral bands. + F_atm_bc: int + Measure outgoing flux at: (0) TOA | (1) Surface. + num_levels: int + Number of atmospheric grid levels. + tropopause: str | None + Choices: None | skin | dynamic. + """ p_top: float spectral_group: str spectral_bands: str @@ -35,12 +67,53 @@ class Janus: @define class Dummy: + """Dummy atmosphere module. + + Attributes + ---------- + gamma: float + Atmosphere opacity between 0 and 1. + """ gamma: float @define class AtmosClim: - """Atmosphere parameters, model selection""" + """Atmosphere parameters, model selection. + + Attributes + ---------- + prevent_warming: bool + Do not allow the planet to heat up. + surface_d: float + M, conductive skin thickness. + surface_k: float + W m-1 K-1, conductive skin thermal conductivity. + cloud_enabled: bool + Enable water cloud radiative effects. + cloud_alpha: float + Condensate retention fraction (1 -> fully retained). + surf_state: str + Surface scheme: "mixed_layer", "fixed", "skin". + surf_albedo: float + Path to file ("string") or grey quantity (float). + albedo_pl: float + Bond albedo (scattering). + rayleigh: bool + Enable rayleigh scattering. + tmp_minimum: float + Temperature floor on solver. + tmp_maximum: float + Temperature ceiling on solver. + module: str + Which atmosphere module to use. + agni: Agni + Config parameters for Agni atmosphere module + janus: Janus + Config parameters for Janus atmosphere module + dummy: Dummy + Config parameters for dummy atmosphere module + """ prevent_warming: bool surface_d: float surface_k: float diff --git a/src/proteus/config/_config.py b/src/proteus/config/_config.py index d44cc241..4409e70a 100644 --- a/src/proteus/config/_config.py +++ b/src/proteus/config/_config.py @@ -19,7 +19,31 @@ @define class Config: - """Root config""" + """Root config. + + Attributes + ---------- + version: str + author: str + params: Params + Parameters for code execution, output files, time-stepping, convergence. + star: Star + Stellar parameters, model selection. + orbit: Orbit + Planetary orbital parameters. + struct: Struct + Planetary structure (mass, radius). + atmos_clim: AtmosClim + Atmosphere parameters, model selection. + escape: Escape + Escape parameters, model selection. + interior: Interior + Magma ocean model selection and parameters. + outgas: Outgas + Outgassing parameters (fO2) and included volatiles. + delivery: Delivery + Initial volatile inventory, and delivery model selection. + """ version: str = field(validator=validators.in_(('2.0',))) author: str From 203f98f7fdb5284c354f3821463325db6e929bc4 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 21 Oct 2024 13:56:37 +0200 Subject: [PATCH 03/13] Add more docstrings --- src/proteus/config/_delivery.py | 48 ++++++++++++++++++++++++++++++++- src/proteus/config/_escape.py | 26 +++++++++++++++++- src/proteus/config/_interior.py | 42 ++++++++++++++++++++++++++++- src/proteus/config/_orbit.py | 16 ++++++++++- src/proteus/config/_outgas.py | 42 ++++++++++++++++++++++++++++- src/proteus/config/_star.py | 33 ++++++++++++++++++++++- src/proteus/config/_struct.py | 12 ++++++++- 7 files changed, 212 insertions(+), 7 deletions(-) diff --git a/src/proteus/config/_delivery.py b/src/proteus/config/_delivery.py index 846ce021..ee0b03f6 100644 --- a/src/proteus/config/_delivery.py +++ b/src/proteus/config/_delivery.py @@ -7,6 +7,19 @@ @define class Elements: + """Initial volatile inventory by planetary element abundances. + + Attributes + ---------- + CH_ratio: float + C/H ratio in mantle/atmosphere system. + H_oceans: float + Hydrogen inventory in units of equivalent Earth oceans, by mass. + N_ppmw: float + Nitrogen inventory in ppmw relative to mantle mass, by mass. + S_ppmw: float + Sulfur inventory in ppmw relative to mass of melt. + """ CH_ratio: float H_oceans: float N_ppmw: float @@ -15,6 +28,27 @@ class Elements: @define class Volatiles: + """Initial volatile inventory by partial pressures in atmosphere. + + Attributes + ---------- + H2O: float + Partial pressure of H2O. + CO2: float + Partial pressure of CO2. + N2: float + Partial pressure of N2. + S2: float + Partial pressure of S2. + SO2: float + Partial pressure of SO2. + H2: float + Partial pressure of H2. + CH4: float + Partial pressure of CH4. + CO: float + Partial pressure of CO. + """ H2O: float = field(default=0) CO2: float = field(default=0) N2: float = field(default=0) @@ -27,7 +61,19 @@ class Volatiles: @define class Delivery: - """Initial volatile inventory, and delivery model selection""" + """Initial volatile inventory, and delivery model selection + + Attributes + ---------- + initial: str + Set initial inventory to use, choice 'volatiles', 'elements'. + module: str + Delivery module to use (Not used as of yet). + elements: Elements + Set initial volatile inventory by planetary element abundances. + volatiles: Volatiles + Set initial volatile inventory by partial pressures in atmosphere. + """ initial: str = field(validator=validators.in_(('elements', 'volatiles'))) module: str | None = field(validator=validators.in_((None,)), converter=none_if_none) diff --git a/src/proteus/config/_escape.py b/src/proteus/config/_escape.py index d3654258..e9a94b53 100644 --- a/src/proteus/config/_escape.py +++ b/src/proteus/config/_escape.py @@ -7,17 +7,41 @@ @define class Zephyrus: + """Parameters for Zephyrus module. + + Attributes + ---------- + some_parameter: str + Not used. + """ some_parameter: str @define class EscapeDummy: + """Dummy module. + + Attributes + ---------- + rate: float + Bulk unfractionated escape rate [kg s-1] + """ rate: float @define class Escape: - """Escape parameters, model selection""" + """Escape parameters, model selection. + + Attributes + ---------- + module: str | None + Select module, choice None, 'dummy', 'zephyrus'. + zephyrus: Zephyrus + Parameters for zephyrus module. + dummy: EscapeDummy + Parameters for dummy module. + """ module: str | None = field( validator=validators.in_((None, 'dummy', 'zephyrus')), converter=none_if_none ) diff --git a/src/proteus/config/_interior.py b/src/proteus/config/_interior.py index 9ab8dc12..8675b8aa 100644 --- a/src/proteus/config/_interior.py +++ b/src/proteus/config/_interior.py @@ -5,6 +5,25 @@ @define class Spider: + """Parameters for Spider module. + + Attributes + ---------- + num_levels: int + Number of SPIDER grid levels + mixing_length: int + Mixing length parameterization + tolerance: float + Solver tolerance + tsurf_atol: float + Tsurf_poststep_change + tsurf_rtol: float + Tsurf_poststep_change_frac + ini_entropy: float + Surface entropy conditions [J K-1 kg-1] + ini_dsdr: float + Interior entropy gradient [J K-1 kg-1 m-1] + """ num_levels: int = field(validator=validators.ge(40)) mixing_length: int tolerance: float @@ -16,12 +35,33 @@ class Spider: @define class Aragog: + """Parameters for Aragog module. + + Attributes + ---------- + some_parameter: str + Not used. + """ some_parameter: str @define class Interior: - """Magma ocean model selection and parameters""" + """Magma ocean model selection and parameters. + + Attributes + ---------- + grain_size: float + Crystal settling grain size [m] + F_initial: float + Initial heat flux guess [W m-2] + module: str + Select interior model, choices: 'spider', 'aragog', 'dummy' + spider: Spider + Parameters for spider module + aragog: Aragog + Parameters for aragog module + """ grain_size: float F_initial: float diff --git a/src/proteus/config/_orbit.py b/src/proteus/config/_orbit.py index 942b29e8..0e64837a 100644 --- a/src/proteus/config/_orbit.py +++ b/src/proteus/config/_orbit.py @@ -7,7 +7,21 @@ @define class Orbit: - """Planetary orbital parameters""" + """Planetary orbital parameters. + + Attributes + ---------- + semimajoraxis: float + AU + eccentricity: float + Dimensionless + zenith_angle: float + Degrees + s0_factor: float + Dimensionless + module: str | None + Select orbit module to use. Not used currently. + """ semimajoraxis: float eccentricity: float = field(validator=[ validators.ge(0), diff --git a/src/proteus/config/_outgas.py b/src/proteus/config/_outgas.py index 012559b3..d19a6fd8 100644 --- a/src/proteus/config/_outgas.py +++ b/src/proteus/config/_outgas.py @@ -5,6 +5,27 @@ @define class Calliope: + """Module parameters for Calliope. + + Attributes + ---------- + include_H2O: bool + If True, include H2O compound. + include_CO2: bool + If True, include CO2 compound. + include_N2: bool + If True, include N2 compound. + include_S2: bool + If True, include S2 compound. + include_SO2: bool + If True, include SO2 compound. + include_H2: bool + If True, include H2 compound. + include_CH4: bool + If True, include CH4 compound. + include_CO: bool + If True, include CO compound. + """ include_H2O: bool include_CO2: bool include_N2: bool @@ -17,12 +38,31 @@ class Calliope: @define class Atmodeller: + """Module parameters for Atmodeller. + + Attributes + ---------- + some_parameter: str + Not used currently. + """ some_parameter: str @define class Outgas: - """Outgassing parameters (fO2) and included volatiles""" + """Outgassing parameters (fO2) and included volatiles. + + Attributes + ---------- + fO2_shift_IW: float + log10(ΔIW), atmosphere/interior boundary oxidation state. + module: str + Which outgassing module to use, choices: 'calliope', 'atmodeller'. + calliope: Calliope + Parameters for calliope module. + atmodeller: Atmodeller + Parameters for atmodeller module. + """ fO2_shift_IW: float module: str = field(validator=validators.in_(('calliope', 'atmodeller'))) diff --git a/src/proteus/config/_star.py b/src/proteus/config/_star.py index 4c847628..44230453 100644 --- a/src/proteus/config/_star.py +++ b/src/proteus/config/_star.py @@ -7,13 +7,44 @@ @define class Mors: + """Module parameters for MORS module. + + Attributes + ---------- + tracks: str + Name of evolution tracks, choice: 'spada', 'baraffe' + spec: str + Path to stellar spectrum + """ tracks: str = field(validator=validators.in_(('spada', 'baraffe'))) spec: str @define class Star: - """Stellar parameters, model selection""" + """Stellar parameters, model selection. + + Attributes + ---------- + mass: float + M_sun + radius: float + R_sun + Teff: float + K + Lbol: float + L_sun + omega: float + Rotation percentile + age_now: float + Gyr, current age of star used for scaling + age_ini: float + Gyr, model initialisation/start age + module: str | None + Select star module to use. + mors: Mors + Parameters for MORS module + """ mass: float radius: float Teff: float diff --git a/src/proteus/config/_struct.py b/src/proteus/config/_struct.py index cb7ca24a..401b3fc1 100644 --- a/src/proteus/config/_struct.py +++ b/src/proteus/config/_struct.py @@ -7,7 +7,17 @@ @define class Struct: - """Planetary structure (mass, radius)""" + """Planetary structure (mass, radius). + + mass: float + M_earth + radius: float + R_earth + corefrac: float + Non-dimensional, radius fraction + module: str | None + Select internal structure module to use. Not used currently. + """ mass: float radius: float corefrac: float From f7d5383af241be2c8a1b052289781c37daf7f05d Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 21 Oct 2024 14:09:42 +0200 Subject: [PATCH 04/13] Add docstrings for params --- src/proteus/config/_params.py | 139 +++++++++++++++++++++++++++++++++- 1 file changed, 138 insertions(+), 1 deletion(-) diff --git a/src/proteus/config/_params.py b/src/proteus/config/_params.py index 9ac438ba..7d2e366e 100644 --- a/src/proteus/config/_params.py +++ b/src/proteus/config/_params.py @@ -5,6 +5,19 @@ @define class OutputParams: + """Parameters for output files and logging + + Attributes + ---------- + path: str + Path where to store output data + logging: str + Set loglevel, choices: 'INFO', 'DEBUG', 'ERROR', 'WARNING' + plot_mod: int + Plotting frequency, 0: wait until completion | n: every n iterations + plot_fmt: str + Plotting image file format, "png" or "pdf" recommended + """ path: str logging: str = field(validator=validators.in_(('INFO', 'DEBUG', 'ERROR', 'WARNING'))) plot_mod: int @@ -13,17 +26,54 @@ class OutputParams: @define class DtProportional: + """Parameters for proportional time-stepping + + Attributes + ---------- + propconst: float + Proportionality constant. + """ propconst: float @define class DtAdaptive: + """Parameters for adaptive time-stepping + + Attributes + ---------- + atol: float + Step size absolute tolerance + rtol: float + Step size relative tolerance + """ atol: float rtol: float @define class TimeStepParams: + """Parameters for time-stepping parameters + + Attributes + ---------- + minimum: float + yr, minimum time-step + maximum: float + yr, maximum time-step + initial: float + yr, inital step size + starspec: float + yr, interval to re-calculate the stellar spectrum + starinst: float + yr, interval to re-calculate the instellation + method: str + Time-stepping method, choices: 'proportional', 'adaptive', 'maximum' + proportional: DtProportional + Parameters for proportional method + adaptive: DtAdaptive + Parameters for adaptive method + """ minimum: float maximum: float initial: float @@ -36,6 +86,17 @@ class TimeStepParams: @define class StopIters: + """Parameters for iteration stopping criteria. + + Attributes + ---------- + enabled: bool + Enable criterium if True + minimum: int + Minimum number of iterations + maximum: int + Maximum number of iterations + """ enabled: bool minimum: int maximum: int @@ -43,6 +104,17 @@ class StopIters: @define class StopTime: + """Parameters for time constraints stopping criteria. + + Attributes + ---------- + enabled: bool + Enable criterium if True + minimum: float + yr, model will certainly run to t > minimum + maximum: float + yr, model will terminate when t > maximum + """ enabled: bool minimum: float maximum: float @@ -50,18 +122,47 @@ class StopTime: @define class StopSolid: + """Parameters for solidification stopping criteria. + + Attributes + ---------- + enabled: bool + Enable criterium if True. + phi_crit: float + Non-dimensional, model will terminate when global melt fraction < phi_crit. + """ enabled: bool phi_crit: float @define class StopRadeqm: + """Parameters for radiative equilibrium stopping criteria. + + Attributes + ---------- + enabled: bool + Enable criterium if True + F_crit: float + W m-2, model will terminate when |F_atm| < F_crit + """ enabled: bool F_crit: float @define class StopSteady: + """Parameters for steady state stopping criteria. + + Attributes + ---------- + enabled: bool + Enable criterium if True + F_crit: float + Maximum absolute value of F_atm allowed for convergence + dprel: float + Percentage change in melt fraction over time (dp/p)/dt*100 + """ enabled: bool F_crit: float dprel: float @@ -69,12 +170,38 @@ class StopSteady: @define class StopEscape: + """Parameters for escape stopping criteria. + + Attributes + ---------- + enabled: bool + Enable criterium if True + mass_frac: float + Stop when atm_mass < this frac of initial mass + """ enabled: bool mass_frac: float @define class StopParams: + """Parameters for termination criteria. + + Attributes + ---------- + iters: StopIters + Parameters for required number of iterations. + time: StopTime + Parameters for required time constraints. + solid: StopSolid + Parameters for solidification. + radeqm: StopRadeqm + Parameters for radiative equilibrium. + steady: StopSteady + Parameters for steady state. + escape: StopEscape + Parameters for escape. + """ iters: StopIters time: StopTime solid: StopSolid @@ -85,7 +212,17 @@ class StopParams: @define class Params: - """Parameters for code execution, output files, time-stepping, convergence""" + """Parameters for code execution, output files, time-stepping, convergence. + + Attributes + ---------- + out: OutputParams + Parameters for data / logging output + dt: TimeStepParams + Parameters for time-stepping + stop: StopParams + Parameters for stopping criteria + """ out: OutputParams dt: TimeStepParams stop: StopParams From b5d479e912483d3bb26775182cece3b611d8d104 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 21 Oct 2024 15:12:46 +0200 Subject: [PATCH 05/13] Reorder classes --- src/proteus/config/_atmos_clim.py | 122 ++++++++++++------------- src/proteus/config/_config.py | 4 +- src/proteus/config/_delivery.py | 8 +- src/proteus/config/_escape.py | 42 ++++----- src/proteus/config/_interior.py | 52 +++++------ src/proteus/config/_outgas.py | 46 +++++----- src/proteus/config/_params.py | 145 +++++++++++++++--------------- src/proteus/config/_star.py | 30 +++---- 8 files changed, 227 insertions(+), 222 deletions(-) diff --git a/src/proteus/config/_atmos_clim.py b/src/proteus/config/_atmos_clim.py index a5c09196..f7060f00 100644 --- a/src/proteus/config/_atmos_clim.py +++ b/src/proteus/config/_atmos_clim.py @@ -5,6 +5,67 @@ from ._converters import none_if_none +@define +class AtmosClim: + """Atmosphere parameters, model selection. + + Attributes + ---------- + prevent_warming: bool + Do not allow the planet to heat up. + surface_d: float + M, conductive skin thickness. + surface_k: float + W m-1 K-1, conductive skin thermal conductivity. + cloud_enabled: bool + Enable water cloud radiative effects. + cloud_alpha: float + Condensate retention fraction (1 -> fully retained). + surf_state: str + Surface scheme: "mixed_layer", "fixed", "skin". + surf_albedo: float + Path to file ("string") or grey quantity (float). + albedo_pl: float + Bond albedo (scattering). + rayleigh: bool + Enable rayleigh scattering. + tmp_minimum: float + Temperature floor on solver. + tmp_maximum: float + Temperature ceiling on solver. + module: str + Which atmosphere module to use. + agni: Agni + Config parameters for Agni atmosphere module + janus: Janus + Config parameters for Janus atmosphere module + dummy: Dummy + Config parameters for dummy atmosphere module + """ + prevent_warming: bool + surface_d: float + surface_k: float + cloud_enabled: bool + cloud_alpha: float + surf_state: str = field(validator=validators.in_(('mixed_layer', 'fixed', 'skin'))) + surf_albedo: float + albedo_pl: float + rayleigh: bool + tmp_minimum: float + tmp_maximum: float + + module: str = field(validator=validators.in_(('dummy', 'agni', 'janus'))) + + agni: Agni + janus: Janus + dummy: Dummy + + @property + def surf_state_int(self) -> int: + """Return integer state for agni.""" + return ('mixed_layer', 'fixed', 'skin').index(self.surf_state) + + @define class Agni: """Agni atmosphere module. @@ -75,64 +136,3 @@ class Dummy: Atmosphere opacity between 0 and 1. """ gamma: float - - -@define -class AtmosClim: - """Atmosphere parameters, model selection. - - Attributes - ---------- - prevent_warming: bool - Do not allow the planet to heat up. - surface_d: float - M, conductive skin thickness. - surface_k: float - W m-1 K-1, conductive skin thermal conductivity. - cloud_enabled: bool - Enable water cloud radiative effects. - cloud_alpha: float - Condensate retention fraction (1 -> fully retained). - surf_state: str - Surface scheme: "mixed_layer", "fixed", "skin". - surf_albedo: float - Path to file ("string") or grey quantity (float). - albedo_pl: float - Bond albedo (scattering). - rayleigh: bool - Enable rayleigh scattering. - tmp_minimum: float - Temperature floor on solver. - tmp_maximum: float - Temperature ceiling on solver. - module: str - Which atmosphere module to use. - agni: Agni - Config parameters for Agni atmosphere module - janus: Janus - Config parameters for Janus atmosphere module - dummy: Dummy - Config parameters for dummy atmosphere module - """ - prevent_warming: bool - surface_d: float - surface_k: float - cloud_enabled: bool - cloud_alpha: float - surf_state: str = field(validator=validators.in_(('mixed_layer', 'fixed', 'skin'))) - surf_albedo: float - albedo_pl: float - rayleigh: bool - tmp_minimum: float - tmp_maximum: float - - module: str = field(validator=validators.in_(('dummy', 'agni', 'janus'))) - - agni: Agni - janus: Janus - dummy: Dummy - - @property - def surf_state_int(self) -> int: - """Return integer state for agni.""" - return ('mixed_layer', 'fixed', 'skin').index(self.surf_state) diff --git a/src/proteus/config/_config.py b/src/proteus/config/_config.py index 4409e70a..cdd3e96d 100644 --- a/src/proteus/config/_config.py +++ b/src/proteus/config/_config.py @@ -19,12 +19,14 @@ @define class Config: - """Root config. + """Root config parameters. Attributes ---------- version: str + Version of the configuration file. author: str + Authors of the configuration. params: Params Parameters for code execution, output files, time-stepping, convergence. star: Star diff --git a/src/proteus/config/_delivery.py b/src/proteus/config/_delivery.py index ee0b03f6..46c8fdc9 100644 --- a/src/proteus/config/_delivery.py +++ b/src/proteus/config/_delivery.py @@ -37,17 +37,17 @@ class Volatiles: CO2: float Partial pressure of CO2. N2: float - Partial pressure of N2. + Partial pressure of N2. S2: float - Partial pressure of S2. + Partial pressure of S2. SO2: float Partial pressure of SO2. H2: float - Partial pressure of H2. + Partial pressure of H2. CH4: float Partial pressure of CH4. CO: float - Partial pressure of CO. + Partial pressure of CO. """ H2O: float = field(default=0) CO2: float = field(default=0) diff --git a/src/proteus/config/_escape.py b/src/proteus/config/_escape.py index e9a94b53..6d3c0ec7 100644 --- a/src/proteus/config/_escape.py +++ b/src/proteus/config/_escape.py @@ -5,6 +5,27 @@ from ._converters import none_if_none +@define +class Escape: + """Escape parameters, model selection. + + Attributes + ---------- + module: str | None + Select module, choice None, 'dummy', 'zephyrus'. + zephyrus: Zephyrus + Parameters for zephyrus module. + dummy: EscapeDummy + Parameters for dummy module. + """ + module: str | None = field( + validator=validators.in_((None, 'dummy', 'zephyrus')), converter=none_if_none + ) + + zephyrus: Zephyrus + dummy: EscapeDummy + + @define class Zephyrus: """Parameters for Zephyrus module. @@ -27,24 +48,3 @@ class EscapeDummy: Bulk unfractionated escape rate [kg s-1] """ rate: float - - -@define -class Escape: - """Escape parameters, model selection. - - Attributes - ---------- - module: str | None - Select module, choice None, 'dummy', 'zephyrus'. - zephyrus: Zephyrus - Parameters for zephyrus module. - dummy: EscapeDummy - Parameters for dummy module. - """ - module: str | None = field( - validator=validators.in_((None, 'dummy', 'zephyrus')), converter=none_if_none - ) - - zephyrus: Zephyrus - dummy: EscapeDummy diff --git a/src/proteus/config/_interior.py b/src/proteus/config/_interior.py index 8675b8aa..93cc93d2 100644 --- a/src/proteus/config/_interior.py +++ b/src/proteus/config/_interior.py @@ -3,6 +3,32 @@ from attrs import define, field, validators +@define +class Interior: + """Magma ocean model selection and parameters. + + Attributes + ---------- + grain_size: float + Crystal settling grain size [m] + F_initial: float + Initial heat flux guess [W m-2] + module: str + Select interior model, choices: 'spider', 'aragog', 'dummy' + spider: Spider + Parameters for spider module + aragog: Aragog + Parameters for aragog module + """ + grain_size: float + F_initial: float + + module: str = field(validator=validators.in_(('spider', 'aragog', 'dummy'))) + + spider: Spider + aragog: Aragog + + @define class Spider: """Parameters for Spider module. @@ -43,29 +69,3 @@ class Aragog: Not used. """ some_parameter: str - - -@define -class Interior: - """Magma ocean model selection and parameters. - - Attributes - ---------- - grain_size: float - Crystal settling grain size [m] - F_initial: float - Initial heat flux guess [W m-2] - module: str - Select interior model, choices: 'spider', 'aragog', 'dummy' - spider: Spider - Parameters for spider module - aragog: Aragog - Parameters for aragog module - """ - grain_size: float - F_initial: float - - module: str = field(validator=validators.in_(('spider', 'aragog', 'dummy'))) - - spider: Spider - aragog: Aragog diff --git a/src/proteus/config/_outgas.py b/src/proteus/config/_outgas.py index d19a6fd8..a3087e24 100644 --- a/src/proteus/config/_outgas.py +++ b/src/proteus/config/_outgas.py @@ -3,6 +3,29 @@ from attrs import define, field, validators +@define +class Outgas: + """Outgassing parameters (fO2) and included volatiles. + + Attributes + ---------- + fO2_shift_IW: float + log10(ΔIW), atmosphere/interior boundary oxidation state. + module: str + Which outgassing module to use, choices: 'calliope', 'atmodeller'. + calliope: Calliope + Parameters for calliope module. + atmodeller: Atmodeller + Parameters for atmodeller module. + """ + fO2_shift_IW: float + + module: str = field(validator=validators.in_(('calliope', 'atmodeller'))) + + calliope: Calliope + atmodeller: Atmodeller + + @define class Calliope: """Module parameters for Calliope. @@ -46,26 +69,3 @@ class Atmodeller: Not used currently. """ some_parameter: str - - -@define -class Outgas: - """Outgassing parameters (fO2) and included volatiles. - - Attributes - ---------- - fO2_shift_IW: float - log10(ΔIW), atmosphere/interior boundary oxidation state. - module: str - Which outgassing module to use, choices: 'calliope', 'atmodeller'. - calliope: Calliope - Parameters for calliope module. - atmodeller: Atmodeller - Parameters for atmodeller module. - """ - fO2_shift_IW: float - - module: str = field(validator=validators.in_(('calliope', 'atmodeller'))) - - calliope: Calliope - atmodeller: Atmodeller diff --git a/src/proteus/config/_params.py b/src/proteus/config/_params.py index 7d2e366e..2558c82e 100644 --- a/src/proteus/config/_params.py +++ b/src/proteus/config/_params.py @@ -1,8 +1,29 @@ +"""This module describes the parameters for the data location, data output, and logging. +It also defines stopping criteria.""" + from __future__ import annotations from attrs import define, field, validators +@define +class Params: + """Parameters for code execution, output files, time-stepping, convergence. + + Attributes + ---------- + out: OutputParams + Parameters for data / logging output + dt: TimeStepParams + Parameters for time-stepping + stop: StopParams + Parameters for stopping criteria + """ + out: OutputParams + dt: TimeStepParams + stop: StopParams + + @define class OutputParams: """Parameters for output files and logging @@ -24,6 +45,39 @@ class OutputParams: plot_fmt: str = field(validator=validators.in_(('pdf', 'png'))) +@define +class TimeStepParams: + """Parameters for time-stepping parameters + + Attributes + ---------- + minimum: float + yr, minimum time-step + maximum: float + yr, maximum time-step + initial: float + yr, inital step size + starspec: float + yr, interval to re-calculate the stellar spectrum + starinst: float + yr, interval to re-calculate the instellation + method: str + Time-stepping method, choices: 'proportional', 'adaptive', 'maximum' + proportional: DtProportional + Parameters for proportional method + adaptive: DtAdaptive + Parameters for adaptive method + """ + minimum: float + maximum: float + initial: float + starspec: float + starinst: float + method: str = field(validator=validators.in_(('proportional', 'adaptive', 'maximum'))) + proportional: DtProportional + adaptive: DtAdaptive + + @define class DtProportional: """Parameters for proportional time-stepping @@ -52,36 +106,30 @@ class DtAdaptive: @define -class TimeStepParams: - """Parameters for time-stepping parameters +class StopParams: + """Parameters for termination criteria. Attributes ---------- - minimum: float - yr, minimum time-step - maximum: float - yr, maximum time-step - initial: float - yr, inital step size - starspec: float - yr, interval to re-calculate the stellar spectrum - starinst: float - yr, interval to re-calculate the instellation - method: str - Time-stepping method, choices: 'proportional', 'adaptive', 'maximum' - proportional: DtProportional - Parameters for proportional method - adaptive: DtAdaptive - Parameters for adaptive method + iters: StopIters + Parameters for required number of iterations. + time: StopTime + Parameters for required time constraints. + solid: StopSolid + Parameters for solidification. + radeqm: StopRadeqm + Parameters for radiative equilibrium. + steady: StopSteady + Parameters for steady state. + escape: StopEscape + Parameters for escape. """ - minimum: float - maximum: float - initial: float - starspec: float - starinst: float - method: str = field(validator=validators.in_(('proportional', 'adaptive', 'maximum'))) - proportional: DtProportional - adaptive: DtAdaptive + iters: StopIters + time: StopTime + solid: StopSolid + radeqm: StopRadeqm + steady: StopSteady + escape: StopEscape @define @@ -181,48 +229,3 @@ class StopEscape: """ enabled: bool mass_frac: float - - -@define -class StopParams: - """Parameters for termination criteria. - - Attributes - ---------- - iters: StopIters - Parameters for required number of iterations. - time: StopTime - Parameters for required time constraints. - solid: StopSolid - Parameters for solidification. - radeqm: StopRadeqm - Parameters for radiative equilibrium. - steady: StopSteady - Parameters for steady state. - escape: StopEscape - Parameters for escape. - """ - iters: StopIters - time: StopTime - solid: StopSolid - radeqm: StopRadeqm - steady: StopSteady - escape: StopEscape - - -@define -class Params: - """Parameters for code execution, output files, time-stepping, convergence. - - Attributes - ---------- - out: OutputParams - Parameters for data / logging output - dt: TimeStepParams - Parameters for time-stepping - stop: StopParams - Parameters for stopping criteria - """ - out: OutputParams - dt: TimeStepParams - stop: StopParams diff --git a/src/proteus/config/_star.py b/src/proteus/config/_star.py index 3419e435..b4038733 100644 --- a/src/proteus/config/_star.py +++ b/src/proteus/config/_star.py @@ -5,21 +5,6 @@ from ._converters import none_if_none -@define -class Mors: - """Module parameters for MORS module. - - Attributes - ---------- - tracks: str - Name of evolution tracks, choice: 'spada', 'baraffe' - spec: str - Path to stellar spectrum - """ - tracks: str = field(validator=validators.in_(('spada', 'baraffe'))) - spec: str - - @define class Star: """Stellar parameters, model selection. @@ -59,3 +44,18 @@ class Star: ) mors: Mors + + +@define +class Mors: + """Module parameters for MORS module. + + Attributes + ---------- + tracks: str + Name of evolution tracks, choice: 'spada', 'baraffe' + spec: str + Path to stellar spectrum + """ + tracks: str = field(validator=validators.in_(('spada', 'baraffe'))) + spec: str From 470ecfa8a19c1182e514a8e427a9cd62c3dbf8ea Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 21 Oct 2024 15:12:55 +0200 Subject: [PATCH 06/13] Update docs --- docs/config.md | 135 +++++++--- docs/config_old.md | 539 ++++++++++++++++++++++++++++++++++++++ docs/usage.md | 631 --------------------------------------------- mkdocs.yml | 6 +- 4 files changed, 641 insertions(+), 670 deletions(-) create mode 100644 docs/config_old.md diff --git a/docs/config.md b/docs/config.md index 638d4ba6..1d264e36 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1,37 +1,98 @@ -::: proteus.config.Config - - -::: proteus.config._atmos_clim.AtmosClim - - -::: proteus.config._atmos_clim.Agni - - -::: proteus.config._atmos_clim.Janus - - -::: proteus.config._atmos_clim.Dummy - - -::: proteus.config._delivery.Delivery - - -::: proteus.config._escape.Escape - - -::: proteus.config._interior.Interior - - -::: proteus.config._orbit.Orbit - - -::: proteus.config._outgas.Outgas - - -::: proteus.config._params.Params - - -::: proteus.config._star.Star - - -::: proteus.config._struct.Struct +## Configuration file + +PROTEUS accepts config files containing parameters in the format +`key = value`. All of the parameters required to run the model are +listed below with short explanations of their purpose and the values +they accept. Configuration files can contain blank lines. Comments are +indicated with a \# symbol. A lot of these parameters are not validated +by the code, so it will misbehave if unreasonable inputs are provided. +Not all of these parameters will be used, depending on the +configuration, but they must all be passed via the config file. + +::: proteus.config._config + options: + heading_level: 3 + show_root_heading: False + show_root_toc_entry: False + members_order: source + +## General parameters + +::: proteus.config._params + options: + heading_level: 3 + show_root_heading: False + show_root_toc_entry: False + members_order: source + +## Star + +::: proteus.config._star + options: + heading_level: 3 + show_root_heading: False + show_root_toc_entry: False + members_order: source + +## Planetary orbit + +::: proteus.config._orbit + options: + heading_level: 3 + show_root_heading: False + show_root_toc_entry: False + members_order: source + +## Planetary structure + +::: proteus.config._struct + options: + heading_level: 3 + show_root_heading: False + show_root_toc_entry: False + members_order: source + +## Planetary atmosphere + +::: proteus.config._atmos_clim + options: + heading_level: 3 + show_root_heading: False + show_root_toc_entry: False + members_order: source + +## Escape + +::: proteus.config._escape + options: + heading_level: 3 + show_root_heading: False + show_root_toc_entry: False + members_order: source + +## Magma ocean and planet interior + +::: proteus.config._interior + options: + heading_level: 3 + show_root_heading: False + show_root_toc_entry: False + members_order: source + +## Outgassing + +::: proteus.config._outgas + options: + heading_level: 3 + show_root_heading: False + show_root_toc_entry: False + members_order: source + +## Delivery + +::: proteus.config._delivery + options: + heading_level: 3 + show_root_heading: False + show_root_toc_entry: False + members_order: source diff --git a/docs/config_old.md b/docs/config_old.md new file mode 100644 index 00000000..b39247d2 --- /dev/null +++ b/docs/config_old.md @@ -0,0 +1,539 @@ +# Config (deprecated) + +These have been deprecated in favour of the [nested config](./config.md). + +## Model input parameters + +#### **star_model** + +Evolution model to use for star + +- Type: Integer +- Domain: 0: Spada, 1: Baraffe + +#### **star_rot_percentile** + +The percentile used to find rotation rate of star from a distribution when the Mors evolution model is selected. + +- Type: Float +- Domain: 0 to 100. + +#### **star_mass** + +Mass of the host star, in units of solar masses. + +- Type: Float +- Domain: Valid range depends on the stellar model used. For the Mors model, it should be between 0.1 and 1.25 solar masses. Values outside of the valid range will be clipped. + +#### **star_radius_modern** + +Assumed radius of the host star as observed today, in units of solar radii. + +- Type: Float +- Domain: Greater than zero. + +#### **star_luminosity_modern** + +Assumed luminosity of the host star as observed today, in units of solar luminosities. + +- Type: Float +- Domain: Greater than zero. + +#### **star_temperature_modern** + +Assumed temperature of the host star as observed today, in units of kelvin. + +- Type: Float +- Domain: Greater than zero. + +#### **star_age_modern** + +Estimated age of the host star as observed today, in units of years. + +- Type: Float +- Domain: Greater than zero. Values outside of the valid range will be clipped. + +#### **star_rot_pctle** + +Rotation rate percentile for the star, relative to other stars of the same mass. + +- Type: Float +- Domain: Between 0 and 100. + +#### **star_spectrum** + +The spectrum of the host star as observed today. These files may be obtained using the ``GetStellarSpectrum`` tool. + +- Type: String +- Domain: Path to file, measured relative to the FWL_DATA directory. + +#### **semimajoraxis** + +Semi major axis of the planet's orbit, in AU + +- Type: Float +- Domain: Greater than zero. + +#### **mass** + +Mass of the planet, in units of Earth mass. + +- Type: Float +- Domain: Greater than zero. + +#### **radius** + +Radius of the planet at the surface, in units of Earth radius. + +- Type: Float +- Domain: Greater than zero. + +#### **zenith_angle** + +Angle of the incoming stellar radiation relative to the zenith, in units of degrees. + +- Type: Float +- Domain: Positive values less than 90 degrees. + +#### **asf_scalefactor** + +Scale factor for the absorbed stellar flux (ASF), used in combination with ``zenith_angle``; see Cronin+14 for a discussion on this. + +- Type: Float +- Domain: Greater than zero. + +#### **albedo_s** + +Albedo of the surface of the planet. + +- Type: Float +- Domain: Between zero and unity, inclusive. + +#### **albedo_pl** + +Enforced bond albedo for the planet. Not physical. + +- Type: Float +- Domain: Between zero and unity, inclusive. + + +#### **eccentricity** + +Eccentricity of the planet's orbit. + +- Type: Float +- Domain: Greater than zero (inclusive), less than unity (exclusive). + + +#### **P_top** + +Pressure at the top of the atmosphere, in units of bar. + +- Type: Float +- Domain: Any reasonable positive value; 1e-5 works well. + +#### **dir_output** + +Name of the directory which will store the model output files. This includes data, plots, temporary files, and config information. + +- Type: String +- Domain: Name for a new folder to be created inside the ``output/`` folder. + +#### **time_star** + +Age of the star at the start of the simulation, in units of years. + +- Type: Float +- Domain: Greater than zero. Values outside of the valid range will be clipped. + +#### **time_target** + +Simulation time at which to stop the model, if it hasn't stopped already, in units of years. + +- Type: Float +- Domain: Greater than zero. + +#### **spectral_file** + +Spectral file to use when running SOCRATES. + +- Type: String +- Domain: Path to file measured relative to the FWL_DATA directory. + +#### **stellar_heating** + +Flag to toggle stellar heating, including the downward shortwave stream. + +- Type: Integer +- Domain: 0: disabled, 1: enabled + +#### **plot_iterfreq** + +Iteration frequency at which to make (or update) the plots. Plots can be generated during the simulation to follow its progress and status. + +- Type: Integer +- Domain: 0: Do not make plots until the simulation is complete. Values greater than 0: make plots every ``plot_iterfreq`` iterations. + +#### **sspec_dt_update** + +Time period at which to update the stellar spectrum using the stellar evolution model of choice, in units of years. + +- Type: Float +- Domain: Greater than or equal to zero. + +#### **sinst_dt_update** + +Period at which to update the instellation flux and the stellar radius using the stellar evolution model of choice, in units of years. + +- Type: Float +- Domain: Greater than or equal to zero. + +#### **dt_maximum** + +Maximum allowable time-step for the model, in units of years. + +- Type: Float +- Domain: Greater than zero. + +#### **dt_minimum** + +Minimum allowable time-step for the model once the start-up phase has completed. Units of years. + +- Type: Float +- Domain: Greater than zero. + +#### **dt_method** + +Method to be used for calculating the time-step once the start-up phase has completed. Units of years. 'Proportional' sets ``dt`` to be some small fraction of the simulation time. 'Adapative' dynamically adjusts ``dt`` according to how rapidly the upward energy fluxes are changing. 'Maximum' sets ``dt`` to always be equal to ``dt_maximum``. + +- Type: Integer +- Domain: 0: Proportional, 1: Adaptive, 2: Maximum. + +#### **dt_propconst** + +Proportionality constant when using ``dt_method=0``. Time step is set by ``dt = t/dt_propconst``, so larger values mean smaller steps. + +- Type: Float +- Domain: Greater than zero. + +#### **dt_atol** + +Absolute tolerance on change in flux and melt fraction for each iteration. + +- Type: Float +- Domain: Greater than zero. + +#### **dt_rtol** + +Relative tolerance on change in flux and melt fraction for each iteration. + +- Type: Float +- Domain: Greater than zero. + +#### **dt_initial** + +Intial step size when using ``dt_method=1``, years. + +- Type: Float +- Domain: Greater than zero. + +#### **F_atm_bc** + +Boundary condition to use for calculating `F_atm`. Can be set to either the top of the atmosphere or the bottom. + +- Type: Integer +- Domain: 0: Top of atmosphere, 1: Bottom of atmosphere. + +#### **F_crit** + +Critical flux. Once the upward net flux at the top of the atmosphere drops below this value, a smaller time-step is imposed. + +- Type: Float +- Domain: Greater than or equal to 0. Set to 0 to disable. + +#### **escape_model** + +Escape model to be used. + +- Type: Integer +- Domain: 0: None, 1: ZEPHYRUS, 2: Dummy + +#### **escape_stop** + +Stop the simulation when the atmosphere mass drops below this fraction of its initial mass. + +- Type: Float +- Domain: Values between zero and unity (exclusive). + +#### **escape_dummy_rate** + +Bulk escape rate for dummy escape model [kg s-1] + +- Type: Float +- Domain: Any reasonable positive value. + +#### **prevent_warming** + +Flag to ensure that the net upward energy flux is always positive, which prevents the star from causing net heating inside the planet. + +- Type: Integer +- Domain: 0: Disabled, 1: Enabled. + +#### **atmosphere_model** + +Atmosphere model used to set T(p) and T_surf. + +- Type: Integer +- Domain: 0: JANUS, 1: AGNI, 2: Dummy + +#### **atmosphere_surf_state** + +Surface boundary condition; e.g. T_surf set by conductive heat transport. + +- Type: Integer +- Domain: 0: Free, 1: Fixed, 2: Conductive. + +#### **skin_d``** + +Conductive skin thickness, parameterising a thin layer at the surface. + +- Type: Float +- Domain: Greater than zero, metres. + +#### **skin_k``** + +Conductive skin thermal conductivity. + +- Type: Float +- Domain: Greater than zero, [W m-1 K-1]. + +#### **atmosphere_nlev** + +Number of atmosphere model levels, measured at cell-centres. + +- Type: Integer +- Domain: Greater than 15. + +#### **solid_stop** + +Flag to toggle the solidification break condition. + +- Type: Integer +- Domain: 0: Disabled, 1: Enabled. + +#### **phi_crit** + +Value used for solidification break condition; stop the model once the global melt fraction drops below this value. This indiciates that the planet has solidified. Only applies when ``solid_stop`` is enabled. + +- Type: Float +- Domain: Values between zero and unity. + +#### **steady_stop** + +Flag to toggle the steady-state break condition. + +- Type: Integer +- Domain: 0: Disabled, 1: Enabled. + +#### **steady_flux** + +Steady-state break condition, requiring that ``F_atm < steady_flux``. + +- Type: Float +- Domain: Values between zero and unity. + +#### **steady_dprel** + +Steady-state break condition, requiring that ``dphi/dt < steady_dprel``. + +- Type: Float +- Domain: Values between zero and unity. + +#### **min_temperature** + +Temperature floor. The temperature of the atmosphere is prevented from dropping below this value. Units of kelvin. + +- Type: Float +- Domain: Greater than 0. + +#### **max_temperature** + +Temperature ceiling. The temperature of the atmosphere is prevented from reaching above this value. Units of kelvin. + +- Type: Float +- Domain: Greater than ``min_temperature``. + +#### **tropopause** + +Model of tropopause to be used before, or in the absence of, a time-stepped solution to the temperature structure. 'None' means no tropopause is applied. 'Skin' means that the tropopause will be set to the radiative skin temperature. 'Flux' dynamically sets the tropopause based on the heating rate. + +- Type: Integer +- Domain: 0: None, 1: Skin, 2: Flux. + +#### **water_cloud** + +Enable water cloud radiative effects. + +- Type: Integer +- Domain: 0: Disabled, 1: Enabled. + +#### **alpha_cloud** + +Condensate retention fraction. A value of 0 means full rainout. A value of 1 means full retention (cf. Li+2018). + +- Type: Float +- Domain: Between 0 and 1, inclusive. + +#### **rayleigh** + +Enable rayleigh scattering. + +- Type: Integer +- Domain: 0: Disabled, 1: Enabled. + +#### **atmosphere_chemistry** + +Type of atmospheric chemistry to apply at runtime. 'None' applies no chemistry. 'Equilibrium' uses FastChem. 'Kinetics' is not yet implemented. + +- Type: Integer +- Domain: 0: None, 1: Equilibrium, 2: Kinetics. + +#### **interior_model** + +The interior model to be used. + +- Type: Integer +- Domain: 0: SPIDER, 1: Aragog, 2: Dummy + +#### **interior_nlev** + +Number of levels used in the interior model + +- Type: Integer +- Domain: Greater than 40. + +#### **grain_size** + +Size of crystal grains considered within mushy interior regions, units of metres. + +- Type: Float +- Domain: Any reasonable value greater than zero (for example, 0.1 metres) + +#### **mixing_length** + +Mixing length parameterisation to use in SPIDER. Can be constant or variable with depth. + +- Type: Integer +- Domain: 1: Variable, 2: Constant. + +#### **solver_tolerance** + +Tolerance to provide to SPIDER when it calls its numerical solver. + +- Type: Float +- Domain: Greater than zero. + +#### **tsurf_poststep_change** + +Maximum allowed change in surface temperature calculated by SPIDER before it quits, to hand back to the other modules. Units of kelvin. + +- Type: Float +- Domain: Greater than zero. + +#### **tsurf_poststep_change_frac** + +Maximum allowed relative change in surface temperature calculated by SPIDER before it quits, to hand back to the other modules. + +- Type: Float +- Domain: Greater than zero. + +#### **planet_coresize** + +Size of the planet's core as a fraction of its total interior radius. + +- Type: Float +- Domain: Between zero and unity, exclusive. + +#### **ic_adiabat_entropy** + +Entropy at the surface for intialising a SPIDER at the start of the run, in units of [J kg-1 K-1]. + +- Type: Float +- Domain: Greater than zero. + +#### **ic_dsdr** + +Entropy gradient for intialising a SPIDER at the start of the run, in units of [J kg-1 K-1 m-1]. + +- Type: Float +- Domain: Less than zero. + +#### **F_atm** + +Initial guess for net upward flux `F_atm`. + +- Type: Float +- Domain: Greater than zero. + +#### **fO2_shift_IW** + +Oxygen fugacity of the interior, measured in log10 units relative to the iron-wustite buffer. Positive values are oxidising, negative are reducing. + +- Type: Float +- Domain: Any reasonable real value. + +#### **solvevol_use_params** + +Flag to enable solving for initial partial pressures subject to interior parameters, rather than using provided initial pressures. + +- Type: Integer +- Domain: 0: Disabled, 1: Enabled. + +#### **Phi_global** + +Initial guess for mantle melt fraction. + +- Type: Float +- Domain: Between 0 and 1, inclusive. + +#### **CH_ratio** + +Required total-planet C/H mass ratio. Used when ``solvevol_use_params == 1``. + +- Type: Float +- Domain: Greater than zero. + +#### **hydrogen_earth_oceans** + +Total hydrogen inventory of the planet. Used when when ``solvevol_use_params == 1``. Units of Earth oceans equivalent. + +- Type: Float +- Domain: Greater than zero. + +#### **nitrogen_ppmw** + +Nitrogen concentration. Used when ``solvevol_use_params == 1``. Parts per million of total mantle mass. + +- Type: Float +- Domain: Greater than zero. + +#### **sulfur_ppmw** + +Sulfur concentration. Used when ``solvevol_use_params == 1``. Parts per million of total mantle mass. + +- Type: Float +- Domain: Greater than zero. + +#### **X_included** + +Flag to include X in the model. For some (H2O, CO2, N2, S2) this will always equal 1. + +- Type: Integer +- Domain: 0: Excluded, 1: Included. + +#### **X_initial_bar** + +Initial partial pressure of X. Used when ``solvepp_enabled == 0``. + +- Type: Float +- Domain: Greater than zero. diff --git a/docs/usage.md b/docs/usage.md index 473bc07d..73b9ed8f 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -28,634 +28,3 @@ safely. Proteus has a command-line interface that can be accessed by running `proteus` on the command line. Try `proteus --help` to see the available commands! - -## Configuration file - -PROTEUS accepts config files containing parameters in the format -`key = value`. All of the parameters required to run the model are -listed below with short explanations of their purpose and the values -they accept. Configuration files can contain blank lines. Comments are -indicated with a \# symbol. A lot of these parameters are not validated -by the code, so it will misbehave if unreasonable inputs are provided. -Not all of these parameters will be used, depending on the -configuration, but they must all be passed via the config file. - -### Model input parameters - -#### **star_model** - -Evolution model to use for star - -- Deprecated: False -- Type: Integer -- Domain: 0: Spada, 1: Baraffe - -#### **star_rot_percentile** - -The percentile used to find rotation rate of star from a distribution when the Mors evolution model is selected. - -- Deprecated: False -- Type: Float -- Domain: 0 to 100. - -#### **star_mass** - -Mass of the host star, in units of solar masses. - -- Deprecated: False -- Type: Float -- Domain: Valid range depends on the stellar model used. For the Mors model, it should be between 0.1 and 1.25 solar masses. Values outside of the valid range will be clipped. - -#### **star_radius_modern** - -Assumed radius of the host star as observed today, in units of solar radii. - -- Deprecated: False -- Type: Float -- Domain: Greater than zero. - -#### **star_luminosity_modern** - -Assumed luminosity of the host star as observed today, in units of solar luminosities. - -- Deprecated: False -- Type: Float -- Domain: Greater than zero. - -#### **star_temperature_modern** - -Assumed temperature of the host star as observed today, in units of kelvin. - -- Deprecated: False -- Type: Float -- Domain: Greater than zero. - -#### **star_age_modern** - -Estimated age of the host star as observed today, in units of years. - -- Deprecated: False -- Type: Float -- Domain: Greater than zero. Values outside of the valid range will be clipped. - -#### **star_rot_pctle** - -Rotation rate percentile for the star, relative to other stars of the same mass. - -- Deprecated: False -- Type: Float -- Domain: Between 0 and 100. - -#### **star_spectrum** - -The spectrum of the host star as observed today. These files may be obtained using the ``GetStellarSpectrum`` tool. - -- Deprecated: False -- Type: String -- Domain: Path to file, measured relative to the FWL_DATA directory. - -#### **semimajoraxis** - -Semi major axis of the planet's orbit, in AU - -- Deprecated: False -- Type: Float -- Domain: Greater than zero. - -#### **mass** - -Mass of the planet, in units of Earth mass. - -- Deprecated: False -- Type: Float -- Domain: Greater than zero. - -#### **radius** - -Radius of the planet at the surface, in units of Earth radius. - -- Deprecated: False -- Type: Float -- Domain: Greater than zero. - -#### **zenith_angle** - -Angle of the incoming stellar radiation relative to the zenith, in units of degrees. - -- Deprecated: False -- Type: Float -- Domain: Positive values less than 90 degrees. - -#### **asf_scalefactor** - -Scale factor for the absorbed stellar flux (ASF), used in combination with ``zenith_angle``; see Cronin+14 for a discussion on this. - -- Deprecated: False -- Type: Float -- Domain: Greater than zero. - -#### **albedo_s** - -Albedo of the surface of the planet. - -- Deprecated: False -- Type: Float -- Domain: Between zero and unity, inclusive. - -#### **albedo_pl** - -Enforced bond albedo for the planet. Not physical. - -- Deprecated: False -- Type: Float -- Domain: Between zero and unity, inclusive. - - -#### **eccentricity** - -Eccentricity of the planet's orbit. - -- Deprecated: False -- Type: Float -- Domain: Greater than zero (inclusive), less than unity (exclusive). - - -#### **P_top** - -Pressure at the top of the atmosphere, in units of bar. - -- Deprecated: False -- Type: Float -- Domain: Any reasonable positive value; 1e-5 works well. - -#### **dir_output** - -Name of the directory which will store the model output files. This includes data, plots, temporary files, and config information. - -- Deprecated: False -- Type: String -- Domain: Name for a new folder to be created inside the ``output/`` folder. - -#### **time_star** - -Age of the star at the start of the simulation, in units of years. - -- Deprecated: False -- Type: Float -- Domain: Greater than zero. Values outside of the valid range will be clipped. - -#### **time_target** - -Simulation time at which to stop the model, if it hasn't stopped already, in units of years. - -- Deprecated: False -- Type: Float -- Domain: Greater than zero. - -#### **spectral_file** - -Spectral file to use when running SOCRATES. - -- Deprecated: False -- Type: String -- Domain: Path to file measured relative to the FWL_DATA directory. - -#### **stellar_heating** - -Flag to toggle stellar heating, including the downward shortwave stream. - -- Deprecated: False -- Type: Integer -- Domain: 0: disabled, 1: enabled - -#### **plot_iterfreq** - -Iteration frequency at which to make (or update) the plots. Plots can be generated during the simulation to follow its progress and status. - -- Deprecated: False -- Type: Integer -- Domain: 0: Do not make plots until the simulation is complete. Values greater than 0: make plots every ``plot_iterfreq`` iterations. - -#### **sspec_dt_update** - -Time period at which to update the stellar spectrum using the stellar evolution model of choice, in units of years. - -- Deprecated: False -- Type: Float -- Domain: Greater than or equal to zero. - -#### **sinst_dt_update** - -Period at which to update the instellation flux and the stellar radius using the stellar evolution model of choice, in units of years. - -- Deprecated: False -- Type: Float -- Domain: Greater than or equal to zero. - -#### **dt_maximum** - -Maximum allowable time-step for the model, in units of years. - -- Deprecated: False -- Type: Float -- Domain: Greater than zero. - -#### **dt_minimum** - -Minimum allowable time-step for the model once the start-up phase has completed. Units of years. - -- Deprecated: False -- Type: Float -- Domain: Greater than zero. - -#### **dt_method** - -Method to be used for calculating the time-step once the start-up phase has completed. Units of years. 'Proportional' sets ``dt`` to be some small fraction of the simulation time. 'Adapative' dynamically adjusts ``dt`` according to how rapidly the upward energy fluxes are changing. 'Maximum' sets ``dt`` to always be equal to ``dt_maximum``. - -- Deprecated: False -- Type: Integer -- Domain: 0: Proportional, 1: Adaptive, 2: Maximum. - -#### **dt_propconst** - -Proportionality constant when using ``dt_method=0``. Time step is set by ``dt = t/dt_propconst``, so larger values mean smaller steps. - -- Deprecated: False -- Type: Float -- Domain: Greater than zero. - -#### **dt_atol** - -Absolute tolerance on change in flux and melt fraction for each iteration. - -- Deprecated: False -- Type: Float -- Domain: Greater than zero. - -#### **dt_rtol** - -Relative tolerance on change in flux and melt fraction for each iteration. - -- Deprecated: False -- Type: Float -- Domain: Greater than zero. - -#### **dt_initial** - -Intial step size when using ``dt_method=1``, years. - -- Deprecated: False -- Type: Float -- Domain: Greater than zero. - -#### **shallow_ocean_layer** - -Legacy method for converging atmospheric and interior upward fluxes. - -- Deprecated: True -- Type: Integer -- Domain: 0: Off, 1: On - -#### **F_atm_bc** - -Boundary condition to use for calculating `F_atm`. Can be set to either the top of the atmosphere or the bottom. - -- Deprecated: False -- Type: Integer -- Domain: 0: Top of atmosphere, 1: Bottom of atmosphere. - -#### **F_crit** - -Critical flux. Once the upward net flux at the top of the atmosphere drops below this value, a smaller time-step is imposed. - -- Deprecated: False -- Type: Float -- Domain: Greater than or equal to 0. Set to 0 to disable. - -#### **escape_model** - -Escape model to be used. - -- Deprecated: False -- Type: Integer -- Domain: 0: None, 1: ZEPHYRUS, 2: Dummy - -#### **escape_stop** - -Stop the simulation when the atmosphere mass drops below this fraction of its initial mass. - -- Deprecated: False -- Type: Float -- Domain: Values between zero and unity (exclusive). - -#### **escape_dummy_rate** - -Bulk escape rate for dummy escape model [kg s-1] - -- Deprecated: False -- Type: Float -- Domain: Any reasonable positive value. - -#### **prevent_warming** - -Flag to ensure that the net upward energy flux is always positive, which prevents the star from causing net heating inside the planet. - -- Deprecated: False -- Type: Integer -- Domain: 0: Disabled, 1: Enabled. - -#### **atmosphere_model** - -Atmosphere model used to set T(p) and T_surf. - -- Deprecated: False -- Type: Integer -- Domain: 0: JANUS, 1: AGNI, 2: Dummy - -#### **atmosphere_surf_state** - -Surface boundary condition; e.g. T_surf set by conductive heat transport. - -- Deprecated: False -- Type: Integer -- Domain: 0: Free, 1: Fixed, 2: Conductive. - -#### **skin_d``** - -Conductive skin thickness, parameterising a thin layer at the surface. - -- Deprecated: False -- Type: Float -- Domain: Greater than zero, metres. - -#### **skin_k``** - -Conductive skin thermal conductivity. - -- Deprecated: False -- Type: Float -- Domain: Greater than zero, [W m-1 K-1]. - -#### **atmosphere_nlev** - -Number of atmosphere model levels, measured at cell-centres. - -- Deprecated: False -- Type: Integer -- Domain: Greater than 15. - -#### **solid_stop** - -Flag to toggle the solidification break condition. - -- Deprecated: False -- Type: Integer -- Domain: 0: Disabled, 1: Enabled. - -#### **phi_crit** - -Value used for solidification break condition; stop the model once the global melt fraction drops below this value. This indiciates that the planet has solidified. Only applies when ``solid_stop`` is enabled. - -- Deprecated: False -- Type: Float -- Domain: Values between zero and unity. - -#### **steady_stop** - -Flag to toggle the steady-state break condition. - -- Deprecated: False -- Type: Integer -- Domain: 0: Disabled, 1: Enabled. - -#### **steady_flux** - -Steady-state break condition, requiring that ``F_atm < steady_flux``. - -- Deprecated: False -- Type: Float -- Domain: Values between zero and unity. - -#### **steady_dprel** - -Steady-state break condition, requiring that ``dphi/dt < steady_dprel``. - -- Deprecated: False -- Type: Float -- Domain: Values between zero and unity. - -#### **min_temperature** - -Temperature floor. The temperature of the atmosphere is prevented from dropping below this value. Units of kelvin. - -- Deprecated: False -- Type: Float -- Domain: Greater than 0. - -#### **max_temperature** - -Temperature ceiling. The temperature of the atmosphere is prevented from reaching above this value. Units of kelvin. - -- Deprecated: False -- Type: Float -- Domain: Greater than ``min_temperature``. - -#### **tropopause** - -Model of tropopause to be used before, or in the absence of, a time-stepped solution to the temperature structure. 'None' means no tropopause is applied. 'Skin' means that the tropopause will be set to the radiative skin temperature. 'Flux' dynamically sets the tropopause based on the heating rate. - -- Deprecated: False -- Type: Integer -- Domain: 0: None, 1: Skin, 2: Flux. - -#### **water_cloud** - -Enable water cloud radiative effects. - -- Deprecated: False -- Type: Integer -- Domain: 0: Disabled, 1: Enabled. - -#### **alpha_cloud** - -Condensate retention fraction. A value of 0 means full rainout. A value of 1 means full retention (cf. Li+2018). - -- Deprecated: False -- Type: Float -- Domain: Between 0 and 1, inclusive. - -#### **rayleigh** - -Enable rayleigh scattering. - -- Deprecated: False -- Type: Integer -- Domain: 0: Disabled, 1: Enabled. - -#### **atmosphere_chemistry** - -Type of atmospheric chemistry to apply at runtime. 'None' applies no chemistry. 'Equilibrium' uses FastChem. 'Kinetics' is not yet implemented. - -- Deprecated: False -- Type: Integer -- Domain: 0: None, 1: Equilibrium, 2: Kinetics. - -#### **interior_model** - -The interior model to be used. - -- Deprecated: False -- Type: Integer -- Domain: 0: SPIDER, 1: Aragog, 2: Dummy - -#### **interior_nlev** - -Number of levels used in the interior model - -- Deprecated: False -- Type: Integer -- Domain: Greater than 40. - -#### **grain_size** - -Size of crystal grains considered within mushy interior regions, units of metres. - -- Deprecated: False -- Type: Float -- Domain: Any reasonable value greater than zero (for example, 0.1 metres) - -#### **mixing_length** - -Mixing length parameterisation to use in SPIDER. Can be constant or variable with depth. - -- Deprecated: False -- Type: Integer -- Domain: 1: Variable, 2: Constant. - -#### **solver_tolerance** - -Tolerance to provide to SPIDER when it calls its numerical solver. - -- Deprecated: False -- Type: Float -- Domain: Greater than zero. - -#### **tsurf_poststep_change** - -Maximum allowed change in surface temperature calculated by SPIDER before it quits, to hand back to the other modules. Units of kelvin. - -- Deprecated: False -- Type: Float -- Domain: Greater than zero. - -#### **tsurf_poststep_change_frac** - -Maximum allowed relative change in surface temperature calculated by SPIDER before it quits, to hand back to the other modules. - -- Deprecated: False -- Type: Float -- Domain: Greater than zero. - -#### **planet_coresize** - -Size of the planet's core as a fraction of its total interior radius. - -- Deprecated: False -- Type: Float -- Domain: Between zero and unity, exclusive. - -#### **ic_adiabat_entropy** - -Entropy at the surface for intialising a SPIDER at the start of the run, in units of [J kg-1 K-1]. - -- Deprecated: False -- Type: Float -- Domain: Greater than zero. - -#### **ic_dsdr** - -Entropy gradient for intialising a SPIDER at the start of the run, in units of [J kg-1 K-1 m-1]. - -- Deprecated: False -- Type: Float -- Domain: Less than zero. - -#### **F_atm** - -Initial guess for net upward flux `F_atm`. - -- Deprecated: False -- Type: Float -- Domain: Greater than zero. - -#### **fO2_shift_IW** - -Oxygen fugacity of the interior, measured in log10 units relative to the iron-wustite buffer. Positive values are oxidising, negative are reducing. - -- Deprecated: False -- Type: Float -- Domain: Any reasonable real value. - -#### **solvevol_use_params** - -Flag to enable solving for initial partial pressures subject to interior parameters, rather than using provided initial pressures. - -- Deprecated: False -- Type: Integer -- Domain: 0: Disabled, 1: Enabled. - -#### **Phi_global** - -Initial guess for mantle melt fraction. - -- Deprecated: False -- Type: Float -- Domain: Between 0 and 1, inclusive. - -#### **CH_ratio** - -Required total-planet C/H mass ratio. Used when ``solvevol_use_params == 1``. - -- Deprecated: False -- Type: Float -- Domain: Greater than zero. - -#### **hydrogen_earth_oceans** - -Total hydrogen inventory of the planet. Used when when ``solvevol_use_params == 1``. Units of Earth oceans equivalent. - -- Deprecated: False -- Type: Float -- Domain: Greater than zero. - -#### **nitrogen_ppmw** - -Nitrogen concentration. Used when ``solvevol_use_params == 1``. Parts per million of total mantle mass. - -- Deprecated: False -- Type: Float -- Domain: Greater than zero. - -#### **sulfur_ppmw** - -Sulfur concentration. Used when ``solvevol_use_params == 1``. Parts per million of total mantle mass. - -- Deprecated: False -- Type: Float -- Domain: Greater than zero. - -#### **X_included** - -Flag to include X in the model. For some (H2O, CO2, N2, S2) this will always equal 1. - -- Deprecated: False -- Type: Integer -- Domain: 0: Excluded, 1: Included. - -#### **X_initial_bar** - -Initial partial pressure of X. Used when ``solvepp_enabled == 0``. - -- Deprecated: False -- Type: Float -- Domain: Greater than zero. diff --git a/mkdocs.yml b/mkdocs.yml index 39f41704..7a055110 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -8,6 +8,7 @@ nav: - Installation: installation.md - Usage: usage.md - Config: config.md + - config_old.md - Troubleshooting: troubleshooting.md - MORS: https://fwl-proteus.readthedocs.io/projects/mors/ - JANUS: https://fwl-proteus.readthedocs.io/projects/janus/ @@ -58,10 +59,11 @@ plugins: ignore_init_summary: yes show_submodules: no show_source: true + show_symbol_type_heading: True show_root_heading: true - shol_root_toc_entry: true + show_root_toc_entry: true show_docstring_attributes: true - show_root_full_path: true + show_root_full_path: false docstring_section_style: list members_order: alphabetical merge_init_into_class: yes From c6eb46c85be7ef3d93e364bbe91869edf65b09cf Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 21 Oct 2024 15:33:58 +0200 Subject: [PATCH 07/13] Add docs on how to add a new variable Add info on how to add parameters to the config --- docs/config.md | 51 ++++++++++++++++++++++++++++++++++++++++++++++---- mkdocs.yml | 1 + 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/docs/config.md b/docs/config.md index 1d264e36..51cc3079 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1,14 +1,57 @@ -## Configuration file +# Configuration file PROTEUS accepts config files containing parameters in the format -`key = value`. All of the parameters required to run the model are +`key = value`. Proteus uses [toml](https://toml.io/en/) as the filetype for configuration. + +All of the parameters required to run the model are listed below with short explanations of their purpose and the values they accept. Configuration files can contain blank lines. Comments are -indicated with a \# symbol. A lot of these parameters are not validated -by the code, so it will misbehave if unreasonable inputs are provided. +indicated with a `#` symbol. + Not all of these parameters will be used, depending on the configuration, but they must all be passed via the config file. +## Adding a new parameter + +So, you are developing a new model and want to add some parameters? +Follow these steps: + +1. Decide on a good parameter name (*e.g.* `my_star_var`), and under which section to place it (*e.g.* `star`). + Add the new variable to the [config submodule](https://github.com/FormingWorlds/PROTEUS/tree/main/src/proteus/config/_star.py). +2. Add the type for your variable, *e.g.* [float][], [int][], [str][]. + You can also add complex types, please check the [code](https://github.com/FormingWorlds/PROTEUS/tree/main/src/proteus/config) for inspiration. +3. Add a [validator](https://www.attrs.org/en/stable/api.html#module-attrs.validators)! + If your variable has a maximum value (*e.g.* 10), you can add a validator to make sure + that any values above 10 are rejected: `my_star_var: float = field(validator=attrs.validators.le(10))` +4. Add a description for your new variable under `Attributes` in the docstring. + The documentation uses the description to generate this documentation. +5. Update the example [input configs](https://github.com/FormingWorlds/PROTEUS/tree/main/input). + Proteus checks tests all input configs in this directory are valid. +6. Use your parameter in your code, *i.e.*: `config.star.my_star_var` + +```python title="src/proteus/config/_star.py" +class Star: + """Stellar parameters. + + Attributes + ---------- + my_star_var: float + Star variable, must be 10 or lower! + """ + my_star_var: float = field(validator=attrs.validators.le(10)) +``` + +Proteus uses [attrs](https://www.attrs.org) for its +parameter handling. Please see the [examples](https://www.attrs.org/en/stable/examples.html) +for more information how to work with attrs. + +### Examples + +Have a look at the [input configs](https://github.com/FormingWorlds/PROTEUS/tree/main/input) +for ideas of how to set up your config in practice. + +## Root config + ::: proteus.config._config options: heading_level: 3 diff --git a/mkdocs.yml b/mkdocs.yml index 7a055110..683b23df 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -49,6 +49,7 @@ plugins: paths: [src] import: - https://installer.readthedocs.io/en/stable/objects.inv + - https://docs.python.org/3/objects.inv - https://numpy.org/doc/stable/objects.inv - https://docs.scipy.org/doc/scipy/objects.inv - https://pandas.pydata.org/docs/objects.inv From 460ab99d901a421f193bf6b4c5148869958a0e15 Mon Sep 17 00:00:00 2001 From: Harrison Nicholls Date: Mon, 21 Oct 2024 17:11:13 +0100 Subject: [PATCH 08/13] Configuration doctstrings and star page --- README.md | 2 - docs/config.md | 8 +-- docs/data.md | 92 +++++++++++++++++++++++++++++++ mkdocs.yml | 5 +- src/proteus/config/_atmos_clim.py | 8 +-- src/proteus/config/_config.py | 14 ++--- src/proteus/config/_delivery.py | 32 +++++------ src/proteus/config/_escape.py | 4 +- src/proteus/config/_interior.py | 26 ++++----- src/proteus/config/_orbit.py | 10 ++-- src/proteus/config/_outgas.py | 22 ++++---- src/proteus/config/_params.py | 86 ++++++++++++++--------------- src/proteus/config/_star.py | 20 +++---- 13 files changed, 210 insertions(+), 119 deletions(-) create mode 100644 docs/data.md diff --git a/README.md b/README.md index 3ef3913a..cec3e748 100644 --- a/README.md +++ b/README.md @@ -42,13 +42,11 @@ Hamish Innes | hamish.innes[at]fu-berlin.de | | Object | Description | | - | - | -| `start_proteus.py` | Main PROTEUS Python script | | `README.md` | Overview file | | `pyproject.toml` | Project configuration file | | `CODE_OF_CONDUCT.md` | Project code of conduct | | `LICENSE.txt` | Project license | | `src/proteus` | Source code for PROTEUS | -| `SPIDER/` | Submodule SPIDER | | `output/` | Output folder with subfolders for each model run | | `input/` | Input folder (e.g. stellar spectra, example configs) | | `docs/` | Documentation source files | diff --git a/docs/config.md b/docs/config.md index 51cc3079..069577f6 100644 --- a/docs/config.md +++ b/docs/config.md @@ -77,7 +77,7 @@ for ideas of how to set up your config in practice. show_root_toc_entry: False members_order: source -## Planetary orbit +## Star system and planetary orbit ::: proteus.config._orbit options: @@ -95,7 +95,7 @@ for ideas of how to set up your config in practice. show_root_toc_entry: False members_order: source -## Planetary atmosphere +## Atmosphere climate ::: proteus.config._atmos_clim options: @@ -104,7 +104,7 @@ for ideas of how to set up your config in practice. show_root_toc_entry: False members_order: source -## Escape +## Atmospheric escape ::: proteus.config._escape options: @@ -113,7 +113,7 @@ for ideas of how to set up your config in practice. show_root_toc_entry: False members_order: source -## Magma ocean and planet interior +## Magma ocean / mantle ::: proteus.config._interior options: diff --git a/docs/data.md b/docs/data.md new file mode 100644 index 00000000..13f7319f --- /dev/null +++ b/docs/data.md @@ -0,0 +1,92 @@ +# Reference data + +## Stars +* Epsilon Eridani + * file: `eps-eri.txt` + * url: https://en.wikipedia.org/wiki/Epsilon_Eridani + * type: K2V + * Teff: 5049 K + * age: 400-800 Myr + * Lum: 0.32 solar + * M: 0.82 solar + * R: 0.738 solar + +* GJ 1132 + * file: `gj1132.txt` + * url: https://en.wikipedia.org/wiki/GJ_1132 + * type: M4 + * Teff: 3196 K + * age: ? + * Lum: 0.00436 solar + * M: 0.194 solar + * R: 0.215 solar + +GJ 1214 + * file: `gj1214.txt` + * url: https://en.wikipedia.org/wiki/GJ_1214 + * type: M4.5 + * Teff: 3111 K + * age: 5-10 Gyr + * Lum: 0.00351 solar + * M: 0.181 solar + * R: 0.204 solar + +HD 85512 + * file: `hd85512.txt` + * url: https://en.wikipedia.org/wiki/HD_85512 + * type: K6V + * Teff: 4404 K + * age: 5.61 Gyr + * Lum: 0.126 solar + * M: 0.69 solar + * R: 0.533 solar + +HD 97658 + * file: `hd97658.txt` + * url: https://en.wikipedia.org/wiki/HD_97658 + * type: K1V + * Teff: 5212 K + * age: 3.9 Gyr + * Lum: 0.351 solar + * M: 0.773 solar + * R: 0.728 solar + +L 98-59 + * file: `l-98-59.txt` + * url: https://en.wikipedia.org/wiki/L_98-59 + * type: M3V + * Teff: 3415 K + * age: >800 Myr + * Lum: 0.01128 solar + * M: 0.273 solar + * R: 0.303 solar + +The Sun + * file: `sun.txt` + * url: https://en.wikipedia.org/wiki/Sun + * type: G2V + * Teff: 5772 K + * age: 4.6 Gyr + * Lum: 1.0 solar + * M: 1.0 solar + * R: 1.0 solar + +TRAPPIST-1 + * file: `trappist-1.txt` + * url: https://en.wikipedia.org/wiki/TRAPPIST-1 + * type: M8V + * Teff: 2566 K + * age: 7.6 Gyr + * Lum: 0.000553 solar + * M: 0.0898 solar + * R: 0.1192 solar + +GJ 846 + * file: `gj849.txt` + * url: https://en.wikipedia.org/wiki/Gliese_849 + * type: M3.5V + * Teff: 3467 K + * age: >3 Gyr + * Lum: 0.02887 solar + * M: 0.465 solar + * R: 0.464 solar diff --git a/mkdocs.yml b/mkdocs.yml index 683b23df..6d28c2c4 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -10,13 +10,14 @@ nav: - Config: config.md - config_old.md - Troubleshooting: troubleshooting.md - - MORS: https://fwl-proteus.readthedocs.io/projects/mors/ - - JANUS: https://fwl-proteus.readthedocs.io/projects/janus/ - Contact: contact.md - Contributing: CONTRIBUTING.md - Code of Conduct: CODE_OF_CONDUCT.md - 🔗 Source code: https://github.com/FormingWorlds/PROTEUS - 🔗 Issues: https://github.com/FormingWorlds/PROTEUS/issues + - 🔗 MORS: https://fwl-proteus.readthedocs.io/projects/mors/ + - 🔗 JANUS: https://fwl-proteus.readthedocs.io/projects/janus/ + - 🔗 AGNI: https://nichollsh.github.io/AGNI/dev/ theme: name: material diff --git a/src/proteus/config/_atmos_clim.py b/src/proteus/config/_atmos_clim.py index f7060f00..c7a90dd9 100644 --- a/src/proteus/config/_atmos_clim.py +++ b/src/proteus/config/_atmos_clim.py @@ -73,15 +73,15 @@ class Agni: Attributes ---------- p_top: float - Bar, top of atmosphere grid pressure. + Top of atmosphere grid pressure [bar]. spectral_group: str - Which gas opacities to include. + Spectral file codename defining the gas opacities to be included. spectral_bands: str - Number of spectral bands? + Number of wavenumer bands in k-table. num_levels: str Number of atmospheric grid levels. chemistry: str | None - Choices: None, "eq", "kin" + Treatment of self-consistent atmospheric chemsitry. Must be one of: "none", "eq", "kin" """ p_top: float spectral_group: str diff --git a/src/proteus/config/_config.py b/src/proteus/config/_config.py index cdd3e96d..47e2c1f7 100644 --- a/src/proteus/config/_config.py +++ b/src/proteus/config/_config.py @@ -26,23 +26,23 @@ class Config: version: str Version of the configuration file. author: str - Authors of the configuration. + Authors of the configuration file. params: Params Parameters for code execution, output files, time-stepping, convergence. star: Star Stellar parameters, model selection. orbit: Orbit - Planetary orbital parameters. + Orbital and star-system parameters. struct: Struct - Planetary structure (mass, radius). + Planetary structure calculation (mass, radius). atmos_clim: AtmosClim - Atmosphere parameters, model selection. + Planetary atmosphere parameters, model selection. escape: Escape - Escape parameters, model selection. + Atmospheric escape parameters, model selection. interior: Interior - Magma ocean model selection and parameters. + Magma ocean / mantle model parameters, model selection. outgas: Outgas - Outgassing parameters (fO2) and included volatiles. + Outgassing parameters (fO2, etc) and included volatiles. delivery: Delivery Initial volatile inventory, and delivery model selection. """ diff --git a/src/proteus/config/_delivery.py b/src/proteus/config/_delivery.py index 46c8fdc9..b8208c04 100644 --- a/src/proteus/config/_delivery.py +++ b/src/proteus/config/_delivery.py @@ -12,13 +12,13 @@ class Elements: Attributes ---------- CH_ratio: float - C/H ratio in mantle/atmosphere system. + Volatile C/H nass ratio in combined mantle+atmosphere system. H_oceans: float - Hydrogen inventory in units of equivalent Earth oceans, by mass. + Bulk hydrogen inventory in units of equivalent Earth oceans. N_ppmw: float - Nitrogen inventory in ppmw relative to mantle mass, by mass. + Bulk nitrogen inventory in ppmw relative to mantle mass. S_ppmw: float - Sulfur inventory in ppmw relative to mass of melt. + Bulk sulfur inventory in ppmw relative to mantle mass. """ CH_ratio: float H_oceans: float @@ -28,26 +28,26 @@ class Elements: @define class Volatiles: - """Initial volatile inventory by partial pressures in atmosphere. + """Initial volatile inventory set by partial pressures in atmosphere. Attributes ---------- H2O: float - Partial pressure of H2O. + Initial atmospheric partial surface pressure of H2O [bar]. CO2: float - Partial pressure of CO2. + Initial atmospheric partial surface pressure of CO2 [bar]. N2: float - Partial pressure of N2. + Initial atmospheric partial surface pressure of N2 [bar]. S2: float - Partial pressure of S2. + Initial atmospheric partial surface pressure of S2 [bar]. SO2: float - Partial pressure of SO2. + Initial atmospheric partial surface pressure of SO2 [bar]. H2: float - Partial pressure of H2. + Initial atmospheric partial surface pressure of H2 [bar]. CH4: float - Partial pressure of CH4. + Initial atmospheric partial surface pressure of CH4 [bar]. CO: float - Partial pressure of CO. + Initial atmospheric partial surface pressure of CO [bar]. """ H2O: float = field(default=0) CO2: float = field(default=0) @@ -66,13 +66,13 @@ class Delivery: Attributes ---------- initial: str - Set initial inventory to use, choice 'volatiles', 'elements'. + Method by which to set the initial volatile inventory to use. Options: 'volatiles', 'elements'. module: str Delivery module to use (Not used as of yet). elements: Elements - Set initial volatile inventory by planetary element abundances. + Parameters used when setting volatile inventory by element abundances. volatiles: Volatiles - Set initial volatile inventory by partial pressures in atmosphere. + Parameters used when setting volatile inventory by partial pressures. """ initial: str = field(validator=validators.in_(('elements', 'volatiles'))) diff --git a/src/proteus/config/_escape.py b/src/proteus/config/_escape.py index 6d3c0ec7..31a52fb4 100644 --- a/src/proteus/config/_escape.py +++ b/src/proteus/config/_escape.py @@ -12,11 +12,11 @@ class Escape: Attributes ---------- module: str | None - Select module, choice None, 'dummy', 'zephyrus'. + Escape module to use. Choices: "none", "dummy", "zephyrus". zephyrus: Zephyrus Parameters for zephyrus module. dummy: EscapeDummy - Parameters for dummy module. + Parameters for dummy escape module. """ module: str | None = field( validator=validators.in_((None, 'dummy', 'zephyrus')), converter=none_if_none diff --git a/src/proteus/config/_interior.py b/src/proteus/config/_interior.py index 93cc93d2..a473ef36 100644 --- a/src/proteus/config/_interior.py +++ b/src/proteus/config/_interior.py @@ -10,15 +10,15 @@ class Interior: Attributes ---------- grain_size: float - Crystal settling grain size [m] + Crystal settling grain size [m]. F_initial: float - Initial heat flux guess [W m-2] + Initial heat flux guess [W m-2]. module: str - Select interior model, choices: 'spider', 'aragog', 'dummy' + Module for simulating the magma ocean. Choices: 'spider', 'aragog', 'dummy'. spider: Spider - Parameters for spider module + Parameters for running the SPIDER module. aragog: Aragog - Parameters for aragog module + Parameters for running the aragog module. """ grain_size: float F_initial: float @@ -31,24 +31,24 @@ class Interior: @define class Spider: - """Parameters for Spider module. + """Parameters for SPIDER module. Attributes ---------- num_levels: int - Number of SPIDER grid levels + Number of SPIDER grid levels. mixing_length: int - Mixing length parameterization + Parameterisation used to determine convective mixing length. tolerance: float - Solver tolerance + Solver tolerance. tsurf_atol: float - Tsurf_poststep_change + Absolute tolerance on change in T_mantle during a single interior iteration. tsurf_rtol: float - Tsurf_poststep_change_frac + Relative tolerance on change in T_mantle during a single interior iteration. ini_entropy: float - Surface entropy conditions [J K-1 kg-1] + Initial specific surface entropy [J K-1 kg-1]. ini_dsdr: float - Interior entropy gradient [J K-1 kg-1 m-1] + Initial interior specific entropy gradient [J K-1 kg-1 m-1]. """ num_levels: int = field(validator=validators.ge(40)) mixing_length: int diff --git a/src/proteus/config/_orbit.py b/src/proteus/config/_orbit.py index 0e64837a..2fd3f082 100644 --- a/src/proteus/config/_orbit.py +++ b/src/proteus/config/_orbit.py @@ -12,20 +12,20 @@ class Orbit: Attributes ---------- semimajoraxis: float - AU + Semi-major axis of the planet's orbit [AU]. eccentricity: float - Dimensionless + Eccentricity of the planet's orbit. zenith_angle: float - Degrees + Characteristic angle of incoming stellar radiation, relative to the zenith [deg]. s0_factor: float - Dimensionless + Scale factor applies to incoming stellar radiation to represent planetary rotation and heat redistribution. module: str | None Select orbit module to use. Not used currently. """ semimajoraxis: float eccentricity: float = field(validator=[ validators.ge(0), - validators.le(1), + validators.lt(1), ]) zenith_angle: float s0_factor: float diff --git a/src/proteus/config/_outgas.py b/src/proteus/config/_outgas.py index a3087e24..5699ea27 100644 --- a/src/proteus/config/_outgas.py +++ b/src/proteus/config/_outgas.py @@ -10,11 +10,11 @@ class Outgas: Attributes ---------- fO2_shift_IW: float - log10(ΔIW), atmosphere/interior boundary oxidation state. + Homogeneous oxygen fugacity in the magma ocean used to represent redox state (log10 units relative to Iron-Wustite). module: str - Which outgassing module to use, choices: 'calliope', 'atmodeller'. + Outgassing module to be used. Choices: 'calliope', 'atmodeller'. calliope: Calliope - Parameters for calliope module. + Parameters for CALLIOPE module. atmodeller: Atmodeller Parameters for atmodeller module. """ @@ -33,21 +33,21 @@ class Calliope: Attributes ---------- include_H2O: bool - If True, include H2O compound. + If True, include H2O outgassing. include_CO2: bool - If True, include CO2 compound. + If True, include CO2 outgassing. include_N2: bool - If True, include N2 compound. + If True, include N2 outgassing. include_S2: bool - If True, include S2 compound. + If True, include S2 outgassing. include_SO2: bool - If True, include SO2 compound. + If True, include SO2 outgassing. include_H2: bool - If True, include H2 compound. + If True, include H2 outgassing. include_CH4: bool - If True, include CH4 compound. + If True, include CH4 outgassing. include_CO: bool - If True, include CO compound. + If True, include CO outgassing. """ include_H2O: bool include_CO2: bool diff --git a/src/proteus/config/_params.py b/src/proteus/config/_params.py index 2558c82e..24fb9536 100644 --- a/src/proteus/config/_params.py +++ b/src/proteus/config/_params.py @@ -13,11 +13,11 @@ class Params: Attributes ---------- out: OutputParams - Parameters for data / logging output + Parameters for data / logging output. dt: TimeStepParams - Parameters for time-stepping + Parameters for time-stepping. stop: StopParams - Parameters for stopping criteria + Parameters for stopping criteria. """ out: OutputParams dt: TimeStepParams @@ -31,13 +31,13 @@ class OutputParams: Attributes ---------- path: str - Path where to store output data + Path to output folder relative to `PROTEUS/output/`. logging: str - Set loglevel, choices: 'INFO', 'DEBUG', 'ERROR', 'WARNING' + Log verbosity. Choices: 'INFO', 'DEBUG', 'ERROR', 'WARNING'. plot_mod: int - Plotting frequency, 0: wait until completion | n: every n iterations + Plotting frequency. 0: wait until completion. n: every n iterations. plot_fmt: str - Plotting image file format, "png" or "pdf" recommended + Plotting output file format. Choices: "png", "pdf". """ path: str logging: str = field(validator=validators.in_(('INFO', 'DEBUG', 'ERROR', 'WARNING'))) @@ -52,21 +52,21 @@ class TimeStepParams: Attributes ---------- minimum: float - yr, minimum time-step + Minimum time-step size [yr]. maximum: float - yr, maximum time-step + Maximum time-step size [yr]. initial: float - yr, inital step size + Initial time-step size [yr]. starspec: float - yr, interval to re-calculate the stellar spectrum + Maximum interval at which to recalculate the stellar spectrum [yr]. starinst: float - yr, interval to re-calculate the instellation + Maximum interval at which to recalculate instellation flux [yr]. method: str - Time-stepping method, choices: 'proportional', 'adaptive', 'maximum' + Time-stepping method. Choices: 'proportional', 'adaptive', 'maximum'. proportional: DtProportional - Parameters for proportional method + Parameters used to configure the proportional time-stepping scheme. adaptive: DtAdaptive - Parameters for adaptive method + Parameters used to configure the adaptive time-stepping scheme. """ minimum: float maximum: float @@ -80,7 +80,7 @@ class TimeStepParams: @define class DtProportional: - """Parameters for proportional time-stepping + """Parameters used to configure the proportional time-stepping scheme. Attributes ---------- @@ -92,14 +92,14 @@ class DtProportional: @define class DtAdaptive: - """Parameters for adaptive time-stepping + """Parameters used to configure the adaptive time-stepping scheme. Attributes ---------- atol: float - Step size absolute tolerance + Absolute tolerance on time-step size [yr]. rtol: float - Step size relative tolerance + Relative tolerance on time-step size [dimensionless]. """ atol: float rtol: float @@ -112,17 +112,17 @@ class StopParams: Attributes ---------- iters: StopIters - Parameters for required number of iterations. + Parameters for iteration number criteria. time: StopTime - Parameters for required time constraints. + Parameters for maximum time criteria. solid: StopSolid - Parameters for solidification. + Parameters for solidification criteria. radeqm: StopRadeqm - Parameters for radiative equilibrium. + Parameters for radiative equilibrium criteria. steady: StopSteady - Parameters for steady state. + Parameters for steady state criteria. escape: StopEscape - Parameters for escape. + Parameters for escape criteria. """ iters: StopIters time: StopTime @@ -134,16 +134,16 @@ class StopParams: @define class StopIters: - """Parameters for iteration stopping criteria. + """Parameters for iteration number criteria. Attributes ---------- enabled: bool - Enable criterium if True + Enable criteria if True minimum: int - Minimum number of iterations + Minimum number of iterations. maximum: int - Maximum number of iterations + Maximum number of iterations. """ enabled: bool minimum: int @@ -152,16 +152,16 @@ class StopIters: @define class StopTime: - """Parameters for time constraints stopping criteria. + """Parameters for maximum time criteria. Attributes ---------- enabled: bool - Enable criterium if True + Enable criteria if True minimum: float - yr, model will certainly run to t > minimum + Model will absolutely not terminate until at least this time is reached [yr]. maximum: float - yr, model will terminate when t > maximum + Model will terminate when this time is reached [yr]. """ enabled: bool minimum: float @@ -170,14 +170,14 @@ class StopTime: @define class StopSolid: - """Parameters for solidification stopping criteria. + """Parameters for solidification criteria. Attributes ---------- enabled: bool - Enable criterium if True. + Enable criteria if True. phi_crit: float - Non-dimensional, model will terminate when global melt fraction < phi_crit. + Model will terminate when global melt fraction is less than this value [dimensionless]. """ enabled: bool phi_crit: float @@ -190,9 +190,9 @@ class StopRadeqm: Attributes ---------- enabled: bool - Enable criterium if True + Enable criteria if True F_crit: float - W m-2, model will terminate when |F_atm| < F_crit + Model will terminate when absolute net outgoing flux is less than this value [W m-2]. """ enabled: bool F_crit: float @@ -205,11 +205,11 @@ class StopSteady: Attributes ---------- enabled: bool - Enable criterium if True + Enable criteria if True F_crit: float - Maximum absolute value of F_atm allowed for convergence + Necessary (not sufficient) condition on maximum absolute net outgoing flux [W m-2]. dprel: float - Percentage change in melt fraction over time (dp/p)/dt*100 + Necessary (not sufficient) condition maximum change in melt fraction over time `(dp/p)/dt*100` [yr-1]. """ enabled: bool F_crit: float @@ -223,9 +223,9 @@ class StopEscape: Attributes ---------- enabled: bool - Enable criterium if True + Enable criteria if True mass_frac: float - Stop when atm_mass < this frac of initial mass + Model will termiante when atmosphere mass is less than this fraction of the initial atmosphere mass [dimensionless]. """ enabled: bool mass_frac: float diff --git a/src/proteus/config/_star.py b/src/proteus/config/_star.py index b4038733..f2872911 100644 --- a/src/proteus/config/_star.py +++ b/src/proteus/config/_star.py @@ -12,23 +12,23 @@ class Star: Attributes ---------- radius: float - R_sun + Observed radius [R_sun]. Teff: float - K + Observed effective temperature [K]. mass: float - M_sun + Stellar mass [M_sun] lum_now: float - L_sun + Observed bolometric luminosity [L_sun]. omega: float - Rotation percentile + Rotation rate, as a percentile of stellar population with the same mass [%]. age_now: float - Gyr, current age of star used for scaling + Observed estimated age of the star [Gyr]. age_ini: float - Gyr, model initialisation/start age + Age of star at model initialisation [Gyr]. module: str | None Select star module to use. mors: Mors - Parameters for MORS module + Parameters for MORS module. """ radius: float mass: float @@ -53,9 +53,9 @@ class Mors: Attributes ---------- tracks: str - Name of evolution tracks, choice: 'spada', 'baraffe' + Stellar evolution track to be used. Choices: 'spada', 'baraffe'. spec: str - Path to stellar spectrum + Name of file containing stellar spectrum. See """ tracks: str = field(validator=validators.in_(('spada', 'baraffe'))) spec: str From 7abb8cad5228d68fffad21c0072fabc90a9dee49 Mon Sep 17 00:00:00 2001 From: Harrison Nicholls Date: Mon, 21 Oct 2024 17:15:28 +0100 Subject: [PATCH 09/13] Stars docs formatting --- docs/data.md | 187 +++++++++++++++++++----------------- mkdocs.yml | 2 +- src/proteus/config/_star.py | 2 +- 3 files changed, 100 insertions(+), 91 deletions(-) diff --git a/docs/data.md b/docs/data.md index 13f7319f..31efc180 100644 --- a/docs/data.md +++ b/docs/data.md @@ -1,92 +1,101 @@ # Reference data ## Stars -* Epsilon Eridani - * file: `eps-eri.txt` - * url: https://en.wikipedia.org/wiki/Epsilon_Eridani - * type: K2V - * Teff: 5049 K - * age: 400-800 Myr - * Lum: 0.32 solar - * M: 0.82 solar - * R: 0.738 solar - -* GJ 1132 - * file: `gj1132.txt` - * url: https://en.wikipedia.org/wiki/GJ_1132 - * type: M4 - * Teff: 3196 K - * age: ? - * Lum: 0.00436 solar - * M: 0.194 solar - * R: 0.215 solar - -GJ 1214 - * file: `gj1214.txt` - * url: https://en.wikipedia.org/wiki/GJ_1214 - * type: M4.5 - * Teff: 3111 K - * age: 5-10 Gyr - * Lum: 0.00351 solar - * M: 0.181 solar - * R: 0.204 solar - -HD 85512 - * file: `hd85512.txt` - * url: https://en.wikipedia.org/wiki/HD_85512 - * type: K6V - * Teff: 4404 K - * age: 5.61 Gyr - * Lum: 0.126 solar - * M: 0.69 solar - * R: 0.533 solar - -HD 97658 - * file: `hd97658.txt` - * url: https://en.wikipedia.org/wiki/HD_97658 - * type: K1V - * Teff: 5212 K - * age: 3.9 Gyr - * Lum: 0.351 solar - * M: 0.773 solar - * R: 0.728 solar - -L 98-59 - * file: `l-98-59.txt` - * url: https://en.wikipedia.org/wiki/L_98-59 - * type: M3V - * Teff: 3415 K - * age: >800 Myr - * Lum: 0.01128 solar - * M: 0.273 solar - * R: 0.303 solar - -The Sun - * file: `sun.txt` - * url: https://en.wikipedia.org/wiki/Sun - * type: G2V - * Teff: 5772 K - * age: 4.6 Gyr - * Lum: 1.0 solar - * M: 1.0 solar - * R: 1.0 solar - -TRAPPIST-1 - * file: `trappist-1.txt` - * url: https://en.wikipedia.org/wiki/TRAPPIST-1 - * type: M8V - * Teff: 2566 K - * age: 7.6 Gyr - * Lum: 0.000553 solar - * M: 0.0898 solar - * R: 0.1192 solar - -GJ 846 - * file: `gj849.txt` - * url: https://en.wikipedia.org/wiki/Gliese_849 - * type: M3.5V - * Teff: 3467 K - * age: >3 Gyr - * Lum: 0.02887 solar - * M: 0.465 solar - * R: 0.464 solar +### Epsilon Eridani + +* file: `eps-eri.txt` +* url: https://en.wikipedia.org/wiki/Epsilon_Eridani +* type: K2V +* Teff: 5049 K +* age: 400-800 Myr +* Lum: 0.32 solar +* M: 0.82 solar +* R: 0.738 solar + +### GJ 1132 + +* file: `gj1132.txt` +* url: https://en.wikipedia.org/wiki/GJ_1132 +* type: M4 +* Teff: 3196 K +* age: ? +* Lum: 0.00436 solar +* M: 0.194 solar +* R: 0.215 solar + +### GJ 1214 + +* file: `gj1214.txt` +* url: https://en.wikipedia.org/wiki/GJ_1214 +* type: M4.5 +* Teff: 3111 K +* age: 5-10 Gyr +* Lum: 0.00351 solar +* M: 0.181 solar +* R: 0.204 solar + +### HD 85512 + +* file: `hd85512.txt` +* url: https://en.wikipedia.org/wiki/HD_85512 +* type: K6V +* Teff: 4404 K +* age: 5.61 Gyr +* Lum: 0.126 solar +* M: 0.69 solar +* R: 0.533 solar + +### HD 97658 + +* file: `hd97658.txt` +* url: https://en.wikipedia.org/wiki/HD_97658 +* type: K1V +* Teff: 5212 K +* age: 3.9 Gyr +* Lum: 0.351 solar +* M: 0.773 solar +* R: 0.728 solar + +### L 98-59 + +* file: `l-98-59.txt` +* url: https://en.wikipedia.org/wiki/L_98-59 +* type: M3V +* Teff: 3415 K +* age: >800 Myr +* Lum: 0.01128 solar +* M: 0.273 solar +* R: 0.303 solar + +### The Sun + +* file: `sun.txt` +* url: https://en.wikipedia.org/wiki/Sun +* type: G2V +* Teff: 5772 K +* age: 4.6 Gyr +* Lum: 1.0 solar +* M: 1.0 solar +* R: 1.0 solar + +### TRAPPIST-1 + +* file: `trappist-1.txt` +* url: https://en.wikipedia.org/wiki/TRAPPIST-1 +* type: M8V +* Teff: 2566 K +* age: 7.6 Gyr +* Lum: 0.000553 solar +* M: 0.0898 solar +* R: 0.1192 solar + +### GJ 846 + +* file: `gj849.txt` +* url: https://en.wikipedia.org/wiki/Gliese_849 +* type: M3.5V +* Teff: 3467 K +* age: >3 Gyr +* Lum: 0.02887 solar +* M: 0.465 solar +* R: 0.464 solar diff --git a/mkdocs.yml b/mkdocs.yml index 6d28c2c4..f638f219 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -8,7 +8,7 @@ nav: - Installation: installation.md - Usage: usage.md - Config: config.md - - config_old.md + - Data: data.md - Troubleshooting: troubleshooting.md - Contact: contact.md - Contributing: CONTRIBUTING.md diff --git a/src/proteus/config/_star.py b/src/proteus/config/_star.py index f2872911..f324efce 100644 --- a/src/proteus/config/_star.py +++ b/src/proteus/config/_star.py @@ -55,7 +55,7 @@ class Mors: tracks: str Stellar evolution track to be used. Choices: 'spada', 'baraffe'. spec: str - Name of file containing stellar spectrum. See + Name of file containing stellar spectrum. See documentation: https://fwl-proteus.readthedocs.io/en/latest/data/#stars """ tracks: str = field(validator=validators.in_(('spada', 'baraffe'))) spec: str From ea500d3d76e89045292eefd051f432d3883dc71c Mon Sep 17 00:00:00 2001 From: Harrison Nicholls Date: Mon, 21 Oct 2024 17:25:03 +0100 Subject: [PATCH 10/13] Star docs --- docs/data.md | 145 ++++++++++++++++++++---------------- src/proteus/config/_star.py | 4 +- 2 files changed, 84 insertions(+), 65 deletions(-) diff --git a/docs/data.md b/docs/data.md index 31efc180..1396b902 100644 --- a/docs/data.md +++ b/docs/data.md @@ -1,101 +1,118 @@ # Reference data ## Stars + ### Epsilon Eridani -* file: `eps-eri.txt` -* url: https://en.wikipedia.org/wiki/Epsilon_Eridani -* type: K2V +* File name: `eps-eri.txt` +* URL: https://en.wikipedia.org/wiki/Epsilon_Eridani +* Spectral type: K2V * Teff: 5049 K -* age: 400-800 Myr -* Lum: 0.32 solar -* M: 0.82 solar -* R: 0.738 solar +* Age: 400-800 Myr +* Luminosity: 0.32 solar +* Mass: 0.82 solar +* Radius: 0.738 solar +* Source: MUSCLES ### GJ 1132 -* file: `gj1132.txt` -* url: https://en.wikipedia.org/wiki/GJ_1132 -* type: M4 +* File name: `gj1132.txt` +* URL: https://en.wikipedia.org/wiki/GJ_1132 +* Spectral type: M4 * Teff: 3196 K -* age: ? -* Lum: 0.00436 solar -* M: 0.194 solar -* R: 0.215 solar +* Age: ? +* Luminosity: 0.00436 solar +* Mass: 0.194 solar +* Radius: 0.215 solar +* Source: Mega-MUSCLES ### GJ 1214 -* file: `gj1214.txt` -* url: https://en.wikipedia.org/wiki/GJ_1214 -* type: M4.5 +* File name: `gj1214.txt` +* URL: https://en.wikipedia.org/wiki/GJ_1214 +* Spectral type: M4.5 * Teff: 3111 K -* age: 5-10 Gyr -* Lum: 0.00351 solar -* M: 0.181 solar -* R: 0.204 solar +* Age: 5-10 Gyr +* Luminosity: 0.00351 solar +* Mass: 0.181 solar +* Radius: 0.204 solar +* Source: MUSCLES ### HD 85512 -* file: `hd85512.txt` -* url: https://en.wikipedia.org/wiki/HD_85512 -* type: K6V +* File name: `hd85512.txt` +* URL: https://en.wikipedia.org/wiki/HD_85512 +* Spectral type: K6V * Teff: 4404 K -* age: 5.61 Gyr -* Lum: 0.126 solar -* M: 0.69 solar -* R: 0.533 solar +* Age: 5.61 Gyr +* Luminosity: 0.126 solar +* Mass: 0.69 solar +* Radius: 0.533 solar +* Source: MUSCLES ### HD 97658 -* file: `hd97658.txt` -* url: https://en.wikipedia.org/wiki/HD_97658 -* type: K1V +* File name: `hd97658.txt` +* URL: https://en.wikipedia.org/wiki/HD_97658 +* Spectral type: K1V * Teff: 5212 K -* age: 3.9 Gyr -* Lum: 0.351 solar -* M: 0.773 solar -* R: 0.728 solar +* Age: 3.9 Gyr +* Luminosity: 0.351 solar +* Mass: 0.773 solar +* Radius: 0.728 solar +* Source: MUSCLES ### L 98-59 -* file: `l-98-59.txt` -* url: https://en.wikipedia.org/wiki/L_98-59 -* type: M3V +* File name: `l-98-59.txt` +* URL: https://en.wikipedia.org/wiki/L_98-59 +* Spectral type: M3V * Teff: 3415 K -* age: >800 Myr -* Lum: 0.01128 solar -* M: 0.273 solar -* R: 0.303 solar +* Age: >800 Myr +* Luminosity: 0.01128 solar +* Mass: 0.273 solar +* Radius: 0.303 solar +* Source: Mega-MUSCLES ### The Sun -* file: `sun.txt` -* url: https://en.wikipedia.org/wiki/Sun -* type: G2V +* File name: `sun.txt` +* URL: https://en.wikipedia.org/wiki/Sun +* Spectral type: G2V * Teff: 5772 K -* age: 4.6 Gyr -* Lum: 1.0 solar -* M: 1.0 solar -* R: 1.0 solar +* Age: 4.6 Gyr +* Luminosity: 1.0 solar +* Mass: 1.0 solar +* Radius: 1.0 solar +* Source: [Gueymard 2003](https://www.sciencedirect.com/science/article/pii/S0038092X03003967), [NREL](https://www.nrel.gov/grid/solar-resource/spectra.html) ### TRAPPIST-1 -* file: `trappist-1.txt` -* url: https://en.wikipedia.org/wiki/TRAPPIST-1 -* type: M8V +* File name: `trappist-1.txt` +* URL: https://en.wikipedia.org/wiki/TRAPPIST-1 +* Spectral type: M8V * Teff: 2566 K -* age: 7.6 Gyr -* Lum: 0.000553 solar -* M: 0.0898 solar -* R: 0.1192 solar +* Age: 7.6 Gyr +* Luminosity: 0.000553 solar +* Mass: 0.0898 solar +* Radius: 0.1192 solar +* Source: Mega-MUSCLES -### GJ 846 +### GJ 849 -* file: `gj849.txt` -* url: https://en.wikipedia.org/wiki/Gliese_849 -* type: M3.5V +* File name: `gj849.txt` +* URL: https://en.wikipedia.org/wiki/Gliese_849 +* Spectral type: M3.5V * Teff: 3467 K -* age: >3 Gyr -* Lum: 0.02887 solar -* M: 0.465 solar -* R: 0.464 solar +* Age: >3 Gyr +* Luminosity: 0.02887 solar +* Mass: 0.465 solar +* Radius: 0.464 solar +* Source: Mega-MUSCLES + + +## Exoplanet population data +These are obtained from the DACE PlanetS database ([Parc et al., 2024](https://arxiv.org/abs/2406.04311)). + +## Mass-radius relations +These are obtained from [Zeng et al., 2019](https://iopscience.iop.org/article/10.3847/0004-637X/819/2/127/meta). diff --git a/src/proteus/config/_star.py b/src/proteus/config/_star.py index f324efce..a58ac0d3 100644 --- a/src/proteus/config/_star.py +++ b/src/proteus/config/_star.py @@ -9,6 +9,8 @@ class Star: """Stellar parameters, model selection. + You can find useful reference data in the documentation: https://fwl-proteus.readthedocs.io/en/latest/data/#stars + Attributes ---------- radius: float @@ -55,7 +57,7 @@ class Mors: tracks: str Stellar evolution track to be used. Choices: 'spada', 'baraffe'. spec: str - Name of file containing stellar spectrum. See documentation: https://fwl-proteus.readthedocs.io/en/latest/data/#stars + Name of file containing stellar spectrum. See documentation for potential file names: https://fwl-proteus.readthedocs.io/en/latest/data/#stars """ tracks: str = field(validator=validators.in_(('spada', 'baraffe'))) spec: str From 1c1aaef4a507d031d8cd68895c91ddde5f82a5a1 Mon Sep 17 00:00:00 2001 From: Harrison Nicholls Date: Mon, 21 Oct 2024 17:39:23 +0100 Subject: [PATCH 11/13] More information in docs. Added spectral file table --- README.md | 4 +- docs/{images => assets}/PROTEUS_black.png | Bin docs/{images => assets}/PROTEUS_white.png | Bin docs/assets/spectral_files.pdf | Bin 0 -> 49419 bytes docs/config.md | 9 ++--- src/proteus/config/_atmos_clim.py | 46 +++++++++++----------- src/proteus/config/_star.py | 4 +- 7 files changed, 31 insertions(+), 32 deletions(-) rename docs/{images => assets}/PROTEUS_black.png (100%) rename docs/{images => assets}/PROTEUS_white.png (100%) create mode 100644 docs/assets/spectral_files.pdf diff --git a/README.md b/README.md index cec3e748..f71644b7 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,8 @@ [![Documentation Status](https://readthedocs.org/projects/fwl-proteus/badge/?version=latest)](https://fwl-proteus.readthedocs.io/en/latest/?badge=latest) [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) -![PROTEUS banner](https://raw.githubusercontent.com/FormingWorlds/PROTEUS/main/docs/images/PROTEUS_white.png#gh-light-mode-only) -![PROTEUS banner](https://raw.githubusercontent.com/FormingWorlds/PROTEUS/main/docs/images/PROTEUS_black.png#gh-dark-mode-only) +![PROTEUS banner](https://raw.githubusercontent.com/FormingWorlds/PROTEUS/main/docs/assets/PROTEUS_white.png#gh-light-mode-only) +![PROTEUS banner](https://raw.githubusercontent.com/FormingWorlds/PROTEUS/main/docs/assets/PROTEUS_black.png#gh-dark-mode-only) # PROTEUS Framework for Planetary Evolution diff --git a/docs/images/PROTEUS_black.png b/docs/assets/PROTEUS_black.png similarity index 100% rename from docs/images/PROTEUS_black.png rename to docs/assets/PROTEUS_black.png diff --git a/docs/images/PROTEUS_white.png b/docs/assets/PROTEUS_white.png similarity index 100% rename from docs/images/PROTEUS_white.png rename to docs/assets/PROTEUS_white.png diff --git a/docs/assets/spectral_files.pdf b/docs/assets/spectral_files.pdf new file mode 100644 index 0000000000000000000000000000000000000000..40dee0d68ac4cc21b488f87fe1bf2899511bee9c GIT binary patch literal 49419 zcmagF19W9g*Qgt_W81cE+qP}ncG7V=wr$(C?T*uNa?MR|PIgvuyNsr)D? z@)8p>vuZ6p1CV6eX?i9W6>4Kd=$z9 z)g+4cT^mpUJb*eFN;;H@t?_>v`Ii2M_cx}$_wT4U=>Jy#EinC0?Ege7;_fV_BM$Z4(xU=E2{q6bRy6@{h zZTwaJZR>v<9|rorX8$z#e;S~_%_@7?o8bS~`#+XSE{4wkC`IiYZT`^+3fj5jYkj+- z$7f(;Va8`*Wa7Zr`KL@ zx|sa8B=l`1Y~pHRWTGf0_*eO#ZY!EN*||6xnKd+NhYeu!=V32CP_?;L=C)fY>&4Up7vA7FeepyG`4Jq=Q#v<1kc?JR)% z*d68^tbVG-IAD=4qq;uyI*FW4V(D@j560pzg}yenu?u!f%U7aUesn3S${N_5v8By& zIwg~7>#lB0cEUYi(_=ij^v3HXIRk?~@8{~s!}B)4vBBdJsI&DK)aDRd;o?JHHaV+O zgZd`|G$YRgp<|tQbTJdsGt|<>Q1FoF}+Hof~4UDg_KP~ zLA}<46JFo1wtDb|HvuO*e@WWSzF`9RE03$+`YeyAWk34)=(@_9>z9YJ7Uk^_3`*aZ zV>kd&Kj)qn=q*2K6fuJRuwNa>MH{9EjoGCmJ)m`;D1Q`24XzWwP7*dOW zO4Z9>BaOu`#+zpOJi#KU8*B}53~(b(2oKOl$Bo5r5;Q*e6CYrn-(($#lFnZuF$h2$ zqQ4PPITRqNFaoM{QogM@d>X|#DHu>V5#-PsAem*9qzo9M9`w06{4h>7N)QzxI6?@$ z1wt_bbto7JgaahMIovo|6xlHfUz)7HRU}^jC%G{?7xjm}s3|C5yb@*DI0Gw20V&3d z*FX=T^uWX}7~vfC4=w(o7JG(DfBfiRJMe_j^Pl9ysPKb{^jG+Zx-sM+=O@cqq~TDMdz%52dMnW>P%MIon#j!}P#c=)`!VqSQJq}!2HH_VlYoZd0dC;s(Nqr6 zT!IixksAR}2b$Q1aPUGf-zFy3Lj<2-Y$Hcun!u3$?ntO8{z8R+Tqgm^{p>)j0Tyl; z0RqH3AqP<90m-$0@Z&?U?QIA+13(c0!$b7Tpu552_#6KO0131QK0uuV6c>f$7f^15 zJb_&V$u&#{AST`uHP8|U&)xqCKpbpNbPZbwEPpEr0A$$s9g`){Ul~!bQDO7{rME|+ zT@h2F-r9E)ZCtbx&ZIBB$sAS&n&Egqyk_}&U1!dsZV1S&to|OXrM1IEK`nUH-?ARMLjHh?NlNm7c4@Wl8A8vy0!q^XBQ0?Kz~-dZ3oZY9EH*23bBaKbhK6kS>h zqawla?!E0I&ZLT2i4gz{zacJAE$-s?e{u^$NPzc$&lAB&rFwY$Vr+vgLK#@iqv(r* zwGsrJG-eR~c?8tt5L3QGbb1Z`7cU}x;IzK?Ebz24Opdd={d6FudvE zR)F&5zj}b`ev-#EK`dGz{Ow?omi0;W zJjIZS9V|esUgpm75fX?@%{&->fc7bsHf1*n_$3*r3ILFNV0mT1o&=flifBnq1&o$1(uq;62qB*LYF@ssbo}0d(7B2XG4@ z_-Kf~^7k^#001EZswL!Hr~IC!VE7sc{{HZ`@Xgkep+AO$< zYVleVi2|c;Xx$R%1#Zb%8;L=qu3x@KxydEJ5u`F{-j8TBfdb@~TMS*1HWvz7oKfB1 z1>EGbn%p4j;EG;f{-7$b8i_(H;8?H?8z6v>rbVGu7#dJpN)I4hf>z8^3JG%ez1hwE z?&|<%$>Y}z4&-0I4)K7q3KDQ2LJ#kIq_79K>=$4l!VaH%8tV>Y0nA%PfbaeJ6yyVE zB_vo!L>xZ%Md1i%75FWa`SsgJ}Ukc!@u_`_2PsWB8A4_e%hboq}B&OiDD zFZFL590F+R5VF;$T2^D9bzF4o2&OiD4yb!upIs|N%~bg&S3miaTiVV^JTfemLr8Xh^EdtoJJW# zZNF771>SW`aT8VfcCX<#bdclS(QnM{M%?TT#QpYW$yTQNH_Sq8*{+0*kNA692shIK#5) zWisL~V@dy=sqWR#;WG~3Ge%`NnVox^BygndXEU%#cN0CTv%h**fD5=K6z84_C=R}= zU4I8S3n-3&k=dX)SyZGRi;K@`7LlDJF+gz` zQ0k4v#izC@;uMKPjN>&wS5sYp{zZ0r7OW}&_+^c*G_MLT_(?e=m+S9|p zqYdQH?bv%*Lrq^)=fGNTq!gNYWan0{bBObx`~WB$0v)k<6c-R>lQ{sMW_c~Kcr+If zd{h|t7GM^a;G6OYJa{vYy{({(2t9WdLBPRFf=(~_B>B;(V4(0d;O`OnM-D{Nr}Tih z$6Y2x9*PMT{IM4Fz4S=)$W4in4W)7aMjf2Lnjr6f6*C6>Jq!i9km4cZw?-kYC<((MKBB4y(%oW>oIYe{ujLl=vY`a!b`y@xVmf6~%Tne-%!D&6p^|%FYl$N$a-Z1YX=&Z9xxz?V07mi&zke z853pjXb|&Q$n~)VL4dqd$Es5@5@CO;Y@Bk>QQcE0|J?0nCE~@xd3hv)JW6&nWtOwW zHNZKMW;r2@H8d!b;J^Y!3C^MzcmV0a38P(zr{q5Z=`kjU@!2awQ6S&B8p^ z2vNpU`?W3+3Ssh+u;*J`wo17~YKTR0Bnq+G7WCXW;XkR2-ryek z{s5mU<@6f5b9%Ij_)tPVB7EBvDI}f z(G@KE8Ay#{AXvPJXdp@Ffh*8ud98dwA}mRFR!i9xEO`d1AxTG|@{ouT@3~Z_ zbdgMYtL$&62%OJZ96XC%C10YIhi|li1kaTfJUbCgKkYE93zJqIf8ifNUl!j)&)UjA zq?*ECZYLtnsSIEAs*s<`m~dJ|4WeN#FOXu1Z*a3lna?weMi>kWA6(`Oho{y@A6NB#o`Q@#$3DBiLYJ`ojKxGWT^bd?J*SafXSRW?FBrK<%@Ye|4Q`tTRjqb8~z zb<_dIhkOHe-28k&;G0n8v>%9*NmSRvqU&2 zdh6c3tQV_*l@mks?3k6uTZ0yLOZ{y)zEy;p*CRzE=r_WPO&4+`INX)I8apL?j?8Kxs(24!*&&q8cP=pAoT~ zZSCMg8i1XA1gmWL!2D8xm5Q?VTNnw@3^(8*;sVkPDCQafr~;)V6_G_@B&#e7#e3GvIVSVa??9y}zLZFpmCMIRuaaE`d9kIOKXt+y^GgufZ87;epJHi>r;u8 zgrZ*aCFF_Bfo6ij>5>WcF0TEc`QK>^1UNSqhTq=PsL@uds^I$l*NiH$CZax^^ z#>H$nxQ!psCjjJCKm!s~pe7X6;6_Ypc3+BLeg>S>a0Z+iBpw}$^l0eZ*(Deqn{cZSP%m$}vnybWI+dkWSiZ9>|4JlnMs~9!q@Sq_b+Yfh36N2|cSAtVh z`<$17-BZWV-ohoKO+Y@nLQ*~hONT8DtE7Br)jTaChSNoOZMq!bXt%t4zXk$ccI9dY#}HHz`e zyVf8UkD{}mYq!!MDjeAny_f745#`z-6b;Y_=Z+rRfDIFUvWrK_fh3r6LHUemm}xp) zZ%mWzphV&&8OWBuiet;gUtlRY!AsMS#fO(LN7ei9g^{s?#Zu$ZS55XZV02JZZq4g^ zC1#Dr#EBw(35BVT1cbx@6BfN*C6IkYMwK~cPE_ns>;zh$ zj!{HW47_9QH_`olRH6PBdTODo>YGs~y2|}zAfl4{XKT{eqN~wRQ+b`%Y{eMGN^h%^ zdP*NMCAdqvV=YkQ&bImZDQc&%I0x=Egy|^b+PQ*%YX=Uf8<(c(`50MeszQq>UsnuJ zxDcZEDWfQ5j$2kGl6enNkbz$~8UQ&-ljuIU#cFZH1#(Xf5yTK+SE>l*hTF@x1j<YuvA71K8y&!Aebt5a1exb^7U~8#h(#}AiNA<=rDbKDyse`{y7N_2iR8r zPq6-$kt65rP6X`mSIa?tH-XY6sn2WlZtgR~*{SVThp|-#x`M^AH0}Yqt|-5Zz0BZuG35W2$K5by)1k(GR@YdTQ z@$>WbsK5v{%uH z9^7u>NPAH1EA2qNz792!ed_?E0}zp*8LXVD<|Am<3vk%Q;1U##^5G{GgA5s zr^!&sKt;U83 zn@>i*8GGlO*8CQ(?^|>0n#w%GnD61pz>&+#&DoJgz7LW_JF*9d@=OD`9(TFkkh-3( zTY_ElpGM-Ns}ABrZn2e*-)AZUdV0n5G6PRnv{63E)tdz6D@P2zp6MZ-6nXJRFB{Y! ze+WO`Pae8LAG#6=83+w!vuq@zMi}71nCO;dvdv6B5hKV>b{|I^SmE|}NR$tL*bUPU zP`?hu**093m{zhzJ+2&%OYt{Oafir_oRzRp)UCIv&(&128&iSdsf6!%oWi!Wq`E`b<*t=e&xhP1pT7S<(S&>#cqZ?X{q_lu>EO`Ll%dJ z;c{)pB!lO*xMg@eP}Ad{QP?FtV7m{%p6b*=BYVF$@M$i|w?9kw2RO7_s$nJ$=Hr%r z{q{yCTj=iHT~~3!=FhE~M|C8USt{8qHn2&jVUy8_f7$*9rt#9mn|pHSZ<*z@Fv2@h zv3Hd&&*X#i$AVLl8YSux_)Gla^sD(6-mwLp_ro_tFAh~YyLwR{n695pVSQdbuw8Tw zifSuoCsQ`<;YE%IKa6A&mM{!)aFUcWLO*e*cN>@n@!u_`Yl)}G+@486*Y>El7-3a$ z>+R;%J$8)estXlz7R(D1s5P0)InPZxlRG|3g~CgXG}3zF`f!1$#=*b-uCEeJ$^h* z;-=0KJP-M1o8~mEP2DI=WqWoy5TdJsu1s7rCQl}(rJJ$nU1glzyguBOPZ!`=#cnKM z|8^rW(?JF-8LFGMt=HX&(zQqw9m{$rcojo*@p96t{(2QP9|!UEldDtM){C7`*6A!< zu5#eOTk)@pOx(Aj)qD6XrcCIWl#!)!)9BUtlilz2;hr4hgZ(3%r?~Pmeq!6!YxvtXX{FP1>#G>Jij{fAhlZDQKhI=@= zV_cKuUN_m;EfeuK<1}2yK&;9aiAoK_Fs_pd6VBc1{@6{p!%J`Co;Efm?dX2^71yFG z2jaLRG0h~dW^C!E{PjbFjyG(|#27 zed8p?t(=+lpY8ywhp~_~8Ag-f8IKs=FCeRj8Cv1a7+vl-gZDv=*St6HeRvICnQ#y* zMKUQtV`|O!&pR)QxKMPV3)JP>K@kW_%BQbAg@FTL#34E)T!M!K?xGW(99C}J)){a* zjL;lxELvfQkWG;XaWr;=gU@`dBN18bAQ`= zJ0z>6T{|Ytz8uj%xA#&$%EcsT<^?-IekBdZ$oSmXeBFEK2n{{%E^vzrZP4B`^V_C+ ztjM`a(s9IBAG~>G*lNJi`HnJKO>yWIp8z-%d1tPmU5~qeVT(2Urg@?5)A=2qF!0RR z8I*{7q}w@orKh^OEct%6I6HW_`KkRJpU6uCq8(TIId4Tl)j1D#3j1U?u2>yxt^rGk z*yB?YtT%q$LHO`H=Jn=MM`Ljd6|RF$2GEUts*Ht}(COpNM#K8p)jGxDtC$wbFDYc} z5cg8$xA_J^tb{F8_1%WrnhRY|O~39A@)KvzheRIs5ZrL^!{p8eugK|X%fNdLpZ)1o zy=RNYlJ~s{wrbJ46B$j(+F%=qt+wM%oo0be7KimO5AmRj_q~cNG29Zle){>C2J8hc zE{qXXAzg$tWP|OgM6poj&k<6u_d1-r_x4Ud-`|TM9ZWr>#q&Zv2`@`xJfUlHwk%4l zamA8cyw!Imw_iRMqS`62%DTVagj`}XSB5ASkm{~(h7L5&pXY9enI*27xK zX;XXFwtN8R0xmO93;Eua(u?gJ&Dyq~Eo9^6?pGpRnxtl^)o9&SA9yDO{7_J4jBZs! z5`91Q_ipO3Cwpx5Ok8GfqCdN(EkNRoC>aNgEkR!|5|yv6^z@EyBicRLWWxyfD%6L~ zCfVqE1p_}o(d(p>TwPt?_SD#Fh*>}N5HNta0Jbx6>FG5x~m+WXC%PwY$mA`0Y z!|HV{3|~lbPOKk>Db+Nh>@^=H%xxqd)!cK(U;jyEG|}!YbO_Fp@#$5WYBQUskMVGQ z3ac|s;`_bEm`~<+WjM|#l~ogO@QEx{b;_Jf)+IHOHs}6$d-^LmPN|3Q+~{${7QpTF zfE)zt0mmo=F~x+@{q&tUZeu8uk+|h#NM4PD_-bY9y$r8-_qbL!=L%*JJF3V)cH#1p zuYn=$Z3yJ#hI|jpA&wodtAqA_PH0<2%;>V@nPloFufSkr#*sM`BDAqUhLTi)v#1>o zx_%3tO2umJO~EogDr=E$=a_t$zI}T}VMJ!(pdyRQcNF8fV?JIcYa1jfsW`QegKyUB zV%7UCetUyy@;xYKVK>dP%OKmNzx0V?T8gPe&DG??@qTVht2Ed$h*q1?(s3FuTWW?>kQ#ZU(N>ME^IMz3Xgzvnt!7IMFhFa#!PsO~ z42=AOrfN-p`kXuIhwS;xJMN#8K0se~+VcvW?ns;7WH(xeL~Qy0A`Aau0{>wa z*f=x3K?*o4s11GD$McZ$(;4jZW zOaCv?@O}UHSpToL{~Pb{PaVU5SqOSs24)U=#($pwul%o%{{RA_cD8?^i2rf~rZn_4 z-;@HwKd`{JtH0h%X&CiI5KYjc!3-JwFC^`QNKKutWVfc%0{EJb@ z;xqg+7NQo8PR{tu|B?TH*b^oC-N@s}BOm}Uc0ir~!|?x?4*3q2f%U(EG5i-K`QLdC z*8d6Q|HgCt8#2Q;sKLg>`2Rp)etUU%|6E$S>3Y&I+gUMYoS8H>O_XL$gd~6;L;61J z4&Vo1GAE`MkcSos&#i(-&<&Kf;8+`+_!B)Enm)GT4@wfpsHzfsYpz} z-ZTRnY-#S5fRSqZPG&LW`bp z{|7O6JX)UB5dk?(EecQ27wFIl?ZbGe+(pjf6XfLrf5%~K{>2Hw0AB~}qX303y`x;{ za1{%l(k`%b(ZR=SWQWwpJj@$hu$T=#FX?DEWDUxE6EHBTb5_pM75HtKwAV5t;re%R>-L*bn1MOxrle=y$(k;z^5c-Bqa z5FDZ3-1eN=4dsc{v7qIM;zA{}GV`)y7WUI*No!IogAPMQKDlIS;YjQL_b=@dOCB;P z)V{r1cI=lze@I6`TsOWJoky!<5g4_g62rg}ECgIZGX#N;vOeAimuXYlI6W0!cb;<7b$dED}xwfp5x3%ZrWd7R-L@H<`*O-x|4wI z2!aj)^4&IWOihh3wyJg0zI&WWye47W&$LIr_(M%D^*Q(P3=`M=M{)+nOJW(tjIYma zZ_ORD+ipeWHuPe}C*z&<<;-k@U$D0KtSoK~e6>zIOxwJJd(X&Q^L_oUDaI$=dlI1` z%Bf6zl6``40@ulwjO!U^-_@q){OK@m)2n>PO3ta|CC+7-Y;a}N?)hXWwNbmIHA0V! zvDmksFmIV1U`$oDRu%H9xiXeIvFM2)wWCN?gInjdzJ_$5eP%H$poli8i56>zumTke zEdy;GjZ0$_v*1Uq@D$O+MEq1F(C4Q7tmKLgLJ@b`Hc#ih9ec+6qnR67&(-jJGl|qy zhuv7B&7dFGaYquJ-)GC={e_|z?s`Ls*-18!a~G3-ms6Y2sDJ$&YTGFGfzf%IM~Y7h zQ%aXmtKMUbRsr|?Xzv{nRYQR z-YDF7H$k~mM<%edt`!GwP4!MmJ4=72eMw(*?%D=5FELqD7q^(*4%#cwtXDlmeuUM9 zKd!paF=St?daWgn;CUVI>C|p(s@tI-T8XSZ&jA`s`w+32mtU#zo%VAb0=rjS`CJrt?6t6u|1U&S|pb+t+C6q9+DU?6BAYt86=2`BLay&kyo?1&DI7au*uVfMq*o#`=M0x4+ zVeOmN9r49Jx(eMu<;cI#mk*LCM&S#p-`zZN=F`aXN67)n0yX zo}!w?B{{RtaE_hGUMgD&YVuqL1Def|ikaFydl#1)9=cBOeg&= z$XF&x)MahF?|l}z@XctpLK3)+GN}3{pHj!7Kw8qKJT9*!G?41az`o4idkZnoEbVo0 zHBZ|)8+n~uE^wc0pZJ$2uGH!qxoaBMJW_ckPc{szlZ|=Srue3M2Cd>mb{G)lY}X)^ z@@Um!k;R-${BXUsvrp$Yo!W?7`h?VUp(4E_z=`7Kke=Qb20Xb#TCvCEE%|lR)}`@O zzF%~JGN>go-BsgCoqx53P zi^Btu8y`k3k5V|PK$?5g$qmn#OZ;@dsb5WZHU&5;2Fn4|q9<|_ptXn@)C>S}{xyeH zQL&c`wwJeT!p@B-Y}&GcUa_?Y9U^34xgv-%mq0`%rds?P-^oqq2Lml)#VHcXxZW*evm* zWye*+wMfd^T--X#N6g4oemq;1kMt$9Z4#pzm#KnUIejCx^r}WQd#nV zsjxbrtGMab)#hga&Tcf=xp-v7?fl(VRqNb_3YGFFf@4B?={bdidA2F z6VD`Z|Av&qYA9v*;4CpU{+*wHXu;a}h{j|(oyBl6-i|ZCz<83ke-4@1LIP>wZtrR^ z(Eb)S6L11S3&jREZ3&$yPrymBQc2w#^-uxDYuIC`kvvnpe-Gs&(6MHfX-QPn{K0D2 zpaJ}uyGAIvj4w(|wb|!(8*DcTeI52oaIJJ+xM??Ftb5+Dt+lMRs*!`Ml0E<8F%v})0~Rzpvu*XS+(F?v5!k$x^FKMSf^S*>45ByJ!$ zGrw9_3Z?08_LNYTb(m!;#$ljwji$@eLiq=<77efEW@RV9+mIw1=t&STpercPb3jM* zSn60X(8g$?-qi-Z*ICx1mL^`ef#TgjA?yjylX9O)Dw{0j`Rhh^Wa}b?Kcavhvbcvb z-uyqfq+@$w?_n?g-1vY}_O0ua91pYueoS=30q>l4-`&5or?I{mzKLdY782QBuu*HF+%id69az+YQ}$HvOzAi(CwVR!%K&#Jx)&2v{=oP#A0K6T z-C5chc<1-W#rL!=iKz|v4pp#m4{XnFr&o_XyM7ZhZ||Bo6YXc5*>htdo>9G_K|mb=(+r?yz1dB+iho812oe zT*jv>1VSaSZTXDnxhFY7u*U=7uPp4H;|c?urtKy-Fh6WJ4`tgVOm8Pn^YXcw+bwiN z53(*6)|i>*lj|N{>V9M|tC}bs75mauFdt(I;d=YS<=`x;SX8Z3W=NY?_zUIyu`EY+ zg97Fmgip!U;ZUUPr4JD}+nvm7j+E+wlcF`bu*u0yz9Lng+^Y-`8oaC(YpIQD)Wn4|eJ zBnfk6=R;Kcmcx9~>&IoX|6;2v0AyKGeR)0Q_(`9byfaM=;rPT&z@|jo7+NUj^I-u{ zv;Txrs<~L6WVNUlOnYb}6Lg!%{?d6I#sD!cl0pbZljIN-Wi$z~I>Gpf3N@8OXYzr& z0!;^x(ULPn%m$JQIOM=hWjP*R!eb{td&-dbA}4k(g>iM|tsq`5xK3K%2eF!}hf1sR zQW0Uf5HVWatRRU)nv+F!Mh>fQQkagtV(;x9cDCY!B0)SYPCkrM${-8kJbg%bBZ}GbRa&KRk(sKhpIr_0mB~kA_WZm z&L>D)ILyTpWYVMj1>7`O{5tg66G};cN>hpoI_~o-9UYgI&H6RMZ<(QALcZOO%-ORl z!jh4c7GmUk%=XnzIXc9*0Cp^sW=oNVfmfd zeu`X`RlIp#jMaIA<$ZUu>|w(nR1W-L&F694c7?5YXie7|b#auAXcOrX-!U*Am);j$L5J`4YB}chUm8EGeu&R z4%rN|eo%$V_oxz8$)^=41(^wW6oBTK84JcfPH)D%puO;=S}^@xZ(EmLo89C%YS}2c ztVm_$(x F0P=>v$d!p0!3~fi5WI_88>ZPfW&=`gl(VE6J>QA`} zJO?~p-iKqOF`3-BCx1e2$XB`R4OLitl(axh_I+cOq)6wo{c?dN$fXm?=?Y7wDuqXW zz>yoEef44g+GyEaf?Vqmo?fTU-tq|e{z}6-?>2>H64U*b`#wyczDPButOU)##tlE8 zL7unY9oA2G4wSgd<&uu(*LPjmK*&#a8?RKefeNh}! zrX)f?cb~ovlS^@7n^0_j62ro1TZ6rHs zMj7jid>fXyvNwM@Q#^6{)tKzfOngbcf|N>wJlvo(G= zTw>B1SEADDN%zZfM;+8x&q~5E;2>bqU0JBT4EEXn{wBU#;9J%~r#4ng=tTe!>|%g` zWvw^*uNBZk!!Hpu#(6q9scfzX8{lXbBx4<5*0GRJVmT{@!AXWU!U4m3!?&qvES-%p z*WXgZsabyX-M`<1zl7fh?;?IqnPuL#aQ6r>6lOsTCGOYJYfCOxbPt+)Yf>B@^jpN6JHMtSTWqd(-Gu)=BAGcX$<4 zjW7{Ybxfz?2C)U_B79N%crS~x({-|05Txf!pws;#eo?dLyWb2uY^XoR(0an%@)(*= z)Z+;==rI5U&&hSn`1uZuV*vAhI5ET;UUSUrnohrg6P?ypRDLDRdU2NZk?y%rV7Bb5r@X2GB9t zLv0`RmC~E@?gw>);1WQ)l7m$`F9IBME~@j(&wCeB$7@$~OXgFi-S*4&5viTWH%hW< z{??awSFyv{_2v}V5+@3$A*)_0lGbIvXj(^hpIdlc0hK&zS?6e~UqeI{Oh&$QCc>5? z;}6fq4Jy0nzB_!>bC1TFjtPifTPgq1JNHp9?Am@fCuWHKsLmzK6Z(Ouq4i)+Cb6=l z+*UptBcO(nlN4RxuUugxe8S#@i!+q=eamdggA1aPQn#|_jBhRp+}GG+7>G~S_(l&A z^;`rNFmSU5$uxtD0Bcf(b4W_H&h8|+*!qv43wn#?K8rpA9%z3(Htkn0don- z<=_J*VC!7(d8w2oWjQ(8Ed%!QRLV|xoa7JqRT(1K{M)C5y5se_{mQZwZ4~Ug+eRo$ z&KJKBVUn|I$o%Q0-SQL>YaXmRN-2XtK7de2X4 zE)&OU&lUN7i6ML(?H-R_D}l#BzP|zZSO8r4L;R>NRDRI4qlb-Vh}>YlDV5GtmKmI~ zw&$}*)@jdj6OI3b%vXUI79|$eSEeSQ9Ia(+G%zVOn|MB0OiY-nms)1FSZ9_FE0z-S zWDde4w2)*GCMswArAU2|nORWIC_Tgpp&AOdagOi{EzssDG7##jLRz+tnK`yv5CAKZ zVxez=+mB+%Kd|CquavwmZ2A@BhC@WdfqNlf$h}BqML;HGwWv%U)it7nosxAR%;-`Y zgNVr**eSDBh{>w}kr->$cCpG~YUdlro3powZRe|3c1*X8x6C(AS5LLCm!V8&XD6Wcd5~+G@kzHzFeBo zdtS(JG!jBe=VRDY^&GK{P@T6Ly_>{agm2EEd)}$LHIdWlDuY|u+eoZP5=#OeTXG*1 z>+16J_)0em9n})z;zUfC8zUJ5Pvn!M9dg?f`I0VHEOXlN7JK2pu88gJt|!2I71h-; zNi%QNZWVQkajiLr^pV@m{VbH6it1b^SYIM~gn0!E!pBr0t=P7##S}Xi!=z<#KDT4; zE?cftta9AiT`OHb)x6$QajlTFnq|A-dc1geI>%db@{}lPI(OC#S}t~44MHtIY0>bi z9JCZkq!Xu~J9}g$KDPis7v(I7J>4FMdb)A&jpyrYcn^&QNC7GWM7&ue&SI@{27eWs z{Q7K{+S56%mb#4#tw`3|oAg253aWa|jG@z4I<}Q+Yb)VYFIK1TvvpJVmS%tiktQ9A zP_%9M{>eDs^VxmTX0~D5T}<~fyRkCUYH9F@=jSK$xCq$>F6$Il+}-}?md`j&vxn}* zOuK>Z7;Ae>ddvoc?F@=W%;kyqrfM1}j>SC6J7Tmh5dCmU7dF-LjicXzGPLMIts)SU z7|NSSh_o~T%xW{STAAzu9jBt*y>C70`spVhc7U16hsa}`_H{td&l_cjkFx4uErA`q zYYN+&a7FdDsnmeC)eNVc_&kFMiW69$B<^eWSzYaAXLVdw1?}_`l5+261}px zXK7Q2$mk+_&3P9IK2JLj1C*L4T#JhmA8GOvh}^k%KsjYvu~ z*>0C@qXE19&L=-r4g*=2N0%w1oMTv%uxzR9&)*9ze2u;OSjG3W|8%u9CkBCmPkU~X^#)rb0 z9Lc$zuv}bjoXu{P=VR$E(DMq~#jiK;0rcxV@Eh58_)ebmClYtPzM6M2$qm2Ck52_6 z1W^Ztwa>T_C`VUdSA1y3Pc2Ve>I96|-oV%eF$Evvz|}aZ9SEQnWpQw?-7mhcKY&;X zRlP{$nJ{_Q!HOl*LXHmS$W;Yt-rxVyln^?W$R(S@v&T)5$NNMzeuQz|Log>CJ+O)& z_htT}IvQ!3YqJ{dD3H%ICmi0W%^qkw0#|G+?h{BW;8q}}IJ4VS)+O(U<_YNo%=Ao$ zS|G^`x;`WP`xNO|=*AHjKxYl$4mYUSh$|y%JM>8^ZGcCA$uGn&{pH*H-^8WuBPk{DCyNDLERjUw;a05hc2Qy#j>D|KN$t4(1TK!RG?x4zrrG zF$Z^Lpc6RfeL$Bqq_Hp=b{f$yj4(&l3{=gxZA9yeoNA5W8v7;l!R&(hFdKNMFB>&S z)(Rv?8rQJCxVqSJ3dQWN8}K;q7T*=<6WBqhk@V_u&ap}`qtC({m~%AV$`xiO!ISk$ za%u??0}v}6;BcI$HP>*ua%y*aZ7gF6li{CXaEMk1E(Kq8yw?&DRY_Wr&ZfXn*^FYk z5#gH0E`A8l8668`_Zc2K8wOu*yeHv~yB+x@+h`2PG0i=St-l?Zc8%714FClcrd918>W9ji@z#&Y-}D|-jmzx+v$w5U+x!! zJ8L(Ts75T?zSphNv&cKwJ4GcTMNLjLfeZb)q9f0Z1x;JnCUgN_*b|6HYNy<%WVbQ< z@JzIE3IiOILvapApZ6f<8obtItbR#-!y2-9adgK|tK&cRZ>=Y-4c;t0{@1&FsLN0n zgF8RaetfARlAw_sjPcIuATXbi?hXo_BFw%4;|Hk)6!e5(z~#~LL)l&q7^JzO*!IS_ zGj?O^MQq$^+83U6NKE%m z;z)o01%@asV$%8;$`rEF0JI@P13YVM{L&@x^UwN{WX#YT(LOxO6=K1KyG{+Mi(&L7~##=H*T?P}~2z7${ zK)iNCZAH}#P0aCngT;k5R3X*~*dcH&M6cwXFA@b0QF0^1x}^cOhv@iMzs{(_tK~h- zl8uF_)!P10FKE*@u?6?(fl;VffqJusxfDZFkH2_6 zI0g7$jJ*X=9oxFDjk~)uaS84g+}$0526uONcXx;2?(R--x8UwUf3nuz`>gYybL-yf zQE&J6^^mU7gK8$s=j{Vz6zbo#XEH}L&lJyr++aAY2sFpX`vwn05AgYjJd--m+&b`0g>cSJsOeD{xf#7DRx*Q1+)B;G*3z^h)xhV?El55Q z9(rPTpdzg9;G69;+^)=L{Zb#7vVQv@ETO!EvUmf=HH1^P?6z7ho$J6CYU`)3P}>h& zcL3A79D$658vox%E=NjttQZ1pbjqRm3|k5ej~I^lVT@w4u4kh7H72(`(J|vcj5zP= zFj|^XA8r+vaZP$1eCXQ>-obZC@B_<7#vV$GEz}q`u+R@tK*;2O9NLEt#8z?q#$C? zHL)WzQDgTS%oOn=;b9J1&*X;h4*v#XL|o4fg>*IE$h@Cko1z?pt;1SgN35yKmfuj= zQp%thn}dk}?f~kYvp;!lWYVf5`|P3+v0}t>6-*XiczHx3jxSQ{2AUs-C}caRIOBX{$Lt*vR`FHJFQ- zOV%6QbOC|&?5t;CSPxbZw`M?V=ZOnPHJdb}Qna*0P+CG}wIpt*qNlB=@W^Tfz;SWG zlj)vKv2Fk5H;-h$B(=e;3DV^%qY7YarfXjcZ!6haK8z<@LbM2n@rWvBG4!|(mKLmN z=a}`*la-*FG%L4z2A?wED(DfG4{c%j=AYI8rYBQyRN{qplFbK`-izALkNyn^MFUSQ z%I1_Uy7*Tj?-Y0xaM_C#7!DH0?FypQ!FS20+-oV}1Z6q8Qk?l5xnYtxR{>xZWPP3y zv;z*+Q8hI5%^5jS2(CyJfF7Ya$mUd36dmxxi>Go=#)~lvBGYx18SQaL;DIq&tTsy6 zpagCuHqST13<-<2sU>ZI4XiIYp?n{$mNuNulL^Br?R|vkaP1qPa&yTkZU$)7&+pCR z_ZwE&n`~200(3fjCxSZU=*^Kf`gP*uB6V0r7>PGyuu*2kBDf|2S21dd?gE*>ManQW z^GNJXGU7gl<~f&Jb9b=2BEoNF^@)-KTM5SBu?g{i>w8Zi-teVnHD&nyt|OY`Fm!fl zeui{{*Yj;_#|2Roa?yHRe^*}W@HK*SM2w{v`TVQzz11Q3Y7SQe=a)@e4>*iks2B)i zGE;3EAe+p^FMCmw^;!@B%0#v)Qwb#Lq2{QF`vXCpaiA9JIz>sk#JNmihf?H#e2UOg zWn=geC?~4MABwsAhmVGZiD8H14Cz~PbH<`YaM{F#BiZ%u4ZKeqrJTVh^dc#xnfWoV zMVevJx)wMNS8F!Y@VIfQuvRMD@w*Kf!0)}w`)Dkipw!YzRe)nl&&-8rE3t!iak(c>XJ)PJt_s*20`MxWetu`V(8^G2MW1NJxfqC;5CHX96%w-eJ+@PDx(Er0R_4Rx^d{=;aDt82${kI z=@alnNc&VVj+`AaQ+Kp>PwP=7SVT>Dl|uXGaxi1VgCHF_e~Gmc0ZV5m4;Q7Ru{={c z9gm#xW|nqmmNsIBTLJy{W8WBP)!QLwP`16BRiA;%kxwR3^k*1vLH!TtmKqrS;w%ji zfnrSm1hVZux3u5BUwsc5VPj>}O4dynlAU^8S!X&RJnubAtBlXKfj!c=hTu0btrpW} zN`{Z6_t6u3!-tt=i^BY7{cewqg+;{^-HQ4ne=ztM=12-1HZ$rsB;kL06@eKAsp`y( z?Xcn*&jU0X>*BG!sC8D7HEEealQ}_`cY`<$wr^013do?3N*4#_nOAbRbPqI_t=W3u zrKA0G^az3(7RFyY=o8QJc_!8iJsXz1R!e1k5)8W!ACE?9%194Ty{xxxw!jg@LWmP7GgWF?@Am zi_MLtfP^3ug{^g0fc6YBd$9KO^~i!1U2-JlOb(<|X(gFWa#X*mIwWc!xOd?_C#Io$ zA(*Vp^-KHJCHC=}V2~Y&`?e7T%_t$mBdwN+M>DN_{#alkCM49j?KSF-D2Y4}OY4$R zP$rCI>^~~6vplO_Szy1qLwvABDFy5cyDP=AQxcRbe+?jC{tTlrFFR*nruZ^OhT$amnsqeTCZ?z5z? zfR8^Msn<*E*hlnr0Opf|h$FmW?2+vWK=SDTc`{S<8v^2u?WK<;Q63y+-UkQ^>dvLi z{G=K{1rd2cXoNmy~A)9GP-9Z(znODR6g3@ z0`3DG3uYd!S!|+ma+jo*@9j)`MM1)cdm6*k425M(5wQy;e}Ty1kZH2>32G1lwqmqzvB* zF9Qyk88-K21=0a(=J)IfS_ivQ^34HW|B?6u=m<<5da)3clFK*$Q_#W@a*u%ih&&}% z;w(2Xr3kKk1MnZALbKwZh4>@I@-x4ifJHI{XTi{9`2Pru2&y~_@E@W2cP0o9jY)ol zpXkfqJJ6sXf1*FTL=X|GKT;;B0E1S<|3_f{ogo4a0z*TQ7l-+K$4^A{C;GD!&1C=y zLZ*y_`6K-LU@!%O`pWx1q4}wTeGQ-}KSewb3nZK<_m2eqoeBMMW-L431w~5XyAKwd zDK9PyGztyi1SX|Gi$~?R2N9PwO70TWhX8KWfUkkbh4r07067QDd`hk$cWJ2_1yE5G zs0beAEtt8``VsMyP1pbP#1cdmLRH>(N06-bTVff9rU_eSLkeiP2IQ^_*F z+6yKPo(funria<%?Q00+AJ2tw17#38(`RZwUyjy4qKpH=D0E}36<9C_yk%&Y4ggTDO+ z{!|5`T|t~;pjzvQQclWXw@z#!WY|doOf9ritCx1c^OV+~0Tp%kut#E+NG}HD12F?z zgR4i&PsWeUkIawMQ;~?y|AMiSb9@8EkJSSSm?etMYD@c`K#7Qizq#?4k1)HXNzv!V z@4|sh2R@$zB?o>dP0TZ`RnZ5jkm@e-WEQ*5+w+3DsU-iVjPo_^iU6X4VkZj3TqZCA zSSJpu`=WATCv9Y0aSj`M9qzQ))xD1!HeE)_^%htJWe3Sh2M82AkBzW7SIIX3yL|ml z+%M1t4&c+LC88BUDGeUurd%i;1Dcz9902Xb>#L zIN;4S`NsnRl{*y9k~?an`6|Iw$R=F0(rbf@i*3TAz!5AYqWk3|hQ}q%31;3CLh2*A zacH0m?ZDiNQAG2&)`^aS<5>GT_bB%g_r@Ad;7#D8}(UyP>sv`%oDzdaI zJ^aHLCCjVLqohuKngB@_^!fc)JMm@5TQ=b(N`2k1$s+xwGgY5 znxcejrHali^B}MfK^_(ixhcL@9Psn03YCt55AC$HBC}3mVG^R7onb2e+)IiZYMF5q zk)j`R8OmjmWfKH&6ciDbn9f>h+{u<=7OY*2;P7L$Tep*72+6*{vrggMsw=4oZNzx4 zGHpe8mmG9(9EaIhSXzf&-Vf{=v&7vD;OsTe;1&QI0NS40fb&Zz7nypTk%ZnHHK&~C z2Xj}bim*-V3DWZzL}sM%LP%HP&PF*_;fxZkF+V>N9~MBZmN`)tHo%rSNpfTSbnc`m zdT!H|P+SE=<|=F8#1_VE1dak;ZQGO=H$#uLg|!OO0*Pm;^(-Q(#!N?ZOCra5XV-U!b&&$wEx2UGHq4*L|%cg@>QS>avRZ*PPI8$qG?o-&7th)4hbgbU!_yea^ z6uZKkap9#nSr<7fBC4Ay>LpYZo@+h%S431jF87dP5CPVnL)8@5z+B5W)Ud%uKRY{o zpi1g;+VUcmnrYLd?9GPn<(U=3Pjv`8U(={b&@w>wW`c4CW<~G1aao4EK7ZvcEg$&R z%12lK>rSCOtJK>L|25zh27J4-g-r9kU^<-8gNvIx<)@s95vO3(wg17;llXHEAsBG5 zc}0YP#`SNeV1+SvmGbBJd4RI09*QeCesnQ$>bs+gs?a=HEJ2qTfJIq-_V6K*_A3m< z6An=5-pH767z%GflGi&R>YM6al5!zqU(JN%;ZH zBixhWycnOw63{s5L}oC=K5bT@ z|Alb)!!7&^F!^I1$@(A2;eRu&{DWltpG_-2(T)E&Kido5% z1}YcfVtAD{5b~c9iBJzQ8O3#1n~+Nu(e(^J;BTFZIiF>7^I64q4i7%G^m4di+Ud~E z5@%lVxTz#=lecfUzc$|@DJO@&oVM+(|F%<*0bLPG*KT$V+DOoneaZy_ctjxV?N8Ud za6K^1e-nJ_#eRcmHP^D`DE_4ze8n{Zg^hX1opMle-X>@46FzOhPucoSoV1-oyI+qH z;XSf^^cExC&Jx}I(WdH0(LT%SB~iI3AGuj}i74yBNM`zgraCIFzEEVJxHc5#fb25a zV$lx`@+#xE^u?w8r5~6wgE%|s8lDypUqcW0_u})4;Y3-2Syfq*)jOzfnEHaf$m)wH ziuP$ZOU~4OdPf;CBnm{NkkixZrguowrDt|fUzb0{+LTBP%Utey$2_1Iwh4Okc)B=R zBn-d2z)0m%zk37Qr&MnLFSqdDpv)(v!py?{pBwmJjL^UNnLk91u(5-oy_v0}js4$* z%x6kg-|7DcaD`;bBB%}PF2BP{_W|nRM z%731u`unV-C^;HisRB6u zZvQ6`|99}`8a{y>V;K%CnVIPr7}z=f!mIx0>HnEwXJVpbWMk)K;{^O)582q* z=r}o<7&-ndzW=`cvn@M29S1WL12ZGwzcu(rm4D>f7#Timb8@i!@e}^vH&#|QI!0Ee zPj6trKWhJ9v;V)TVEV7i`ZLTwLJkhj&naMFWM%tj|Nj{3PkrY9s`QVM|1rit>i^}% z`?GI#p@LyOP(|;(r|J6SE&+_;;O~%a5%E9s9XtMoI zH$CNr-|XH~tuJgYXdgJozA?Nh1 zTlQ_H2@n|2h#s~czxl~}#i3V+-di9Pe{hBMpSt2w zwp(BHW&GNR%LDqsa`jxx$u8ZAV|vR5S_4zD7-i@g?k}aWV4LPoChpwq$Bu~(k@>{WrMbS z40RV*Ymr5|@ybLdd_QuJ^V!VoY{Q(gpGF?^&PSASA47eEPW5TkaK1@?@VAK&ygIxBwLT^S~f+w)Tg#6Wpwhc zmAswRPcvGN>5v9}j__2x;b_@9k^u0!_G|R6V7t+a#OBnsT@*dMv z9w@EyrBg_wv~a6v!QxHW#{N30D&J^WpbNl7jjJ7e!4q ze|IDi%EM{_Z6*X%-s-0wN=f;e`L_A>z(F0$ms)QFQm2wlq@-LAAloat*YDkSzF<9F z#mqp;;U_g$WwtfFfI6me8NKR6eDmGwpKj|!kRZAt=09CO@AF9S=Tv#X@5Mrvgf`a0VJn^{JU2o~(Ebc$8{Cfb1)uXgYe?*vVg z;A%A9V8T5;)vewxnsG_Z&tH^3vudgfw43Eau;mq{-HK9gBpH82@78^N)_SIJkD0&V4&pHjCXu0)TUR=Ml9c}tU~;5wz-X;Ni4I^k@z z^5!Hjini@sU5ic#gg~R>laGt`u~p_4vEm^FK_|cwC`W5Rvd(J-oInKQo=gDg7yaPl zcV?SMeNXF>z;=D_BeNjpZ85#giP8CZ@%Ywy-)iQg`%ytp;9)(w3y*8l>DC{(Y@Ft| zB#YPan_&5Awg9Qh%W$m%jL}Nmi@(N?`oDzy_l4NP{p^`G(d;eOi@KS zLPf<~Ma9iZ-qzOBbYW11R#R$$#_Ib*;%fWn_ZVVAyzx8)U{xC)@vKN#6{DfKB})(U z=~d4{yR>WRpH&A5{XdOcFa!1Cn@G!O$BD^G;_LD{4`aWk%Mb4CidVIj^G+XB(0`{d zC!l9LERJAyh?rkEu{dd7ZRT{a?L@2-mC^8W)#E}+({>XgE0>;sO80zx$-cXPYN7DT z@ci~0i_pwIsG&}dEOU<}KZqeAhDR`+Au@(7J7&pA`@0153vuD7R~Hy6`HxDG@=njUL7beSP!3}jzEI?ZtvK6d>(hnfs~+#NmoiXVL|WtO zeUiq)Jg8HB!kCr3(w?SY_K(Mo9FmZA$=PWw#MD;0>~W2vEUC3JHWGi`sN*%oy~kQz zx-F5kmD)}s0JyE9pvFDL2r8%hdCo=Z&E)cKm@>l>=Vu7yg*ZEdAHve>zP@VlP#Rm|%U$W9?-7*H}n=;z)5q%do0Iv9yb znb=U|ozOiVm$ZCg!Jpchisg1!5ko5T85PBmWR=Rbr>2FI9g?%$@Yt)m(? znftn)0!8XQs2cJITlDO^aaKGzv? zv0j0FC{t9n05*LCS7d!=EE2UqObY+Rgn++`u?=)A0BGObH7%1|zID$47!ngMbm{UG z{2M|+_VDAJYV;)|fHFmCg?Bv{f(U3$V|2>d1sO}25T z=JlAe+4Od~#Bb@EQy=yj{Vo7E*%WaP<@WA-(!neu&@iu|s99LDB=0BMY~G-pMRLUb zVp=wo#ykQ}cfXJRdW^vzuaF7_%Kp}vJ zUkSAec}`$&?G8-eFXp^8%u__Kqf6qu<>X>qc6n(fyEsv4Jo+55YO7*ZvPHnWfM&oY zqf%K7^($sjdgXT?2is!SpM1=&u-)SAgB`547Pdvs&8>@?r`=z!N;?GH23=Ry@t*|W zX|Cid*PhsB62vvNT%YHOy5mFZpTVDDCK_fphfAhI2E}0qP3=5tsw#rbG??`AfxGz( zM}a%?E85DwqhZ7Ht;o$M_9ejj2FCHThJA%jG!>IsbJE6i&c)Z!|00uYl{dOb0IP9+ z)q&4N1KhvMv?5|LE?d@kVw!|q@K7o~C}vqfv;oT6IH(j+B4*!m)27v~sc9G|EA1>A zS=Fzw$8gZEK5$fs7OJOe!E&`_UgaaJZE)509Jo8 z&VSAclbBs#I}&^F9gb=$Cvb&*=JqR_#LzI%Ni zgiViyZhXDsj;uBNwj4E%NiSG0*VT61aZoEv7k$au7u|IgZPAhyU#E>NO}=bo>|Zf2$;yfn)FX*4Oj;aB(@DBz>X?%U>N$WWns>5EvpL|IsDB zzV7r{WOXODa<+NLnga|-TOWp(E{Kc``wK*)2c2ER%SSs^OoYi}8p6(MB9B-6x(2aobT#!GoE`Y4Z-OW?$TBtt7+TC4Z zqX<|^W2Vb|aiY<$=?=5I<@f!{&+1M?ot>lh?h8K`Q39>b-_e6|;NIcZx=i=c=wB4q zeAo?78xwMla$bLV;RpE;*xemdU=?N$c#;Glp1~SXHv`ccQ`dh=IW!P$?F{3oNxjtU z+Yw`&S6C3rHs^pio-(qh4n$yqkz$;0`bCS%n)c}%?C>@aw0Yf&Htc&UK3OT8d?+ZK zdHb;P)Z(3cv}X6dCZ4n%TS!Z39WGm6lCOGvhy>y30<~+Aoe_KRyNteee|F_jd6Z+> z=&c}VFtgK<(ORp`x9bs~1sWq8ZWFs}dOA-pCctJy?bn=I1#Luqc^LDwopyeZ0P6&0 z;m8MazvMD!8w+Ti>O5n<>JpXs4Vb*T62y|wR#L$+;Y;_(Dm5;otyX_4#Ts!JBeUa7 z*-w9B>XN_C{QL2R#m3eVtMIB1>VPgGB_)Y=B#zKG zC@f3S1zsMU3F!dUrWC_qL}4a5#2ro~$td~2WGn!q8E_Xa08`)(#)Z#Oz_CsBq-~O2 z$|BZ$R*2Z=f!N25Xx|c515R|r_V{juD>UJUQWv+LoQYldT`aci`1tYGI`|UYVjc3T zOPC4X8mf0}W-u?JUTl8ag0l>R4p?g2z&UTZd_v7;-Wq-j^di_|MP=9CIH*mso&B}A zb;~A6FL^Uvd~k#~shlXnyNo7IcXlihCLTF=cUXOk@S)61?t=7dYl0)bN~&g!nE#wL z3+VoOfc>UGtL{#sR_+?rI-(<#BWT5|^OG+=K2{z+t6;lnp!3v-|0JBz>MR_$x~NO? zY?iU3$%=pOQl6p!cc}j<#OoBQjrErZhi#DNalH6g4_+Cck{e+Hzk1uy7r8`f`!U<8&Xc^p#{O z%G-JcpWfQmXuTfDmTcWRm){9<#uh#BwbwmaLh{D_cW$H+0+9$BXKiN*KQ8|r4iM_F zRTu~HU?SjZ09P=I738dRa#X2vBw?sJ{{W{jSaX~S-dsHILOQ6)S8yXuax5uKU3gdQ ziSIXS7*=nhcvbk)htp~&w*7jBxnuy9RV158MoFy+t5^-#8ECDJi%CTN;B}4hTPLt zF5dabh}(TdH4YD~W7u{GjH-4*wBW1wyA z>JQzWj7r_p_Jy_upOpLXd$Y5jPqnFSVk^gDb|m^}*b)IBD$|VG5h1>zDJY9xwS|_U zJRk1F7~-S`2E;@Bq(dl?$t+Os*j9q|_@Ye->_Gc*%>spE*(}GWAg@DlA2I6jIbBCU<)umY|R;9OtRfxE8t@`oQF|uQ$8}b zy1icW4uc->vX@?pl9nUHa78^+i%)R54f;39x`8$T;Okm z+F{j+4LD*kfcUv`5SVBLz*FjzO?4q{?yOxJ_U(w{6@^u-6O^m*W z?Tp4<*M8Z13?vj1Wf^5qRgCl3l|yuA#UlNh^)Rc)M#kT3N6-o<>t43aF;8U|iNFOl z@Fr5JXV2hdpWwYF9JRAtN333`1f2U>eny;X%zcQ2|4>fiYA}U7G`ox@FP1&Ik875v zKcuXN^}sFVch*U#rLFV^ErhI7W$;~|i)Uh4z7AO;Sx3;L)&_;_1P=M=sH`!Z)(YCd z)eRE4e8V2H`Tgqmq2h|ziE!ALb4L4m)-MNh+T0C8@m_va-KSMUFw`vYDmHb*788#w6ruWoG&*%Z@EP&2@de>=r%s&kTxd+Unr+-?tS*z$kBq@&Wr5uc~__h zE}CC;lblF>IMSVVp09YsXrQE@->NbLA`OiugeqDkXp94&iFfh2!D_>n8D#HHz7JX& zZ^Z}=wL$q4Og(iRb(cIYVG9!nuRA__`w`nI!KvK=_s+`+#_S& zVrDP(=%n!6R8a`%lDIN#fed>w_k3C2CTRiQNCy%U27)G^WTmOo1k?N0%w(sN(8mAp z@(oEfr?JHP67k#9X<@6F>et(EQ1DMD`_()5K2K=TYxYM`-lv3~ZC4AR^q9QeFX&>3 zyngq3jEey%o`a3ZA_h&0YZBLq@mLB%Xsh^*5m02r!4l90{7Ay243U(zP!j$lyCkx6 zyaTRYp_aX?@s^U;JYqZz!j*QNtMT>X-MyzDb@heLEy;->N@G~Y;Y@NG#kS#;pHB^= zlSwJgbj5zedpZG%quu+`uL)NaF>i>)kb z+jcoRlay?%DLU>}xbaD>#T5u^6Kt(XZWmy5wHc{-&Os#?An;%wTC(B!0y44FY!}TQ z#urm6dBSpWDZg+!1;-}TAd9FcafP#sCnor8Oo!4NoXno$qV2cUgE8Ya)a9btcLN zyHLg;E4UYlYdd;csAutW?)n;S0_r6seL~?FrH~{1R09BeCQeAVV(`@qix7)4-dApY zggy#7Lp;V(2{T7l0vi?`u#PsL=s_HXC8uflLVZ8|UyPfs!>T7Y(h}V~{TS%1T+x6T z|Cn0P^2+@MW5b*BtjP*8=#I0)hRg1tX+R3w&(C*tIM&P?Nrw_#==yoz^uN8V!NA+z zOsC?P(EZlfq53gFc#?g7cP_E){f3*I)_Bz1&ff|w;jE?!Sc5` zjW5|z5-XCa;JHlSYe6B6dRf*B8oZkaF2f64$qVnLl1=o2VePni6uDQ}-Ut-pW0owT>46}%4 zV#)#3%@8jgQp5>J6M6J$?r~BTF_ilxK~zVO#K_#v z4D2VzmU~#vpUhS#e>U{*;`nMrgj(Cz{DRgvQTREkv4}2=AqFYk8D8F)92dga?u=7q ze%p{)u@!ldysoe47^m5@8jZlAUzf)9@PZZYrB+&aizrL{;|8jbW;!`ZNhsdE&pqpX z2MM=0nvuX_;;b-hbzd!I{c3laF=2{&qSf*sa;^J)mU*jc*ZCCp+w!ZjHy_qCKiDXz(R$7`k z1gZG~;o-OB~*ulq_)y#5ql#VvM$HqylXOizO2*w0`td) zg5mb>xH;iC>VbG`;fiC`HM6LF-(Y>5EW@J=elM6t)rtB{4omo>2=u?EK+uO}6L$CU zQE^axew1or&`LYWLCwU^Lg@zI7@$|QUQoM@fkDKr7UAW;yt$c6nAz;7=Ovr1 zzx;IQX>?!vV4LZ?3c)+!HC!L05}MK7c`4Cgx>uf#WSNGbIQR?TcGxp#rBInj|p@&vL2Wqh^ct zO^<8&%Kydkn!PaKFkf=H%d1^U&BL}9ZwVb#>WtFff5tQnto+6_EaShlp?QHT;V$cHeaf1b0Y_!K=7dSR-3IiwA@|r% zO;pp-PkC3`xNcYs^igsl&*MlOXhU|Onyyvk)~tyNh8Ao|kP}cA^2|iC4yj^4r-Z%) zOffwMbw6<2ba$}x{jxLi3uof5qP%eZVdDu{G)}!oX#RWz46g2Tjk@!J#UgtPzY8LJ zxDZX5;j(8xK}KD>!K|s^+TjcHL*tm2&<;XY3WS9X{v2!_Ts9(gK{KP8sfz?li=~*y zD+_|Uv4olC`iD8RI`0X_(=dgkicUb(UNxzzJRNUC5X8@j(l z*tc4D#8>BSG7Mu6=^x1rJiBbS{q(ccXt?jNhGVVFLtAZDeCY|X>QZO1F{qg7`<9b6 zf=dScN;|Zr%Uq2;&SO(Zj|cN2mG)lBqorxSI~i?3`-ax$v6a!>_5LstZkO`lc#iM# zmh?79@(z-t`TMF=ESqZHzFn-_eH`@?!+1<|L)|n8RP_gbKGX&~lT(0A>lIfyro0^c z!NT{|Z(gOLV0xZ=ttfJCKsUHH^UFl)=G>W0z;27RU>gDJu?%q(WKumaI%4H(*X?Hx zWUEeA7@XMG;>+*jv*T7yR03;Y)m1^o9Z^CA*1Gh3fQoU zRx%28$fg_o&|k!^wtM-Fu$P(_s?CfSGlaE7l@aAr`Z4pqlc1iopiWpYf-+oJet_yG zAkRp9Q||lAl71DON&tRaCsco=39vF$sLtv;9UqTJLGBi8BX(;E9eQ%ec7b5Zu3Uqr z!eA}uX9nW%8|#7g0X13UaD-k9yTBPLr*wh~z1(PHCa4*#L0O#~uoLp!eyPx{VS(mz z?E?mCfzmSrO)L{tJ5}5tHITC?A&6m5YLw>_NLQvI*?}?C<<;f&qUtb(Qhyx!`A9_0 zNJx>%oEbWaq&&Oegy5fM2a9Iu|6OTff9=9sRD+PrWHyxZz3x{>Pj1^*0W{%T$IGx> zC*sFT?G9NOS3cPGmmt^~;is#rjEl~Yqks~3-U35f;L=rl)tnw#q;IGz^6lIwiqqL- z2qyH%n8(w0Von0!Bc#!;x-hOcB-^8i(s)|}&)$Ft9;;w?FNx4{CWDE!H;EK6+A<{R zprJq{=yF{Q13?^g;=hX~8=26GgX1XGQqVRO>Iy2keKkW|nUKUoVA%Q>>HTDY9p!!0 zck({N!r8ew$s&pBie%B81AbVxUpkmppo=+Eu_>dnD;`!m``jNDwg#JOF$&>lV55)6nssYCvTo^%L>w`C zqcvv8=NXQn>3L*wQhv!#`_}ZnKh{t|HnNe9nj$F4^RMOMXx%hn8UkfQYdlO&&~BjI z5A)E>5QzeeC|tY zMBAL%Np3{_zz-76U)$5p^$=@4Aw42Rd}V4OuW_V=F`P(i3TgWX5{=CqDZeDV)C12| z{Xp%KgoebJIZTvLsxKIT9Tt8b`hhGjtPjj~o%MbI7u+;q^X9!|$LDPc$<)%i)X>;i z>*H}+nIORCaRUnJPzB-3*_RC}Xd7{Uh_xBRhIKylEp7UBICalEn{2yPc=p7Gal2rs zcO*|-E>I>6_#428j05!zUQxi5jQ>QC$WVuT z$0=wrTv0H_)|fpehIk<#=|^#_yMmDc6t!^9PkFwul%LpNzrd=c?3d;q1gGqf=fOV^YHQh;M4UhVr=jk?DpI77vQD~_YTuuSCiIDh(0FM3ZHK}1V?r~q(dV4$>hJ|o_G@i zWy$?rtdier3UOT6M?B~~whwegngOO1)~yo%Mw5GfZ8cAtR63nZbd5(^i`#N`=6w_D zn4xmR)`mL-)H?QqU6wmUMR8hxZVIRDG@IcJs{g7KtL)r^PJFj%1l~Tc8L6Ho$A$(4;MJT4Q?!NGP?hhQubkiYVv#Ij(U+Oe_%s=5t zmpQevi{d$@MQ#Ct%rX%lPXQ*PxRMzLx;`t$k68;3!fPT9V(c{hh|V_cEk%VjeiJNlw;*&0xeBE?awo&bj%r z0LDX0_K1a7f7x5d9y(^5fGNZSrVS?s7{a3`p=1Kus<2_KoeHTU%||+-9aokSAEZV` zfS^wq!vt2n;mxs=pi8Mqq)_?+1h^vQF#EF@4RnjvYEnjT=DKYg$!q$aC6h5bDGHHJ zUFTAa%?0tZEp_y4n3oP>)rPYd$ro4~G~2ZmzFH2czi^q}GQ8|e>Wr|)YXL6F;D3B4E^t~kqmgKX%3e67AP5;%YV zb`^gh7(qff=H4Z$vTg`~ix@qM3W!MLouvY&51l1)jfpK|Ceo7Q-cgsPi7=ooH)k^9 zABnYZn+T~PosB|~2Vot@&d;MUQ<$+bR$e9v?Jv|<3UtGYuR>J^6b9b+ea{o(puBQK zTE~aK%r6atP@J1_6Ju))Ml$0qdBlW!tyNP>Va+Culp9eC(w{dvWBr zzFa$n;KHhix3FP)P}!lOX40`Z{5lqBwq?a2_4zf5UdM(&gD*w{bXFbTW$(k$*P3h| z52@qjzM5q+pPR8b(V`uoUFfX6^~WtRiec;-Fxw$4-) zVp!XkfGl)R*@?0c)Y}&POaXibG|ZrSrV^UHTqN0Wue$Eyj+B|gk4xVYzQNK+CE}kCgy*vg1=ThGd&BRaRnYDi|B%r^AKMk zGsaNfL@ox34SXd&KrUZmXNkFT3%o$~wt>jnK~5G+CD?g%tp58b&&>~zFSZ^1MBzai zY=`~8;GzC3_4E_%QS8DMCTLK(3@xmr28c$6{0Wfu9IT*2)%36*fZak@&l|wBV>^+e zVIr777GvPndjf#sq3KGoSo~&}lZn*qp5}7B@rL;%gd_w;f_zF=wIR;yK+zz%q$Mas{Y*8A z@i#kYy>`+Zz^HUx4pMNu*tq;wN|xHi;4_?i;}(CbTd)}5Epx;R*JiNXQC;Rk<=|YI zfRz@UQB^0HpFYD5rFb-mr^bhT7E&T-y) z&$I2UN~Itg*CR%ydrk&!WH>vf6y!{#@!aK^v=a(w*>t&0>>)aKZ&`5T6|p@Cwev$s z0n^Z#KJip0z^(Pb89H0gY@or3o%ZLKr2_}|Q-ZG{0E?)8jaKQr5ao$=PJ-Q`>`2iI z0TY^chEkBG`cq&9PZ|N*c$g%^3V331MZ$4K^AR*;EBKOq7+-;13rdA@|wQ5z#dL6?!kzT{!6t>Kf@o z?y#qNgTE!D@mWzlx#q-PUz_8Z=U*^F2ms6K6`?k6HFvIAU#j0lAX~9d5jfDZ?YDP( z*Zf+cXrm}7QQcyD=px&oH*D=JKctk}b%2ux`&MrgkXfE$2fxk`Z9%=M9T^@Wh2j); zi*g&jgnldZ7L_-&T$CqeNNW(mCSU{o24IuQEYKnrm0&;l`7 z-}llUO72pAq1q&>F{U8eVrB_6uD()X%JYfAk^x4Xh9Xy?Fc|30TnN&grrP-iZ73Px zpi<^<)d(|gR=$#C&7AlV)zNu8y&MThOi)hzEeKU189R(482#iNI83qPjxL+8RAM#! zT-(rPdVU!CaN;EOxdpgxhw@`Y41y)y;751OrZ;`ehZXHiK?5+eRw1=ib6)N#hgWtj zfe=znNRv>SKZ_8!Nfl;*ipYLR1J)_FTeohlZkx61%NFQ7-^SIx7d+b`(zqX+u+zCi zJB;vM5_)}{!oqw*-+Y7ibe(STK_W5&lV zB*?8Z32lOwRrOt`<#NlZv0qeb>9v3AmGPvr@Y9(>SLE@pnyb9r}kwuXOC(vDv9 z_Z=s5M%8mK=V6x1A|i+c+l%t4h)@oFca7QD>xE0HrDb2!J%%=W;{?Xq<-h@FIGyA; zOibSRSK?D->=?@1P{kO^>(ByN)W)wVlRb~~5$p(CG{o8o_m8Muiit*BGu8YR7pd=emyq?$4~tsJXp`1o0P8)#l% z#!hE97rcM^&v-gAR366wgp0gSOCylXUiB+3qM^k`b`#v zmVFdwGl`WGp;_uDL`UE0fHF8GY>Dvo|;gBJkLhBwJ4QG zE8JecT)Lz_!s+?UJzTbiD4kkL2Z%TQrDrsNA5!8jUheZvuh4!+K+qS1|+qP}n)3%Li+qP{? z+wOk7_qqG-Iq#ga-hFGm_5P@;sI17SjHt-Std)_!558wZOr!zajHHImV7rf^8DX~C zs&4d!NW7WXaeq%bVe4pS*XoIXo`H+zW` ze}z^A(xxbzwuHRVGHBnf`fbo3a?Si+BDGU-7C>W(n~l>?9G5oT1DL|8)}V zd2=o1Y5RRpIEy3ymv4=@7u)n&IrWcb7bQ{!1nru`*eiwy8rKs~7bm^@S5uU9P4r>N zHkYSj2Y8;JJ((6$}$3yB&#;aipZ96;Wa_TXIS(P9a+^;wdD4#dK z>{{ptbTbz)7s=R`%283FqhhK!Xic}xwIr}Ieg=3FeT;Ldb4g?;<0Ru2Pp_C@JP0x# zJp$4%ElHN}p@q>{hm70Il@y(OHoKE2|eawRAzRTx}bz<)`w` zgX-fCt_rdF(v*ubg*WUTXb@mRCt`IgdQW1c3NNQ4|HTS6){_Bgt27sH@0(^JmXFt` zK!^rJBfHMFm)g;Vd(LNx?LDq!=ritNPIsM63~!I!yN8hT%iRI(fp(~#>KQ3e!eSBg z+@G=>>@?5%cVEvyBqL0bRt`)=5+dRGbOyst!UZE`?*btGNl`BAAeHK*L3OeRr732t z>#ST@E7oZ%7Hxt+Al+cuL0dD!L_veHCQT56Dcp8{;CKOcTtu=6$#bw~wl!C5~6Y9fIp)g84#bYShcJO?eqlx65Lmi*t0lig0<-^sk=~ zjFos(F-`EAc-q*gX+L}`_X|bkf#u<``Y&v}Z@m%U<~~ff$}Tr^v*a`|$f+m#!BMf{ z2!>RSqDSiAb8?FLFnohddx23%Dia3H8S15D=qielV^^ ziMAFkpErfps7lFmrf4-}a38Rr-^!D+svkMY6q&QH*GpsrwnPQ;waEK1mnwPrgj((uWZQ|H| z1Z8Ce3hAo5De5Iqc&7e5h+*7rf0z(#-r!iI)nYq6$-L%tBVXp#a=*tQ&3|w{Iw917 z&>MSqaMHQ)(Vg~!nKkV(H4JU|c})?rCcOI&{#nVO^6-mRi`h~+hN4cq z8atB@=)y()i*fUp6%4Mo6>Q!sfviVYnxsr6GM>yVQo5FVm~+<2@8qT~8{vnsT>RJI z0~vLr(HMhkgaqNzPqTOUUmt2lLV+JtFtpS#*JBDXPLW(7CTlTAVUnl~njtr(GjTUR z)oJgp*F==eU0t#)BznC}9DF9zyq`u5DOtFT;^Ir{O@sMwuQ*H2Pra{)J)Mu%{nY5xGiwgks(%sXysa*IszJez#WI*>@X9Nk?fUl%J56g zyhXKH+pA{5ZjQhAA{i2*Hs7&+6+RzvypQ^-lL>V=oDHzbvgxlA5~)WZAnq(Eh=JFw zXA0tj9D@?1_ebh)M8LxEpUK`_B zkg1Eyj|Dwe!MfVO^aP7y3-wAC_~k3R`*FeTz8#KX5*wywh9;~`Kq}9}ES&{kAjupN zVk`JWD>fC39|Jo0i@KY`D`Uf!vA@ENqj{Xyn2y$zjp`jY9c=owzXf~SElx+`IKp6i zZWcdHa(k{;(A4UC)|rVcWZvut%NHTO-vzgFSO*hq={@#Tv7B<<$&QAPpYeD)%o3Ad zRDt?H*-ipOjn#R+Fb?f_6V}4#0n#HhA@eE8{RDyZ|E?HS$e@OXINJ|0v)N@bCKV4i z8-T*nRS**>o0XR4k1ifb(8?}?HYl0|o;UmTf^dSfw5J+~fUcWU$0f%h#t^C_b-ANq zicK%3BfNPR$GL`txze*(2T7{o!7bw9)ZS`eFD`Wvma=#&14j=B<;=vXv6n~ zFYf3+d5)pQWAc6lz6$NQbf~6xPa^ia=@&CG&cUJ?MN|t11PKw_#^;YlB9{?4xEfHi zD7P&9Fdv7~#AyBsN|ZTUsaLsG8B-;9NITnPdX1?FO`_5*K`ORsQbJAR^$TNFI-}Uo zHjHlvF&e!6E9;jq?zLB?%=jpH>Rk>~Hes)P(rL*6?$SaaE7DSJVmFNvp&kqIZGMFc25cFfgRXG6GvKnm$i z-4Bdbu#h2e2uo0{7fjZnTh`-0bs8=Z<`-Dtv$7HKl?!UtRF2Wl(L;%P;xYG&#-KEm zF4EGs{ERQ2&$4un8amf+M04yH7v{?vtkj#`D6V_2UyzaBXFRv8ox2D>{~zp*Z+_fI zE|S6A0N8LWQ&u+(w*p-50HnKROWotoPkS4XhPtt_ktBq<@uhJ025G~Bad3yY0k~{H zO>k~U>Sox$N3uc#jjrO|pToL1Kc1M22y^^e%+^iiJn>7HFVYWsmSC%CBZJqwfaY^N zOmTLF)6|?OE>zt)XZ_Vp$PycxV&~MlJA>n{Yk*@-5ReBN(s67z@EKFM4(DQ};$n(Y zpgdkWP-j2k*XfbT4V$edmJ?KtL|Wx2F|h9l1m~V3+ED7qY?B!RzLJsTG8UP=aIqx) z)xOWwIpA&vreyW}+}=SK$5~j2ek&6|*^(HVrk%zee-$-#o+{u-ZsB+;wTB*0e*-tQr{1>g^%5i&#v9(UP%sN|XZtv<~$ zje)T{;QJnL{5S9?fq^^JUX2~S&m`V*r7~mRWO5Q;$Zze+h-tq- zHdw(chep#!7f<#=nfPC)w_u%aIlpN2`&@V)le#N>jQ!e?{{A%(RIRL@(S<}YZ`Uwa zZbXR3cDbkynN|ppfS+rZAPOL>%S2|}=DR(4yWNr)MgP_oB0K%0&EwYDWz)x_L#bUZ!RI7>{B^2|$E+_U^@369aOwQ- z>68$Jja0Uu@o5VPj@$I%tFPNZ4#eQA`EwPAlBf1Q=jUH7eYI2*lgv?eg9Z%g?8x-D z%vO@#_VOrZQ5U}n8NbuFjYe>Xwt@ry(uFajFJe)d7y8(jDWD#ZP&aQU5G1PZH zrhy^u=dT{9X4hY#1HN*$R`RgZei(S{YBZT+X%{Bxi|1Ka@Z`3!th>+0^bTKtN&?=n zZ2!S}L=fy-N0H#(y5s$vubYuYEPWF!3i?y7Fx{8n8_k7RPH2U@?qWQY@x_vYiThLF z$itGwLo`fURo+P}j^{2ws@FAey~|5UV|Dq4&((k!Jq|XfWtQaO_jQ`C4O2N@#LVwG z34SsXPaljlBX`rqmC=Ql?W(fZs`2l;<;A_w!Z~CyoeTtKz&Fz+($fd$bOy|GQ<3Yl zp&PD<09qva!4gYK{p5k9Xlib8N`(4#d%l8MMl(alG^^m3_)8{kJv0po0b)al zkYR}kDL5lBnbx}75jc*vG66B2+ZibL+Fwf=7z$D3u2!aXF*%p`T3o3Q$BF?r9D4P9 zrG$1&ho|BSh(yHoJXQ-BThf&91qKsiE*#c6%Ub~UF=)>H*hQagRiR7CmP;2+yGvAH zpAd2N)Ela3=4=~>X!5SQfI!i$&8^I@Hum61h=cN@dwNPo(ZH-M9JC4xCSP%b4R`P5 zd>rU}cJN!jYZi2bmC3cMw5u4CFGnbyrFCiaQ_oo4S1bsE*y?Fv>|sO-(=MsOiI^Qe z?TJk5kM;KS?tuP5VZkPe{KV{ug9=3jnYY6y7P|Y?eCXT!1Y-rI^;8cTzH>;{B&iOq zL^1@aZ0sn|i)Xb%ZPQVxrl#%1JsOPB!)93?!MTGA8t|v^A(QKoZs~hR= z=GQ~xyJ8P-f7}Xi*Cu{Q60uaiQeu0|)0EHMH~u+2>38q!NtZnedQXA4hmut zi%~><-LFwrFX3CnQ~EGPhaI?zyFeUo#fehfV0%EcUb;HkbG^B~Z}Tft@C7C$-emK2 zfNPLO2k*+(vGS!t7v-hwNE{p4Ahdm5$KRk_C#(u8n(JO z$45-PXzQDd2zm)bZDbU3j9QL5++fMK8XcaI?UwFM;AUVp836#HOe6bv5ZSTscD!*0 zUALtkQUi|y@ItxUAgVofK4r2wYWOP+R8$1BzPcW*k;@pmZ&-~5h_$+**ZnvlzT01t z8~X5nWN9+3m-URlrnId|Y!h(Wi%DvquzRvEle`M)PEV)UXW`<&(DUTv1rtQ zSJ)na(%w45b34E8WPht%15weyNK|02?G+zPmZH(bt%!L{sljM=odMdHI+qHhff1F+ zZzD$|k886ChyxormN;b1@Wy+pFi=!9B>IjBhozh@k;)t4;%fspnHs@Lx7CN2xz8ni z0LLLfaw$s@RRoY$^fc^39_WhB+N~XXRk^STVYhZ4UuIZq=BFWJ85pn#TZ zYS<-_s^83YYs)@HfG46BV?%}3b7179O5^_IXCO{bT{29wLEj~Zm)avk`iuYR6GE`o z)znIlu$A*or74d~W#wz4Awz=%T9<}ZP+@f2W6((a35es+>2~raeHU6d=HWqsgdcgm z7s`~ac+w1FKU`5hHk(=!yDPaOi&VFyAR7G|_;%jJZ3eF6OyX=Uquolq_(LHUIGUE7 zU&AcN=OyM|$0Mw>_$|vKIZR(%ec|-`?Ti?_8Bn+xbfkPueB!fi;yc(hxH|SC1wu#d z8teM#t0y2G$N)x0UIqyZ>FVJCCI0ISxK>Z?N<-W`H7EzkAWTzCf0uXeXG`muMsAoZ z5JPzWB}K;J3ek0_kL^n1jT4T>(qngmRxgv&nHWts#iNm#iXhw=K2qW zI56$7?nL)ON8f+BjCea873D;r);@hh($;jgfoNSc=!Ur&$N(PDmXm!!?##AD{y-olg{2~_ z$W68X!~KeY`OLLC!tAY2ycO%)2Pj29$6)_hLQG0ZL5CAnVe zOeVTSObjazADIl_jw9!bVuaNdQCjL68@gdFVSykuZWyKyZD11se|muRovYY@jcqD; z5ne1YRPj(W+%~;!M#v&wJ(Gd*9tnX9j~hImV8ahGE689oI&h6aN1H)bXy9(9)dVsO zOxz_g_^UYU0KrK;UG#7#;nbr&2b_Bm@7~sll;4q2sq}Hr(PJO0 zzj-X-hCKm@LT^d{k9F=AoddVjs5#1LVhJ8Pbv}bN<$K$T@-#VlKWIT7Y^XC|9HcFa zu_yz^7MPy1#RL>tbZ(-FItmxzXLdLQ92|dHndmd_+(phShzBT9ZnSIn$Mu>=%Pz>E z-;wfhxV{lHHrgt5y|9cFmL~MDqeqoc>FcgIqKpOM1`l8$L{oHzOKrL5jbz!FZl7FA zCh(9mWsBvn$AoJwI6BV_ew%#p&g&?9XQLK-52+#_`2JI)fia~xvd%R-(Z>O&b<&uopxKYF}5&vJK#Vo|Bh2FI<_{qP70#(~#%yIr%& zsn>8|{o&O8`Klr>jsK`qo18LLf%W}mldJkJhQyzGfPQE)-wCi6X|4qWQL=|}(xHL< zRgkMe;g`(>qFamNiQ?e9mRH@0)Q$FnpDe1JOo8Gt4iFfFKp)-=tYvXkH~MKZmG_9) zqI!OpGl$?nG?Oz~vv_QT*?9LC@hH9TzBL_wwH5_3ISNm;3%E|jtO|I_ZQtAcEa6DV z5ImJt7`7Oll33MKj?;|Rhc?LL=G0hJS)P<@oFSY?VQS8Hq|A9tx<$_gL7$WN=e7~`X7 z1R0@vWsC_hK#uplu5%!b(@?~)#AwI8y(?S@GE&VuBcor>s+#CQ9lYAGCdpYoj{?Oz z7w$RQ1&MX@bqXqqo{-41pH0WXK5DfoEIBhTyq@68YtM~A@BNlihCD71r-lzdscs;{ zmifQ|vBSR!HyKWJ#hHTCz!Y1=^F=9r=;cf>vs-%{Q?Cm~4s7AXsexyKBZI}8l^+eg&_w*|5;DnG(Ch$E zl)1@l&IX6Br|Q?UbE^anrKV0+E?gCrV5uB!q=mI5#sjgYTKByY>)4qpU5Q$N5{<0Y z8??r7cMO9qQVwL8K7SK2wpZVyU}SkE&>1CEL*6*yoH$5mR6Ty~^jo@PLK;4g6NwZs z=n+mbr31pzZn<*Gep<2w@+^J^FzoYj{;dMo*X;3efhog9*^9YX!~N>EkQI6%L|#N$ z^}>(??Cf4{`u=V^Mvl8u208yI2l?3grW~7qS@(Xf6sviR!edFPW*@3Z61`9pzwP<* z*sn(6b$UVLNk;f;vgiR0-sm`(mqlONlzI$jXmbK)X?1q+$qHt(Bf3Fs(!vMK+_K2o z2SJz(#u(t^f_nJ91rHd&Q3q8ipRgd}n-Ry`J8f*9poS~ zvyfZVEpHlnGvr_oFqMJSdDX^9+mxn?e|6?zI(mN`M?)sI{K+S=mJ&A>Mu`*IhaaMB zU;#G@i3173{|?(bh_)t}1cL%c7aN4PECIaoUGcFl{mVcRSe%YZ+#||rZptk$%bOir z1F!eD&bOz&)ie}pRL2uwFeT)Mu2*0l3|fml0()Ug%C_M%Xk<+{$?XcyNtACi8eBHJ z*?_&=-seM|rEwD%40g%0tfZY824bLxLZ&9oYh5sLGznD(N^}==J@`+a2cECl`Shkg zm2AwHTbogqX#}N=bb()}#p%njYKf#PXdQ-VtncPI4Mahw8jz+92bn1Z8@w&Du=*dy z45|skgeQq}L~990FnepsNN`2r`x6lI3H47SR6@Q8^_BYasVvooTA<374Jjb&ig`fBZ6ie0H#^gCaB)KX%uu&dm| zD#MRcNnt^n@6?d$hmBL(wYGj?Gq4{J2fgmoS=m!>s4aP54mdmmXXllI7mgo0b9qNY zC?H8gd!b{@DpKAj4CY{fgS_YBUw-V9H9_OEhFg1P@^iqa?!1@#WZ^B-FWmCTgiqGL zKTY-|D>T6HtEaeETO4-J&*4}5`*LLR@_?t1sxm+ zLf#7(2n76*4TBe2LEk~`A;Ugb2iMCV4;R3!O9$5iQR$VyjP z(@$yuX`lWr5gn$=i%^$Q%`Lmv!R<31zv)cowFT+z1-EaQU4vR*t-xCOz=hqo2h-c) zTrskK!rRMyWkrbqWbtv|F5qJE6Wv0%mm0%M_B-k3Y$`YApY-H{x#xuN0(GLRx_8j0 z4)-m2yx^ToUdwXh?z80i%J~HwII9b+;A|a{f;+_6V;Y1 zlIpX<{F#VW{@0j*{P>OxDRfbiFF+Ff@bOYJSW`X$us^IK@&!UbJ$#5mU;>2qb^Uvq zsPm3O@}ltB?PmE3fmyR3QLg|`XxX{>9F*3rQKv3$xC$StRx@~wmfsqz-`R^M*c2Uq zt=XR_Il6QKb5sPtd>hYYS;jl(zsR^{8#O2saN-}-Tv+V4_RLQi1RDh=zd}x66CMKMw zRVb~3Orcx1?7^K$vkMcBahZ>lb4I8pAr5=-GW{|*)_;F(;HAJ>$XW4fFowp8hULq# zlMi;xatkEhEupwDZe@H?E$zx>y$f?Kzr(#xwr?rVVbmT|S&>7&L@HO{b{vwNnMOiaDgBDH9=!RCPp_ zD2z23y#dV$)d@Y5xy^*tT!MK$D)|B9!{hYxE?pk%Y~M)WRnQ(__uMQU5RCBjTD`Mk zzlXD?q#ZA7fq}C^p1RMuiQ!1KX3Pk&ruyQx9Zg?j+Yrk3FB~?r48dRvoR`ra(|amf zCJ`PLv<8iL)rL5p?mQ?ulP|U}E^z`y2}2d=gb~AzcfL)Nx%G|frA_r=>=4+Bc~HEE zQj`*sGZRVMl2aSD%oLW(U@LJebF&XK~Ym7d(jdU-Fj;b9_cG`0Mi`*5G%UEw9ePA>mN~cfRQvRJF<5JlJ0lubsXT| zMZHJY&JB1ZZ3u3u4g@stq&1Br5FSUSq80TSOvp4>vx23%X>@SLhVL_q|dbk zs~L#xJhN#6ab|D=YE`iB65bwc>|U7Ti^Iey815RA8o^&- zS^{;)0B;ip*-r5g4=VcB`W=mOB-T;)ArrntA-%|g-H|30UC;K(tzKH<6|IHOJEbFG zru&BSMH18*j5P-Qwy|Y4uR^=&AWu=8t!AU+HAcpf<73}(7~B+AzKj0~N!TMit={Kp zCTGpVugb&AHk#sdG3C@1wm(f!Jj{o`N_fs&D4WDcIDf-x_eo+Vw#avaHHv^ zM$eiB#=*logVnS59sJ07XI5m>z2aFp&6cn8C%q;EZsYkddDO9WIg)19(>YTIA%Vys z8pGjO;j8MNsU{DjbiysPl_H}}`*maXiVm4d7ppcM%<2JcDdGyMP=Uiu(_%&6$>=y;}!YI8yn?Sso%C%k+cI!@}LD2=sl=uwv1T z&XIL8_sZHx8oVLR@=sZT}cDTt8b#(;D_8)uIxS)770flRM-kSj2H z-p$j@b~+O7+=jBT7#AFe39sSoJq$iz(<+(8MZQlmTxQzO-lL{PEWEaNkJ|Q$2|FfL zz(1AlCZCwK7|jgZ<})N4AHyqPG@{#ogi%JWCgdBpMVM|0&bD3F~ROA9om z@Z-^72U{r&#S4UG&WS6F9P`+O3W0&z9r1+(pjXtpd@W46l-R_UfD))wB3c5aXN0r+ z4`YIKOGAo`baP~9`7#@*DrM+07<(Ev!Yx{@#7HU#{+vEt_Ix#qF7cf&Xwp>Nt!h=% zoSZ2jkD-DviQPfZslb~Q6${n z6^^v?oWDPjL!|6C(*qJzFPX;;DR9}K&8r^`uJdf@hdy1`K1g5!pfTua zI*Z7#YDRd;0^pqYqojH`_!N4VT9dd2+j5alnc!q98pu*6GY11V-qING%m?fZZTgd{ zYsX>RJ3d;2!NHqQ3ulFeU;7$r za=WVnDzy`{5tjEFjG7xr`hu35{t{wQJ^B(cJo8pzt&kXIE2Fr8TJ++9^>dr{RIZ{mtDeRos@X1tDl23Dq6a_EAMigXcx?~k{v#J3kDGGZ0qD1n^-ND74az|B>Ds+tXk z)|hZ0a~Fm|vI7eO@-Zh6by;LXEdiYZM6_fiPy#Oifce(73{cVcJV*syplwUCAFI1b zmS|Zvbm3emF4jz@W(fw*BG*W_NNMj@-&XhsP+YQrWtjK00HPsV4&RKDYjS?;F zz1k;5^A43m>t%j|qYGm6fza33K{oY#nwY@?3*?uu>9#5VDFpKsSqe>6Eo~_86|x{U z^20wX%JlKL1CBu4c}{CYdipb}DDESfM%JaY2^0^RepD^!5+LT6C?I110-n&5FO|_x zgDyMVx$xPbCZE*=^JVY}^$wWn;YnD|O^&MqWc`3G2=w+b_4J`n?1VY@eCO79v2U_a zGwqyc65ENWz@0EK7)+_ZodNgec?7HnI+7L1XsZ3QP^jPFs zI(q;8OwcQx(Wf_l7xjs?gcku8APHF5=EBE4*sn`z3yv2!#*mcCXCxZH8sK6|unUS2 z(8!B2LKpwlWJ%SyOmYzLN^yj@Z*$Lk<{0A@DWhXTd*RqTyE$9rkz!i|W1g5#+C(4l zr%w{E^%l+Te$jI7Pl6}DzKNjPFU5dHz?NOeT|+R}ZI^oL=St&F+gWfBAHcJypWor*cq*Ur}N0ZMCaHtcCwRar0AAf=Ee)EE5X18-6>x`%t3 zUC2HcqtyGx2iiM9up+{}U*cR3E{_;#kI$_rbim81g_2eXCMd=AD364D$>dwZ1VKQ+ z)tp%^KJu&E;6PyObQ>XiB!F8g`Q-YYh2OBiGmJP(!q++VD__kot|a8>={` za>Ro~S8rXYR;PhvP^xtKJy90d(mMyN_9ja#gesGG{=CisZf`;_lO}H@$aUIl!!qyT zOAzrb*0S&YJ|2!1J)X!|RaH%_lqDnEQtkxG6A=__ivj&dY)x?LyAI-y z!Io`v5jq_2uorM}8s)L1}vFCh}+i9eTPtZWIs{sUygjU;u5E6eKGaf=bj+zBH)2w3 zST;`sN70~bfSrhH{N>MXcL#l#D5R3yI#fTt$1u+P)}vrXPQNV4EFVR-%D9ql)bK;( zNBnrGQQfkM(%72B!SwZ_A$9W&n&lh|ukafRY1o8%6Q!#~Szk)ZY(ah`d}N!g6_)uN zw4=-}zT%5hB|#5-4F)souOCSZ-y^9U)tbxb^un0U4J(Dm=Ny`=l55;wW6V4VoP4P| zz{AC+TP$49Pe}%ZD_c3#XTlfO&mQEBo+Fu3m`vvhikMueWxnj}yLQryU=AFbtfC)2 z*K4wQRVdI;V|wS^TVLy}Om-L zP^?cxpw!h9%%@}2tzy?v@VYPUivzU=d?BAY`vwp1z!50gx^eDNRm8%h-8d{$qTYBs zAv4*?CI^t_2eeMi^fY!B$H9Ro!u1ie*U4Kcl~uw)&zTU_?_Z2huVG)_tvEo5TNC3q-KhmO>F7C)8lTD zr?HN#NOJyJM(XDD@iaRo_Rq%JJD^`mC6x{?ZYA@pJ13To&Tc)4=VDcP>$?|e8;k`O zODfJ#kxT{0Kp9NK6NN)Hg~^({n#A+7`znTZ<@9U|4i65Vlr#2i!;9vH>^u`O>}R{8 zp+k$j4eQ#;R;pSRB-RC7_Kx@5r%Fz8@KJNaQS4M8F{L{zJ8C683`B|qdn_!riU+^M z-0!&?7%FRdIcH==Dl?JRDM)8q`w(7^2f%VOk?6N-X6D~IJ+p7j&Yh%L?#Ck4w%3F! zK#K~r;=j)Lq{k`Ik&265@0_9{NcmLre+xvVPpBm)6aOB9@jm&|xwA&&@lrFrv^lue zTprx=#y@Ilv90n=ZAWC!b4h%7QJ@hA;nawFfon-*?X0`AcMqTKknfW`x4%-k?K3SW zN_Btc+K7}|ZlTIf0$3L5?qCH|k{xogUgTCLK;w%t&;NWl0Sa3k>2$`GR9JoB!5`B2J5 z`KZ8~JZ*K-7?XVW#kPn_svAuqYIJ35!#*&b9iOa)9BezbO_d*B+*b-Jmww_LH#2rf z4LaKue-9S#EG;C)xmcvqhQ4VkuACjOYH?j3(d6-v93}IXRXaHl5p9;ZQRR7cWutd! zt2lA**mIq&Sh;W<(WiQ-(C&OlF2@k{;>>U1v3wXzy^p?n=`ga~a~Bcqjk|U{3)Xmk zN>^NLa9@wy)!Ju!Ydp+Ku|p4T>?odqN?d7hl-0cSJCU;`jOyap!Kx-|KpHgec9hL9 zT*J2-ZroZW*(nOcssU~Yvh{x)azR={`$adkt1_EYINFES9MxQ@CmjVg7^5FB8#jxe z+=1zlA}Gb5{)~0&zHloSztU!shXO{E>DYD~+zi<4dkC72F&w%j_#AnOp~{o%l|6{d zRg?+9<@*ZYl^p~C70ddqaFg_{Xb?OaF9yfQRjEt$K(LdfFBG_%Xw%Qyby4X&)fvtP zCH5+$iD1+BqIj9l-hfjqogK?T?S4?qdicr?`9*&kN4isM19Z~P4*8Db$a(HGdpSnG z>*~~1^Kytsiy@Qa;MzVaNS(|vz`(`OiI!{t^TJz$yMgZTv^sLrO+gSXKVt${zm-^^jEfKY1R^jGvwdJ>y@V2QAb8 z6VKzn%#Z(x=kceT@H?dNr*rYI&GJ9;JpKnw^q(mY`hU12{~P7;**1S+Ie*C=|5ua; z9UCn*8{MB8#~(rjEiMx)1NA44@d-ZsE>`@;PW{+-B|ImK^PX|NAI6m_pUf95kC!`CxQpC9Rd6R@Kz5=;0p?a39>OM=2YOAI7 zgca@0Ws~xD%CThEHdlsio!IZOGaOwyh@p7&Zg_&op^$G0BCb(;ZyIET6sqJXfZw(5 zHgq8XgP5G4Qd6Gyy7PwfW!r|Og{W>#7jv8KHhkCojz*LgPEYt%9ln)R07knaGdMtR zC|jiyLQz$eL$}z})EG9p+t!J>3Dg!mO%LYv)iwO;_3(di8Pl^}EEqSXZs#}VMwYl` zLr8~l=c4n_dyTEJ;@Hp@=9G!b))p<}FQ&BxPBN?7Pq1hRK&|cIWf!x?V0ATfKH7Xn zS(rn*=0wctaAB+$!pK$1)Ie$rvk%wavaDD!YxsKdG83pqQwTUS=3AA>@RQ19wmt1I zC?K#i;{2%XV`n@+SwvoIcAD*?M^j4pgAXA88D!xt-RJ`E>BD}z6V zQ-(i!^*@iRDsqNKzyGRqbpQF+`{NWx-qg(ym*F47q%y8L9WFgC{hu9*M$X#W0hj)7 zS4`B($og}5`~1c~yVieuV){Bdj~`i~zR|vbg4MM2=|(y_23ufotGs%cyvTXnF*0Hx z@L`d-_z2$vut4Bj3;hVS075-;aTj=S;XJ+xa)QF=wBzc1jS0C0gkR+oYd8T6%{a!* zh1Me?2+;w88^iTWwEbYpK7DV5gaqh3MG5@Z=COCswR3Q>`>Z)58yy3~HzFb-Y2k1G E3q^h4;s5{u literal 0 HcmV?d00001 diff --git a/docs/config.md b/docs/config.md index 069577f6..917014f5 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1,15 +1,14 @@ # Configuration file -PROTEUS accepts config files containing parameters in the format -`key = value`. Proteus uses [toml](https://toml.io/en/) as the filetype for configuration. +PROTEUS uses [TOML](https://toml.io/en/) to structure its configuration files. All of the parameters required to run the model are listed below with short explanations of their purpose and the values they accept. Configuration files can contain blank lines. Comments are -indicated with a `#` symbol. +indicated with a `#` symbol. Whitespace indentation is purely stylistic. Not all of these parameters will be used, depending on the -configuration, but they must all be passed via the config file. +configuration, but they must all be provided. ## Adding a new parameter @@ -50,7 +49,7 @@ for more information how to work with attrs. Have a look at the [input configs](https://github.com/FormingWorlds/PROTEUS/tree/main/input) for ideas of how to set up your config in practice. -## Root config +## Root parameters ::: proteus.config._config options: diff --git a/src/proteus/config/_atmos_clim.py b/src/proteus/config/_atmos_clim.py index c7a90dd9..5915ac27 100644 --- a/src/proteus/config/_atmos_clim.py +++ b/src/proteus/config/_atmos_clim.py @@ -12,33 +12,33 @@ class AtmosClim: Attributes ---------- prevent_warming: bool - Do not allow the planet to heat up. + When True, require the planet to monotonically cool over time. surface_d: float - M, conductive skin thickness. + Conductive skin thickness [m], surface_k: float - W m-1 K-1, conductive skin thermal conductivity. + Conductive skin thermal conductivity [W m-1 K-1]. cloud_enabled: bool Enable water cloud radiative effects. cloud_alpha: float - Condensate retention fraction (1 -> fully retained). + Condensate retention fraction (0 => full rainout, 1 => fully retained). surf_state: str - Surface scheme: "mixed_layer", "fixed", "skin". + Surface energy balance scheme. Choices: "mixed_layer", "fixed", "skin". surf_albedo: float - Path to file ("string") or grey quantity (float). + Grey albedo applied to the surface of the planet [dimensionless]. albedo_pl: float - Bond albedo (scattering). + Planetary/bold albedo used to emulate scattering [dimensionless]. rayleigh: bool - Enable rayleigh scattering. + Include Rayleigh scattering in the radiative transfer calculations. tmp_minimum: float - Temperature floor on solver. + Minimum temperature throughout the atmosphere [K]. tmp_maximum: float - Temperature ceiling on solver. + Maximum temperature throughout the atmosphere [K]. module: str Which atmosphere module to use. agni: Agni - Config parameters for Agni atmosphere module + Config parameters for AGNI atmosphere module janus: Janus - Config parameters for Janus atmosphere module + Config parameters for JANUS atmosphere module dummy: Dummy Config parameters for dummy atmosphere module """ @@ -68,20 +68,20 @@ def surf_state_int(self) -> int: @define class Agni: - """Agni atmosphere module. + """AGNI atmosphere module. Attributes ---------- p_top: float Top of atmosphere grid pressure [bar]. spectral_group: str - Spectral file codename defining the gas opacities to be included. + Spectral file codename defining the gas opacities to be included. See [documentation](See documentation: https://raw.githubusercontent.com/FormingWorlds/PROTEUS/main/docs/assets/spectral_files.pdf). spectral_bands: str - Number of wavenumer bands in k-table. + Number of wavenumer bands in k-table. See documentation. num_levels: str Number of atmospheric grid levels. chemistry: str | None - Treatment of self-consistent atmospheric chemsitry. Must be one of: "none", "eq", "kin" + Treatment of self-consistent atmospheric chemsitry. Choices: "none", "eq", "kin". """ p_top: float spectral_group: str @@ -99,27 +99,27 @@ def chemistry_int(self) -> int: @define class Janus: - """Janus atmosphere module. + """JANUS atmosphere module. Attributes ---------- p_top: float - Bar, top of atmosphere grid pressure. + Top of atmosphere grid pressure [bar]. spectral_group: str - Which gas opacities to include. + Spectral file codename defining the gas opacities to be included. See [documentation](https://raw.githubusercontent.com/FormingWorlds/PROTEUS/main/docs/assets/spectral_files.pdf). spectral_bands: str - Number of spectral bands. + Number of wavenumer bands in k-table. See documentation. F_atm_bc: int - Measure outgoing flux at: (0) TOA | (1) Surface. + Measure outgoing flux using value at TOA (0) or surface (1). num_levels: int Number of atmospheric grid levels. tropopause: str | None - Choices: None | skin | dynamic. + Scheme for determining tropopause location. Choices: "none", "skin", "dynamic". """ p_top: float spectral_group: str spectral_bands: str - F_atm_bc: int = field(validator=validators.in_((0, 5))) + F_atm_bc: int = field(validator=validators.in_((0, 1))) num_levels: int = field(validator=validators.ge(15)) tropopause: str | None = field( validator=validators.in_((None, 'skin', 'dynamic')), converter=none_if_none diff --git a/src/proteus/config/_star.py b/src/proteus/config/_star.py index a58ac0d3..18920b7d 100644 --- a/src/proteus/config/_star.py +++ b/src/proteus/config/_star.py @@ -9,7 +9,7 @@ class Star: """Stellar parameters, model selection. - You can find useful reference data in the documentation: https://fwl-proteus.readthedocs.io/en/latest/data/#stars + You can find useful reference data in the [documentation](https://fwl-proteus.readthedocs.io/en/latest/data/#stars). Attributes ---------- @@ -57,7 +57,7 @@ class Mors: tracks: str Stellar evolution track to be used. Choices: 'spada', 'baraffe'. spec: str - Name of file containing stellar spectrum. See documentation for potential file names: https://fwl-proteus.readthedocs.io/en/latest/data/#stars + Name of file containing stellar spectrum. See [documentation](https://fwl-proteus.readthedocs.io/en/latest/data/#stars) for potential file names. """ tracks: str = field(validator=validators.in_(('spada', 'baraffe'))) spec: str From 64af18216e4694954b5994fee7a934ec3e451267 Mon Sep 17 00:00:00 2001 From: Harrison Nicholls Date: Mon, 21 Oct 2024 17:46:05 +0100 Subject: [PATCH 12/13] Fixed link in docs --- src/proteus/config/_atmos_clim.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/proteus/config/_atmos_clim.py b/src/proteus/config/_atmos_clim.py index 5915ac27..8023cde1 100644 --- a/src/proteus/config/_atmos_clim.py +++ b/src/proteus/config/_atmos_clim.py @@ -75,7 +75,7 @@ class Agni: p_top: float Top of atmosphere grid pressure [bar]. spectral_group: str - Spectral file codename defining the gas opacities to be included. See [documentation](See documentation: https://raw.githubusercontent.com/FormingWorlds/PROTEUS/main/docs/assets/spectral_files.pdf). + Spectral file codename defining the gas opacities to be included. See [documentation](https://raw.githubusercontent.com/FormingWorlds/PROTEUS/main/docs/assets/spectral_files.pdf). spectral_bands: str Number of wavenumer bands in k-table. See documentation. num_levels: str From 0772197d46c37a5a6f66f283715bf62f6e1bc819 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Tue, 22 Oct 2024 09:36:12 +0200 Subject: [PATCH 13/13] Make urls clickable --- docs/data.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/data.md b/docs/data.md index 1396b902..0811da62 100644 --- a/docs/data.md +++ b/docs/data.md @@ -5,7 +5,7 @@ ### Epsilon Eridani * File name: `eps-eri.txt` -* URL: https://en.wikipedia.org/wiki/Epsilon_Eridani +* URL: [https://en.wikipedia.org/wiki/Epsilon_Eridani]() * Spectral type: K2V * Teff: 5049 K * Age: 400-800 Myr @@ -17,7 +17,7 @@ ### GJ 1132 * File name: `gj1132.txt` -* URL: https://en.wikipedia.org/wiki/GJ_1132 +* URL: [https://en.wikipedia.org/wiki/GJ_1132]() * Spectral type: M4 * Teff: 3196 K * Age: ? @@ -29,7 +29,7 @@ ### GJ 1214 * File name: `gj1214.txt` -* URL: https://en.wikipedia.org/wiki/GJ_1214 +* URL: [https://en.wikipedia.org/wiki/GJ_1214]() * Spectral type: M4.5 * Teff: 3111 K * Age: 5-10 Gyr @@ -41,7 +41,7 @@ ### HD 85512 * File name: `hd85512.txt` -* URL: https://en.wikipedia.org/wiki/HD_85512 +* URL: [https://en.wikipedia.org/wiki/HD_85512]() * Spectral type: K6V * Teff: 4404 K * Age: 5.61 Gyr @@ -53,7 +53,7 @@ ### HD 97658 * File name: `hd97658.txt` -* URL: https://en.wikipedia.org/wiki/HD_97658 +* URL: [https://en.wikipedia.org/wiki/HD_97658]() * Spectral type: K1V * Teff: 5212 K * Age: 3.9 Gyr @@ -65,7 +65,7 @@ ### L 98-59 * File name: `l-98-59.txt` -* URL: https://en.wikipedia.org/wiki/L_98-59 +* URL: [https://en.wikipedia.org/wiki/L_98-59]() * Spectral type: M3V * Teff: 3415 K * Age: >800 Myr @@ -77,7 +77,7 @@ ### The Sun * File name: `sun.txt` -* URL: https://en.wikipedia.org/wiki/Sun +* URL: [https://en.wikipedia.org/wiki/Sun]() * Spectral type: G2V * Teff: 5772 K * Age: 4.6 Gyr @@ -89,7 +89,7 @@ ### TRAPPIST-1 * File name: `trappist-1.txt` -* URL: https://en.wikipedia.org/wiki/TRAPPIST-1 +* URL: [https://en.wikipedia.org/wiki/TRAPPIST-1]() * Spectral type: M8V * Teff: 2566 K * Age: 7.6 Gyr @@ -101,7 +101,7 @@ ### GJ 849 * File name: `gj849.txt` -* URL: https://en.wikipedia.org/wiki/Gliese_849 +* URL: [https://en.wikipedia.org/wiki/Gliese_849]() * Spectral type: M3.5V * Teff: 3467 K * Age: >3 Gyr