Skip to content

Commit

Permalink
fix: 🐛 unconformities weren't working.
Browse files Browse the repository at this point in the history
Adding unconformities back required changing unconformity feature so it uses a semi-copy of the geological feature.
The unconformity feature has different regions.
Also changed featuretype to be enum from string.
Removed parameter attribute from model
  • Loading branch information
Lachlan Grose committed Jul 15, 2022
1 parent a35f41a commit 304335d
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 126 deletions.
94 changes: 25 additions & 69 deletions LoopStructural/modelling/core/geological_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,15 +194,7 @@ def __init__(
)
logger.info("Reusing interpolation supports: {}".format(self.reuse_supports))
self.stratigraphic_column = None
self.parameters = {
"features": [],
"model": {
"bounding_box": self.origin.tolist() + self.maximum.tolist(),
"rescale": rescale,
"nsteps": nsteps,
"reuse_supports": reuse_supports,
},
}

self.tol = 1e-10 * np.max(self.bounding_box[1, :] - self.bounding_box[0, :])
self._dtm = None

Expand Down Expand Up @@ -427,7 +419,7 @@ def faults(self):
def series(self):
series = []
for f in self.features:
if f.type == "series":
if f.type == FeatureType.INTERPOLATED:
series.append(f)
return series

Expand Down Expand Up @@ -835,9 +827,7 @@ def create_and_add_foliation(
# if tol is not specified use the model default
if tol is None:
tol = self.tol
self.parameters["features"].append(
{"feature_type": "foliation", "feature_name": series_surface_data, **kwargs}
)

interpolator = self.get_interpolator(**kwargs)
series_builder = GeologicalFeatureBuilder(
interpolator, name=series_surface_data, **kwargs
Expand All @@ -855,9 +845,7 @@ def create_and_add_foliation(
series_feature = series_builder.feature
series_builder.build_arguments = kwargs
series_builder.build_arguments["tol"] = tol
series_feature.type = "series"
# see if any unconformities are above this feature if so add region
# self._add_unconformity_above(series_feature)self._add_feature(series_feature)
series_feature.type = FeatureType.INTERPOLATED
self._add_feature(series_feature)
return series_feature

Expand All @@ -876,9 +864,7 @@ def create_and_add_dtm(self, series_surface_data, **kwargs):
"""
if self.check_inialisation() == False:
return False
self.parameters["features"].append(
{"feature_type": "foliation", "feature_name": series_surface_data, **kwargs}
)

interpolator = self.get_interpolator(**kwargs)
series_builder = GeologicalFeatureBuilder(
interpolator, name=series_surface_data, **kwargs
Expand Down Expand Up @@ -919,9 +905,7 @@ def create_and_add_fold_frame(self, foldframe_data, tol=None, **kwargs):
return False
if tol is None:
tol = self.tol
self.parameters["features"].append(
{"feature_type": "fold_frame", "feature_name": foldframe_data, **kwargs}
)

# create fault frame
interpolator = self.get_interpolator(**kwargs)
#
Expand All @@ -939,7 +923,7 @@ def create_and_add_fold_frame(self, foldframe_data, tol=None, **kwargs):
fold_frame = fold_frame_builder.frame
# for i in range(3):
# self._add_unconformity_above(fold_frame[i])
fold_frame.type = "structuralframe"
fold_frame.type = FeatureType.STRUCTURALFRAME
fold_frame.builder = fold_frame_builder
self._add_feature(fold_frame)

Expand Down Expand Up @@ -970,14 +954,7 @@ def create_and_add_folded_foliation(
return False
if tol is None:
tol = self.tol
self.parameters["features"].append(
{
"feature_type": "fold_foliation",
"feature_name": foliation_data,
"fold_frame": fold_frame,
**kwargs,
}
)

if fold_frame is None:
logger.info("Using last feature as fold frame")
fold_frame = self.features[-1]
Expand All @@ -1004,7 +981,7 @@ def create_and_add_folded_foliation(
# series_feature = series_builder.build(**kwargs)
series_feature = series_builder.feature
series_builder.build_arguments = kwargs
series_feature.type = "series"
series_feature.type = FeatureType.INTERPOLATED
series_feature.fold = fold
# see if any unconformities are above this feature if so add region
# self._add_unconformity_above(series_feature)self._add_feature(series_feature)
Expand Down Expand Up @@ -1036,14 +1013,7 @@ def create_and_add_folded_fold_frame(
return False
if tol is None:
tol = self.tol
self.parameters["features"].append(
{
"feature_type": "folded_fold_frame",
"feature_name": fold_frame_data,
"fold_frame": fold_frame,
**kwargs,
}
)

if fold_frame is None:
logger.info("Using last feature as fold frame")
fold_frame = self.features[-1]
Expand Down Expand Up @@ -1265,7 +1235,7 @@ def _add_domain_fault_below(self, domain_fault):
if f.name == domain_fault.name:
continue
f.add_region(lambda pos: domain_fault.evaluate_value(pos) > 0)
if f.type == "unconformity":
if f.type == FeatureType.UNCONFORMITY:
break

def _add_unconformity_above(self, feature):
Expand All @@ -1286,7 +1256,7 @@ def _add_unconformity_above(self, feature):
"""
for f in reversed(self.features):
if f.type == "unconformity":
if f.type == FeatureType.UNCONFORMITY and f.name != feature.name:
feature.add_region(lambda pos: f.evaluate(pos))
break

Expand All @@ -1303,14 +1273,15 @@ def _add_unconformity_below(self, feature):
-------
"""
for f in self.features:
if f.type == "series" and feature.feature.name != f.name:
f.add_region(lambda pos: ~feature.evaluate(pos))
# for f in self.features:
# if f.type == FeatureType.INTERPOLATED and feature.name != f.name:
# feature.add_region(lambda pos: f.evaluate(pos))
# for f in reversed(self.features):
# if f.type == 'unconformity':
# if f.type == FeatureType.UNCONFORMITY:
# feature.add_region(lambda pos: f.evaluate(pos))
# break
# feature.add_region(lambda pos: ~uc.evaluate(pos))
# feature.add_region(lambda pos: ~feature.evaluate(pos))
pass

def create_and_add_unconformity(self, unconformity_surface_data, **kwargs):
"""
Expand All @@ -1324,7 +1295,6 @@ def create_and_add_unconformity(self, unconformity_surface_data, **kwargs):
"""
if not self.check_initialisation():
return False
# self.parameters['features'].append({'feature_type':'unconformity','feature_name':unconformity_surface_data,**kwargs})
interpolator = self.get_interpolator(**kwargs)
unconformity_feature_builder = GeologicalFeatureBuilder(
interpolator, name=unconformity_surface_data
Expand Down Expand Up @@ -1371,17 +1341,14 @@ def add_unconformity(self, feature, value):
if feature is None:
logger.warning(f"Cannot add unconformtiy, base feature is None")
return
self.parameters["features"].append(
{"feature_type": "unconformity", "feature": feature, "value": value}
)
uc_feature = UnconformityFeature(feature, value)

# for f in self.features:
# f.add_region(lambda pos: uc_feature.evaluate(pos))

for f in self.features:
f.add_region(lambda pos: ~uc_feature.evaluate(pos))
# feature.add_region(lambda pos: ~uc_feature.evaluate(pos))
# see if any unconformities are above this feature if so add region
# self._add_unconformity_above(uc_feature)
# self._add_unconformity_below(feature)#, uc_feature)
# self._add_unconformity_below(uc_feature) # , uc_feature)
self._add_feature(uc_feature)

return uc_feature
Expand All @@ -1403,9 +1370,6 @@ def add_onlap_unconformity(self, feature, value):
the created unconformity
"""
self.parameters["features"].append(
{"feature_type": "onlap", "feature": feature, "value": value}
)

uc_feature = UnconformityFeature(feature, value)

Expand All @@ -1432,7 +1396,6 @@ def create_and_add_domain_fault(self, fault_surface_data, **kwargs):
the created domain fault
"""
# self.parameters['features'].append({'feature_type':'unconformity','feature_name':unconformity_surface_data,**kwargs})
interpolator = self.get_interpolator(**kwargs)
domain_fault_feature_builder = GeologicalFeatureBuilder(
interpolator, name=fault_surface_data
Expand Down Expand Up @@ -1516,14 +1479,7 @@ def create_and_add_fault(

if tol is None:
tol = self.tol
self.parameters["features"].append(
{
"feature_type": "fault",
"feature_name": fault_surface_data,
"displacement": displacement,
**kwargs,
}
)

if displacement == 0:
logger.warning(f"{fault_surface_data} displacement is 0")

Expand Down Expand Up @@ -1656,7 +1612,7 @@ def create_and_add_fault(
fault.faultfunction = faultfunction

for f in reversed(self.features):
if f.type == "unconformity":
if f.type == FeatureType.UNCONFORMITY:
fault.add_region(lambda pos: f.evaluate_value(pos) <= 0)
break
if displacement == 0:
Expand Down Expand Up @@ -1948,7 +1904,7 @@ def update(self, verbose=False, progressbar=True):
if isinstance(f, StructuralFrame):
nfeatures += 3
total_dof += f[0].interpolator.nx * 3
if f.type == "series":
if f.type == FeatureType.INTERPOLATED:
nfeatures += 1
total_dof += f.interpolator.nx
if verbose == True:
Expand Down
1 change: 1 addition & 0 deletions LoopStructural/modelling/features/_geological_feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ def __init__(
self.builder = builder
self.type = FeatureType.INTERPOLATED


def is_valid(self):
return self.interpolator.valid

Expand Down
58 changes: 13 additions & 45 deletions LoopStructural/modelling/features/_unconformity_feature.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,29 @@
from LoopStructural.modelling.features import BaseFeature
from LoopStructural.modelling.features import GeologicalFeature
from LoopStructural.modelling.features import FeatureType


class UnconformityFeature(BaseFeature):
class UnconformityFeature(GeologicalFeature):
""" """

def __init__(self, feature: BaseFeature, value: float):
def __init__(self, feature: GeologicalFeature, value: float):
"""
Parameters
----------
feature
value
"""
BaseFeature.__init__(
# create a shallow(ish) copy of the geological feature
# just don't link the regions
GeologicalFeature.__init__(
self,
f"{feature.name}_unconformity",
feature.model,
feature.faults,
feature.regions,
feature.builder,
name=f"{feature.name}_unconformity",
faults=feature.faults,
regions=[], # feature.regions.copy(), # don't want to share regionsbetween unconformity and # feature.regions,
builder=feature.builder,
model=feature.model,
interpolator=feature.interpolator,
)
self.feature = feature
self.value = value
self.type = FeatureType.UNCONFORMITY

Expand All @@ -38,38 +40,4 @@ def evaluate(self, pos):
boolean
true if above the unconformity, false if below
"""
return self.feature.evaluate_value(pos) < self.value

def evaluate_value(self, pos):
"""
Parameters
----------
pos : numpy array
locations to evaluate the value of the base geological feature
Returns
-------
"""
return self.feature.evaluate_value(pos)

def evaluate_gradient(self, pos):
"""
Parameters
----------
pos : numpy array
location to evaluate the gradient of the base geological feature
Returns
-------
"""
return self.feature.evaluate_gradient(pos)

def min(self):
return self.feature.min()

def max(self):
return self.feature.max()
return self.evaluate_value(pos) < self.value
3 changes: 2 additions & 1 deletion LoopStructural/modelling/features/fault/_fault_segment.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from LoopStructural.modelling.features.fault._fault_function_feature import (
FaultDisplacementFeature,
)
from LoopStructural.modelling.features import FeatureType
from LoopStructural.modelling.features.fault._fault_function import BaseFault
from LoopStructural.utils import getLogger, NegativeRegion, PositiveRegion
from LoopStructural.modelling.features import StructuralFrame
Expand Down Expand Up @@ -36,7 +37,7 @@ def __init__(
kwargs
"""
StructuralFrame.__init__(self, features, name, fold)
self.type = "fault"
self.type = FeatureType.INTERPOLATED
self.displacement = displacement
self._faultfunction = BaseFault.fault_displacement
self.steps = steps
Expand Down
8 changes: 4 additions & 4 deletions LoopStructural/modelling/intrusions/intrusion_feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

# import logging
from LoopStructural.utils import getLogger
from LoopStructural.modelling.features import FeatureType

logger = getLogger(__name__)

Expand Down Expand Up @@ -34,15 +35,15 @@ def __init__(self, frame, builder, name="UnnamedIntrusion", model=None):
self.model = model
self.intrusion_frame = frame
self.builder = builder
self.type = "intrusion"
self.type = FeatureType.INTRUSION
# simulated thresholds:
self._lateral_simulated_thresholds = None
self._growth_simulated_thresholds = None

@property
def lateral_simulated_thresholds(self):
self.builder.up_to_date()

return self._lateral_simulated_thresholds

@lateral_simulated_thresholds.setter
Expand All @@ -61,12 +62,11 @@ def growth_simulated_thresholds(self, growth_simulated_threshold):
# TODO check type is correct and will work?
self._growth_simulated_thresholds = growth_simulated_threshold


@property
def lateral_sgs_input_data(self):
self.builder.up_to_date()
return self.builder.lateral_sgs_input_data

@property
def vertical_sgs_input_data(self):
self.builder.up_to_date()
Expand Down

0 comments on commit 304335d

Please sign in to comment.