Example #1
0
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)
Example #2
0
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
Example #3
0
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