Skip to content

Commit 91d0db0

Browse files
committed
(REMOVED) support no longer contains property values
this is stored on the interpolator now and the can be evaluated by providing an array to the support
1 parent f04a43f commit 91d0db0

File tree

5 files changed

+66
-79
lines changed

5 files changed

+66
-79
lines changed

LoopStructural/interpolators/discrete_interpolator.py

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,9 @@ def __init__(self, support):
3131
GeologicalInterpolator.__init__(self)
3232
self.B = []
3333
self.support = support
34-
self.region_function = None
35-
self.region = np.arange(0, support.n_nodes)
36-
self.region_map = np.zeros(support.n_nodes).astype(int)
34+
self.region_function = lambda xyz : np.ones(xyz.shape[0],dtype=int)
3735
# self.region_map[self.region] = np.array(range(0,
3836
# len(self.region_map[self.region])))
39-
self.nx = len(self.support.nodes[self.region])
4037
self.shape = 'rectangular'
4138
if self.shape == 'square':
4239
self.B = np.zeros(self.nx)
@@ -53,7 +50,21 @@ def __init__(self, support):
5350
self.constraints = {}
5451
self.interpolation_weights= {}
5552
logger.info("Creating discrete interpolator with {} degrees of freedom".format(self.nx))
56-
53+
54+
@property
55+
def nx(self):
56+
return len(self.support.nodes[self.region])
57+
58+
@property
59+
def region(self):
60+
return self.region_function(self.support.nodes)
61+
62+
@property
63+
def region_map(self):
64+
region_map = np.zeros(self.support.n_nodes).astype(int)
65+
region_map[self.region] = np.array(
66+
range(0, len(region_map[self.region])))
67+
return region_map
5768
def set_property_name(self, propertyname):
5869
"""
5970
Set the property name attribute, this is usually used to
@@ -85,11 +96,6 @@ def set_region(self, region=None):
8596
# evaluate the region function on the support to determine
8697
# which nodes are inside update region map and degrees of freedom
8798
self.region_function = region
88-
self.region = region(self.support.nodes)
89-
self.region_map = np.zeros(self.support.n_nodes).astype(int)
90-
self.region_map[self.region] = np.array(
91-
range(0, len(self.region_map[self.region])))
92-
self.nx = len(self.support.nodes[self.region])
9399
logger.info("Interpolation now uses region and has {} degrees of freedom".format(self.nx))
94100

95101
def set_interpolation_weights(self, weights):
@@ -511,7 +517,7 @@ def _solve(self, solver='cg', **kwargs):
511517
logger.warning("Using external solver")
512518
self.c[self.region] = kwargs['external'](A, B)[:self.nx]
513519
# check solution is not nan
514-
self.support.properties[self.propertyname] = self.c
520+
# self.support.properties[self.propertyname] = self.c
515521
if np.all(self.c == np.nan):
516522
logger.warning("Solver not run, no scalar field")
517523
# if solution is all 0, probably didn't work
@@ -544,7 +550,7 @@ def evaluate_value(self, evaluation_points):
544550

545551
if evaluation_points[~mask, :].shape[0] > 0:
546552
evaluated[~mask] = self.support.evaluate_value(
547-
evaluation_points[~mask], self.propertyname)
553+
evaluation_points[~mask], self.c)
548554
return evaluated
549555

550556
def evaluate_gradient(self, evaluation_points):
@@ -561,5 +567,5 @@ def evaluate_gradient(self, evaluation_points):
561567
"""
562568
if evaluation_points.shape[0] > 0:
563569
return self.support.evaluate_gradient(evaluation_points,
564-
self.propertyname)
570+
self.c)
565571
return np.zeros((0, 3))

LoopStructural/interpolators/piecewiselinear_interpolator.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ def __init__(self, mesh):
3333
DiscreteInterpolator.__init__(self, mesh)
3434
# whether to assemble a rectangular matrix or a square matrix
3535
self.interpolator_type = 'PLI'
36-
self.nx = len(self.support.nodes[self.region])
3736
self.support = mesh
3837

3938
self.interpolation_weights = {'cgw': 0.1, 'cpw': 1., 'npw': 1.,

LoopStructural/interpolators/structured_grid.py

Lines changed: 21 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,22 @@
66

77
import numpy as np
88

9+
from .base_structured_3d_support import BaseStructuredSupport
10+
11+
912
from LoopStructural.utils import getLogger
1013
logger = getLogger(__name__)
1114

1215

13-
class StructuredGrid:
16+
class StructuredGrid(BaseStructuredSupport):
1417
"""
1518
1619
"""
1720
def __init__(self,
1821
origin=np.zeros(3),
1922
nsteps=np.array([10, 10, 10]),
2023
step_vector=np.ones(3),
24+
name=None
2125
):
2226
"""
2327
@@ -27,57 +31,15 @@ def __init__(self,
2731
nsteps - 3d list or numpy array of ints
2832
step_vector - 3d list or numpy array of int
2933
"""
30-
31-
self.nsteps = np.array(nsteps)
32-
self.step_vector = np.array(step_vector)
33-
self.origin = np.array(origin)
34-
self.maximum = origin+self.nsteps*self.step_vector
35-
36-
# self.nsteps+=1
37-
self.n_nodes = self.nsteps[0] * self.nsteps[1] * self.nsteps[2]
38-
# self.nsteps-=1
39-
self.dim = 3
40-
self.nsteps_cells = self.nsteps - 1
41-
self.n_cell_x = self.nsteps[0] - 1
42-
self.n_cell_y = self.nsteps[1] - 1
43-
self.n_cell_z = self.nsteps[2] - 1
44-
self.properties = {}
45-
self.n_elements = self.n_cell_x * self.n_cell_y * self.n_cell_z
46-
47-
# calculate the node positions using numpy (this should probably not
48-
# be stored as it defeats
49-
# the purpose of a structured grid
50-
51-
# self.barycentre = self.cell_centres(np.arange(self.n_elements))
52-
34+
BaseStructuredSupport.__init__(self,origin,nsteps,step_vector)
5335
self.regions = {}
5436
self.regions['everywhere'] = np.ones(self.n_nodes).astype(bool)
55-
56-
57-
@property
58-
def nodes(self):
59-
max = self.origin + self.nsteps_cells * self.step_vector
60-
x = np.linspace(self.origin[0], max[0], self.nsteps[0])
61-
y = np.linspace(self.origin[1], max[1], self.nsteps[1])
62-
z = np.linspace(self.origin[2], max[2], self.nsteps[2])
63-
xx, yy, zz = np.meshgrid(x, y, z, indexing='ij')
64-
return np.array([xx.flatten(order='F'), yy.flatten(order='F'),
65-
zz.flatten(order='F')]).T
37+
self.name = name
6638

6739
def barycentre(self):
6840
return self.cell_centres(np.arange(self.n_elements))
6941

70-
# @property
71-
# def barycentre(self):
72-
# return self.cell_centres(np.arange(self.n_elements))
7342

74-
def print_geometry(self):
75-
print('Origin: %f %f %f' % (
76-
self.origin[0], self.origin[1], self.origin[2]))
77-
print('Cell size: %f %f %f' % (
78-
self.step_vector[0], self.step_vector[1], self.step_vector[2]))
79-
max = self.origin + self.nsteps_cells * self.step_vector
80-
print('Max extent: %f %f %f' % (max[0], max[1], max[2]))
8143

8244
def update_property(self, propertyname, values):
8345
"""[summary]
@@ -373,7 +335,7 @@ def position_to_cell_corners(self, pos):
373335
globalidx[~inside] = -1
374336
return globalidx, inside
375337

376-
def evaluate_value(self, evaluation_points, property_name):
338+
def evaluate_value(self, evaluation_points, property_array):
377339
"""
378340
Evaluate the value of of the property at the locations.
379341
Trilinear interpolation dot corner values
@@ -387,25 +349,33 @@ def evaluate_value(self, evaluation_points, property_name):
387349
-------
388350
389351
"""
352+
if property_array.shape[0] != self.n_nodes:
353+
logger.error("Property array does not match grid")
354+
raise BaseException
390355
idc, inside = self.position_to_cell_corners(evaluation_points)
391356
v = np.zeros(idc.shape)
392357
v[:, :] = np.nan
393358

394359
v[inside, :] = self.position_to_dof_coefs(
395360
evaluation_points[inside, :]).T
396-
v[inside, :] *= self.properties[property_name][idc[inside, :]]
361+
362+
v[inside, :] *= property_array[idc[inside, :]]
363+
397364
return np.sum(v, axis=1)
398365

399-
def evaluate_gradient(self, evaluation_points, property_name):
366+
def evaluate_gradient(self, evaluation_points, property_array):
367+
if property_array.shape[0] != self.n_nodes:
368+
logger.error("Property array does not match grid")
369+
raise BaseException
400370
idc, inside = self.position_to_cell_corners(evaluation_points)
401371
T = np.zeros((idc.shape[0], 3, 8))
402372
T[inside, :, :] = self.calcul_T(evaluation_points[inside, :])
403373
# indices = np.array([self.position_to_cell_index(evaluation_points)])
404374
# idc = self.global_indicies(indices.swapaxes(0,1))
405375
# print(idc)
406-
T[inside, 0, :] *= self.properties[property_name][idc[inside, :]]
407-
T[inside, 1, :] *= self.properties[property_name][idc[inside, :]]
408-
T[inside, 2, :] *= self.properties[property_name][idc[inside, :]]
376+
T[inside, 0, :] *= property_array[idc[inside, :]]
377+
T[inside, 1, :] *= property_array[idc[inside, :]]
378+
T[inside, 2, :] *= property_array[idc[inside, :]]
409379
return np.array(
410380
[np.sum(T[:, 0, :], axis=1), np.sum(T[:, 1, :], axis=1) ,
411381
np.sum(T[:, 2, :], axis=1) ]).T

LoopStructural/interpolators/structured_tetra.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,7 @@ def barycentre(self, elements = None):
8585
axis=1) / 4.
8686
return barycentre
8787

88-
def update_property(self, name, value):
89-
90-
self.properties[name] = value
91-
92-
def evaluate_value(self, pos, prop):
88+
def evaluate_value(self, pos, property_array):
9389
"""
9490
Evaluate value of interpolant
9591
@@ -107,10 +103,10 @@ def evaluate_value(self, pos, prop):
107103
values = np.zeros(pos.shape[0])
108104
values[:] = np.nan
109105
vertices, c, tetras, inside = self.get_tetra_for_location(pos)
110-
values[inside] = np.sum(c[inside,:]*self.properties[prop][tetras[inside,:]],axis=1)
106+
values[inside] = np.sum(c[inside,:]*property_array[tetras[inside,:]],axis=1)
111107
return values
112108

113-
def evaluate_gradient(self, pos, prop):
109+
def evaluate_gradient(self, pos, property_array):
114110
"""
115111
Evaluate the gradient of an interpolant at the locations
116112
@@ -131,7 +127,7 @@ def evaluate_gradient(self, pos, prop):
131127
vertices, element_gradients, tetras, inside = self.get_tetra_gradient_for_location(pos)
132128
vertex_vals = self.properties[prop][tetras]
133129
#grads = np.zeros(tetras.shape)
134-
values[inside,:] = (element_gradients[inside,:,:]*self.properties[prop][tetras[inside,None,:]]).sum(2)
130+
values[inside,:] = (element_gradients[inside,:,:]*property_array[tetras[inside,None,:]]).sum(2)
135131
length = np.sum(values[inside,:],axis=1)
136132
# values[inside,:] /= length[:,None]
137133
return values

LoopStructural/modelling/features/geological_feature_builder.py

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
weight_name, gradient_vec_names, tangent_vec_names, interface_name
1515
from LoopStructural.modelling.features import GeologicalFeature
1616
from LoopStructural.utils.helper import get_data_bounding_box_map as get_data_bounding_box
17-
17+
from LoopStructural.utils import get_data_axis_aligned_bounding_box
1818

1919
class GeologicalFeatureInterpolator:
2020
"""[summary]
@@ -310,13 +310,29 @@ def build(self, fold=None, fold_weights={}, data_region=None, **kwargs):
310310
311311
"""
312312

313-
if data_region is not None:
314-
xyz = self.get_data_locations()
315-
bb, region = get_data_bounding_box(xyz, data_region)
316-
self.interpolator.set_region(region=region)
313+
317314
if not self.data_added:
318315
self.add_data_to_interpolator(**kwargs)
319-
316+
if data_region is not None:
317+
xyz = self.interpolator.get_data_locations()
318+
bb, region = get_data_bounding_box(xyz, data_region)
319+
# if self.model.reuse_supports == False:
320+
if np.any(np.min(bb[0,:])< self.interpolator.support.origin):
321+
neworigin = np.min([self.interpolator.support.origin,bb[0,:]],axis=0)
322+
logger.info("Changing origin of support for {} from {} {} {} to {} {} {}"\
323+
.format(self.name,self.interpolator.support.origin[0],\
324+
self.interpolator.support.origin[1],self.interpolator.support.origin[2],\
325+
neworigin[0],neworigin[1],neworigin[2]))
326+
self.interpolator.support.origin = neworigin
327+
if np.any(np.max(bb[0,:])< self.interpolator.support.maximum):
328+
newmax = np.max([self.interpolator.support.maximum,bb[0,:]],axis=0)
329+
logger.info("Changing origin of support for {} from {} {} {} to {} {} {}"\
330+
.format(self.name,self.interpolator.support.maximum[0],
331+
self.interpolator.support.maximum[1],self.interpolator.support.maximum[2],\
332+
newmax[0],newmax[1],newmax[2]))
333+
334+
self.interpolator.support.maximum = newmax
335+
self.interpolator.set_region(region=region)
320336
# moving this to init because it needs to be done before constraints
321337
# are added?
322338
if fold is not None:

0 commit comments

Comments
 (0)