tilupy 2.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.
- tilupy/__init__.py +23 -0
- tilupy/analytic_sol.py +2403 -0
- tilupy/benchmark.py +1563 -0
- tilupy/calibration.py +134 -0
- tilupy/cmd.py +177 -0
- tilupy/compare.py +195 -0
- tilupy/download_data.py +68 -0
- tilupy/initdata.py +207 -0
- tilupy/initsimus.py +50 -0
- tilupy/make_mass.py +111 -0
- tilupy/make_topo.py +468 -0
- tilupy/models/__init__.py +0 -0
- tilupy/models/lave2D/__init__.py +0 -0
- tilupy/models/lave2D/initsimus.py +665 -0
- tilupy/models/lave2D/read.py +264 -0
- tilupy/models/ravaflow/__init__.py +0 -0
- tilupy/models/ravaflow/initsimus.py +192 -0
- tilupy/models/ravaflow/read.py +273 -0
- tilupy/models/saval2D/__init__.py +0 -0
- tilupy/models/saval2D/read.py +298 -0
- tilupy/models/shaltop/__init__.py +0 -0
- tilupy/models/shaltop/initsimus.py +375 -0
- tilupy/models/shaltop/read.py +613 -0
- tilupy/notations.py +866 -0
- tilupy/plot.py +234 -0
- tilupy/raster.py +199 -0
- tilupy/read.py +2588 -0
- tilupy/utils.py +656 -0
- tilupy-2.0.0.dist-info/METADATA +876 -0
- tilupy-2.0.0.dist-info/RECORD +34 -0
- tilupy-2.0.0.dist-info/WHEEL +5 -0
- tilupy-2.0.0.dist-info/entry_points.txt +3 -0
- tilupy-2.0.0.dist-info/licenses/LICENSE +516 -0
- tilupy-2.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
import os
|
|
5
|
+
import posixpath
|
|
6
|
+
import numpy as np
|
|
7
|
+
|
|
8
|
+
from tilupy.utils import format_path_linux
|
|
9
|
+
|
|
10
|
+
import tilupy.notations
|
|
11
|
+
import tilupy.raster
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
README_PARAM_MATCH = dict(tmax="tmax", CFL="cflhyp", h_min="eps0", dt_im_output="dt_im")
|
|
15
|
+
"""Dictionary of correspondence between parameters in read_me file and param file."""
|
|
16
|
+
|
|
17
|
+
SHALTOP_LAW_ID = dict(No_Friction=1, Herschel_Bulkley=61, Voellmy=8, Bingham=6, Coulomb=1, Coulomb_muI=7)
|
|
18
|
+
"""Dictionary of correspondence between the name of rheological laws and the corresponding ID in SHALTOP.
|
|
19
|
+
|
|
20
|
+
Correspondence :
|
|
21
|
+
|
|
22
|
+
- No_Friction = 1
|
|
23
|
+
- Coulomb = 1
|
|
24
|
+
- Coulomb_muI = 7
|
|
25
|
+
- Voellmy = 8
|
|
26
|
+
- Bingham = 6
|
|
27
|
+
- Herschel_Bulkley = 61
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def raster_to_shaltop_txtfile(file_in: str,
|
|
32
|
+
file_out: str,
|
|
33
|
+
folder_out: str=None
|
|
34
|
+
) -> dict:
|
|
35
|
+
"""Convert a raster file to a Shaltop ASCII text format.
|
|
36
|
+
|
|
37
|
+
Reads a raster (formats readable by :func:`tilupy.raster.read_raster`) and saves it as a
|
|
38
|
+
ASCII text file with values flattened column-wise and rows flipped vertically.
|
|
39
|
+
|
|
40
|
+
Parameters
|
|
41
|
+
----------
|
|
42
|
+
file_in : str
|
|
43
|
+
Path to the input raster file.
|
|
44
|
+
file_out : str
|
|
45
|
+
Name of the output ASCII text file.
|
|
46
|
+
folder_out : str, optional
|
|
47
|
+
Directory where the output file will be saved. If None, `file_out`
|
|
48
|
+
is used as-is, by default None.
|
|
49
|
+
|
|
50
|
+
Returns
|
|
51
|
+
-------
|
|
52
|
+
dict
|
|
53
|
+
Dictionary containing grid metadata:
|
|
54
|
+
|
|
55
|
+
- 'x0': X coordinate of the first column.
|
|
56
|
+
- 'y0': Y coordinate of the first row.
|
|
57
|
+
- 'dx': Grid spacing along X.
|
|
58
|
+
- 'dy': Grid spacing along Y.
|
|
59
|
+
- 'nx': Number of columns.
|
|
60
|
+
- 'ny': Number of rows.
|
|
61
|
+
"""
|
|
62
|
+
if folder_out is not None:
|
|
63
|
+
file_out = os.path.join(folder_out, file_out)
|
|
64
|
+
|
|
65
|
+
x, y, rast = tilupy.raster.read_raster(file_in)
|
|
66
|
+
np.savetxt(file_out,
|
|
67
|
+
np.reshape(np.flip(rast, axis=0), (rast.size, 1)),
|
|
68
|
+
fmt="%.12G")
|
|
69
|
+
|
|
70
|
+
res = dict(x0=x[0],
|
|
71
|
+
y0=y[0],
|
|
72
|
+
dx=x[1] - x[0],
|
|
73
|
+
dy=y[1] - y[0],
|
|
74
|
+
nx=len(x),
|
|
75
|
+
ny=len(y))
|
|
76
|
+
|
|
77
|
+
return res
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def write_params_file(params: dict,
|
|
81
|
+
directory: str=None,
|
|
82
|
+
file_name: str="params.txt"
|
|
83
|
+
) -> None:
|
|
84
|
+
"""Write a dictionary of parameters to a text file.
|
|
85
|
+
|
|
86
|
+
Each key-value pair in the dictionary is written on a separate line.
|
|
87
|
+
|
|
88
|
+
Parameters
|
|
89
|
+
----------
|
|
90
|
+
params : dict
|
|
91
|
+
Dictionary of parameter names and values. Values can be int, float,
|
|
92
|
+
or str.
|
|
93
|
+
directory : str, optional
|
|
94
|
+
Directory where the parameter file will be written. Default is the
|
|
95
|
+
current working directory.
|
|
96
|
+
file_name : str, optional
|
|
97
|
+
Name of the parameter file. Default is "params.txt".
|
|
98
|
+
"""
|
|
99
|
+
if directory is None:
|
|
100
|
+
directory = os.getcwd()
|
|
101
|
+
|
|
102
|
+
with open(os.path.join(directory, file_name), "w") as file_params:
|
|
103
|
+
for name in params:
|
|
104
|
+
val = params[name]
|
|
105
|
+
if (isinstance(val, int)
|
|
106
|
+
or isinstance(val, np.int64)
|
|
107
|
+
or isinstance(val, np.int32)
|
|
108
|
+
):
|
|
109
|
+
file_params.write("{:s} {:d}\n".format(name, val))
|
|
110
|
+
|
|
111
|
+
if (isinstance(val, float)
|
|
112
|
+
or isinstance(val, np.float64)
|
|
113
|
+
or isinstance(val, np.float32)
|
|
114
|
+
):
|
|
115
|
+
file_params.write("{:s} {:.8G}\n".format(name, val))
|
|
116
|
+
|
|
117
|
+
if isinstance(val, str):
|
|
118
|
+
file_params.write("{:s} {:s}\n".format(name, val))
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def write_simu(raster_topo: str,
|
|
122
|
+
raster_mass: str,
|
|
123
|
+
tmax : float,
|
|
124
|
+
dt_im : float,
|
|
125
|
+
rheology_type: str,
|
|
126
|
+
rheology_params: dict,
|
|
127
|
+
folder_out: str=None,
|
|
128
|
+
) -> None:
|
|
129
|
+
"""
|
|
130
|
+
Prepares the input files required for a SHALTOP simulation and saves them in a dedicated folder.
|
|
131
|
+
|
|
132
|
+
Parameters
|
|
133
|
+
----------
|
|
134
|
+
raster_topo : str
|
|
135
|
+
Name of the ASCII topography file.
|
|
136
|
+
raster_mass : str
|
|
137
|
+
Name of the ASCII initial mass file.
|
|
138
|
+
tmax : float
|
|
139
|
+
Maximum simulation time.
|
|
140
|
+
dt_im : float
|
|
141
|
+
Output image interval (in time steps).
|
|
142
|
+
rheology_type : str
|
|
143
|
+
Rheology to use for the simulation.
|
|
144
|
+
rheology_params : dict
|
|
145
|
+
Necessary parameters for the rheology. For instance:
|
|
146
|
+
|
|
147
|
+
- delta1
|
|
148
|
+
- ksi
|
|
149
|
+
- tau_density
|
|
150
|
+
etc.
|
|
151
|
+
folder_out : str, optional
|
|
152
|
+
Output folder where simulation inputs will be saved.
|
|
153
|
+
|
|
154
|
+
Raises
|
|
155
|
+
------
|
|
156
|
+
ValueError
|
|
157
|
+
If the rheology is wrong.
|
|
158
|
+
"""
|
|
159
|
+
if folder_out is None:
|
|
160
|
+
folder_out = "."
|
|
161
|
+
|
|
162
|
+
# output_file = os.path.join(folder_out, "shaltop")
|
|
163
|
+
|
|
164
|
+
os.makedirs(folder_out, exist_ok=True)
|
|
165
|
+
|
|
166
|
+
x, y, z = tilupy.raster.read_raster(raster_topo)
|
|
167
|
+
raster_to_shaltop_txtfile(raster_topo, os.path.join(folder_out, "z.d"))
|
|
168
|
+
raster_to_shaltop_txtfile(raster_mass, os.path.join(folder_out, "m.d"))
|
|
169
|
+
folder_output = "data2"
|
|
170
|
+
os.makedirs(os.path.join(folder_out, folder_output), exist_ok=True)
|
|
171
|
+
|
|
172
|
+
if rheology_type not in SHALTOP_LAW_ID:
|
|
173
|
+
raise ValueError(f"Wrong law, choose in: {SHALTOP_LAW_ID}")
|
|
174
|
+
|
|
175
|
+
params = dict(nx=len(x),
|
|
176
|
+
ny=len(y),
|
|
177
|
+
per=x[-1],
|
|
178
|
+
pery=y[-1],
|
|
179
|
+
tmax=tmax,
|
|
180
|
+
dt_im=dt_im,
|
|
181
|
+
initz=0,
|
|
182
|
+
file_z_init="z.d",
|
|
183
|
+
ipr=0,
|
|
184
|
+
file_m_init="m.d",
|
|
185
|
+
folder_output="data2",
|
|
186
|
+
icomp=SHALTOP_LAW_ID[rheology_type],
|
|
187
|
+
**rheology_params)
|
|
188
|
+
write_params_file(params, directory=folder_out, file_name="params.txt")
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def write_job_files(dirs: list[str],
|
|
192
|
+
param_files: list[str],
|
|
193
|
+
file_job: str,
|
|
194
|
+
job_name: str,
|
|
195
|
+
max_time_hours: int=24,
|
|
196
|
+
ncores_per_node: int=6,
|
|
197
|
+
partitions: str="cpuall,data,datanew",
|
|
198
|
+
shaltop_file: str="shaltop",
|
|
199
|
+
folder_conf_in_job: str=None,
|
|
200
|
+
replace_path: list=None,
|
|
201
|
+
number_conf_file: bool=True,
|
|
202
|
+
) -> None:
|
|
203
|
+
"""
|
|
204
|
+
Write job/conf files for slurm jobs. The conf contains all the commands
|
|
205
|
+
needed to run each simulation (one command per simulation).
|
|
206
|
+
|
|
207
|
+
Parameters
|
|
208
|
+
----------
|
|
209
|
+
dirs : list[str]
|
|
210
|
+
list of paths where simus will be run.
|
|
211
|
+
param_files : list[str]
|
|
212
|
+
list of shaltop parameter files.
|
|
213
|
+
file_job : str
|
|
214
|
+
name of job file called by sbatch.
|
|
215
|
+
job_name : str
|
|
216
|
+
name of conf file used by file_job.
|
|
217
|
+
max_time_hours : int, optional
|
|
218
|
+
Maximum job duration in hours before stop. The default is 24.
|
|
219
|
+
ncores_per_node : int, optional
|
|
220
|
+
Number of cores per nodes. Used to know the number of nodes required
|
|
221
|
+
for the job. The default is 6.
|
|
222
|
+
partitions : str, optional
|
|
223
|
+
Names of partitions on which jobs can be launched.
|
|
224
|
+
The default is "cpuall,data,datanew".
|
|
225
|
+
shaltop_file : str, optional
|
|
226
|
+
Bash command used to call shaltop. Can be a path.
|
|
227
|
+
The default is "shaltop".
|
|
228
|
+
folder_conf_in_job : str, optional
|
|
229
|
+
Folder where the conf file is located. The default is the folder
|
|
230
|
+
path of file_job.
|
|
231
|
+
replace_path : list, optional
|
|
232
|
+
replace replace_path[0] by replace_path[1] for every path in dir. This
|
|
233
|
+
is used if simulations are prepared and run on two different machines
|
|
234
|
+
(e.g. laptop and cluster).
|
|
235
|
+
The default is None.
|
|
236
|
+
number_conf_file : bool, optional
|
|
237
|
+
If True, add a number in front of each line of the conf file. Required
|
|
238
|
+
to identify slurm jobs.
|
|
239
|
+
The default is True.
|
|
240
|
+
"""
|
|
241
|
+
ntasks = len(dirs)
|
|
242
|
+
nnodes = int(np.ceil(ntasks / ncores_per_node))
|
|
243
|
+
|
|
244
|
+
if folder_conf_in_job is None:
|
|
245
|
+
folder_conf_in_job = os.path.dirname(file_job)
|
|
246
|
+
if folder_conf_in_job == "":
|
|
247
|
+
folder_conf_in_job = "."
|
|
248
|
+
|
|
249
|
+
with open(file_job + ".conf", "w", newline="\n") as conf_file:
|
|
250
|
+
if number_conf_file:
|
|
251
|
+
line = "{:d} {:s} {:s} {:s}\n"
|
|
252
|
+
else:
|
|
253
|
+
line = "{:s} {:s} {:s}\n"
|
|
254
|
+
for i in range(ntasks):
|
|
255
|
+
if replace_path is not None:
|
|
256
|
+
folder = dirs[i].replace(replace_path[0], replace_path[1])
|
|
257
|
+
param_file = param_files[i].replace(
|
|
258
|
+
replace_path[0], replace_path[1]
|
|
259
|
+
)
|
|
260
|
+
else:
|
|
261
|
+
folder = dirs[i]
|
|
262
|
+
param_file = param_files[i]
|
|
263
|
+
folder = format_path_linux(folder)
|
|
264
|
+
param_file = format_path_linux(param_file)
|
|
265
|
+
if number_conf_file:
|
|
266
|
+
line2 = line.format(i, shaltop_file, folder, param_file)
|
|
267
|
+
else:
|
|
268
|
+
line2 = line.format(shaltop_file, folder, param_file)
|
|
269
|
+
conf_file.write(line2)
|
|
270
|
+
|
|
271
|
+
n_hours = np.floor(max_time_hours)
|
|
272
|
+
n_min = (max_time_hours - n_hours) * 60
|
|
273
|
+
str_time = "{:02.0f}:{:02.0f}:00\n".format(n_hours, n_min)
|
|
274
|
+
|
|
275
|
+
basename = os.path.basename(file_job)
|
|
276
|
+
path_conf_in_job = posixpath.join(folder_conf_in_job, basename + ".conf")
|
|
277
|
+
|
|
278
|
+
with open(file_job + ".job", "w", newline="\n") as job_file:
|
|
279
|
+
job_file.write("#!/bin/sh\n")
|
|
280
|
+
job_file.write("#SBATCH -J multijob\n")
|
|
281
|
+
job_file.write("#SBATCH --job-name={:s}\n".format(job_name))
|
|
282
|
+
job_file.write("#SBATCH --output={:s}%j.out\n".format(job_name))
|
|
283
|
+
job_file.write("#SBATCH --partition " + partitions + "\n")
|
|
284
|
+
job_file.write("#SBATCH --nodes={:d}".format(nnodes) + "\n")
|
|
285
|
+
job_file.write("#SBATCH --ntasks={:d}".format(ntasks) + "\n")
|
|
286
|
+
job_file.write("#SBATCH --time={:s}\n".format(str_time))
|
|
287
|
+
job_file.write("\n")
|
|
288
|
+
job_file.write("module purge\n")
|
|
289
|
+
job_file.write("module load slurm\n")
|
|
290
|
+
job_file.write("\n")
|
|
291
|
+
line = "srun -n {:d} -l --multi-prog {:s}"
|
|
292
|
+
job_file.write(line.format(ntasks, path_conf_in_job))
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
def make_simus(law: str,
|
|
296
|
+
rheol_params: dict,
|
|
297
|
+
folder_data: str,
|
|
298
|
+
folder_out: str,
|
|
299
|
+
readme_file: str
|
|
300
|
+
) -> None:
|
|
301
|
+
"""Write shaltop initial file for simple slope test case
|
|
302
|
+
|
|
303
|
+
Reads topography and initial mass files in ASCII format,
|
|
304
|
+
writes them in Shaltop-compatible format, prepares simulation parameters
|
|
305
|
+
based on a README file and user-provided values,
|
|
306
|
+
and generates a shell script to run the simulations.
|
|
307
|
+
|
|
308
|
+
Parameters
|
|
309
|
+
----------
|
|
310
|
+
law : str
|
|
311
|
+
Name of the rheological law to use (must match a key in :data:`SHALTOP_LAW_ID`).
|
|
312
|
+
rheol_params : dict of list
|
|
313
|
+
Dictionary of rheology parameters. Each key corresponds to a parameter
|
|
314
|
+
name and its value is a list of parameter values to simulate.
|
|
315
|
+
folder_data : str
|
|
316
|
+
Path to the folder containing input data files "topo.asc" and "mass.asc".
|
|
317
|
+
folder_out : str
|
|
318
|
+
Path to the folder where output simulation folders and Shaltop files
|
|
319
|
+
will be created.
|
|
320
|
+
readme_file : str
|
|
321
|
+
Path to the README file containing simulation parameters and metadata.
|
|
322
|
+
"""
|
|
323
|
+
# Get topography and initial mass, and write them in Shaltop format
|
|
324
|
+
zfile = os.path.join(folder_data, "topo.asc")
|
|
325
|
+
mfile = os.path.join(folder_data, "mass.asc")
|
|
326
|
+
x, y, z, dx = tilupy.raster.read_ascii(zfile)
|
|
327
|
+
_, _, m, _ = tilupy.raster.read_ascii(mfile)
|
|
328
|
+
np.savetxt(os.path.join(folder_out, "z.d"), z.T.flatten())
|
|
329
|
+
np.savetxt(os.path.join(folder_out, "m.d"), m.T.flatten())
|
|
330
|
+
|
|
331
|
+
# Get simulation parameters from README.txt and raster .asc files
|
|
332
|
+
params = tilupy.notations.readme_to_params(readme_file, README_PARAM_MATCH)
|
|
333
|
+
params["nx"] = len(x)
|
|
334
|
+
params["ny"] = len(y)
|
|
335
|
+
params["per"] = dx * len(x)
|
|
336
|
+
params["pery"] = dx * len(y)
|
|
337
|
+
params["file_m_init"] = "../m.d"
|
|
338
|
+
params["file_z_init"] = "../z.d"
|
|
339
|
+
|
|
340
|
+
# Folder for rheological law, and set params accordingly
|
|
341
|
+
folder_law = os.path.join(folder_out, law)
|
|
342
|
+
params["icomp"] = SHALTOP_LAW_ID[law]
|
|
343
|
+
|
|
344
|
+
param_names = [param for param in rheol_params]
|
|
345
|
+
|
|
346
|
+
texts = tilupy.notations.make_rheol_string(rheol_params, law)
|
|
347
|
+
|
|
348
|
+
# Run shaltop file
|
|
349
|
+
run_shaltop_file = os.path.join(folder_law, "run_shaltop.sh")
|
|
350
|
+
file_txt = ""
|
|
351
|
+
|
|
352
|
+
for i in range(len(rheol_params[param_names[0]])):
|
|
353
|
+
simu_text = texts[i]
|
|
354
|
+
for param_name in param_names:
|
|
355
|
+
params[param_name] = rheol_params[param_name][i]
|
|
356
|
+
params["folder_output"] = simu_text
|
|
357
|
+
folder_results = os.path.join(folder_law, simu_text)
|
|
358
|
+
os.makedirs(folder_results, exist_ok=True)
|
|
359
|
+
with open(os.path.join(folder_results, ".gitignore"), "w") as fid:
|
|
360
|
+
fid.write("# Ignore everything in this directory")
|
|
361
|
+
fid.write("*")
|
|
362
|
+
fid.write("# Except this file")
|
|
363
|
+
fid.write("!.gitignore")
|
|
364
|
+
|
|
365
|
+
write_params_file(params, directory=folder_law, file_name=simu_text + ".txt")
|
|
366
|
+
file_txt += "start_time=`date +%s`\n"
|
|
367
|
+
file_txt += 'shaltop "" ' + simu_text + ".txt\n"
|
|
368
|
+
file_txt += "end_time=`date +%s`\n"
|
|
369
|
+
file_txt += "elapsed_time=$(($end_time - $start_time))\n"
|
|
370
|
+
file_txt += ('string_time="${start_time} ' + simu_text + ' ${elapsed_time}"\n')
|
|
371
|
+
file_txt += "echo ${string_time} >> simulation_duration.txt\n\n"
|
|
372
|
+
|
|
373
|
+
with open(run_shaltop_file, "w") as fid:
|
|
374
|
+
fid.write(file_txt)
|
|
375
|
+
|