Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions tests/test_realisation.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,17 @@ def test_srf_config_example(tmp_path: Path) -> None:
risetimedep=0.0,
inittime=0.0,
),
side_taper=0.02,
bot_taper=0.02,
top_taper=0.0,
alpha_rough=0.0,
gwid=[],
rvfac_seg=[],
seg_delay=False,
ymag_exp=None,
xmag_exp=None,
kx_corner=None,
ky_corner=None,
)

realisation_ffp = tmp_path / "realisation.json"
Expand Down Expand Up @@ -134,6 +145,17 @@ def test_srf_config_example(tmp_path: Path) -> None:
"risetimedep": 0.0,
"inittime": 0.0,
},
"side_taper": 0.02,
"bot_taper": 0.02,
"top_taper": 0.0,
"alpha_rough": 0.0,
"gwid": [],
"rvfac_seg": [],
"seg_delay": False,
"ymag_exp": None,
"xmag_exp": None,
"kx_corner": None,
"ky_corner": None,
},
}

Expand Down
11 changes: 11 additions & 0 deletions workflow/default_parameters/develop/defaults.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,17 @@ srf:
resolution: 0.1
genslip_dt: 0.05
genslip_version: 5.4.2
side_taper: 0.02
bot_taper: 0.02
top_taper: 0.0
alpha_rough: 0.0
gwid: []
rvfac_seg: []
seg_delay: false
ymag_exp: null
xmag_exp: null
kx_corner: null
ky_corner: null
# The following parameters are only used for the point source approximation.
point_source_params:
# Valid options for the slip time function (stype) are:
Expand Down
11 changes: 11 additions & 0 deletions workflow/default_parameters/v24_2_2_1/defaults.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,17 @@ srf:
resolution: 0.1
genslip_dt: 0.05
genslip_version: 5.4.2
side_taper: 0.02
bot_taper: 0.02
top_taper: 0.0
alpha_rough: 0.0
gwid: []
rvfac_seg: []
seg_delay: false
ymag_exp: null
xmag_exp: null
kx_corner: null
ky_corner: null
# The following parameters are only used for the point source approximation.
point_source_params:
# Valid options for the slip time function (stype) are:
Expand Down
11 changes: 11 additions & 0 deletions workflow/default_parameters/v24_2_2_2/defaults.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,17 @@ srf:
resolution: 0.1
genslip_dt: 0.05
genslip_version: 5.4.2
side_taper: 0.02
bot_taper: 0.02
top_taper: 0.0
alpha_rough: 0.0
gwid: []
rvfac_seg: []
seg_delay: false
ymag_exp: null
xmag_exp: null
kx_corner: null
ky_corner: null
# The following parameters are only used for the point source approximation.
point_source_params:
# Valid options for the slip time function (stype) are:
Expand Down
11 changes: 11 additions & 0 deletions workflow/default_parameters/v24_2_2_4/defaults.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,17 @@ srf:
resolution: 0.1
genslip_dt: 0.05
genslip_version: 5.4.2
side_taper: 0.02
bot_taper: 0.02
top_taper: 0.0
alpha_rough: 0.0
gwid: []
rvfac_seg: []
seg_delay: false
ymag_exp: null
xmag_exp: null
kx_corner: null
ky_corner: null
# The following parameters are only used for the point source approximation.
point_source_params:
# Valid options for the slip time function (stype) are:
Expand Down
21 changes: 16 additions & 5 deletions workflow/realisations.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,21 @@ class SRFConfig(RealisationConfiguration):
point_source_params: schemas.PointSourceParams | None
"""Parameters for point source approximation, if applicable."""

side_taper: float
bot_taper: float
top_taper: float

alpha_rough: float
gwid: list[float]
rvfac_seg: list[float]
seg_delay: bool

# Subduction settings
ymag_exp: float | None = None
xmag_exp: float | None = None
kx_corner: float | None = None
ky_corner: float | None = None

def to_dict(self) -> dict[str, Any]:
"""
Convert the object to a dictionary representation.
Expand All @@ -376,11 +391,7 @@ def to_dict(self) -> dict[str, Any]:
dict
Dictionary representation of the object.
"""
config_dict = {
"genslip_dt": self.genslip_dt,
"genslip_version": self.genslip_version,
"resolution": self.resolution,
}
config_dict = dataclasses.asdict(self)
if self.point_source_params is not None:
config_dict["point_source_params"] = dataclasses.asdict(
self.point_source_params
Expand Down
60 changes: 38 additions & 22 deletions workflow/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,6 @@
from velocity_modelling.bounding_box import BoundingBox
from workflow.defaults import DefaultsVersion

# NOTE: These functions seem silly and short, however there is a good
# reason for the choice to create functions like this. The reason is
# because when the schema library reports an error (such as the input
# file having a negative depth value) it prints the name of the
# function. So
#
# And(float, lambda x: x > 0).validate(-12)
#
# Would report the error
#
# schema.SchemaError: <lambda>(-12) should evaluate to True
#
# But using the function `is_positive` we instead have
#
# And(float, is_positive).validate(-12)
# schema.SchemaError: is_positive(-12) should evaluate to True
#
# So using short functions with names improves the error reporting
# from the library.
#
# Accordingly, the most trivial of these functions lack docstrings.


class Stype(StrEnum):
"""Options for slip time function (stype) in generic_slip2srf."""
Expand Down Expand Up @@ -94,6 +72,29 @@ def from_dict(cls, params_dict: dict) -> "PointSourceParams":
return cls(**params_dict)


# NOTE: These functions seem silly and short, however there is a good
# reason for the choice to create functions like this. The reason is
# because when the schema library reports an error (such as the input
# file having a negative depth value) it prints the name of the
# function. So
#
# And(float, lambda x: x > 0).validate(-12)
#
# Would report the error
#
# schema.SchemaError: <lambda>(-12) should evaluate to True
#
# But using the function `is_positive` we instead have
#
# And(float, is_positive).validate(-12)
# schema.SchemaError: is_positive(-12) should evaluate to True
#
# So using short functions with names improves the error reporting
# from the library.
#
# Accordingly, the most trivial of these functions lack docstrings.


def _is_positive(x: float) -> bool: # noqa: D103 # numpydoc ignore=GL08
return x > 0

Expand Down Expand Up @@ -130,6 +131,10 @@ def _is_valid_bearing(bearing: float) -> bool: # noqa: D103 # numpydoc ignore=G
return 0 <= bearing <= 360


def _is_proportion(x: float | int) -> bool: # noqa: D103 # numpydoc ignore=GL08
return 0 <= x <= 1


def _is_correct_corner_shape(corners: np.ndarray) -> bool:
"""Check if the corner shape matches the corner shape for plane sources.

Expand Down Expand Up @@ -392,6 +397,17 @@ def _corners_to_array(corners_spec: list[dict[str, float]]) -> np.ndarray:
description="Parameters for point source approximation, if applicable",
)
): Or(None, POINT_SOURCE_PARAMS_SCHEMA),
Literal("side_taper"): And(NUMBER, _is_proportion),
Literal("bot_taper"): And(NUMBER, _is_proportion),
Literal("top_taper"): And(NUMBER, _is_proportion),
Literal("alpha_rough"): And(NUMBER, _is_proportion),
Literal("gwid"): [And(NUMBER, _is_positive)],
Literal("rvfac_seg"): [And(NUMBER, _is_proportion)],
Literal("seg_delay"): bool,
Literal("ymag_exp"): Or(NUMBER, None),
Literal("xmag_exp"): Or(NUMBER, None),
Literal("kx_corner"): Or(NUMBER, None),
Literal("ky_corner"): Or(NUMBER, None),
}
)

Expand Down
29 changes: 17 additions & 12 deletions workflow/scripts/realisation_to_srf.py
Original file line number Diff line number Diff line change
Expand Up @@ -433,33 +433,38 @@ def generate_fault_srf(
)
genslip_cmd = [
str(environment.genslip_path),
"plane_header=1",
"srf_version=1.0",
"read_erf=0",
"write_srf=1",
"read_gsf=1",
"write_gsf=0",
"ns=1",
"nh=1",
f"infile={gsf_file_path}",
f"mag={params.magnitudes.magnitudes[name]}",
f"nstk={nx}",
f"ndip={ny}",
"ns=1",
"nh=1",
f"seed={environment.seeds.genslip_seed}",
f"velfile={environment.velocity_model_path}",
f"shypo={genslip_hypocentre_coords[0]}",
f"dhypo={genslip_hypocentre_coords[1]}",
f"dt={params.srf_config.genslip_dt}",
"plane_header=1",
"srf_version=1.0",
"seg_delay={0}",
"rvfac_seg=-1",
"gwid=-1",
"side_taper=0.02",
"bot_taper=0.02",
"top_taper=0.0",
"rup_delay=0",
"alpha_rough=0.0",
f"side_taper={params.srf_config.side_taper}",
f"bot_taper={params.srf_config.bot_taper}",
f"top_taper={params.srf_config.top_taper}",
f"alpha_rough={params.srf_config.alpha_rough}",
f"gwid={params.srf_config.gwid or -1}",
f"rvfac_seg={params.srf_config.rvfac_seg or -1}",
f"seg_delay={int(params.srf_config.seg_delay)}",
]

genslip_cmd.extend(
f"{key}={getattr(params.srf_config, key)}"
for key in ["ymag_exp", "xmag_exp", "kx_corner", "ky_corner"]
if getattr(params.srf_config, key) is not None
)

srf_file_path = environment.srf_directory / (normalise_name(name) + ".srf")
with open(srf_file_path, "w", encoding="utf-8") as srf_file_handle:
logger = log_utils.get_logger(__name__)
Expand Down
Loading