def get_receivers(lasif_root, event: str): """ Get a list of receiver dictionaries which are compatible with Salvus. SalvusFlow can then use these dictionaries to place the receivers. :param lasif_root: Path to project root :type lasif_root: Union[str, pathlib.Path, object] :param event: Name of event which we want to find the receivers for :type event: str """ from lasif.utils import place_receivers comm = find_project_comm(lasif_root) assert comm.events.has_event(event), f"Event: {event} not in project" return place_receivers(event, comm)
def get_adjoint_source(comm: object, event: str, iteration: str) -> List[object]: """ Get a list of adjoint source objects :param comm: The lasif communicator object :type comm: object :param event: Name of event :type event: str :param iteration: Name of iteration :type iteration: str :return: Adjoint source objects :type return: List[object] """ from salvus.flow.simple_config import source, stf import h5py receivers = place_receivers(comm=comm, event=event) iteration_name = comm.iterations.get_long_iteration_name(iteration) adjoint_filename = str(comm.project.paths["adjoint_sources"] / iteration_name / event / "stf.h5") p = h5py.File(adjoint_filename, "r") adjoint_recs = list(p.keys()) adjoint_sources = [] for rec in receivers: if rec["network-code"] + "_" + rec["station-code"] in adjoint_recs: adjoint_sources.append(rec) p.close() adj_src = [ source.seismology.VectorPoint3DZNE( latitude=rec["latitude"], longitude=rec["longitude"], fz=1.0, fn=1.0, fe=1.0, source_time_function=stf.Custom( filename=adjoint_filename, dataset_name=f"/{rec['network-code']}_{rec['station-code']}", ), ) for rec in adjoint_sources ] return adj_src
def create_salvus_forward_simulation( comm: object, event: str, iteration: str, mesh=None, side_set: str = None, ): """ Create a Salvus simulation object based on simulation and salvus specific parameters specified in config file. :param comm: The lasif communicator object :type comm: object :param event: Name of event :type event: str :param iteration: Name of iteration :type iteration: str :param mesh: Path to mesh or Salvus mesh object, if None it will use the domain file from config file, defaults to None :type mesh: Union[str, salvus.mesh.unstructured_mesh.UnstructuredMesh], optional :param side_set: Name of side set on mesh to place receivers, defaults to None. :type side_set: str, optional """ import salvus.flow.simple_config as sc from salvus.flow.simple_config import stf source_info = prepare_source(comm=comm, event=event, iteration=iteration) iteration = comm.iterations.get_long_iteration_name(iteration) receivers = place_receivers(comm=comm, event=event) stf_path = os.path.join(comm.project.paths["salvus_files"], iteration, "stf.h5") if mesh is None: mesh = comm.project.lasif_config["domain_settings"]["domain_file"] if side_set is None: recs = [ sc.receiver.seismology.Point3D( latitude=rec["latitude"], longitude=rec["longitude"], network_code=rec["network-code"], station_code=rec["station-code"], fields=["displacement"], ) for rec in receivers ] else: recs = [ sc.receiver.seismology.SideSetPoint3D( latitude=rec["latitude"], longitude=rec["longitude"], network_code=rec["network-code"], station_code=rec["station-code"], side_set_name=side_set, fields=["displacement"], ) for rec in receivers ] sources = [ sc.source.seismology.MomentTensorPoint3D( latitude=src["latitude"], longitude=src["longitude"], depth_in_m=src["depth_in_m"], mrr=src["mrr"], mtt=src["mtt"], mpp=src["mpp"], mtp=src["mtp"], mrp=src["mrp"], mrt=src["mrt"], source_time_function=stf.Custom(filename=stf_path, dataset_name="/source"), ) for src in source_info ] w = sc.simulation.Waveform( mesh=mesh, sources=sources, receivers=recs, ) sim_set = comm.project.simulation_settings sal_set = comm.project.salvus_settings w.physics.wave_equation.end_time_in_seconds = sim_set["end_time_in_s"] w.physics.wave_equation.time_step_in_seconds = sim_set["time_step_in_s"] w.physics.wave_equation.start_time_in_seconds = sim_set["start_time_in_s"] w.physics.wave_equation.attenuation = sal_set["attenuation"] import lasif.domain domain = lasif.domain.HDF5Domain(mesh, sim_set["absorbing_boundaries_in_km"]) if not domain.is_global_domain(): absorbing = sc.boundary.Absorbing( width_in_meters=comm.project. simulation_settings["absorbing_boundaries_in_km"] * 1000.0, side_sets=["r0", "t0", "t1", "p0", "p1"], taper_amplitude=1.0 / comm.project.simulation_settings["minimum_period_in_s"], ) w.physics.wave_equation.boundaries = [absorbing] w.output.memory_per_rank_in_MB = 4000.0 w.output.volume_data.format = "hdf5" w.output.volume_data.filename = "output.h5" w.output.volume_data.fields = ["adjoint-checkpoint"] w.output.volume_data.sampling_interval_in_time_steps = ( "auto-for-checkpointing") w.validate() return w