tilupy 0.1.4__py3-none-any.whl → 1.0.0__py3-none-any.whl
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.
Potentially problematic release.
This version of tilupy might be problematic. Click here for more details.
- tilupy/calibration.py +29 -32
- tilupy/cmd.py +114 -60
- tilupy/initdata.py +36 -0
- tilupy/make_mass.py +108 -0
- tilupy/make_topo.py +415 -0
- tilupy/models/shaltop/initsimus.py +168 -55
- tilupy/models/shaltop/read.py +319 -164
- tilupy/notations.py +332 -47
- tilupy/plot.py +472 -175
- tilupy/read.py +817 -235
- tilupy/utils.py +99 -71
- {tilupy-0.1.4.dist-info → tilupy-1.0.0.dist-info}/METADATA +3 -2
- tilupy-1.0.0.dist-info/RECORD +26 -0
- {tilupy-0.1.4.dist-info → tilupy-1.0.0.dist-info}/WHEEL +1 -1
- tilupy-0.1.4.dist-info/RECORD +0 -24
- {tilupy-0.1.4.dist-info → tilupy-1.0.0.dist-info}/LICENSE +0 -0
- {tilupy-0.1.4.dist-info → tilupy-1.0.0.dist-info}/entry_points.txt +0 -0
- {tilupy-0.1.4.dist-info → tilupy-1.0.0.dist-info}/top_level.txt +0 -0
tilupy/calibration.py
CHANGED
|
@@ -10,51 +10,54 @@ import pandas as pd
|
|
|
10
10
|
|
|
11
11
|
from tilupy import read
|
|
12
12
|
from tilupy import utils
|
|
13
|
-
from tilupy import
|
|
13
|
+
from tilupy import raster
|
|
14
|
+
|
|
14
15
|
|
|
15
16
|
def CSI(simu, observation=None, h_threshs=[1], state='h_final'):
|
|
16
|
-
|
|
17
|
-
res=[]
|
|
17
|
+
|
|
18
|
+
res = []
|
|
18
19
|
assert(observation is not None)
|
|
19
|
-
|
|
20
|
+
|
|
20
21
|
if isinstance(observation, str):
|
|
21
|
-
_, _, observation, _ =
|
|
22
|
-
|
|
22
|
+
_, _, observation, _ = raster.read_raster(observation)
|
|
23
|
+
|
|
23
24
|
strs = state.split('_')
|
|
24
25
|
if state == 'h_max':
|
|
25
26
|
d = simu.h_max
|
|
26
27
|
else:
|
|
27
28
|
d = simu.get_static_output(strs[0], strs[1]).d
|
|
28
29
|
for h_thresh in h_threshs:
|
|
29
|
-
array = 1*d>h_thresh
|
|
30
|
+
array = 1*d > h_thresh
|
|
30
31
|
res.append(utils.CSI(array, observation))
|
|
31
|
-
|
|
32
|
+
|
|
32
33
|
return h_threshs, res
|
|
33
|
-
|
|
34
|
+
|
|
35
|
+
|
|
34
36
|
def diff_runout(simu, point=None, h_threshs=[1],
|
|
35
37
|
section=None, orientation='W-E',
|
|
36
38
|
state='h_max',
|
|
37
39
|
get_contour_kws=None):
|
|
38
|
-
|
|
40
|
+
|
|
39
41
|
res = []
|
|
40
42
|
assert(point is not None)
|
|
41
|
-
|
|
43
|
+
|
|
42
44
|
if get_contour_kws is None:
|
|
43
45
|
get_contour_kws = dict()
|
|
44
|
-
|
|
46
|
+
|
|
45
47
|
if state == 'h_max':
|
|
46
|
-
d=simu.h_max
|
|
48
|
+
d = simu.h_max
|
|
47
49
|
else:
|
|
48
50
|
strs = state.split('_')
|
|
49
51
|
d = simu.get_static_output(strs[0], strs[1]).d
|
|
50
|
-
xc, yc = utils.get_contour(simu.x,simu.y,d,h_threshs, **get_contour_kws)
|
|
51
|
-
|
|
52
|
+
xc, yc = utils.get_contour(simu.x, simu.y, d, h_threshs, **get_contour_kws)
|
|
53
|
+
|
|
52
54
|
for h in h_threshs:
|
|
53
55
|
res.append(utils.diff_runout(xc[h], yc[h], point, section=section,
|
|
54
56
|
orientation=orientation))
|
|
55
|
-
|
|
57
|
+
|
|
56
58
|
return h_threshs, res
|
|
57
|
-
|
|
59
|
+
|
|
60
|
+
|
|
58
61
|
def eval_simus(simus, methods, calib_parameters, methods_kws,
|
|
59
62
|
code='shaltop',
|
|
60
63
|
recorded_params=['delta1'],
|
|
@@ -80,16 +83,17 @@ def eval_simus(simus, methods, calib_parameters, methods_kws,
|
|
|
80
83
|
methods_kws = [methods_kws]
|
|
81
84
|
|
|
82
85
|
if isinstance(simus, dict):
|
|
83
|
-
simus=pd.DataFrame(simus)
|
|
86
|
+
simus = pd.DataFrame(simus)
|
|
84
87
|
if isinstance(simus, pd.DataFrame):
|
|
85
88
|
simus_list = []
|
|
86
89
|
for i in range(simus.shape[0]):
|
|
87
|
-
simus_list.append(read.get_results(
|
|
90
|
+
simus_list.append(read.get_results(
|
|
91
|
+
code, **simus.iloc[i, :].to_dict()))
|
|
88
92
|
simus2 = simus.copy()
|
|
89
93
|
else:
|
|
90
94
|
simus_list = simus
|
|
91
95
|
simus2 = pd.DataFrame()
|
|
92
|
-
|
|
96
|
+
|
|
93
97
|
for param in recorded_params:
|
|
94
98
|
simus2[param] = np.nan
|
|
95
99
|
fn = dict()
|
|
@@ -97,13 +101,13 @@ def eval_simus(simus, methods, calib_parameters, methods_kws,
|
|
|
97
101
|
fn[method] = globals()[method]
|
|
98
102
|
simus2[method] = np.nan
|
|
99
103
|
simus2[calib_parameter_name] = np.nan
|
|
100
|
-
|
|
104
|
+
|
|
101
105
|
ns = len(simus_list)
|
|
102
106
|
nc = len(calib_parameters)
|
|
103
107
|
nn = ns*nc
|
|
104
|
-
|
|
105
|
-
res = pd.DataFrame(columns=simus2.columns, index=np.arange(nn))
|
|
106
|
-
|
|
108
|
+
|
|
109
|
+
res = pd.DataFrame(columns=simus2.columns, index=np.arange(nn))
|
|
110
|
+
|
|
107
111
|
for i, simu in enumerate(simus_list):
|
|
108
112
|
# Initiate fields
|
|
109
113
|
istart = i*nc
|
|
@@ -117,12 +121,5 @@ def eval_simus(simus, methods, calib_parameters, methods_kws,
|
|
|
117
121
|
res.loc[:, param].iloc[istart:iend] = simu.params[param]
|
|
118
122
|
res.loc[:, calib_parameter_name].iloc[istart:iend] = calib_parameters
|
|
119
123
|
res.loc[:, method].iloc[istart:iend] = calib_res
|
|
120
|
-
|
|
121
|
-
return res
|
|
122
124
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
125
|
+
return res
|
tilupy/cmd.py
CHANGED
|
@@ -13,23 +13,29 @@ import argparse
|
|
|
13
13
|
import glob
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
def process_results(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
def process_results(
|
|
17
|
+
fn_name,
|
|
18
|
+
model,
|
|
19
|
+
res_name,
|
|
20
|
+
folder=None,
|
|
21
|
+
param_files=None,
|
|
22
|
+
kwargs_read=None,
|
|
23
|
+
**kwargs_fn
|
|
24
|
+
):
|
|
25
|
+
assert model is not None
|
|
20
26
|
|
|
21
27
|
if folder is None:
|
|
22
28
|
folder = os.getcwd()
|
|
23
29
|
|
|
24
30
|
if param_files is None:
|
|
25
|
-
param_files =
|
|
31
|
+
param_files = "*.txt"
|
|
26
32
|
|
|
27
33
|
print(folder, param_files)
|
|
28
34
|
|
|
29
35
|
param_files = glob.glob(os.path.join(folder, param_files))
|
|
30
36
|
|
|
31
37
|
if len(param_files) == 0:
|
|
32
|
-
print(
|
|
38
|
+
print("No parameter file matching param_files pattern was found")
|
|
33
39
|
return
|
|
34
40
|
|
|
35
41
|
if kwargs_read is None:
|
|
@@ -39,87 +45,135 @@ def process_results(fn_name, model, res_name, folder=None, param_files=None,
|
|
|
39
45
|
kw_read.update(kwargs_read)
|
|
40
46
|
|
|
41
47
|
for param_file in param_files:
|
|
42
|
-
print_str =
|
|
48
|
+
print_str = "Processing simulation {:s}, {:s} {:s} ....."
|
|
43
49
|
print(print_str.format(param_file, fn_name, res_name))
|
|
44
|
-
kw_read[
|
|
50
|
+
kw_read["file_params"] = param_file
|
|
45
51
|
res = tilupy.read.get_results(model, **kw_read)
|
|
46
52
|
getattr(res, fn_name)(res_name, **kwargs_fn)
|
|
47
53
|
|
|
48
54
|
|
|
49
|
-
def to_raster(
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
55
|
+
def to_raster(
|
|
56
|
+
model=None,
|
|
57
|
+
res_name="h",
|
|
58
|
+
param_files=None,
|
|
59
|
+
folder=None,
|
|
60
|
+
kwargs_read=None,
|
|
61
|
+
**kwargs
|
|
62
|
+
):
|
|
63
|
+
kw = dict(fmt="asc")
|
|
53
64
|
kw.update(kwargs)
|
|
54
65
|
|
|
55
|
-
process_results(
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
66
|
+
process_results(
|
|
67
|
+
"save",
|
|
68
|
+
model,
|
|
69
|
+
res_name,
|
|
70
|
+
folder=folder,
|
|
71
|
+
param_files=param_files,
|
|
72
|
+
kwargs_read=kwargs_read,
|
|
73
|
+
**kw
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def plot_results(
|
|
78
|
+
model=None,
|
|
79
|
+
res_name="h",
|
|
80
|
+
param_files=None,
|
|
81
|
+
folder=None,
|
|
82
|
+
kwargs_read=None,
|
|
83
|
+
**kwargs
|
|
84
|
+
):
|
|
63
85
|
kw = dict(save=True)
|
|
64
86
|
kw.update(kwargs)
|
|
65
87
|
|
|
66
|
-
process_results(
|
|
67
|
-
|
|
68
|
-
|
|
88
|
+
process_results(
|
|
89
|
+
"plot",
|
|
90
|
+
model,
|
|
91
|
+
res_name,
|
|
92
|
+
folder=folder,
|
|
93
|
+
param_files=param_files,
|
|
94
|
+
kwargs_read=kwargs_read,
|
|
95
|
+
**kwargs
|
|
96
|
+
)
|
|
69
97
|
|
|
70
98
|
|
|
71
99
|
def _get_parser(prog, description):
|
|
72
|
-
parser = argparse.ArgumentParser(
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
parser.add_argument(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
100
|
+
parser = argparse.ArgumentParser(
|
|
101
|
+
prog=prog,
|
|
102
|
+
description=description,
|
|
103
|
+
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
|
104
|
+
)
|
|
105
|
+
parser.add_argument("model", help="Model name", type=str)
|
|
106
|
+
parser.add_argument(
|
|
107
|
+
"-n",
|
|
108
|
+
"--res_name",
|
|
109
|
+
help="Name of output, only for maps",
|
|
110
|
+
default="h",
|
|
111
|
+
type=str,
|
|
112
|
+
)
|
|
113
|
+
parser.add_argument(
|
|
114
|
+
"-p",
|
|
115
|
+
"--param_files",
|
|
116
|
+
help="Parameter file (globbing)",
|
|
117
|
+
default="*.txt",
|
|
118
|
+
type=str,
|
|
119
|
+
)
|
|
120
|
+
parser.add_argument(
|
|
121
|
+
"-f",
|
|
122
|
+
"--folder",
|
|
123
|
+
help="Root folder, default is current folder",
|
|
124
|
+
default=None,
|
|
125
|
+
type=str,
|
|
126
|
+
)
|
|
84
127
|
return parser
|
|
85
128
|
|
|
86
129
|
|
|
87
130
|
def _tilupy_plot():
|
|
88
|
-
parser = _get_parser(
|
|
89
|
-
parser.add_argument(
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
parser.add_argument(
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
131
|
+
parser = _get_parser("tilupy_plot", "Plot thin-layer simulation results")
|
|
132
|
+
parser.add_argument(
|
|
133
|
+
"--fmt",
|
|
134
|
+
help=("Plot output format " "(any accepted by matplotlib.savefig)"),
|
|
135
|
+
default="png",
|
|
136
|
+
type=str,
|
|
137
|
+
)
|
|
138
|
+
parser.add_argument(
|
|
139
|
+
"--vmin",
|
|
140
|
+
help=("Minimum plotted value, " "adapted to data by default"),
|
|
141
|
+
default=None,
|
|
142
|
+
type=float,
|
|
143
|
+
)
|
|
144
|
+
parser.add_argument(
|
|
145
|
+
"--vmax",
|
|
146
|
+
help=("Maximum plotted value, " "adapted to data by default"),
|
|
147
|
+
default=None,
|
|
148
|
+
type=float,
|
|
149
|
+
)
|
|
150
|
+
parser.add_argument(
|
|
151
|
+
"--minval_abs",
|
|
152
|
+
help=("Minimum plotted absolute value," " adapted to data by default"),
|
|
153
|
+
default=None,
|
|
154
|
+
type=float,
|
|
155
|
+
)
|
|
105
156
|
args = parser.parse_args()
|
|
106
157
|
plot_results(**vars(args))
|
|
107
158
|
|
|
108
159
|
|
|
109
160
|
def _tilupy_to_raster():
|
|
110
|
-
parser = _get_parser(
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
161
|
+
parser = _get_parser(
|
|
162
|
+
"tilupy_to_raster", "Convert simulation results to rasters"
|
|
163
|
+
)
|
|
164
|
+
parser.add_argument(
|
|
165
|
+
"--fmt",
|
|
166
|
+
help=("File output format, " "tif/tiff requires rasterio"),
|
|
167
|
+
default="asc",
|
|
168
|
+
type=str,
|
|
169
|
+
choices=["tif", "tiff", "txt", "asc", "ascii"],
|
|
170
|
+
)
|
|
116
171
|
args = parser.parse_args()
|
|
117
172
|
# plot_results(parser.model, parser.res_name)
|
|
118
173
|
to_raster(**vars(args))
|
|
119
174
|
|
|
120
175
|
|
|
121
|
-
if __name__ ==
|
|
122
|
-
|
|
176
|
+
if __name__ == "__main__":
|
|
123
177
|
# folder = 'd:/Documents/peruzzetto/tmp/test_shaltop/7p30e04_m3/coulomb'
|
|
124
178
|
# plot_results('shaltop', 'h_max', '*18p00.txt', folder=folder)
|
|
125
179
|
_tilupy_plot()
|
tilupy/initdata.py
CHANGED
|
@@ -8,6 +8,10 @@ Created on Fri May 21 12:10:46 2021
|
|
|
8
8
|
import os
|
|
9
9
|
import numpy as np
|
|
10
10
|
|
|
11
|
+
import tilupy.make_topo
|
|
12
|
+
import tilupy.make_mass
|
|
13
|
+
import tilupy.plot
|
|
14
|
+
|
|
11
15
|
|
|
12
16
|
def make_constant_slope(folder_out, theta=10, m_radius=50, m_height=50,
|
|
13
17
|
m_x=None, m_y=None,
|
|
@@ -43,3 +47,35 @@ def make_constant_slope(folder_out, theta=10, m_radius=50, m_height=50,
|
|
|
43
47
|
np.savetxt(os.path.join(folder_out, name+'.asc'), a,
|
|
44
48
|
header=header_txt,
|
|
45
49
|
comments='')
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def gray99_topo_mass(dx=0.1, dy=0.1, save=False, folder_out=None):
|
|
53
|
+
|
|
54
|
+
# Initiate topography
|
|
55
|
+
X, Y, Z = tilupy.make_topo.gray99(dx=dx, dy=dy)
|
|
56
|
+
|
|
57
|
+
# Initiate initial mass. It is a spherical calotte above the topography,
|
|
58
|
+
# in Gray et al 99 (p. 1859) the resulting mass has a height of 0.22 m and a radius
|
|
59
|
+
# of 0.32 m (more precisely it is the length in the downslope direction)
|
|
60
|
+
# The correspondig radius of the sphere, and the offset from the topography
|
|
61
|
+
# in the topography normal direction (norm_offset) are deduced from these
|
|
62
|
+
# parameters
|
|
63
|
+
|
|
64
|
+
x0 = 0.06*np.cos(np.deg2rad(40))
|
|
65
|
+
hmass = 0.22
|
|
66
|
+
wmass = 0.32
|
|
67
|
+
radius = (wmass**2+hmass**2)/(2*hmass)
|
|
68
|
+
norm_offset = (hmass**2-wmass**2)/(2*hmass)
|
|
69
|
+
# Z = -np.tile(X, [len(Y), 1])*np.tan(np.deg2rad(20))
|
|
70
|
+
M = tilupy.make_mass.calotte(X, Y, Z, x0, 0,
|
|
71
|
+
radius, norm_offset=norm_offset,
|
|
72
|
+
res_type='true_normal')
|
|
73
|
+
|
|
74
|
+
return X, Y, Z, M
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
if __name__ == '__main__':
|
|
78
|
+
|
|
79
|
+
x, y, z, m = gray99_topo_mass(dx=0.01, dy=0.01)
|
|
80
|
+
tilupy.plot.plot_data_on_topo(x, y, z, m,
|
|
81
|
+
topo_kwargs=dict(level_min=0.1))
|
tilupy/make_mass.py
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Created on Fri Aug 4 19:27:09 2023
|
|
4
|
+
|
|
5
|
+
@author: peruzzetto
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import numpy as np
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def calotte(x, y, z, x0, y0, radius, norm_offset=0, res_type='projected_normal'):
|
|
12
|
+
"""
|
|
13
|
+
Construct mass on topography as volume between sphere and topography.
|
|
14
|
+
|
|
15
|
+
Parameters
|
|
16
|
+
----------
|
|
17
|
+
x : np.array
|
|
18
|
+
xaxis array, with length nx
|
|
19
|
+
y : np.array
|
|
20
|
+
yaxis array, with length ny
|
|
21
|
+
z : np.array
|
|
22
|
+
array of altitudes, of size (ny, nx). z[0, 0] has coordinates
|
|
23
|
+
(x[0], y[-1])
|
|
24
|
+
x0 : float
|
|
25
|
+
x position of the calotte
|
|
26
|
+
y0 : float
|
|
27
|
+
y position of the calotte
|
|
28
|
+
radius : float
|
|
29
|
+
radius of the shpere
|
|
30
|
+
norm_offset : float, optional
|
|
31
|
+
downwards offset between the sphere center and the topography, in the
|
|
32
|
+
direction normal to the topography. The default is 0.
|
|
33
|
+
res_type : string, optional
|
|
34
|
+
Type of thickness output. 'true_normal': real thickness in the
|
|
35
|
+
direction normal to the topography. 'vertical': Thickness in the
|
|
36
|
+
vertical direction. 'projected_normal': Thickness normal to the
|
|
37
|
+
topography is computed from the vertical thickness projected on
|
|
38
|
+
the axe normal to the topography. The default is 'projected_normal'.
|
|
39
|
+
|
|
40
|
+
Returns
|
|
41
|
+
-------
|
|
42
|
+
m : np.array
|
|
43
|
+
array of mass height, in the direction normal to topography
|
|
44
|
+
|
|
45
|
+
"""
|
|
46
|
+
z = np.flip(z, axis=0).T
|
|
47
|
+
|
|
48
|
+
xmesh, ymesh = np.meshgrid(x, y, indexing='ij')
|
|
49
|
+
nx = len(x)
|
|
50
|
+
ny = len(y)
|
|
51
|
+
|
|
52
|
+
# Get altitude of mass center on topography
|
|
53
|
+
i0 = np.unravel_index(np.argmin(np.abs(x-x0), axis=None), (nx,))
|
|
54
|
+
j0 = np.unravel_index(np.argmin(np.abs(y-y0), axis=None), (ny,))
|
|
55
|
+
z0 = z[i0, j0]
|
|
56
|
+
# Topography gradient
|
|
57
|
+
[Fx, Fy] = np.gradient(z, x, y, edge_order=2)
|
|
58
|
+
Fz = np.ones((nx, ny))
|
|
59
|
+
c = 1/np.sqrt(1+Fx**2+Fy**2)
|
|
60
|
+
Fx = -Fx*c
|
|
61
|
+
Fy = -Fy*c
|
|
62
|
+
Fz = Fz*c
|
|
63
|
+
# Correct position from offset (shpere is moved downward,
|
|
64
|
+
# perpendicular to topography)
|
|
65
|
+
x0 = x0-norm_offset*Fx[i0, j0]
|
|
66
|
+
y0 = y0-norm_offset*Fy[i0, j0]
|
|
67
|
+
z0 = z0-norm_offset*Fz[i0, j0]
|
|
68
|
+
|
|
69
|
+
# Compute mass height only where relevant (ie around the mass center)
|
|
70
|
+
dist_to_mass = (xmesh-x0)**2+(ymesh-y0)**2
|
|
71
|
+
ind = (dist_to_mass <= radius**2)
|
|
72
|
+
|
|
73
|
+
B = 2*(Fx*(xmesh-x0)+Fy *
|
|
74
|
+
(ymesh-y0)+Fz*(z-z0))
|
|
75
|
+
C = (xmesh-x0)**2+(ymesh-y0)**2+(z-z0)**2-radius**2
|
|
76
|
+
D = B**2-4*C
|
|
77
|
+
|
|
78
|
+
# Intersection between shpere and normal to the topography, solution of
|
|
79
|
+
# t**2+B*t+C=0
|
|
80
|
+
m = np.zeros((nx, ny))
|
|
81
|
+
|
|
82
|
+
if res_type == 'true_normal':
|
|
83
|
+
# B = 2*(Fx[ind]*(xmesh[ind]-x0)+Fy[ind] *
|
|
84
|
+
# (ymesh[ind]-y0)+Fz[ind]*(z[ind]-z0))
|
|
85
|
+
# C = (xmesh[ind]-x0)**2+(ymesh[ind]-y0)**2+(z[ind]-z0)**2-radius**2
|
|
86
|
+
# D = B**2-4*C
|
|
87
|
+
B = 2*(Fx*(xmesh-x0)+Fy *
|
|
88
|
+
(ymesh-y0)+Fz*(z-z0))
|
|
89
|
+
C = (xmesh-x0)**2+(ymesh-y0)**2+(z-z0)**2-radius**2
|
|
90
|
+
D = B**2-4*C
|
|
91
|
+
ind = D > 0
|
|
92
|
+
t1 = (-B-np.sqrt(D))/2
|
|
93
|
+
t2 = (-B+np.sqrt(D))/2
|
|
94
|
+
ind2 = t1*t2 < 0
|
|
95
|
+
m[ind2] = np.maximum(t1[ind2], t2[ind2])
|
|
96
|
+
|
|
97
|
+
# Vertical thickness of calotte.
|
|
98
|
+
if res_type in ['vertical', 'projected_normal']:
|
|
99
|
+
zs = z0 + np.sqrt(radius**2 - (xmesh - x0)**2 - (ymesh - y0)**2)
|
|
100
|
+
zi = z0 - np.sqrt(radius**2 - (xmesh - x0)**2 - (ymesh - y0)**2)
|
|
101
|
+
ind = (z < zs) & (z > zi)
|
|
102
|
+
m[ind] = zs[ind] - z[ind]
|
|
103
|
+
if res_type == 'projected_normal':
|
|
104
|
+
m = m * c
|
|
105
|
+
|
|
106
|
+
m = np.flip(m.T, axis=0)
|
|
107
|
+
|
|
108
|
+
return m
|