ladim 2.0.1__tar.gz → 2.0.2__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.
- {ladim-2.0.1 → ladim-2.0.2}/PKG-INFO +1 -1
- {ladim-2.0.1 → ladim-2.0.2}/ladim/__init__.py +1 -1
- {ladim-2.0.1 → ladim-2.0.2}/ladim/gridforce/ROMS.py +19 -16
- {ladim-2.0.1 → ladim-2.0.2}/ladim/gridforce/zROMS.py +15 -12
- {ladim-2.0.1 → ladim-2.0.2}/ladim/main.py +14 -13
- {ladim-2.0.1 → ladim-2.0.2}/ladim/state.py +8 -0
- {ladim-2.0.1 → ladim-2.0.2}/ladim.egg-info/PKG-INFO +1 -1
- {ladim-2.0.1 → ladim-2.0.2}/LICENSE +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/README.md +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/ladim/__main__.py +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/ladim/config.py +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/ladim/forcing.py +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/ladim/grid.py +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/ladim/gridforce/__init__.py +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/ladim/gridforce/analytical.py +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/ladim/ibms/__init__.py +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/ladim/ibms/light.py +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/ladim/model.py +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/ladim/output.py +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/ladim/plugins/__init__.py +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/ladim/release.py +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/ladim/sample.py +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/ladim/solver.py +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/ladim/tracker.py +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/ladim/utilities.py +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/ladim.egg-info/SOURCES.txt +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/ladim.egg-info/dependency_links.txt +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/ladim.egg-info/entry_points.txt +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/ladim.egg-info/requires.txt +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/ladim.egg-info/top_level.txt +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/postladim/__init__.py +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/postladim/cellcount.py +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/postladim/kde_plot.py +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/postladim/particlefile.py +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/postladim/variable.py +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/pyproject.toml +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/setup.cfg +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/tests/test_ladim.py +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/tests/test_output.py +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/tests/test_release.py +0 -0
- {ladim-2.0.1 → ladim-2.0.2}/tests/test_solver.py +0 -0
|
@@ -15,10 +15,12 @@ import glob
|
|
|
15
15
|
import logging
|
|
16
16
|
import numpy as np
|
|
17
17
|
from netCDF4 import Dataset, num2date
|
|
18
|
-
|
|
19
18
|
from ladim.sample import sample2D, bilin_inv
|
|
20
19
|
|
|
21
20
|
|
|
21
|
+
logger = logging.getLogger(__name__)
|
|
22
|
+
|
|
23
|
+
|
|
22
24
|
class Grid:
|
|
23
25
|
"""Simple ROMS grid object
|
|
24
26
|
|
|
@@ -34,7 +36,7 @@ class Grid:
|
|
|
34
36
|
|
|
35
37
|
def __init__(self, config):
|
|
36
38
|
|
|
37
|
-
|
|
39
|
+
logger.info("Initializing ROMS-type grid object")
|
|
38
40
|
|
|
39
41
|
# Grid file
|
|
40
42
|
if "grid_file" in config["gridforce"]:
|
|
@@ -44,14 +46,14 @@ class Grid:
|
|
|
44
46
|
files.sort()
|
|
45
47
|
grid_file = files[0]
|
|
46
48
|
else:
|
|
47
|
-
|
|
49
|
+
logger.error("No grid file specified")
|
|
48
50
|
raise SystemExit(1)
|
|
49
51
|
|
|
50
52
|
try:
|
|
51
53
|
ncid = Dataset(grid_file)
|
|
52
54
|
ncid.set_auto_mask(False)
|
|
53
55
|
except OSError:
|
|
54
|
-
|
|
56
|
+
logger.error("Could not open grid file " + grid_file)
|
|
55
57
|
raise SystemExit(1)
|
|
56
58
|
|
|
57
59
|
# Subgrid, only considers internal grid cells
|
|
@@ -242,7 +244,7 @@ class Forcing:
|
|
|
242
244
|
|
|
243
245
|
def __init__(self, config, grid):
|
|
244
246
|
|
|
245
|
-
|
|
247
|
+
logger.info("Initiating forcing")
|
|
246
248
|
|
|
247
249
|
self._grid = grid # Get the grid object, make private?
|
|
248
250
|
# self.config = config["gridforce"]
|
|
@@ -255,9 +257,9 @@ class Forcing:
|
|
|
255
257
|
files = self.find_files(config["gridforce"])
|
|
256
258
|
numfiles = len(files)
|
|
257
259
|
if numfiles == 0:
|
|
258
|
-
|
|
260
|
+
logger.error("No input file: {}".format(config["gridforce"]["input_file"]))
|
|
259
261
|
raise SystemExit(3)
|
|
260
|
-
|
|
262
|
+
logger.info("Number of forcing files = {}".format(numfiles))
|
|
261
263
|
|
|
262
264
|
# ---------------------------
|
|
263
265
|
# Overview of all the files
|
|
@@ -357,6 +359,7 @@ class Forcing:
|
|
|
357
359
|
all_frames = [] # All time frames
|
|
358
360
|
num_frames = {} # Number of time frames in each file
|
|
359
361
|
for fname in files:
|
|
362
|
+
logger.info(f'Open forcing file {fname}')
|
|
360
363
|
with Dataset(fname) as nc:
|
|
361
364
|
new_times = nc.variables["ocean_time"][:]
|
|
362
365
|
num_frames[fname] = len(new_times)
|
|
@@ -370,11 +373,11 @@ class Forcing:
|
|
|
370
373
|
if np.any(I):
|
|
371
374
|
i = I.nonzero()[0][0] + 1 # Index of first out-of-order frame
|
|
372
375
|
oooframe = str(all_frames[i]).split('.')[0] # Remove microseconds
|
|
373
|
-
|
|
374
|
-
|
|
376
|
+
logger.info(f"Time frame {i} = {oooframe} out of order")
|
|
377
|
+
logger.critical("Forcing time frames not strictly sorted")
|
|
375
378
|
raise SystemExit(4)
|
|
376
379
|
|
|
377
|
-
|
|
380
|
+
logger.info(f"Number of available forcing times = {len(all_frames)}")
|
|
378
381
|
return all_frames, num_frames
|
|
379
382
|
|
|
380
383
|
@staticmethod
|
|
@@ -382,8 +385,8 @@ class Forcing:
|
|
|
382
385
|
|
|
383
386
|
time0 = all_frames[0]
|
|
384
387
|
time1 = all_frames[-1]
|
|
385
|
-
|
|
386
|
-
|
|
388
|
+
logger.info(f"First forcing time = {time0}")
|
|
389
|
+
logger.info(f"Last forcing time = {time1}")
|
|
387
390
|
start_time = np.datetime64(config["start_time"])
|
|
388
391
|
dt = np.timedelta64(int(config["dt"]), "s")
|
|
389
392
|
|
|
@@ -391,10 +394,10 @@ class Forcing:
|
|
|
391
394
|
# ------------------------------------------------------
|
|
392
395
|
|
|
393
396
|
if time0 > start_time:
|
|
394
|
-
|
|
397
|
+
logger.error("No forcing at start time")
|
|
395
398
|
raise SystemExit(3)
|
|
396
399
|
if time1 < config["stop_time"]:
|
|
397
|
-
|
|
400
|
+
logger.error("No forcing at stop time")
|
|
398
401
|
raise SystemExit(3)
|
|
399
402
|
|
|
400
403
|
# Make a list steps of the forcing time steps
|
|
@@ -427,7 +430,7 @@ class Forcing:
|
|
|
427
430
|
interpolate_velocity_in_time = True
|
|
428
431
|
interpolate_ibm_forcing_in_time = False
|
|
429
432
|
|
|
430
|
-
|
|
433
|
+
logger.debug("Updating forcing, time step = {}".format(t))
|
|
431
434
|
if t in self.steps: # No time interpolation
|
|
432
435
|
self.U = self.Unew
|
|
433
436
|
self.V = self.Vnew
|
|
@@ -486,7 +489,7 @@ class Forcing:
|
|
|
486
489
|
|
|
487
490
|
# Handle file opening/closing
|
|
488
491
|
# Always read velocity before other fields
|
|
489
|
-
|
|
492
|
+
logger.info("Reading velocity for time step = {}".format(n))
|
|
490
493
|
|
|
491
494
|
# If finished a file or first read (self._nc == "")
|
|
492
495
|
if not self._nc: # First read
|
|
@@ -18,6 +18,9 @@ from netCDF4 import Dataset, num2date
|
|
|
18
18
|
from ladim.sample import sample2D
|
|
19
19
|
|
|
20
20
|
|
|
21
|
+
logger = logging.getLogger(__name__)
|
|
22
|
+
|
|
23
|
+
|
|
21
24
|
class Grid:
|
|
22
25
|
"""Simple ROMS grid object
|
|
23
26
|
|
|
@@ -33,11 +36,11 @@ class Grid:
|
|
|
33
36
|
|
|
34
37
|
def __init__(self, config):
|
|
35
38
|
|
|
36
|
-
|
|
39
|
+
logger.info("Initializing zROMS grid object")
|
|
37
40
|
try:
|
|
38
41
|
ncid = Dataset(config["gridforce"]["grid_file"])
|
|
39
42
|
except OSError:
|
|
40
|
-
|
|
43
|
+
logger.error(
|
|
41
44
|
"Grid file {} not found".format(config["gridforce"]["grid_file"])
|
|
42
45
|
)
|
|
43
46
|
raise SystemExit(1)
|
|
@@ -188,7 +191,7 @@ class Forcing:
|
|
|
188
191
|
|
|
189
192
|
def __init__(self, config, grid):
|
|
190
193
|
|
|
191
|
-
|
|
194
|
+
logger.info("Initiating forcing")
|
|
192
195
|
|
|
193
196
|
self._grid = grid # Get the grid object, make private?
|
|
194
197
|
|
|
@@ -199,9 +202,9 @@ class Forcing:
|
|
|
199
202
|
files.sort()
|
|
200
203
|
numfiles = len(files)
|
|
201
204
|
if numfiles == 0:
|
|
202
|
-
|
|
205
|
+
logger.error("No input file: {}".format(config["gridforce"]["input_file"]))
|
|
203
206
|
raise SystemExit(3)
|
|
204
|
-
|
|
207
|
+
logger.info("Number of forcing files = {}".format(numfiles))
|
|
205
208
|
|
|
206
209
|
# ----------------------------------------
|
|
207
210
|
# Open first file for some general info
|
|
@@ -250,14 +253,14 @@ class Forcing:
|
|
|
250
253
|
new_times = nc.variables["time"][:]
|
|
251
254
|
times.extend(new_times)
|
|
252
255
|
num_frames.append(len(new_times))
|
|
253
|
-
|
|
256
|
+
logger.info("Number of available forcing times = {:d}".format(len(times)))
|
|
254
257
|
|
|
255
258
|
# Find first/last forcing times
|
|
256
259
|
# -----------------------------
|
|
257
260
|
time0 = num2date(times[0], time_units)
|
|
258
261
|
time1 = num2date(times[-1], time_units)
|
|
259
|
-
|
|
260
|
-
|
|
262
|
+
logger.info("time0 = {}".format(str(time0)))
|
|
263
|
+
logger.info("time1 = {}".format(str(time1)))
|
|
261
264
|
# print(time0)
|
|
262
265
|
# print(time1)
|
|
263
266
|
start_time = np.datetime64(config["start_time"])
|
|
@@ -269,10 +272,10 @@ class Forcing:
|
|
|
269
272
|
# Use logging module for this
|
|
270
273
|
|
|
271
274
|
if time0 > start_time:
|
|
272
|
-
|
|
275
|
+
logger.error("No forcing at start time")
|
|
273
276
|
raise SystemExit(3)
|
|
274
277
|
if time1 < config["stop_time"]:
|
|
275
|
-
|
|
278
|
+
logger.error("No forcing at stop time")
|
|
276
279
|
raise SystemExit(3)
|
|
277
280
|
|
|
278
281
|
# Make a list steps of the forcing time steps
|
|
@@ -362,7 +365,7 @@ class Forcing:
|
|
|
362
365
|
interpolate_velocity_in_time = True
|
|
363
366
|
interpolate_ibm_forcing_in_time = False
|
|
364
367
|
|
|
365
|
-
|
|
368
|
+
logger.debug("Updating forcing, time step = {}".format(t))
|
|
366
369
|
if t in self.steps: # No time interpolation
|
|
367
370
|
self.U = self.Unew
|
|
368
371
|
self.V = self.Vnew
|
|
@@ -399,7 +402,7 @@ class Forcing:
|
|
|
399
402
|
|
|
400
403
|
# Handle file opening/closing
|
|
401
404
|
# Always read velocity before other fields
|
|
402
|
-
|
|
405
|
+
logger.debug("Reading velocity for time step = {}".format(n))
|
|
403
406
|
first = True
|
|
404
407
|
if first: # Open file initiallt
|
|
405
408
|
self._nc = Dataset(self._files[self.file_idx[n]])
|
|
@@ -12,13 +12,14 @@ Lagrangian Advection and Diffusion Model
|
|
|
12
12
|
# ---------------------------------
|
|
13
13
|
|
|
14
14
|
import logging
|
|
15
|
-
|
|
16
15
|
import ladim
|
|
17
|
-
|
|
18
16
|
from .config import configure
|
|
19
17
|
from .model import Model
|
|
20
18
|
|
|
21
19
|
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
22
23
|
def main(config_stream, loglevel=logging.INFO):
|
|
23
24
|
"""Main function for LADiM"""
|
|
24
25
|
|
|
@@ -67,23 +68,23 @@ def run():
|
|
|
67
68
|
|
|
68
69
|
args = parser.parse_args()
|
|
69
70
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
logger.info(" ================================================")
|
|
72
|
+
logger.info(" === Lagrangian Advection and Diffusion Model ===")
|
|
73
|
+
logger.info(" ================================================\n")
|
|
73
74
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
logger.info(f"ladim path: {ladim.__file__.strip('__init.py__')}")
|
|
76
|
+
logger.info(f"ladim version: {ladim.__version__}\n")
|
|
77
|
+
logger.info(f"python version: {sys.version.split()[0]}\n")
|
|
77
78
|
|
|
78
|
-
|
|
79
|
-
|
|
79
|
+
logger.info(f" Configuration file: {args.config_file}")
|
|
80
|
+
logger.info(f" loglevel = {logging.getLevelName(args.loglevel)}")
|
|
80
81
|
|
|
81
82
|
# =============
|
|
82
83
|
# Sanity check
|
|
83
84
|
# =============
|
|
84
85
|
|
|
85
86
|
if not Path(args.config_file).exists():
|
|
86
|
-
|
|
87
|
+
logger.critical(f'Configuration file {args.config_file} not found')
|
|
87
88
|
raise SystemExit(1)
|
|
88
89
|
|
|
89
90
|
# ===================
|
|
@@ -92,7 +93,7 @@ def run():
|
|
|
92
93
|
|
|
93
94
|
# Start message
|
|
94
95
|
now = datetime.datetime.now().replace(microsecond=0)
|
|
95
|
-
|
|
96
|
+
logger.info(f'LADiM simulation starting, wall time={now}')
|
|
96
97
|
|
|
97
98
|
fp = open(args.config_file, encoding='utf8')
|
|
98
99
|
ladim.main(config_stream=fp, loglevel=args.loglevel)
|
|
@@ -100,4 +101,4 @@ def run():
|
|
|
100
101
|
# Reset logging and print final message
|
|
101
102
|
logging.getLogger().setLevel(logging.INFO)
|
|
102
103
|
now = datetime.datetime.now().replace(microsecond=0)
|
|
103
|
-
|
|
104
|
+
logger.info(f'LADiM simulation finished, wall time={now}')
|
|
@@ -122,6 +122,14 @@ class DynamicState(State):
|
|
|
122
122
|
raise AttributeError(f'Attribute not defined: {item}')
|
|
123
123
|
return self[item]
|
|
124
124
|
|
|
125
|
+
def __setattr__(self, item, value):
|
|
126
|
+
if item in list(self.__dict__.keys()) + ['_data', '_model', '_num_released', '_varnames']:
|
|
127
|
+
super().__setattr__(item, value)
|
|
128
|
+
elif item in self._data:
|
|
129
|
+
self._data[item] = value
|
|
130
|
+
else:
|
|
131
|
+
raise AttributeError(f"Attribute not defined: '{item}'")
|
|
132
|
+
|
|
125
133
|
def __contains__(self, item):
|
|
126
134
|
return item in self._data
|
|
127
135
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|