Пример #1
0
def test_create_and_add_fault():
    model = GeologicalModel([0, 0, 0], [1, 1, 1])
    data = pd.DataFrame(
        [
            [0.5, 0.5, 0.5, 0, 1, 0, 0, "fault", 0],
            # [0.5, 0.5, 0.5, 0, 1, 0, 0, "fault", 0],

            [0.5, 0.5, 0.5, 1, 0, 0, 1, "fault", 0],
            [0.5, 0.5, 0.5, 0, 0, 1, 2, "fault", 0],
        ],
        columns=["X", "Y", "Z", "nx", "ny", "nz", "coord", "feature_name", "val"],
    )
    model.data = data
    model.create_and_add_fault(
        "fault",
        1,
        nelements=1e4,
        # force_mesh_geometry=True
    )
    assert isinstance(model["fault"], FaultSegment)
Пример #2
0
def build_model(m2l_data,
                evaluate=True,
                skip_faults=False,
                unconformities=False,
                fault_params=None,
                foliation_params=None,
                rescale=True,
                skip_features=[],
                **kwargs):
    """[summary]

    [extended_summary]

    Parameters
    ----------
    m2l_data : dict
        [description]
    skip_faults : bool, optional
        [description], by default False
    fault_params : dict, optional
        [description], by default None
    foliation_params : dict, optional
        [description], by default None

    Returns
    -------
    [type]
        [description]
    """
    from LoopStructural import GeologicalModel

    boundary_points = np.zeros((2, 3))
    boundary_points[0, 0] = m2l_data["bounding_box"]["minx"]
    boundary_points[0, 1] = m2l_data["bounding_box"]["miny"]
    boundary_points[0, 2] = m2l_data["bounding_box"]["lower"]
    boundary_points[1, 0] = m2l_data["bounding_box"]["maxx"]
    boundary_points[1, 1] = m2l_data["bounding_box"]["maxy"]
    boundary_points[1, 2] = m2l_data["bounding_box"]["upper"]

    model = GeologicalModel(boundary_points[0, :],
                            boundary_points[1, :],
                            rescale=rescale)
    # m2l_data['data']['val'] /= model.scale_factor
    model.set_model_data(m2l_data["data"])
    if not skip_faults:
        faults = []
        for f in m2l_data["max_displacement"].keys():
            if model.data[model.data["feature_name"] == f].shape[0] == 0:
                continue
            if f in skip_features:
                continue
            fault_id = f
            overprints = []
            try:
                overprint_id = m2l_data["fault_fault"][
                    m2l_data["fault_fault"][fault_id] ==
                    1]["fault_id"].to_numpy()
                for i in overprint_id:
                    overprints.append(i)
                logger.info("Adding fault overprints {}".format(f))
            except:
                logger.info("No entry for %s in fault_fault_relations" % f)
            #     continue
            fault_center = m2l_data["stratigraphic_column"]["faults"][f][
                "FaultCenter"]
            fault_influence = m2l_data["stratigraphic_column"]["faults"][f][
                "InfluenceDistance"]
            fault_extent = m2l_data["stratigraphic_column"]["faults"][f][
                "HorizontalRadius"]
            fault_vertical_radius = m2l_data["stratigraphic_column"]["faults"][
                f]["VerticalRadius"]
            fault_slip_vector = m2l_data["stratigraphic_column"]["faults"][f][
                "FaultSlip"]
            faults.append(
                model.create_and_add_fault(
                    f,
                    -m2l_data["max_displacement"][f],
                    faultfunction="BaseFault",
                    fault_slip_vector=fault_slip_vector,
                    fault_center=fault_center,
                    fault_extent=fault_extent,
                    fault_influence=fault_influence,
                    fault_vectical_radius=fault_vertical_radius,
                    # overprints=overprints,
                    **fault_params,
                ))
    # for f in m2l_data['fault_intersection_angles']:
    #     if f in m2l_data['max_displacement'].keys():
    #         f1_norm = m2l_data['stratigraphic_column']['faults'][f]['FaultNorm']
    #         for intersection in m2l_data['fault_intersection_angles'][f]:
    #             if intersection[0] in m2l_data['max_displacement'].keys():
    #                 f2_norm = m2l_data['stratigraphic_column']['faults'][intersection[0]]['FaultNorm']
    #                 if intersection[2] < 30 and np.dot(f1_norm,f2_norm)>0:
    #                     logger.info('Adding splay {} to {}'.format(intersection[0],f))
    #                     if model[f] is None:
    #                         logger.error('Fault {} does not exist, cannot be added as splay')
    #                     elif model[intersection[0]] is None:
    #                         logger.error('Fault {} does not exist')
    #                     else:
    #                         model[intersection[0]].builder.add_splay(model[f])

    #                 else:
    #                     logger.info('Adding abut {} to {}'.format(intersection[0],f))
    #                     model[intersection[0]].add_abutting_fault(model[f])
    faults = m2l_data.get("fault_graph", None)
    if faults:
        for f in faults.nodes:
            f1_norm = m2l_data["stratigraphic_column"]["faults"][f][
                "FaultNorm"]
            for e in faults.edges(f):
                data = faults.get_edge_data(*e)
                f2_norm = m2l_data["stratigraphic_column"]["faults"][
                    e[1]]["FaultNorm"]

                if float(data["angle"]) < 30 and np.dot(f1_norm, f2_norm) > 0:
                    if model[f] is None or model[e[1]] is None:
                        logger.error(
                            "Fault {} does not exist, cannot be added as splay"
                        )
                    elif model[e[1]] is None:
                        logger.error("Fault {} does not exist")
                    else:
                        region = model[e[1]].builder.add_splay(model[f])
                        model[e[1]].splay[model[f].name] = region
                else:
                    if model[f] is None or model[e[1]] is None:
                        continue

                    logger.info("Adding abut {} to {}".format(e[1], f))
                    model[e[1]].add_abutting_fault(model[f])
    ## loop through all of the groups and add them to the model in youngest to oldest.
    group_features = []
    for i in np.sort(m2l_data["groups"]["group number"].unique()):
        g = (m2l_data["groups"].loc[m2l_data["groups"]["group number"] == i,
                                    "group"].unique()[0])
        group_features.append(
            model.create_and_add_foliation(g, **foliation_params))
        # if the group was successfully added (not null) then lets add the base (0 to be unconformity)
        if group_features[-1] and unconformities:
            model.add_unconformity(group_features[-1], 0)
    model.set_stratigraphic_column(m2l_data["stratigraphic_column"])
    if evaluate:
        model.update(verbose=True)
    return model
Пример #3
0
plt.contourf(val)

######################################################################
# LoopStructural applies structural frames to the fault geometry to
# capture the geometry and kinematics of the fault. A fault frame
# consisting of the fault surface, fault slip direction and fault extent
# are built from observations. The geometry of the deformed surface is
# then interpolated by first restoring the observations by combining the
# fault frame and an expected displacement model.
#

model = GeologicalModel(bb[0, :], bb[1, :])
model.set_model_data(data)
fault = model.create_and_add_fault('fault',
                                   500,
                                   nelements=10000,
                                   steps=4,
                                   interpolatortype='PLI',
                                   buffer=0.3)

viewer = LavaVuModelViewer(model)
viewer.add_isosurface(fault,
                      isovalue=0
                      #                       slices=[0,1]#nslices=10
                      )
xyz = model.data[model.data['feature_name'] == 'strati'][['X', 'Y',
                                                          'Z']].to_numpy()
xyz = xyz[fault.evaluate(xyz).astype(bool), :]
viewer.add_vector_field(fault, locations=xyz)
viewer.add_points(
    model.data[model.data['feature_name'] == 'strati'][['X', 'Y', 'Z']],
    name='prefault')
Пример #4
0
def build_model(m2l_data,
                skip_faults=False,
                unconformities=False,
                fault_params=None,
                foliation_params=None,
                rescale=True,
                **kwargs):
    """[summary]

    [extended_summary]

    Parameters
    ----------
    m2l_data : dict
        [description]
    skip_faults : bool, optional
        [description], by default False
    fault_params : dict, optional
        [description], by default None
    foliation_params : dict, optional
        [description], by default None

    Returns
    -------
    [type]
        [description]
    """
    from LoopStructural import GeologicalModel

    boundary_points = np.zeros((2, 3))
    boundary_points[0, 0] = m2l_data['bounding_box']['minx']
    boundary_points[0, 1] = m2l_data['bounding_box']['miny']
    boundary_points[0, 2] = m2l_data['bounding_box']['lower']
    boundary_points[1, 0] = m2l_data['bounding_box']['maxx']
    boundary_points[1, 1] = m2l_data['bounding_box']['maxy']
    boundary_points[1, 2] = m2l_data['bounding_box']['upper']

    model = GeologicalModel(boundary_points[0, :],
                            boundary_points[1, :],
                            rescale=rescale)
    # m2l_data['data']['val'] /= model.scale_factor
    model.set_model_data(m2l_data['data'])
    if not skip_faults:
        faults = []
        for f in m2l_data['max_displacement'].keys():
            if model.data[model.data['feature_name'] == f].shape[0] == 0:
                continue
            fault_id = f
            overprints = []
            try:
                overprint_id = m2l_data['fault_fault'][
                    m2l_data['fault_fault'][fault_id] ==
                    1]['fault_id'].to_numpy()
                for i in overprint_id:
                    overprints.append(i)
                logger.info('Adding fault overprints {}'.format(f))
            except:
                logger.info('No entry for %s in fault_fault_relations' % f)
        #     continue
            faults.append(
                model.create_and_add_fault(
                    f,
                    -m2l_data['max_displacement'][f],
                    faultfunction='BaseFault',
                    overprints=overprints,
                    **fault_params,
                ))

    ## loop through all of the groups and add them to the model in youngest to oldest.
    group_features = []
    for i in np.sort(m2l_data['groups']['group number'].unique()):
        g = m2l_data['groups'].loc[m2l_data['groups']['group number'] == i,
                                   'group'].unique()[0]
        group_features.append(
            model.create_and_add_foliation(g, **foliation_params))
        # if the group was successfully added (not null) then lets add the base (0 to be unconformity)
        if group_features[-1] and unconformities:
            model.add_unconformity(group_features[-1], 0)
    model.set_stratigraphic_column(m2l_data['stratigraphic_column'])
    return model