Skip to content

Commit 434d802

Browse files
committed
(BUG) issues building folded fold frame
- trying to solve by being creative with how to build the fold frame
1 parent 8b77966 commit 434d802

File tree

6 files changed

+128
-15
lines changed

6 files changed

+128
-15
lines changed

LoopStructural/interpolators/piecewiselinear_interpolator.py

Lines changed: 61 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,10 @@ def _setup_interpolator(self, **kwargs):
7272
self.interpolation_weights[key] = kwargs[key]
7373
if self.interpolation_weights['cgw'] > 0.:
7474
self.up_to_date = False
75-
self.add_constant_gradient(self.interpolation_weights['cgw'])
75+
self.add_constant_gradient(self.interpolation_weights['cgw'],
76+
direction_feature=kwargs.get('direction_feature',None),
77+
direction_vector=kwargs.get('direction_vector',None)
78+
)
7679
logger.info("Using constant gradient regularisation w = %f"
7780
%self.interpolation_weights['cgw'])
7881
logger.info("Added %i gradient constraints, %i normal constraints,"
@@ -87,7 +90,7 @@ def _setup_interpolator(self, **kwargs):
8790
if 'constant_norm' in kwargs:
8891
self.add_constant_norm(w=kwargs['constant_norm'])
8992

90-
def add_constant_gradient(self, w=0.1):
93+
def add_constant_gradient(self, w= 0.1, direction_vector=None, direction_feature=None):
9194
"""
9295
Add the constant gradient regularisation to the system
9396
@@ -99,8 +102,59 @@ def add_constant_gradient(self, w=0.1):
99102
-------
100103
101104
"""
105+
if direction_feature is not None:
106+
print('dir fe')
107+
direction_vector = direction_feature.evaluate_gradient(self.support.barycentre())
108+
if direction_vector is not None:
109+
if direction_vector.shape[0] == 1:
110+
# if using a constant direction, tile array so it works for cg calc
111+
direction_vector = np.tile(direction_vector,(self.support.barycentre().shape[0],1))
112+
113+
114+
# iterate over all elements
115+
A, idc, B = self.support.get_constant_gradient(region=self.region,direction=direction_vector)
116+
A = np.array(A)
117+
B = np.array(B)
118+
idc = np.array(idc)
119+
120+
gi = np.zeros(self.support.n_nodes)
121+
gi[:] = -1
122+
gi[self.region] = np.arange(0, self.nx)
123+
idc = gi[idc]
124+
outside = ~np.any(idc == -1, axis=1)
125+
126+
# w/=A.shape[0]
127+
self.add_constraints_to_least_squares(A[outside, :] * w,
128+
B[outside] * w, idc[outside, :],
129+
name='regularisation')
130+
return
131+
132+
def add_direction_constant_gradient(self, w= 0.1, direction_vector=None, direction_feature=None):
133+
"""
134+
Add the constant gradient regularisation to the system where regularisation is projected
135+
on a vector
136+
137+
Parameters
138+
----------
139+
w (double) - weighting of the cg parameter
140+
direction_vector
141+
direction_feature
142+
143+
Returns
144+
-------
145+
146+
"""
147+
if direction_feature:
148+
print('dir fe')
149+
direction_vector = direction_feature.evaluate_gradient(self.support.barycentre())
150+
if direction_vector:
151+
if direction_vector.shape[0] == 1:
152+
# if using a constant direction, tile array so it works for cg calc
153+
direction_vector = np.tile(direction_vector,(self.support.barycentre().shape[0],1))
154+
155+
102156
# iterate over all elements
103-
A, idc, B = self.support.get_constant_gradient(region=self.region)
157+
A, idc, B = self.support.get_constant_gradient(region=self.region,direction=direction_vector)
104158
A = np.array(A)
105159
B = np.array(B)
106160
idc = np.array(idc)
@@ -116,6 +170,8 @@ def add_constant_gradient(self, w=0.1):
116170
B[outside] * w, idc[outside, :],
117171
name='regularisation')
118172
return
173+
174+
119175
def add_constant_norm(self, w=0.1):
120176
"""
121177
Add the constant gradient regularisation to the system
@@ -128,7 +184,6 @@ def add_constant_norm(self, w=0.1):
128184
-------
129185
130186
"""
131-
print('adding gradient norm')
132187
# iterate over all elements
133188
A, idc, B = self.support.get_constant_norm(region=self.region)
134189
A = np.array(A)
@@ -358,6 +413,7 @@ def add_gradient_orthogonal_constraint(self, points, vector, w=1.0,
358413
vertices, element_gradients, tetras, inside = self.support.get_tetra_gradient_for_location(points[:,:3])
359414
#e, inside = self.support.elements_for_array(points[:, :3])
360415
#nodes = self.support.nodes[self.support.elements[e]]
416+
vector /= np.linalg.norm(vector,axis=1)[:,None]
361417
vecs = vertices[:, 1:, :] - vertices[:, 0, None, :]
362418
vol = np.abs(np.linalg.det(vecs)) # / 6
363419
# d_t = self.support.get_elements_gradients(e)
@@ -373,7 +429,7 @@ def add_gradient_orthogonal_constraint(self, points, vector, w=1.0,
373429
gi[self.region] = np.arange(0, self.nx).astype(int)
374430
w /= 3
375431
idc = gi[tetras]
376-
B = np.zeros(idc.shape[0])
432+
B = np.zeros(idc.shape[0])+B
377433
outside = ~np.any(idc == -1, axis=1)
378434
self.add_constraints_to_least_squares(A[outside, :] * w,
379435
B[outside], idc[outside, :])

LoopStructural/interpolators/structured_tetra.py

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import logging
55

66
import numpy as np
7-
from LoopStructural.interpolators.cython.dsi_helper import cg, constant_norm
7+
from LoopStructural.interpolators.cython.dsi_helper import cg, constant_norm, fold_cg
88

99
logger = logging.getLogger(__name__)
1010

@@ -233,7 +233,7 @@ def get_tetra_for_location(self, pos):
233233
tetra_return[inside,:] = tetras[mask,:]
234234
return vertices_return, c_return, tetra_return, inside
235235

236-
def get_constant_gradient(self, region):
236+
def get_constant_gradient(self, region, direction=None):
237237
"""
238238
Get the constant gradient for the specified nodes
239239
@@ -246,6 +246,34 @@ def get_constant_gradient(self, region):
246246
-------
247247
248248
"""
249+
"""
250+
Add the constant gradient regularisation to the system
251+
252+
Parameters
253+
----------
254+
w (double) - weighting of the cg parameter
255+
256+
Returns
257+
-------
258+
259+
"""
260+
if direction is not None:
261+
print('using cg direction')
262+
logger.info("Running constant gradient")
263+
elements_gradients = self.get_element_gradients(np.arange(self.ntetra))
264+
if elements_gradients.shape[0] != direction.shape[0]:
265+
logger.error('Cannot add directional CG, vector field is not the correct length')
266+
return
267+
region = region.astype('int64')
268+
269+
neighbours = self.get_neighbours()
270+
elements = self.get_elements()
271+
idc, c, ncons = fold_cg(elements_gradients, direction, neighbours.astype('int64'), elements.astype('int64'), self.nodes)
272+
273+
idc = np.array(idc[:ncons, :])
274+
c = np.array(c[:ncons, :])
275+
B = np.zeros(c.shape[0])
276+
return c, idc, B
249277
if self.cg is None:
250278
logger.info("Running constant gradient")
251279
elements_gradients = self.get_element_gradients(np.arange(self.ntetra))

LoopStructural/modelling/core/geological_model.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -718,8 +718,10 @@ def create_and_add_folded_fold_frame(self, fold_frame_data,
718718
assert type(fold_frame) == FoldFrame, "Please specify a FoldFrame"
719719
fold = FoldEvent(fold_frame,name='Fold_{}'.format(fold_frame_data))
720720
fold_interpolator = self.get_interpolator("DFI", fold=fold, **kwargs)
721+
gy_fold_interpolator = self.get_interpolator("DFI", fold=fold, **kwargs)
722+
721723
frame_interpolator = self.get_interpolator(**kwargs)
722-
interpolators = [fold_interpolator, frame_interpolator,
724+
interpolators = [fold_interpolator, gy_fold_interpolator,
723725
frame_interpolator.copy()]
724726
fold_frame_builder = StructuralFrameBuilder(
725727
interpolators=interpolators, name=fold_frame_data, **kwargs)

LoopStructural/modelling/features/cross_product_geological_feature.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def __init__(self, name, geological_feature_a, geological_feature_b):
3434
super().__init__(name, None)
3535
self.geological_feature_a = geological_feature_a
3636
self.geological_feature_b = geological_feature_b
37-
37+
self.value_feature = None
3838
def evaluate_gradient(self, locations):
3939
"""
4040
Calculate the gradient of the geological feature by using numpy to
@@ -49,8 +49,11 @@ def evaluate_gradient(self, locations):
4949
-------
5050
5151
"""
52-
return np.cross(self.geological_feature_a.evaluate_gradient(locations),
53-
self.geological_feature_b.evaluate_gradient(locations),
52+
v1 = self.geological_feature_a.evaluate_gradient(locations)
53+
# v1 /= np.linalg.norm(v1,axis=1)[:,None]
54+
v2 = self.geological_feature_b.evaluate_gradient(locations)
55+
# v2 /= np.linalg.norm(v2,axis=1)[:,None]
56+
return np.cross(v1,v2,
5457
axisa=1,
5558
axisb=1)
5659

@@ -65,13 +68,22 @@ def evaluate_value(self, evaluation_points):
6568
-------
6669
6770
"""
68-
return np.zeros(evaluation_points.shape[0])
71+
values = np.zeros(evaluation_points.shape[0])
72+
if self.value_feature is not None:
73+
values[:] = self.value_feature.evaluate_value(evaluation_points)
74+
return values
6975

7076
def mean(self):
77+
if self.value_feature:
78+
return self.value_feature.mean()
7179
return 0.
7280

7381
def min(self):
82+
if self.value_feature:
83+
return self.value_feature.min()
7484
return 0.
7585

7686
def max(self):
87+
if self.value_feature:
88+
return self.value_feature.max()
7789
return 0.

LoopStructural/modelling/features/structural_frame_builder.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ def build(self, w1=1., w2=1., w3=1., frame=StructuralFrame, **kwargs):
128128
0], **kwargs)
129129
# remove fold from kwargs
130130

131-
fold = kwargs.pop('fold', False)
131+
fold = kwargs.pop('fold', None)
132132
if gx_feature is None:
133133
logger.warning(
134134
"Not enough constraints for structural frame coordinate 0, \n"
@@ -159,7 +159,22 @@ def build(self, w1=1., w2=1., w3=1., frame=StructuralFrame, **kwargs):
159159
self.builders[1].add_orthogonal_feature(gx_feature, gxxgy,step=step)
160160
if gz_feature is not None and gyxgz>0:
161161
self.builders[1].add_orthogonal_feature(gz_feature, gyxgz,step=step)
162-
gy_feature = self.builders[1].build(regularisation=regularisation[1], **kwargs)
162+
gy_const_norm = kwargs.get('gy_const_norm',0.)
163+
164+
## bit of an ugly hack, adding in norm constraints for the norm we are forcing
165+
tmp = CrossProductGeologicalFeature('tmp',gx_feature,gz_feature)
166+
self.builders[1].add_orthogonal_feature(tmp,10.,step=step,B=1)
167+
# gy_feature.value_feature = fold.fold frame[0]
168+
# vector = feature.evaluate_gradient(self.builders[1].interpolator.support.barycentre())
169+
# vector /= np.linalg.norm(vector,axis=1)[:,None]
170+
# element_idx = np.arange(self.builders[1].interpolator.support.n_elements)
171+
# np.random.shuffle(element_idx)
172+
# norm_pts = np.hstack([self.builders[1].interpolator.support.barycentre()[element_idx[::step],:],vector[element_idx[::step],:],np.ones((vector[element_idx[::step],:].shape[0],1))])
173+
174+
# self.builders[1].interpolator.set_normal_constraints(norm_pts)
175+
self.builders[1].data_added=True
176+
177+
gy_feature = self.builders[1].build(regularisation=regularisation[1],**kwargs)
163178

164179
if gy_feature is None:
165180
logger.warning(

LoopStructural/modelling/fold/fold.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def __init__(self, foldframe, fold_axis_rotation=None, fold_limb_rotation=None,
2626
self.fold_limb_rotation = fold_limb_rotation
2727
self.fold_axis = fold_axis
2828
self.name = name
29-
29+
3030
def get_fold_axis_orientation(self, points):
3131
"""
3232
gets the fold axis orientation for evaluation points

0 commit comments

Comments
 (0)