LoopStructural 1.0.3__zip → 1.0.71.dev0__zip
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/__init__.py +12 -7
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/__pycache__/__init__.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/__pycache__/__init__.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/__pycache__/_base.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__init__.py +3 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/__init__.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/base_structured_3d_support.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/discrete_fold_interpolator.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/discrete_interpolator.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/finite_difference_interpolator.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/geological_interpolator.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/operator.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/piecewiselinear_interpolator.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/structured_grid.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/structured_tetra.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/surfe_wrapper.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/base_structured_3d_support.py +101 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/cython/__pycache__/__init__.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/cython/dsi_helper.c +4137 -2716
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/cython/dsi_helper.cp36-win_amd64.pyd +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/discrete_fold_interpolator.py +56 -22
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/discrete_interpolator.py +61 -28
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/finite_difference_interpolator.py +71 -11
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/geological_interpolator.py +22 -3
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/operator.py +16 -1
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/piecewiselinear_interpolator.py +150 -11
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/structured_grid.py +31 -69
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/structured_tetra.py +89 -45
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/surfe_wrapper.py +7 -8
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/__pycache__/__init__.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/__pycache__/__init__.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/__pycache__/geological_model.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/__pycache__/geological_model_graph.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/__pycache__/stratigraphic_column.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/geological_model.py +515 -197
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/geological_model_graph.py +881 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/stratigraphic_column.py +5 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__init__.py +1 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/__init__.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/fault_builder.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/fault_function.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/fault_function_feature.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/fault_segment.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/fault_builder.py +127 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/fault_function.py +2 -1
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/fault_function_feature.py +2 -1
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/fault_segment.py +30 -3
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__init__.py +1 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/__init__.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/cross_product_geological_feature.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/geological_feature.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/geological_feature_builder.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/lambda_geological_feature.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/region_feature.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/structural_frame.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/structural_frame_builder.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/unconformity_feature.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/cross_product_geological_feature.py +18 -5
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/geological_feature.py +22 -49
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/geological_feature_builder.py +171 -47
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/lambda_geological_feature.py +31 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/region_feature.py +3 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/structural_frame.py +28 -11
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/structural_frame_builder.py +32 -22
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/unconformity_feature.py +6 -1
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/__init__.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/fold.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/fold_rotation_angle.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/fold_rotation_angle_feature.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/foldframe.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/svariogram.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/fold.py +13 -5
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/fold_rotation_angle.py +5 -4
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/fold_rotation_angle_feature.py +2 -1
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/foldframe.py +7 -5
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/svariogram.py +2 -1
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__init__.py +5 -1
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/__init__.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/bounding_box.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/exceptions.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/helper.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/logging.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/map2loop.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/regions.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/utils.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/bounding_box.py +21 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/exceptions.py +2 -1
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/helper.py +10 -2
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/logging.py +60 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/map2loop.py +128 -37
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/regions.py +11 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/utils.py +40 -47
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/__init__.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/map_viewer.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/model_plotter.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/model_visualisation.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/rotation_angle_plotter.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/sphinx_scraper.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/stratigraphic_column.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/map_viewer.py +236 -36
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/model_plotter.py +2 -1
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/model_visualisation.py +427 -79
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/rotation_angle_plotter.py +29 -12
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/stratigraphic_column.py +60 -0
- Miniconda/envs/loop/Lib/site-packages/{LoopStructural-1.0.3-py3.6.egg-info → LoopStructural-1.0.71.dev0-py3.6.egg-info}/PKG-INFO +1 -1
- Miniconda/envs/loop/Lib/site-packages/{LoopStructural-1.0.3-py3.6.egg-info → LoopStructural-1.0.71.dev0-py3.6.egg-info}/SOURCES.txt +10 -5
- Miniconda/envs/loop/Lib/site-packages/LoopStructural-1.0.71.dev0-py3.6.egg-info/requires.txt +8 -0
- Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/__init__.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural-1.0.3-py3.6.egg-info/requires.txt +0 -3
- Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/test_faults.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/test_fold.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/test_interpolator.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/test_refolded.cpython-36.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/tests/test_faults.py +0 -17
- Miniconda/envs/loop/Lib/site-packages/tests/test_fold.py +0 -57
- Miniconda/envs/loop/Lib/site-packages/tests/test_interpolator.py +0 -88
- Miniconda/envs/loop/Lib/site-packages/tests/test_refolded.py +0 -22
- /Miniconda/envs/loop/Lib/site-packages/{LoopStructural-1.0.3-py3.6.egg-info → LoopStructural-1.0.71.dev0-py3.6.egg-info}/dependency_links.txt +0 -0
- /Miniconda/envs/loop/Lib/site-packages/{LoopStructural-1.0.3-py3.6.egg-info → LoopStructural-1.0.71.dev0-py3.6.egg-info}/top_level.txt +0 -0
Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/piecewiselinear_interpolator.py
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Piecewise linear interpolator
|
|
3
|
+
"""
|
|
1
4
|
import logging
|
|
2
5
|
|
|
3
6
|
import numpy as np
|
|
@@ -6,7 +9,8 @@ from LoopStructural.interpolators.discrete_interpolator import \
|
|
|
6
9
|
DiscreteInterpolator
|
|
7
10
|
from LoopStructural.utils.helper import get_vectors
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
from LoopStructural.utils import getLogger
|
|
13
|
+
logger = getLogger(__name__)
|
|
10
14
|
|
|
11
15
|
|
|
12
16
|
class PiecewiseLinearInterpolator(DiscreteInterpolator):
|
|
@@ -29,11 +33,10 @@ class PiecewiseLinearInterpolator(DiscreteInterpolator):
|
|
|
29
33
|
DiscreteInterpolator.__init__(self, mesh)
|
|
30
34
|
# whether to assemble a rectangular matrix or a square matrix
|
|
31
35
|
self.interpolator_type = 'PLI'
|
|
32
|
-
self.nx = len(self.support.nodes[self.region])
|
|
33
36
|
self.support = mesh
|
|
34
37
|
|
|
35
|
-
self.
|
|
36
|
-
'gpw': 1., 'tpw': 1.}
|
|
38
|
+
self.interpolation_weights = {'cgw': 0.1, 'cpw': 1., 'npw': 1.,
|
|
39
|
+
'gpw': 1., 'tpw': 1., 'ipw': 1.}
|
|
37
40
|
self.__str = 'Piecewise Linear Interpolator with %i unknowns. \n' % \
|
|
38
41
|
self.nx
|
|
39
42
|
|
|
@@ -69,7 +72,10 @@ class PiecewiseLinearInterpolator(DiscreteInterpolator):
|
|
|
69
72
|
self.interpolation_weights[key] = kwargs[key]
|
|
70
73
|
if self.interpolation_weights['cgw'] > 0.:
|
|
71
74
|
self.up_to_date = False
|
|
72
|
-
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
|
+
)
|
|
73
79
|
logger.info("Using constant gradient regularisation w = %f"
|
|
74
80
|
%self.interpolation_weights['cgw'])
|
|
75
81
|
logger.info("Added %i gradient constraints, %i normal constraints,"
|
|
@@ -80,8 +86,11 @@ class PiecewiseLinearInterpolator(DiscreteInterpolator):
|
|
|
80
86
|
self.add_norm_ctr_pts(self.interpolation_weights['npw'])
|
|
81
87
|
self.add_ctr_pts(self.interpolation_weights['cpw'])
|
|
82
88
|
self.add_tangent_ctr_pts(self.interpolation_weights['tpw'])
|
|
83
|
-
|
|
84
|
-
|
|
89
|
+
self.add_interface_ctr_pts(self.interpolation_weights['ipw'])
|
|
90
|
+
if 'constant_norm' in kwargs:
|
|
91
|
+
self.add_constant_norm(w=kwargs['constant_norm'])
|
|
92
|
+
|
|
93
|
+
def add_constant_gradient(self, w= 0.1, direction_vector=None, direction_feature=None):
|
|
85
94
|
"""
|
|
86
95
|
Add the constant gradient regularisation to the system
|
|
87
96
|
|
|
@@ -93,8 +102,17 @@ class PiecewiseLinearInterpolator(DiscreteInterpolator):
|
|
|
93
102
|
-------
|
|
94
103
|
|
|
95
104
|
"""
|
|
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
|
+
|
|
96
114
|
# iterate over all elements
|
|
97
|
-
A, idc, B = self.support.get_constant_gradient(region=self.region)
|
|
115
|
+
A, idc, B = self.support.get_constant_gradient(region=self.region,direction=direction_vector)
|
|
98
116
|
A = np.array(A)
|
|
99
117
|
B = np.array(B)
|
|
100
118
|
idc = np.array(idc)
|
|
@@ -111,6 +129,79 @@ class PiecewiseLinearInterpolator(DiscreteInterpolator):
|
|
|
111
129
|
name='regularisation')
|
|
112
130
|
return
|
|
113
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
|
+
|
|
156
|
+
# iterate over all elements
|
|
157
|
+
A, idc, B = self.support.get_constant_gradient(region=self.region,direction=direction_vector)
|
|
158
|
+
A = np.array(A)
|
|
159
|
+
B = np.array(B)
|
|
160
|
+
idc = np.array(idc)
|
|
161
|
+
|
|
162
|
+
gi = np.zeros(self.support.n_nodes)
|
|
163
|
+
gi[:] = -1
|
|
164
|
+
gi[self.region] = np.arange(0, self.nx)
|
|
165
|
+
idc = gi[idc]
|
|
166
|
+
outside = ~np.any(idc == -1, axis=1)
|
|
167
|
+
|
|
168
|
+
# w/=A.shape[0]
|
|
169
|
+
self.add_constraints_to_least_squares(A[outside, :] * w,
|
|
170
|
+
B[outside] * w, idc[outside, :],
|
|
171
|
+
name='directional regularisation')
|
|
172
|
+
return
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def add_constant_norm(self, w=0.1):
|
|
176
|
+
"""
|
|
177
|
+
Add the constant gradient regularisation to the system
|
|
178
|
+
|
|
179
|
+
Parameters
|
|
180
|
+
----------
|
|
181
|
+
w (double) - weighting of the cg parameter
|
|
182
|
+
|
|
183
|
+
Returns
|
|
184
|
+
-------
|
|
185
|
+
|
|
186
|
+
"""
|
|
187
|
+
# iterate over all elements
|
|
188
|
+
A, idc, B = self.support.get_constant_norm(region=self.region)
|
|
189
|
+
A = np.array(A)
|
|
190
|
+
B = np.array(B)
|
|
191
|
+
idc = np.array(idc)
|
|
192
|
+
|
|
193
|
+
gi = np.zeros(self.support.n_nodes)
|
|
194
|
+
gi[:] = -1
|
|
195
|
+
gi[self.region] = np.arange(0, self.nx)
|
|
196
|
+
idc = gi[idc]
|
|
197
|
+
outside = ~np.any(idc == -1, axis=1)
|
|
198
|
+
|
|
199
|
+
# w/=A.shape[0]
|
|
200
|
+
self.add_constraints_to_least_squares(A[outside, :] * w,
|
|
201
|
+
B[outside] * w, idc[outside, :],
|
|
202
|
+
name='norm_regularisation')
|
|
203
|
+
return
|
|
204
|
+
|
|
114
205
|
def add_gradient_ctr_pts(self, w=1.0):
|
|
115
206
|
"""
|
|
116
207
|
Adds gradient constraints to the least squares system with a weight
|
|
@@ -131,6 +222,7 @@ class PiecewiseLinearInterpolator(DiscreteInterpolator):
|
|
|
131
222
|
requires at least two other
|
|
132
223
|
value constraints OR a norm constraint for the interpolant to solve.
|
|
133
224
|
"""
|
|
225
|
+
|
|
134
226
|
points = self.get_gradient_constraints()
|
|
135
227
|
if points.shape[0] > 0:
|
|
136
228
|
vertices, element_gradients, tetras, inside = self.support.get_tetra_gradient_for_location(points[:,:3])
|
|
@@ -226,7 +318,8 @@ class PiecewiseLinearInterpolator(DiscreteInterpolator):
|
|
|
226
318
|
|
|
227
319
|
Parameters
|
|
228
320
|
----------
|
|
229
|
-
w
|
|
321
|
+
w : double
|
|
322
|
+
weight
|
|
230
323
|
|
|
231
324
|
Returns
|
|
232
325
|
-------
|
|
@@ -255,6 +348,51 @@ class PiecewiseLinearInterpolator(DiscreteInterpolator):
|
|
|
255
348
|
points[inside,:][outside, 3] * w * vol[outside],
|
|
256
349
|
idc[outside, :], name='value')
|
|
257
350
|
|
|
351
|
+
def add_interface_ctr_pts(self, w=1.0): # for now weight all value points the same
|
|
352
|
+
"""
|
|
353
|
+
Adds a constraint that defines all points with the same 'id' to be the same value
|
|
354
|
+
Sets all P1-P2 = 0 for all pairs of points
|
|
355
|
+
|
|
356
|
+
Parameters
|
|
357
|
+
----------
|
|
358
|
+
w : double
|
|
359
|
+
weight
|
|
360
|
+
|
|
361
|
+
Returns
|
|
362
|
+
-------
|
|
363
|
+
|
|
364
|
+
"""
|
|
365
|
+
|
|
366
|
+
# get elements for points
|
|
367
|
+
points = self.get_interface_constraints()
|
|
368
|
+
if points.shape[0] > 1:
|
|
369
|
+
vertices, c, tetras, inside = self.support.get_tetra_for_location(points[:,:3])
|
|
370
|
+
# calculate volume of tetras
|
|
371
|
+
vecs = vertices[inside, 1:, :] - vertices[inside, 0, None, :]
|
|
372
|
+
vol = np.abs(np.linalg.det(vecs)) / 6
|
|
373
|
+
A = c[inside]
|
|
374
|
+
A *= vol[:,None]
|
|
375
|
+
idc = tetras[inside,:]
|
|
376
|
+
for id in np.unique(points[np.logical_and(~np.isnan(points[:,3]),inside),3]):
|
|
377
|
+
mask = points[inside,3] == id
|
|
378
|
+
interface_A = A[None,mask,:] - A[mask,None,:]
|
|
379
|
+
interface_A = np.sum(interface_A,axis=0)
|
|
380
|
+
# interface_A = interface_A.reshape((interface_A.shape[0]*interface_A.shape[0],A.shape[1]))
|
|
381
|
+
interface_idc = idc[mask,:]
|
|
382
|
+
|
|
383
|
+
# now map the index from global to region create array size of mesh
|
|
384
|
+
# initialise as np.nan, then map points inside region to 0->nx
|
|
385
|
+
gi = np.zeros(self.support.n_nodes).astype(int)
|
|
386
|
+
gi[:] = -1
|
|
387
|
+
|
|
388
|
+
gi[self.region] = np.arange(0, self.nx)
|
|
389
|
+
interface_idc = gi[interface_idc]
|
|
390
|
+
# interface_idc = np.tile(interface_idc,(interface_idc.shape[0],1)).reshape(interface_A.shape)#flatten()
|
|
391
|
+
outside = ~np.any(interface_idc == -1, axis=1)
|
|
392
|
+
self.add_constraints_to_least_squares(interface_A[outside,:] * w,
|
|
393
|
+
np.zeros(interface_A[outside,:].shape[0]),
|
|
394
|
+
interface_idc[outside, :], name='interface')
|
|
395
|
+
|
|
258
396
|
def add_gradient_orthogonal_constraint(self, points, vector, w=1.0,
|
|
259
397
|
B=0):
|
|
260
398
|
"""
|
|
@@ -275,6 +413,7 @@ class PiecewiseLinearInterpolator(DiscreteInterpolator):
|
|
|
275
413
|
vertices, element_gradients, tetras, inside = self.support.get_tetra_gradient_for_location(points[:,:3])
|
|
276
414
|
#e, inside = self.support.elements_for_array(points[:, :3])
|
|
277
415
|
#nodes = self.support.nodes[self.support.elements[e]]
|
|
416
|
+
vector /= np.linalg.norm(vector,axis=1)[:,None]
|
|
278
417
|
vecs = vertices[:, 1:, :] - vertices[:, 0, None, :]
|
|
279
418
|
vol = np.abs(np.linalg.det(vecs)) # / 6
|
|
280
419
|
# d_t = self.support.get_elements_gradients(e)
|
|
@@ -290,9 +429,9 @@ class PiecewiseLinearInterpolator(DiscreteInterpolator):
|
|
|
290
429
|
gi[self.region] = np.arange(0, self.nx).astype(int)
|
|
291
430
|
w /= 3
|
|
292
431
|
idc = gi[tetras]
|
|
293
|
-
B = np.zeros(idc.shape[0])
|
|
432
|
+
B = np.zeros(idc.shape[0])+B
|
|
294
433
|
outside = ~np.any(idc == -1, axis=1)
|
|
295
434
|
self.add_constraints_to_least_squares(A[outside, :] * w,
|
|
296
|
-
B[outside], idc[outside, :])
|
|
435
|
+
B[outside], idc[outside, :], name='gradient_orthogonal')
|
|
297
436
|
|
|
298
437
|
|
|
@@ -1,11 +1,19 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Cartesian grid for fold interpolator
|
|
3
|
+
|
|
4
|
+
"""
|
|
1
5
|
import logging
|
|
2
6
|
|
|
3
7
|
import numpy as np
|
|
4
8
|
|
|
5
|
-
|
|
9
|
+
from .base_structured_3d_support import BaseStructuredSupport
|
|
10
|
+
|
|
6
11
|
|
|
12
|
+
from LoopStructural.utils import getLogger
|
|
13
|
+
logger = getLogger(__name__)
|
|
7
14
|
|
|
8
|
-
|
|
15
|
+
|
|
16
|
+
class StructuredGrid(BaseStructuredSupport):
|
|
9
17
|
"""
|
|
10
18
|
|
|
11
19
|
"""
|
|
@@ -13,7 +21,7 @@ class StructuredGrid:
|
|
|
13
21
|
origin=np.zeros(3),
|
|
14
22
|
nsteps=np.array([10, 10, 10]),
|
|
15
23
|
step_vector=np.ones(3),
|
|
16
|
-
|
|
24
|
+
name=None
|
|
17
25
|
):
|
|
18
26
|
"""
|
|
19
27
|
|
|
@@ -22,69 +30,15 @@ class StructuredGrid:
|
|
|
22
30
|
origin - 3d list or numpy array
|
|
23
31
|
nsteps - 3d list or numpy array of ints
|
|
24
32
|
step_vector - 3d list or numpy array of int
|
|
25
|
-
maximum
|
|
26
33
|
"""
|
|
27
|
-
|
|
28
|
-
self.nsteps = np.array(nsteps)
|
|
29
|
-
self.step_vector = np.array(step_vector)
|
|
30
|
-
self.origin = np.array(origin)
|
|
31
|
-
# self.nsteps+=1
|
|
32
|
-
self.n_nodes = self.nsteps[0] * self.nsteps[1] * self.nsteps[2]
|
|
33
|
-
# self.nsteps-=1
|
|
34
|
-
self.dim = 3
|
|
35
|
-
self.nsteps_cells = self.nsteps - 1
|
|
36
|
-
self.n_cell_x = self.nsteps[0] - 1
|
|
37
|
-
self.n_cell_y = self.nsteps[1] - 1
|
|
38
|
-
self.n_cell_z = self.nsteps[2] - 1
|
|
39
|
-
self.properties = {}
|
|
40
|
-
self.n_elements = self.n_cell_x * self.n_cell_y * self.n_cell_z
|
|
41
|
-
|
|
42
|
-
# calculate the node positions using numpy (this should probably not
|
|
43
|
-
# be stored as it defeats
|
|
44
|
-
# the purpose of a structured grid
|
|
45
|
-
|
|
46
|
-
# self.barycentre = self.cell_centres(np.arange(self.n_elements))
|
|
47
|
-
|
|
34
|
+
BaseStructuredSupport.__init__(self,origin,nsteps,step_vector)
|
|
48
35
|
self.regions = {}
|
|
49
36
|
self.regions['everywhere'] = np.ones(self.n_nodes).astype(bool)
|
|
50
|
-
|
|
51
|
-
@property
|
|
52
|
-
def nodes(self):
|
|
53
|
-
max = self.origin + self.nsteps_cells * self.step_vector
|
|
54
|
-
x = np.linspace(self.origin[0], max[0], self.nsteps[0])
|
|
55
|
-
y = np.linspace(self.origin[1], max[1], self.nsteps[1])
|
|
56
|
-
z = np.linspace(self.origin[2], max[2], self.nsteps[2])
|
|
57
|
-
xx, yy, zz = np.meshgrid(x, y, z, indexing='ij')
|
|
58
|
-
return np.array([xx.flatten(order='F'), yy.flatten(order='F'),
|
|
59
|
-
zz.flatten(order='F')]).T
|
|
37
|
+
self.name = name
|
|
60
38
|
|
|
61
39
|
def barycentre(self):
|
|
62
40
|
return self.cell_centres(np.arange(self.n_elements))
|
|
63
41
|
|
|
64
|
-
def print_geometry(self):
|
|
65
|
-
print('Origin: %f %f %f' % (
|
|
66
|
-
self.origin[0], self.origin[1], self.origin[2]))
|
|
67
|
-
print('Cell size: %f %f %f' % (
|
|
68
|
-
self.step_vector[0], self.step_vector[1], self.step_vector[2]))
|
|
69
|
-
max = self.origin + self.nsteps_cells * self.step_vector
|
|
70
|
-
print('Max extent: %f %f %f' % (max[0], max[1], max[2]))
|
|
71
|
-
|
|
72
|
-
def update_property(self, propertyname, values):
|
|
73
|
-
"""[summary]
|
|
74
|
-
|
|
75
|
-
[extended_summary]
|
|
76
|
-
|
|
77
|
-
Parameters
|
|
78
|
-
----------
|
|
79
|
-
propertyname : [type]
|
|
80
|
-
[description]
|
|
81
|
-
values : [type]
|
|
82
|
-
[description]
|
|
83
|
-
"""
|
|
84
|
-
if values.shape[0] == self.n_nodes:
|
|
85
|
-
self.properties[propertyname] = values
|
|
86
|
-
if values.shape[0] == self.n_elements:
|
|
87
|
-
self.cell_properties[propertyname] = values
|
|
88
42
|
|
|
89
43
|
def cell_centres(self, global_index):
|
|
90
44
|
"""[summary]
|
|
@@ -293,10 +247,10 @@ class StructuredGrid:
|
|
|
293
247
|
1, 1, 1, 1, 1, 1, 1, 1, 1]
|
|
294
248
|
])
|
|
295
249
|
neighbours = indexes[:, None, :] + mask[:, :, None]
|
|
296
|
-
return
|
|
250
|
+
return(neighbours[0, :, :] + self.nsteps[0, None, None] * neighbours[1,
|
|
297
251
|
:, :] + \
|
|
298
252
|
self.nsteps[0, None, None] * self.nsteps[
|
|
299
|
-
1, None, None] * neighbours[2, :, :]
|
|
253
|
+
1, None, None] * neighbours[2, :, :]).astype(np.int64)
|
|
300
254
|
|
|
301
255
|
def cell_corner_indexes(self, x_cell_index, y_cell_index, z_cell_index):
|
|
302
256
|
"""
|
|
@@ -363,7 +317,7 @@ class StructuredGrid:
|
|
|
363
317
|
globalidx[~inside] = -1
|
|
364
318
|
return globalidx, inside
|
|
365
319
|
|
|
366
|
-
def evaluate_value(self, evaluation_points,
|
|
320
|
+
def evaluate_value(self, evaluation_points, property_array):
|
|
367
321
|
"""
|
|
368
322
|
Evaluate the value of of the property at the locations.
|
|
369
323
|
Trilinear interpolation dot corner values
|
|
@@ -377,28 +331,36 @@ class StructuredGrid:
|
|
|
377
331
|
-------
|
|
378
332
|
|
|
379
333
|
"""
|
|
334
|
+
if property_array.shape[0] != self.n_nodes:
|
|
335
|
+
logger.error("Property array does not match grid")
|
|
336
|
+
raise BaseException
|
|
380
337
|
idc, inside = self.position_to_cell_corners(evaluation_points)
|
|
381
338
|
v = np.zeros(idc.shape)
|
|
382
339
|
v[:, :] = np.nan
|
|
383
340
|
|
|
384
341
|
v[inside, :] = self.position_to_dof_coefs(
|
|
385
342
|
evaluation_points[inside, :]).T
|
|
386
|
-
|
|
343
|
+
|
|
344
|
+
v[inside, :] *= property_array[idc[inside, :]]
|
|
345
|
+
|
|
387
346
|
return np.sum(v, axis=1)
|
|
388
347
|
|
|
389
|
-
def evaluate_gradient(self, evaluation_points,
|
|
348
|
+
def evaluate_gradient(self, evaluation_points, property_array):
|
|
349
|
+
if property_array.shape[0] != self.n_nodes:
|
|
350
|
+
logger.error("Property array does not match grid")
|
|
351
|
+
raise BaseException
|
|
390
352
|
idc, inside = self.position_to_cell_corners(evaluation_points)
|
|
391
353
|
T = np.zeros((idc.shape[0], 3, 8))
|
|
392
354
|
T[inside, :, :] = self.calcul_T(evaluation_points[inside, :])
|
|
393
355
|
# indices = np.array([self.position_to_cell_index(evaluation_points)])
|
|
394
356
|
# idc = self.global_indicies(indices.swapaxes(0,1))
|
|
395
357
|
# print(idc)
|
|
396
|
-
T[inside, 0, :] *=
|
|
397
|
-
T[inside, 1, :] *=
|
|
398
|
-
T[inside, 2, :] *=
|
|
358
|
+
T[inside, 0, :] *= property_array[idc[inside, :]]
|
|
359
|
+
T[inside, 1, :] *= property_array[idc[inside, :]]
|
|
360
|
+
T[inside, 2, :] *= property_array[idc[inside, :]]
|
|
399
361
|
return np.array(
|
|
400
|
-
[np.sum(T[:, 0, :], axis=1)
|
|
401
|
-
np.sum(T[:, 2, :], axis=1)
|
|
362
|
+
[np.sum(T[:, 0, :], axis=1), np.sum(T[:, 1, :], axis=1) ,
|
|
363
|
+
np.sum(T[:, 2, :], axis=1) ]).T
|
|
402
364
|
|
|
403
365
|
def calcul_T(self, pos):
|
|
404
366
|
"""
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tetmesh based on cartesian grid for piecewise linear interpolation
|
|
3
|
+
"""
|
|
1
4
|
import logging
|
|
2
5
|
|
|
3
6
|
import numpy as np
|
|
4
|
-
from LoopStructural.interpolators.cython.dsi_helper import cg
|
|
7
|
+
from LoopStructural.interpolators.cython.dsi_helper import cg, constant_norm, fold_cg
|
|
5
8
|
|
|
6
|
-
|
|
9
|
+
from LoopStructural.utils import getLogger
|
|
10
|
+
logger = getLogger(__name__)
|
|
7
11
|
|
|
8
12
|
class TetMesh:
|
|
9
13
|
"""
|
|
@@ -13,13 +17,14 @@ class TetMesh:
|
|
|
13
17
|
self.origin = np.array(origin)
|
|
14
18
|
self.step_vector = np.array(step_vector)
|
|
15
19
|
self.nsteps = np.array(nsteps)
|
|
20
|
+
self.n_nodes = self.nsteps[0]*self.nsteps[1]*self.nsteps[2]
|
|
21
|
+
|
|
16
22
|
self.nsteps_cells = self.nsteps - 1
|
|
17
23
|
self.n_cell_x = self.nsteps[0] - 1
|
|
18
24
|
self.n_cell_y = self.nsteps[1] - 1
|
|
19
25
|
self.n_cell_z = self.nsteps[2] - 1
|
|
20
26
|
self.n_cells = self.n_cell_x * self.n_cell_y * self.n_cell_z
|
|
21
|
-
self.
|
|
22
|
-
|
|
27
|
+
self.maximum = origin+self.nsteps*self.step_vector
|
|
23
28
|
self.tetra_mask_even = np.array([
|
|
24
29
|
[7,1,2,4],
|
|
25
30
|
[6,2,4,7],
|
|
@@ -36,8 +41,6 @@ class TetMesh:
|
|
|
36
41
|
[1,0,3,5]
|
|
37
42
|
])
|
|
38
43
|
self.ntetra = self.n_cells * 5
|
|
39
|
-
self.properties = {}
|
|
40
|
-
self.property_gradients = {}
|
|
41
44
|
self.n_elements = self.ntetra
|
|
42
45
|
self.cg = None
|
|
43
46
|
|
|
@@ -80,11 +83,7 @@ class TetMesh:
|
|
|
80
83
|
axis=1) / 4.
|
|
81
84
|
return barycentre
|
|
82
85
|
|
|
83
|
-
def
|
|
84
|
-
|
|
85
|
-
self.properties[name] = value
|
|
86
|
-
|
|
87
|
-
def evaluate_value(self, pos, prop):
|
|
86
|
+
def evaluate_value(self, pos, property_array):
|
|
88
87
|
"""
|
|
89
88
|
Evaluate value of interpolant
|
|
90
89
|
|
|
@@ -102,10 +101,10 @@ class TetMesh:
|
|
|
102
101
|
values = np.zeros(pos.shape[0])
|
|
103
102
|
values[:] = np.nan
|
|
104
103
|
vertices, c, tetras, inside = self.get_tetra_for_location(pos)
|
|
105
|
-
values[inside] = np.sum(c[inside,:]*
|
|
104
|
+
values[inside] = np.sum(c[inside,:]*property_array[tetras[inside,:]],axis=1)
|
|
106
105
|
return values
|
|
107
106
|
|
|
108
|
-
def evaluate_gradient(self, pos,
|
|
107
|
+
def evaluate_gradient(self, pos, property_array):
|
|
109
108
|
"""
|
|
110
109
|
Evaluate the gradient of an interpolant at the locations
|
|
111
110
|
|
|
@@ -124,13 +123,20 @@ class TetMesh:
|
|
|
124
123
|
values = np.zeros(pos.shape)
|
|
125
124
|
values[:] = np.nan
|
|
126
125
|
vertices, element_gradients, tetras, inside = self.get_tetra_gradient_for_location(pos)
|
|
127
|
-
vertex_vals = self.properties[prop][tetras]
|
|
128
126
|
#grads = np.zeros(tetras.shape)
|
|
129
|
-
values[inside,:] = (element_gradients[inside,:,:]*
|
|
127
|
+
values[inside,:] = (element_gradients[inside,:,:]*property_array[tetras[inside,None,:]]).sum(2)
|
|
130
128
|
length = np.sum(values[inside,:],axis=1)
|
|
131
|
-
values[inside,:] /= length[:,None]
|
|
129
|
+
# values[inside,:] /= length[:,None]
|
|
132
130
|
return values
|
|
133
131
|
|
|
132
|
+
def inside(self, pos):
|
|
133
|
+
inside = np.ones(pos.shape[0]).astype(bool)
|
|
134
|
+
for i in range(3):
|
|
135
|
+
inside *= pos[:, i] > self.origin[None, i]
|
|
136
|
+
inside *= pos[:, i] < self.origin[None, i] + \
|
|
137
|
+
self.step_vector[None, i] * self.nsteps_cells[None, i]
|
|
138
|
+
return inside
|
|
139
|
+
|
|
134
140
|
def get_tetra_for_location(self, pos):
|
|
135
141
|
"""
|
|
136
142
|
Determine the tetrahedron from a numpy array of points
|
|
@@ -146,11 +152,13 @@ class TetMesh:
|
|
|
146
152
|
|
|
147
153
|
"""
|
|
148
154
|
pos = np.array(pos)
|
|
155
|
+
inside = self.inside(pos)
|
|
149
156
|
# initialise array for tetrahedron vertices
|
|
150
157
|
vertices = np.zeros((5, 4, pos.shape[0], 3))
|
|
151
158
|
vertices[:] = np.nan
|
|
152
159
|
# get cell indexes
|
|
153
160
|
c_xi, c_yi, c_zi = self.position_to_cell_index(pos)
|
|
161
|
+
|
|
154
162
|
# determine if using +ve or -ve mask
|
|
155
163
|
even_mask = (c_xi + c_yi + c_zi) % 2 == 0
|
|
156
164
|
# get cell corners
|
|
@@ -188,15 +196,18 @@ class TetMesh:
|
|
|
188
196
|
# if all coords are +ve then point is inside cell
|
|
189
197
|
mask = np.all(c > 0, axis=2)
|
|
190
198
|
|
|
191
|
-
inside = np.any(mask,axis=1)
|
|
199
|
+
inside = np.logical_and(inside,np.any(mask,axis=1))
|
|
192
200
|
# get cell corners
|
|
193
201
|
xi, yi, zi = self.cell_corner_indexes(c_xi, c_yi, c_zi)
|
|
194
|
-
|
|
195
202
|
#create mask to see which cells are even
|
|
196
203
|
even_mask = (c_xi + c_yi + c_zi) % 2 == 0
|
|
197
204
|
# create global node index list
|
|
198
|
-
|
|
205
|
+
# print('nsteps',self.nsteps, 'nsteps_cells', self.nsteps_cells)
|
|
206
|
+
# print('x',np.min(c_xi),np.max(c_xi),np.min(xi),np.max(xi))
|
|
207
|
+
# print('y',np.min(c_yi),np.max(c_yi),np.min(yi),np.max(yi))
|
|
208
|
+
# print('z',np.min(c_zi),np.max(c_zi),np.min(zi),np.max(zi))
|
|
199
209
|
|
|
210
|
+
gi = xi + yi * self.nsteps[0] + zi * self.nsteps[0] * self.nsteps[1]
|
|
200
211
|
# container for tetras
|
|
201
212
|
tetras = np.zeros((xi.shape[0], 5, 4)).astype(int)
|
|
202
213
|
|
|
@@ -207,7 +218,6 @@ class TetMesh:
|
|
|
207
218
|
vertices_return[:] = np.nan
|
|
208
219
|
# set all masks not inside to False
|
|
209
220
|
mask[~inside,:] = False
|
|
210
|
-
#print(mask.shape,inside.shape,vertices.shape,vertices_return.shape,vertices[mask,:,:].shape)
|
|
211
221
|
vertices_return[inside,:,:] = vertices[mask,:,:]#[mask,:,:]#[inside,:,:]
|
|
212
222
|
c_return = np.zeros((pos.shape[0],4))
|
|
213
223
|
c_return[:] = np.nan
|
|
@@ -217,7 +227,7 @@ class TetMesh:
|
|
|
217
227
|
tetra_return[inside,:] = tetras[mask,:]
|
|
218
228
|
return vertices_return, c_return, tetra_return, inside
|
|
219
229
|
|
|
220
|
-
def get_constant_gradient(self, region):
|
|
230
|
+
def get_constant_gradient(self, region, direction=None):
|
|
221
231
|
"""
|
|
222
232
|
Get the constant gradient for the specified nodes
|
|
223
233
|
|
|
@@ -230,6 +240,34 @@ class TetMesh:
|
|
|
230
240
|
-------
|
|
231
241
|
|
|
232
242
|
"""
|
|
243
|
+
"""
|
|
244
|
+
Add the constant gradient regularisation to the system
|
|
245
|
+
|
|
246
|
+
Parameters
|
|
247
|
+
----------
|
|
248
|
+
w (double) - weighting of the cg parameter
|
|
249
|
+
|
|
250
|
+
Returns
|
|
251
|
+
-------
|
|
252
|
+
|
|
253
|
+
"""
|
|
254
|
+
if direction is not None:
|
|
255
|
+
print('using cg direction')
|
|
256
|
+
logger.info("Running constant gradient")
|
|
257
|
+
elements_gradients = self.get_element_gradients(np.arange(self.ntetra))
|
|
258
|
+
if elements_gradients.shape[0] != direction.shape[0]:
|
|
259
|
+
logger.error('Cannot add directional CG, vector field is not the correct length')
|
|
260
|
+
return
|
|
261
|
+
region = region.astype('int64')
|
|
262
|
+
|
|
263
|
+
neighbours = self.get_neighbours()
|
|
264
|
+
elements = self.get_elements()
|
|
265
|
+
idc, c, ncons = fold_cg(elements_gradients, direction, neighbours.astype('int64'), elements.astype('int64'), self.nodes)
|
|
266
|
+
|
|
267
|
+
idc = np.array(idc[:ncons, :])
|
|
268
|
+
c = np.array(c[:ncons, :])
|
|
269
|
+
B = np.zeros(c.shape[0])
|
|
270
|
+
return c, idc, B
|
|
233
271
|
if self.cg is None:
|
|
234
272
|
logger.info("Running constant gradient")
|
|
235
273
|
elements_gradients = self.get_element_gradients(np.arange(self.ntetra))
|
|
@@ -245,7 +283,34 @@ class TetMesh:
|
|
|
245
283
|
B = np.zeros(c.shape[0])
|
|
246
284
|
self.cg = (c,idc,B)
|
|
247
285
|
return self.cg[0], self.cg[1], self.cg[2]
|
|
286
|
+
def get_constant_norm(self, region):
|
|
287
|
+
"""
|
|
288
|
+
Get the constant gradient for the specified nodes
|
|
289
|
+
|
|
290
|
+
Parameters
|
|
291
|
+
----------
|
|
292
|
+
region : np.array(dtype=bool)
|
|
293
|
+
mask of nodes to calculate cg for
|
|
294
|
+
|
|
295
|
+
Returns
|
|
296
|
+
-------
|
|
297
|
+
|
|
298
|
+
"""
|
|
299
|
+
|
|
300
|
+
logger.info("Running constant gradient")
|
|
301
|
+
elements_gradients = self.get_element_gradients(np.arange(self.ntetra))
|
|
302
|
+
region = region.astype('int64')
|
|
303
|
+
|
|
304
|
+
neighbours = self.get_neighbours()
|
|
305
|
+
elements = self.get_elements()
|
|
306
|
+
idc, c, ncons = constant_norm(elements_gradients, neighbours.astype('int64'), elements.astype('int64'), self.nodes,
|
|
307
|
+
region.astype('int64'))
|
|
248
308
|
|
|
309
|
+
idc = np.array(idc[:ncons, :])
|
|
310
|
+
c = np.array(c[:ncons, :])
|
|
311
|
+
B = np.zeros(c.shape[0])
|
|
312
|
+
|
|
313
|
+
return c,idc,B
|
|
249
314
|
def get_elements(self):
|
|
250
315
|
"""
|
|
251
316
|
Get a numpy array of all of the elements in the mesh
|
|
@@ -346,12 +411,9 @@ class TetMesh:
|
|
|
346
411
|
vertices, bc, tetras, inside = self.get_tetra_for_location(pos)
|
|
347
412
|
ps = vertices
|
|
348
413
|
m = np.array(
|
|
349
|
-
[[(ps[:, 1, 0] - ps[:, 0, 0]), (ps[:, 1, 1] - ps[:, 0, 1]),
|
|
350
|
-
|
|
351
|
-
[(ps[:,
|
|
352
|
-
(ps[:, 2, 2] - ps[:, 0, 2])],
|
|
353
|
-
[(ps[:, 3, 0] - ps[:, 0, 0]), (ps[:, 3, 1] - ps[:, 0, 1]),
|
|
354
|
-
(ps[:, 3, 2] - ps[:, 0, 2])]])
|
|
414
|
+
[[(ps[:, 1, 0] - ps[:, 0, 0]), (ps[:, 1, 1] - ps[:, 0, 1]),(ps[:, 1, 2] - ps[:, 0, 2])],
|
|
415
|
+
[(ps[:, 2, 0] - ps[:, 0, 0]), (ps[:, 2, 1] - ps[:, 0, 1]),(ps[:, 2, 2] - ps[:, 0, 2])],
|
|
416
|
+
[(ps[:, 3, 0] - ps[:, 0, 0]), (ps[:, 3, 1] - ps[:, 0, 1]),(ps[:, 3, 2] - ps[:, 0, 2])]])
|
|
355
417
|
I = np.array(
|
|
356
418
|
[[-1., 1., 0., 0.],
|
|
357
419
|
[-1., 0., 1., 0.],
|
|
@@ -363,25 +425,7 @@ class TetMesh:
|
|
|
363
425
|
element_gradients = element_gradients @ I
|
|
364
426
|
return vertices, element_gradients, tetras, inside
|
|
365
427
|
|
|
366
|
-
def inside(self, pos):
|
|
367
|
-
"""
|
|
368
|
-
Check if a point is inside the structured grid
|
|
369
|
-
|
|
370
|
-
Parameters
|
|
371
|
-
----------
|
|
372
|
-
pos
|
|
373
|
-
|
|
374
|
-
Returns
|
|
375
|
-
-------
|
|
376
428
|
|
|
377
|
-
"""
|
|
378
|
-
# check whether point is inside box
|
|
379
|
-
inside = np.ones(pos.shape[0]).astype(bool)
|
|
380
|
-
for i in range(3):
|
|
381
|
-
inside *= pos[:, i] > self.origin[None, i]
|
|
382
|
-
inside *= pos[:, i] < self.origin[None, i] + \
|
|
383
|
-
self.step_vector[None, i] * self.nsteps_cells[None, i]
|
|
384
|
-
return inside
|
|
385
429
|
|
|
386
430
|
def global_node_indicies(self, indexes):
|
|
387
431
|
"""
|