tilupy 0.1.4__tar.gz → 1.0.0__tar.gz
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-0.1.4/src/tilupy.egg-info → tilupy-1.0.0}/PKG-INFO +10 -3
- {tilupy-0.1.4 → tilupy-1.0.0}/README.md +1 -1
- {tilupy-0.1.4 → tilupy-1.0.0}/pyproject.toml +2 -2
- {tilupy-0.1.4 → tilupy-1.0.0}/src/tilupy/calibration.py +29 -32
- tilupy-1.0.0/src/tilupy/cmd.py +179 -0
- {tilupy-0.1.4 → tilupy-1.0.0}/src/tilupy/initdata.py +36 -0
- tilupy-1.0.0/src/tilupy/make_mass.py +108 -0
- tilupy-1.0.0/src/tilupy/make_topo.py +415 -0
- tilupy-1.0.0/src/tilupy/models/shaltop/initsimus.py +261 -0
- tilupy-1.0.0/src/tilupy/models/shaltop/read.py +455 -0
- tilupy-1.0.0/src/tilupy/notations.py +402 -0
- tilupy-1.0.0/src/tilupy/plot.py +827 -0
- tilupy-1.0.0/src/tilupy/read.py +982 -0
- tilupy-1.0.0/src/tilupy/utils.py +159 -0
- {tilupy-0.1.4 → tilupy-1.0.0/src/tilupy.egg-info}/PKG-INFO +10 -3
- {tilupy-0.1.4 → tilupy-1.0.0}/src/tilupy.egg-info/SOURCES.txt +6 -0
- {tilupy-0.1.4 → tilupy-1.0.0}/src/tilupy.egg-info/requires.txt +1 -0
- tilupy-1.0.0/tests/test_generated_data.py +17 -0
- tilupy-1.0.0/tests/test_notations.py +68 -0
- tilupy-1.0.0/tests/test_read.py +130 -0
- tilupy-1.0.0/tests/test_read_from_simu.py +103 -0
- tilupy-1.0.0/tests/test_shaltop.py +126 -0
- tilupy-0.1.4/src/tilupy/cmd.py +0 -125
- tilupy-0.1.4/src/tilupy/models/shaltop/initsimus.py +0 -148
- tilupy-0.1.4/src/tilupy/models/shaltop/read.py +0 -300
- tilupy-0.1.4/src/tilupy/notations.py +0 -117
- tilupy-0.1.4/src/tilupy/plot.py +0 -530
- tilupy-0.1.4/src/tilupy/read.py +0 -400
- tilupy-0.1.4/src/tilupy/utils.py +0 -131
- tilupy-0.1.4/tests/test_shaltop.py +0 -106
- {tilupy-0.1.4 → tilupy-1.0.0}/LICENSE +0 -0
- {tilupy-0.1.4 → tilupy-1.0.0}/MANIFEST.in +0 -0
- {tilupy-0.1.4 → tilupy-1.0.0}/data/frankslide/rasters/Frankslide_pile.asc +0 -0
- {tilupy-0.1.4 → tilupy-1.0.0}/data/frankslide/rasters/Frankslide_topography.asc +0 -0
- {tilupy-0.1.4 → tilupy-1.0.0}/setup.cfg +0 -0
- {tilupy-0.1.4 → tilupy-1.0.0}/src/tilupy/__init__.py +0 -0
- {tilupy-0.1.4 → tilupy-1.0.0}/src/tilupy/compare.py +0 -0
- {tilupy-0.1.4 → tilupy-1.0.0}/src/tilupy/download_data.py +0 -0
- {tilupy-0.1.4 → tilupy-1.0.0}/src/tilupy/models/__init__.py +0 -0
- {tilupy-0.1.4 → tilupy-1.0.0}/src/tilupy/models/ravaflow/__init__.py +0 -0
- {tilupy-0.1.4 → tilupy-1.0.0}/src/tilupy/models/ravaflow/initsimus.py +0 -0
- {tilupy-0.1.4 → tilupy-1.0.0}/src/tilupy/models/ravaflow/read.py +0 -0
- {tilupy-0.1.4 → tilupy-1.0.0}/src/tilupy/models/shaltop/__init__.py +0 -0
- {tilupy-0.1.4 → tilupy-1.0.0}/src/tilupy/raster.py +0 -0
- {tilupy-0.1.4 → tilupy-1.0.0}/src/tilupy.egg-info/dependency_links.txt +0 -0
- {tilupy-0.1.4 → tilupy-1.0.0}/src/tilupy.egg-info/entry_points.txt +0 -0
- {tilupy-0.1.4 → tilupy-1.0.0}/src/tilupy.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: tilupy
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 1.0.0
|
|
4
4
|
Summary: Thin-layer models unified processing tool
|
|
5
5
|
Author-email: Marc Peruzzetto <m.peruzzetto@brgm.fr>
|
|
6
6
|
License: CeCILL-C FREE SOFTWARE LICENSE AGREEMENT
|
|
@@ -526,10 +526,17 @@ Classifier: Programming Language :: Python
|
|
|
526
526
|
Classifier: Programming Language :: Python :: 3
|
|
527
527
|
Requires-Python: >=3.8
|
|
528
528
|
Description-Content-Type: text/markdown
|
|
529
|
+
License-File: LICENSE
|
|
530
|
+
Requires-Dist: seaborn
|
|
531
|
+
Requires-Dist: requests
|
|
532
|
+
Requires-Dist: scipy
|
|
529
533
|
Provides-Extra: test
|
|
534
|
+
Requires-Dist: pytest; extra == "test"
|
|
530
535
|
Provides-Extra: dev
|
|
536
|
+
Requires-Dist: pipreqs; extra == "dev"
|
|
531
537
|
Provides-Extra: gis
|
|
532
|
-
|
|
538
|
+
Requires-Dist: rasterio; extra == "gis"
|
|
539
|
+
Requires-Dist: shapely; extra == "gis"
|
|
533
540
|
|
|
534
541
|
# tilupy
|
|
535
542
|
|
|
@@ -553,7 +560,7 @@ It contains one submodule per thin-layer model for writing and reading raw input
|
|
|
553
560
|
Outputs are then easily compared between different simulations / models. The models themselves are not part of this package and must
|
|
554
561
|
be installed separately.
|
|
555
562
|
|
|
556
|
-
Note that `tilupy` is still under development, thus only minimal documentation is available at the moment and testing is underway.
|
|
563
|
+
Note that `tilupy` is still under development, thus only minimal documentation is available at the moment, and testing is underway.
|
|
557
564
|
Contributions are feedback are most welcome. Reading and writing is available for the `SHALTOP` model (most commonly used by the author) and `r.avaflow`
|
|
558
565
|
(only partly maintained).
|
|
559
566
|
|
|
@@ -20,7 +20,7 @@ It contains one submodule per thin-layer model for writing and reading raw input
|
|
|
20
20
|
Outputs are then easily compared between different simulations / models. The models themselves are not part of this package and must
|
|
21
21
|
be installed separately.
|
|
22
22
|
|
|
23
|
-
Note that `tilupy` is still under development, thus only minimal documentation is available at the moment and testing is underway.
|
|
23
|
+
Note that `tilupy` is still under development, thus only minimal documentation is available at the moment, and testing is underway.
|
|
24
24
|
Contributions are feedback are most welcome. Reading and writing is available for the `SHALTOP` model (most commonly used by the author) and `r.avaflow`
|
|
25
25
|
(only partly maintained).
|
|
26
26
|
|
|
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
|
|
|
6
6
|
|
|
7
7
|
[project]
|
|
8
8
|
name = "tilupy"
|
|
9
|
-
version = "0.
|
|
9
|
+
version = "v1.0.0"
|
|
10
10
|
description = "Thin-layer models unified processing tool"
|
|
11
11
|
readme = "README.md"
|
|
12
12
|
authors = [{ name = "Marc Peruzzetto", email = "m.peruzzetto@brgm.fr" }]
|
|
@@ -18,7 +18,7 @@ classifiers = [
|
|
|
18
18
|
]
|
|
19
19
|
keywords = ["thin-layer", "shallow-water", "display", "simulation", "model", "processing", "benchmark"]
|
|
20
20
|
dependencies = [
|
|
21
|
-
"seaborn", "requests",
|
|
21
|
+
"seaborn", "requests", "scipy"
|
|
22
22
|
]
|
|
23
23
|
requires-python = ">=3.8"
|
|
24
24
|
|
|
@@ -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
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Created on Wed Jun 14 18:16:45 2023
|
|
4
|
+
|
|
5
|
+
@author: peruzzetto
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import tilupy.raster
|
|
9
|
+
import tilupy.read
|
|
10
|
+
|
|
11
|
+
import os
|
|
12
|
+
import argparse
|
|
13
|
+
import glob
|
|
14
|
+
|
|
15
|
+
|
|
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
|
|
26
|
+
|
|
27
|
+
if folder is None:
|
|
28
|
+
folder = os.getcwd()
|
|
29
|
+
|
|
30
|
+
if param_files is None:
|
|
31
|
+
param_files = "*.txt"
|
|
32
|
+
|
|
33
|
+
print(folder, param_files)
|
|
34
|
+
|
|
35
|
+
param_files = glob.glob(os.path.join(folder, param_files))
|
|
36
|
+
|
|
37
|
+
if len(param_files) == 0:
|
|
38
|
+
print("No parameter file matching param_files pattern was found")
|
|
39
|
+
return
|
|
40
|
+
|
|
41
|
+
if kwargs_read is None:
|
|
42
|
+
kwargs_read = dict()
|
|
43
|
+
|
|
44
|
+
kw_read = dict(folder_base=folder)
|
|
45
|
+
kw_read.update(kwargs_read)
|
|
46
|
+
|
|
47
|
+
for param_file in param_files:
|
|
48
|
+
print_str = "Processing simulation {:s}, {:s} {:s} ....."
|
|
49
|
+
print(print_str.format(param_file, fn_name, res_name))
|
|
50
|
+
kw_read["file_params"] = param_file
|
|
51
|
+
res = tilupy.read.get_results(model, **kw_read)
|
|
52
|
+
getattr(res, fn_name)(res_name, **kwargs_fn)
|
|
53
|
+
|
|
54
|
+
|
|
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")
|
|
64
|
+
kw.update(kwargs)
|
|
65
|
+
|
|
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
|
+
):
|
|
85
|
+
kw = dict(save=True)
|
|
86
|
+
kw.update(kwargs)
|
|
87
|
+
|
|
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
|
+
)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _get_parser(prog, description):
|
|
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
|
+
)
|
|
127
|
+
return parser
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def _tilupy_plot():
|
|
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
|
+
)
|
|
156
|
+
args = parser.parse_args()
|
|
157
|
+
plot_results(**vars(args))
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def _tilupy_to_raster():
|
|
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
|
+
)
|
|
171
|
+
args = parser.parse_args()
|
|
172
|
+
# plot_results(parser.model, parser.res_name)
|
|
173
|
+
to_raster(**vars(args))
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
if __name__ == "__main__":
|
|
177
|
+
# folder = 'd:/Documents/peruzzetto/tmp/test_shaltop/7p30e04_m3/coulomb'
|
|
178
|
+
# plot_results('shaltop', 'h_max', '*18p00.txt', folder=folder)
|
|
179
|
+
_tilupy_plot()
|
|
@@ -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))
|
|
@@ -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
|