Skip to content

Commit c77681f

Browse files
author
Lachlan Grose
committed
fix: abutting fault polarity was being calculated inconsistently.
Have changed to use the estimated down_throw direction, if different <90 then use positive, otherwise use negative
1 parent 6723790 commit c77681f

File tree

4 files changed

+47
-18
lines changed

4 files changed

+47
-18
lines changed

LoopStructural/modelling/core/geological_model.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,9 @@ def from_processor(cls, processor):
235235
model[edge[1]].splay[model[edge[0]].name] = region
236236
splay = True
237237
if splay == False:
238-
model[edge[1]].add_abutting_fault(model[edge[0]])
238+
model[edge[1]].add_abutting_fault(model[edge[0]],np.abs(processor.stratigraphic_column['faults'][edge[0]]['downthrow_dir']-
239+
processor.stratigraphic_column['faults'][edge[1]]['downthrow_dir']) < 90)
240+
# model[edge[1]].add_abutting_fault(model[edge[0]])
239241
for s in processor.stratigraphic_column.keys():
240242
if s != 'faults':
241243
f = model.create_and_add_foliation(s,**processor.foliation_properties[s])

LoopStructural/modelling/fault/fault_segment.py

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from LoopStructural.modelling.fault.fault_function_feature import FaultDisplacementFeature
44
from LoopStructural.modelling.fault.fault_function import BaseFault
5-
from LoopStructural.utils import getLogger
5+
from LoopStructural.utils import getLogger, NegativeRegion, PositiveRegion
66
logger = getLogger(__name__)
77
from concurrent.futures import ThreadPoolExecutor
88
import numpy as np
@@ -347,19 +347,24 @@ def apply_to_points(self, points):
347347
newp[mask, :] += g
348348
return newp
349349

350-
def add_abutting_fault(self,abutting_fault_feature):
351-
pts = self.faultframe[0].builder.data[['X','Y','Z']].to_numpy()#get_value_constraints()
350+
def add_abutting_fault(self,abutting_fault_feature,positive=None):
352351
# check whether the fault is on the hanging wall or footwall of abutting fault
353-
354-
def abutting_region(pos):
352+
abutting_region = None
353+
if positive is None:
354+
pts = self.faultframe[0].builder.data[['X','Y','Z']].to_numpy()#get_value_constraints()
355355
abut_value = np.nanmedian(abutting_fault_feature.evaluate_value(pts))
356-
if abut_value > 0:
357-
## adding the nan check avoids truncating the fault at the edge of the abutting fault bounding box.
358-
## it makes the assumption that the abutted fault is not drawn across the abutting fault... but this should be ok
359-
return np.logical_or(abutting_fault_feature.evaluate_value(pos) > 0,
360-
np.isnan(abutting_fault_feature.evaluate_value(pos)))
361-
if abut_value < 0:
362-
return np.logical_or(abutting_fault_feature.evaluate_value(pos) < 0,
363-
np.isnan(abutting_fault_feature.evaluate_value(pos)))
356+
positive = abut_value > 0
357+
if positive:
358+
abutting_region = PositiveRegion(abutting_fault_feature)
359+
if positive == False:
360+
abutting_region = NegativeRegion(abutting_fault_feature)
361+
# if positive == True:
362+
# ## adding the nan check avoids truncating the fault at the edge of the abutting fault bounding box.
363+
# ## it makes the assumption that the abutted fault is not drawn across the abutting fault... but this should be ok
364+
# return np.logical_or(abutting_fault_feature.evaluate_value(pos) > 0,
365+
# np.isnan(abutting_fault_feature.evaluate_value(pos)))
366+
# if positive == False:
367+
# return np.logical_or(abutting_fault_feature.evaluate_value(pos) < 0,
368+
# np.isnan(abutting_fault_feature.evaluate_value(pos)))
364369
self.abut[abutting_fault_feature.name] = abutting_region
365370
self.faultframe[0].add_region(abutting_region)

LoopStructural/utils/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66
from .map2loop import process_map2loop, build_model
77
from .helper import get_data_axis_aligned_bounding_box, get_data_bounding_box, get_data_bounding_box_map
88
from .helper import get_dip_vector,get_strike_vector, get_vectors, strike_dip_vector
9-
from .regions import RegionEverywhere
9+
from .regions import RegionEverywhere, RegionFunction, NegativeRegion, PositiveRegion
1010
from .exceptions import LoopException, LoopImportError, InterpolatorError, LoopTypeError, LoopValueError

LoopStructural/utils/regions.py

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,33 @@
11
import numpy as np
2+
class BaseRegion:
3+
def __init__(self):
4+
self.type="BaseRegion"
25

3-
class RegionEverywhere:
6+
class RegionEverywhere(BaseRegion):
7+
def __init__(self):
8+
super().__init__()
9+
self.type = "RegionEverywhere"
410
def __call__(self,xyz):
511
return np.ones(xyz.shape[0],dtype='bool')
612

7-
class RegionFunction:
13+
class RegionFunction(BaseRegion):
814
def __init__(self,function):
15+
super().__init__()
916
self.function = function
1017
def __call__(self,xyz):
11-
return self.function(xyz)
18+
return self.function(xyz)
19+
20+
class PositiveRegion:
21+
def __init__(self,feature):
22+
self.feature = feature
23+
def __call__(self,xyz):
24+
return np.logical_or(self.feature.evaluate_value(xyz) > 0,
25+
np.isnan(self.feature.evaluate_value(xyz)))
26+
27+
class NegativeRegion:
28+
def __init__(self,feature):
29+
self.feature = feature
30+
def __call__(self,xyz):
31+
return np.logical_or(self.feature.evaluate_value(xyz) < 0,
32+
np.isnan(self.feature.evaluate_value(xyz)))
33+

0 commit comments

Comments
 (0)