icon4py-standalone-driver 0.2.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.
- icon4py_standalone_driver-0.2.0/PKG-INFO +64 -0
- icon4py_standalone_driver-0.2.0/README.md +30 -0
- icon4py_standalone_driver-0.2.0/pyproject.toml +92 -0
- icon4py_standalone_driver-0.2.0/setup.cfg +4 -0
- icon4py_standalone_driver-0.2.0/src/icon4py/model/standalone_driver/__init__.py +29 -0
- icon4py_standalone_driver-0.2.0/src/icon4py/model/standalone_driver/config.py +43 -0
- icon4py_standalone_driver-0.2.0/src/icon4py/model/standalone_driver/driver_constants.py +28 -0
- icon4py_standalone_driver-0.2.0/src/icon4py/model/standalone_driver/driver_states.py +183 -0
- icon4py_standalone_driver-0.2.0/src/icon4py/model/standalone_driver/driver_utils.py +602 -0
- icon4py_standalone_driver-0.2.0/src/icon4py/model/standalone_driver/main.py +105 -0
- icon4py_standalone_driver-0.2.0/src/icon4py/model/standalone_driver/py.typed +0 -0
- icon4py_standalone_driver-0.2.0/src/icon4py/model/standalone_driver/standalone_driver.py +703 -0
- icon4py_standalone_driver-0.2.0/src/icon4py/model/standalone_driver/testcases/__init__.py +7 -0
- icon4py_standalone_driver-0.2.0/src/icon4py/model/standalone_driver/testcases/initial_condition.py +372 -0
- icon4py_standalone_driver-0.2.0/src/icon4py/model/standalone_driver/testcases/utils.py +221 -0
- icon4py_standalone_driver-0.2.0/src/icon4py_standalone_driver.egg-info/PKG-INFO +64 -0
- icon4py_standalone_driver-0.2.0/src/icon4py_standalone_driver.egg-info/SOURCES.txt +19 -0
- icon4py_standalone_driver-0.2.0/src/icon4py_standalone_driver.egg-info/dependency_links.txt +1 -0
- icon4py_standalone_driver-0.2.0/src/icon4py_standalone_driver.egg-info/entry_points.txt +2 -0
- icon4py_standalone_driver-0.2.0/src/icon4py_standalone_driver.egg-info/requires.txt +8 -0
- icon4py_standalone_driver-0.2.0/src/icon4py_standalone_driver.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: icon4py-standalone_driver
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: ICON model driver.
|
|
5
|
+
Author-email: ETH Zurich <gridtools@cscs.ch>
|
|
6
|
+
License: BSD-3 License
|
|
7
|
+
Project-URL: Homepage, https://github.com/C2SM/icon4py
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Intended Audience :: Science/Research
|
|
10
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
11
|
+
Classifier: Operating System :: POSIX
|
|
12
|
+
Classifier: Programming Language :: Python
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Atmospheric Science
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
23
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
Requires-Dist: icon4py-atmosphere-dycore~=0.2.0
|
|
27
|
+
Requires-Dist: icon4py-atmosphere-diffusion~=0.2.0
|
|
28
|
+
Requires-Dist: icon4py-common~=0.2.0
|
|
29
|
+
Requires-Dist: icon4py-testing~=0.2.0
|
|
30
|
+
Requires-Dist: typer>=0.20.0
|
|
31
|
+
Requires-Dist: devtools>=0.12
|
|
32
|
+
Requires-Dist: gt4py==1.1.10
|
|
33
|
+
Requires-Dist: packaging>=20.0
|
|
34
|
+
|
|
35
|
+
# model driver for Python ICON4Py
|
|
36
|
+
|
|
37
|
+
`main.py` contains a simple python program to run the experimental ICON python port.
|
|
38
|
+
|
|
39
|
+
Currently, it does only diffusion and solve_nonhydro (dry atmosphere with no physics). The configuration for the granules and driver is hardcoded in [standalone_driver.py](src/icon4py/model/standalone_driver/standalone_driver.py). Time step, total integration time, number of substeps, and etc. can be configured there.
|
|
40
|
+
|
|
41
|
+
The code is meant to be changed and enlarged as we port new parts of the model.
|
|
42
|
+
|
|
43
|
+
It runs single node.
|
|
44
|
+
|
|
45
|
+
## Installation
|
|
46
|
+
|
|
47
|
+
See the general instructions in the [README.md](../../README.md) in the base folder of the repository.
|
|
48
|
+
|
|
49
|
+
## Usage
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# set environment variables (optional but convenient)
|
|
53
|
+
export ICON4PY_ROOT=<path to the icon4py clone>
|
|
54
|
+
export GRID_FOLDER=<path to the folder holding grids>
|
|
55
|
+
|
|
56
|
+
# command line arguments:
|
|
57
|
+
icon4py-standalone-driver \
|
|
58
|
+
$ICON4PY_ROOT/configuration_path/ \
|
|
59
|
+
--grid-file-path $GRID_FOLDER/icon_grid_0013_R02B04_R.nc \
|
|
60
|
+
--output-path $ICON4PY_ROOT/output_path \
|
|
61
|
+
--icon4py-backend gtfn_cpu
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
#### Remarks
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# model driver for Python ICON4Py
|
|
2
|
+
|
|
3
|
+
`main.py` contains a simple python program to run the experimental ICON python port.
|
|
4
|
+
|
|
5
|
+
Currently, it does only diffusion and solve_nonhydro (dry atmosphere with no physics). The configuration for the granules and driver is hardcoded in [standalone_driver.py](src/icon4py/model/standalone_driver/standalone_driver.py). Time step, total integration time, number of substeps, and etc. can be configured there.
|
|
6
|
+
|
|
7
|
+
The code is meant to be changed and enlarged as we port new parts of the model.
|
|
8
|
+
|
|
9
|
+
It runs single node.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
See the general instructions in the [README.md](../../README.md) in the base folder of the repository.
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# set environment variables (optional but convenient)
|
|
19
|
+
export ICON4PY_ROOT=<path to the icon4py clone>
|
|
20
|
+
export GRID_FOLDER=<path to the folder holding grids>
|
|
21
|
+
|
|
22
|
+
# command line arguments:
|
|
23
|
+
icon4py-standalone-driver \
|
|
24
|
+
$ICON4PY_ROOT/configuration_path/ \
|
|
25
|
+
--grid-file-path $GRID_FOLDER/icon_grid_0013_R02B04_R.nc \
|
|
26
|
+
--output-path $ICON4PY_ROOT/output_path \
|
|
27
|
+
--icon4py-backend gtfn_cpu
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
#### Remarks
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# -- Build system requirements (PEP 518) --
|
|
2
|
+
|
|
3
|
+
[build-system]
|
|
4
|
+
build-backend = "setuptools.build_meta"
|
|
5
|
+
requires = ["setuptools>=61.0", "wheel>=0.40.0"]
|
|
6
|
+
|
|
7
|
+
# -- Standard project description options (PEP 621) --
|
|
8
|
+
[project]
|
|
9
|
+
authors = [{email = "gridtools@cscs.ch", name = "ETH Zurich"}]
|
|
10
|
+
classifiers = [
|
|
11
|
+
'Development Status :: 3 - Alpha',
|
|
12
|
+
'Intended Audience :: Science/Research',
|
|
13
|
+
'License :: OSI Approved :: BSD License',
|
|
14
|
+
'Operating System :: POSIX',
|
|
15
|
+
'Programming Language :: Python',
|
|
16
|
+
'Programming Language :: Python :: 3',
|
|
17
|
+
'Programming Language :: Python :: 3 :: Only',
|
|
18
|
+
'Programming Language :: Python :: 3.10',
|
|
19
|
+
'Programming Language :: Python :: 3.11',
|
|
20
|
+
'Programming Language :: Python :: 3.12',
|
|
21
|
+
'Programming Language :: Python :: 3.13',
|
|
22
|
+
'Programming Language :: Python :: 3.14',
|
|
23
|
+
'Programming Language :: Python :: Implementation :: CPython',
|
|
24
|
+
'Topic :: Scientific/Engineering :: Atmospheric Science',
|
|
25
|
+
'Topic :: Scientific/Engineering :: Mathematics',
|
|
26
|
+
'Topic :: Scientific/Engineering :: Physics'
|
|
27
|
+
]
|
|
28
|
+
dependencies = [
|
|
29
|
+
# workspace members
|
|
30
|
+
"icon4py-atmosphere-dycore~=0.2.0",
|
|
31
|
+
"icon4py-atmosphere-diffusion~=0.2.0",
|
|
32
|
+
"icon4py-common~=0.2.0",
|
|
33
|
+
"icon4py-testing~=0.2.0", # TODO(): remove this dependency when driver is fully standalone
|
|
34
|
+
# external dependencies
|
|
35
|
+
"typer>=0.20.0",
|
|
36
|
+
"devtools>=0.12",
|
|
37
|
+
"gt4py==1.1.10",
|
|
38
|
+
"packaging>=20.0"
|
|
39
|
+
]
|
|
40
|
+
description = "ICON model driver."
|
|
41
|
+
license = {text = "BSD-3 License"}
|
|
42
|
+
name = "icon4py-standalone_driver"
|
|
43
|
+
readme = "README.md"
|
|
44
|
+
requires-python = ">=3.10"
|
|
45
|
+
# managed by bump-my-version:
|
|
46
|
+
version = "0.2.0"
|
|
47
|
+
|
|
48
|
+
[project.scripts]
|
|
49
|
+
icon4py-standalone-driver = "icon4py.model.standalone_driver.main:click" # TODO (Yilu): change the name (remove the standalone) when it becomes the main driver
|
|
50
|
+
|
|
51
|
+
[project.urls]
|
|
52
|
+
Homepage = "https://github.com/C2SM/icon4py"
|
|
53
|
+
|
|
54
|
+
# -- bumpversion --
|
|
55
|
+
[tool.bumpversion]
|
|
56
|
+
allow_dirty = false
|
|
57
|
+
commit = false
|
|
58
|
+
current_version = "0.2.0"
|
|
59
|
+
ignore_missing_version = false
|
|
60
|
+
message = 'Bump icon4py-standalone_driver version: {current_version} → {new_version}'
|
|
61
|
+
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)(?:(?P<pre_l>a|b|rc)(?P<pre_n>\\d+))?"
|
|
62
|
+
serialize = ["{major}.{minor}.{patch}{pre_l}{pre_n}", "{major}.{minor}.{patch}"]
|
|
63
|
+
tag = false
|
|
64
|
+
|
|
65
|
+
[[tool.bumpversion.files]]
|
|
66
|
+
filename = "pyproject.toml"
|
|
67
|
+
replace = '''
|
|
68
|
+
# managed by bump-my-version:
|
|
69
|
+
version = "{new_version}"
|
|
70
|
+
'''
|
|
71
|
+
search = '''
|
|
72
|
+
# managed by bump-my-version:
|
|
73
|
+
version = "{current_version}"
|
|
74
|
+
'''
|
|
75
|
+
|
|
76
|
+
[[tool.bumpversion.files]]
|
|
77
|
+
filename = "src/icon4py/model/standalone_driver/__init__.py"
|
|
78
|
+
|
|
79
|
+
# --ruff --
|
|
80
|
+
[tool.ruff]
|
|
81
|
+
extend = "../../pyproject.toml"
|
|
82
|
+
|
|
83
|
+
[tool.ruff.lint.isort]
|
|
84
|
+
known-first-party = ['icon4py']
|
|
85
|
+
known-third-party = ['gt4py']
|
|
86
|
+
|
|
87
|
+
# -- setuptools --
|
|
88
|
+
[tool.setuptools.package-data]
|
|
89
|
+
'*' = ['*.in', '*.md', '*.rst', '*.txt', 'LICENSE', 'py.typed']
|
|
90
|
+
|
|
91
|
+
[tool.setuptools.packages]
|
|
92
|
+
find = {namespaces = true, where = ['src']}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# ICON4Py - ICON inspired code in Python and GT4Py
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2022-2024, ETH Zurich and MeteoSwiss
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# Please, refer to the LICENSE file in the root directory.
|
|
7
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
|
8
|
+
|
|
9
|
+
from typing import Final
|
|
10
|
+
|
|
11
|
+
from packaging import version as pkg_version
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"__author__",
|
|
16
|
+
"__copyright__",
|
|
17
|
+
"__license__",
|
|
18
|
+
"__version__",
|
|
19
|
+
"__version_info__",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
__author__: Final = "ETH Zurich, MeteoSwiss and individual contributors"
|
|
24
|
+
__copyright__: Final = "Copyright (c) 2022-2024 ETH Zurich and MeteoSwiss"
|
|
25
|
+
__license__: Final = "BSD-3-Clause"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
__version__: Final = "0.2.0"
|
|
29
|
+
__version_info__: Final = pkg_version.parse(__version__)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# ICON4Py - ICON inspired code in Python and GT4Py
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2022-2024, ETH Zurich and MeteoSwiss
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# Please, refer to the LICENSE file in the root directory.
|
|
7
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
|
8
|
+
|
|
9
|
+
import dataclasses
|
|
10
|
+
import datetime
|
|
11
|
+
import pathlib
|
|
12
|
+
|
|
13
|
+
from gt4py.next.instrumentation import metrics as gtx_metrics
|
|
14
|
+
|
|
15
|
+
from icon4py.model.common import type_alias as ta
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclasses.dataclass
|
|
19
|
+
class ProfilingStats:
|
|
20
|
+
gt4py_metrics_level: int = gtx_metrics.ALL
|
|
21
|
+
gt4py_metrics_output_file: str = "gt4py_metrics.json"
|
|
22
|
+
skip_first_timestep: bool = True
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@dataclasses.dataclass(frozen=True)
|
|
26
|
+
class DriverConfig:
|
|
27
|
+
"""
|
|
28
|
+
Standalone driver configuration.
|
|
29
|
+
|
|
30
|
+
Default values should correspond to default values in ICON.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
experiment_name: str
|
|
34
|
+
output_path: pathlib.Path
|
|
35
|
+
profiling_stats: ProfilingStats | None
|
|
36
|
+
dtime: datetime.timedelta = datetime.timedelta(seconds=600.0)
|
|
37
|
+
start_date: datetime.datetime = datetime.datetime(1, 1, 1, 0, 0, 0)
|
|
38
|
+
end_date: datetime.datetime = datetime.datetime(1, 1, 1, 1, 0, 0)
|
|
39
|
+
apply_extra_second_order_divdamp: bool = False
|
|
40
|
+
vertical_cfl_threshold: ta.wpfloat = dataclasses.field(default_factory=lambda: ta.wpfloat(0.85))
|
|
41
|
+
ndyn_substeps: int = 5
|
|
42
|
+
enable_statistics_output: bool = False
|
|
43
|
+
ntracer: int = 0
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# ICON4Py - ICON inspired code in Python and GT4Py
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2022-2024, ETH Zurich and MeteoSwiss
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# Please, refer to the LICENSE file in the root directory.
|
|
7
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
|
8
|
+
|
|
9
|
+
from icon4py.model.common import type_alias as ta
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
#: Factor multiplied to the user-defined CFL number to determine the whether to enter watchmode
|
|
13
|
+
CFL_ENTER_WATCHMODE_FACTOR = ta.wpfloat("0.81")
|
|
14
|
+
|
|
15
|
+
#: Threshold factor multiplied to the user-defined CFL number to maintain the number of substeps
|
|
16
|
+
CFL_THRESHOLD_FACTOR = ta.wpfloat("0.9")
|
|
17
|
+
|
|
18
|
+
#: Factor multiplied to the user-defined CFL number to determine the whether to leave watchmode
|
|
19
|
+
CFL_LEAVE_WATCHMODE_FACTOR = ta.wpfloat("0.76")
|
|
20
|
+
|
|
21
|
+
#: Adjustment factor for second order divergence damping
|
|
22
|
+
ADJUST_FACTOR_FOR_SECOND_ORDER_DIVDAMP = ta.wpfloat("0.8")
|
|
23
|
+
|
|
24
|
+
#: Initial period for second order divergence damping
|
|
25
|
+
INITIAL_PERIOD_FOR_SECOND_ORDER_DIVDAMP = ta.wpfloat("1800.0")
|
|
26
|
+
|
|
27
|
+
#: Transition end period for second order divergence damping
|
|
28
|
+
TRANSITION_END_PERIOD_FOR_SECOND_ORDER_DIVDAMP = ta.wpfloat("7200.0")
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# ICON4Py - ICON inspired code in Python and GT4Py
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2022-2024, ETH Zurich and MeteoSwiss
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# Please, refer to the LICENSE file in the root directory.
|
|
7
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
|
8
|
+
|
|
9
|
+
import dataclasses
|
|
10
|
+
import datetime
|
|
11
|
+
import enum
|
|
12
|
+
import functools
|
|
13
|
+
import logging
|
|
14
|
+
import statistics
|
|
15
|
+
from typing import NamedTuple
|
|
16
|
+
|
|
17
|
+
import devtools
|
|
18
|
+
|
|
19
|
+
import icon4py.model.common.utils as common_utils
|
|
20
|
+
from icon4py.model.atmosphere.advection import advection_states
|
|
21
|
+
from icon4py.model.atmosphere.diffusion import diffusion_states
|
|
22
|
+
from icon4py.model.atmosphere.dycore import dycore_states
|
|
23
|
+
from icon4py.model.common import type_alias as ta
|
|
24
|
+
from icon4py.model.common.grid import geometry as grid_geometry
|
|
25
|
+
from icon4py.model.common.interpolation import interpolation_factory
|
|
26
|
+
from icon4py.model.common.metrics import metrics_factory
|
|
27
|
+
from icon4py.model.common.states import (
|
|
28
|
+
diagnostic_state as diagnostics,
|
|
29
|
+
prognostic_state as prognostics,
|
|
30
|
+
)
|
|
31
|
+
from icon4py.model.standalone_driver import config as driver_config
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
log = logging.getLogger(__name__)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class StaticFieldFactories(NamedTuple):
|
|
38
|
+
"""
|
|
39
|
+
Factories of static fields for the driver and components.
|
|
40
|
+
|
|
41
|
+
Attributes:
|
|
42
|
+
geometry_field_source: grid geometry field factory that stores geometrical properties of a grid
|
|
43
|
+
interpolation_field_source: interpolation field factory that stores pre-computed coefficients for interpolation employed in the model
|
|
44
|
+
metrics_field_source: metrics field factory that stores pre-computed coefficients for numerical operations employed in the model
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
geometry_field_source: grid_geometry.GridGeometry
|
|
48
|
+
interpolation_field_source: interpolation_factory.InterpolationFieldsFactory
|
|
49
|
+
metrics_field_source: metrics_factory.MetricsFieldsFactory
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class DriverStates(NamedTuple):
|
|
53
|
+
"""
|
|
54
|
+
Initialized states for the driver run.
|
|
55
|
+
|
|
56
|
+
Attributes:
|
|
57
|
+
prep_advection_prognostic: Fields collecting data for advection during the solve nonhydro timestep.
|
|
58
|
+
solve_nonhydro_diagnostic: Initial state for solve_nonhydro diagnostic variables.
|
|
59
|
+
diffusion_diagnostic: Initial state for diffusion diagnostic variables.
|
|
60
|
+
prognostics: Initial state for prognostic variables (double buffered).
|
|
61
|
+
diagnostic: Initial state for global diagnostic variables.
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
prep_advection_prognostic: dycore_states.PrepAdvection
|
|
65
|
+
solve_nonhydro_diagnostic: dycore_states.DiagnosticStateNonHydro
|
|
66
|
+
tracer_advection_diagnostic: advection_states.AdvectionDiagnosticState
|
|
67
|
+
prep_tracer_advection_prognostic: advection_states.AdvectionPrepAdvState
|
|
68
|
+
diffusion_diagnostic: diffusion_states.DiffusionDiagnosticState
|
|
69
|
+
prognostics: common_utils.TimeStepPair[prognostics.PrognosticState]
|
|
70
|
+
diagnostic: diagnostics.DiagnosticState
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@dataclasses.dataclass
|
|
74
|
+
class ModelTimeVariables:
|
|
75
|
+
"""
|
|
76
|
+
This class contains driver's run-time time or date variables.
|
|
77
|
+
It tracks the current simulation date, substepping information, and cfl watch mode.
|
|
78
|
+
|
|
79
|
+
"""
|
|
80
|
+
|
|
81
|
+
config: dataclasses.InitVar[driver_config.DriverConfig]
|
|
82
|
+
|
|
83
|
+
n_time_steps: int = dataclasses.field(init=False)
|
|
84
|
+
dtime: datetime.timedelta = dataclasses.field(init=False)
|
|
85
|
+
ndyn_substeps_var: int = dataclasses.field(init=False)
|
|
86
|
+
max_ndyn_substeps: int = dataclasses.field(init=False)
|
|
87
|
+
elapsed_time_in_seconds: ta.wpfloat = dataclasses.field(init=False)
|
|
88
|
+
simulation_date: datetime.datetime = dataclasses.field(init=False)
|
|
89
|
+
is_first_step_in_simulation: bool = dataclasses.field(init=False)
|
|
90
|
+
cfl_watch_mode: bool = dataclasses.field(init=False)
|
|
91
|
+
|
|
92
|
+
def __post_init__(self, config: driver_config.DriverConfig) -> None:
|
|
93
|
+
self.n_time_steps = int((config.end_date - config.start_date) / config.dtime)
|
|
94
|
+
self.dtime = config.dtime
|
|
95
|
+
self.elapsed_time_in_seconds = ta.wpfloat("0.0")
|
|
96
|
+
self.simulation_date = config.start_date
|
|
97
|
+
self.ndyn_substeps_var = config.ndyn_substeps
|
|
98
|
+
self.max_ndyn_substeps = config.ndyn_substeps + 7
|
|
99
|
+
self.is_first_step_in_simulation = True
|
|
100
|
+
self.cfl_watch_mode = False
|
|
101
|
+
|
|
102
|
+
if self.n_time_steps < 0:
|
|
103
|
+
raise ValueError("end_date should be larger than start_date. Please check.")
|
|
104
|
+
|
|
105
|
+
@functools.cached_property
|
|
106
|
+
def dtime_in_seconds(self) -> ta.wpfloat:
|
|
107
|
+
return ta.wpfloat(self.dtime.total_seconds())
|
|
108
|
+
|
|
109
|
+
@property
|
|
110
|
+
def substep_timestep(self) -> ta.wpfloat:
|
|
111
|
+
return ta.wpfloat(self.dtime_in_seconds / self.ndyn_substeps_var)
|
|
112
|
+
|
|
113
|
+
def next_simulation_date(self) -> None:
|
|
114
|
+
self.simulation_date += self.dtime
|
|
115
|
+
self.elapsed_time_in_seconds += self.dtime_in_seconds
|
|
116
|
+
|
|
117
|
+
def update_ndyn_substeps(self, new_ndyn_substeps: int) -> None:
|
|
118
|
+
self.ndyn_substeps_var = new_ndyn_substeps
|
|
119
|
+
|
|
120
|
+
def update_cfl_watch_mode(self, mode: bool) -> None:
|
|
121
|
+
self.cfl_watch_mode = mode
|
|
122
|
+
|
|
123
|
+
def reset(self, config: driver_config.DriverConfig) -> None:
|
|
124
|
+
"""
|
|
125
|
+
Re-initialize all time-integration-related runtime values from the given config.
|
|
126
|
+
"""
|
|
127
|
+
self.__post_init__(config)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
class DriverTimers(enum.Enum):
|
|
131
|
+
SOLVE_NH_FIRST_STEP = "solve_nh_first_step"
|
|
132
|
+
SOLVE_NH = "solve_nh"
|
|
133
|
+
DIFFUSION_FIRST_STEP = "diffusion_first_step"
|
|
134
|
+
DIFFUSION = "diffusion"
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
@dataclasses.dataclass
|
|
138
|
+
class TimerCollection:
|
|
139
|
+
timer_names: dataclasses.InitVar[list[str]]
|
|
140
|
+
timers: dict[str, devtools.Timer] = dataclasses.field(init=False)
|
|
141
|
+
|
|
142
|
+
def __post_init__(self, timer_names: str | list[str]) -> None:
|
|
143
|
+
self.timers = {}
|
|
144
|
+
self.add_timers(timer_names)
|
|
145
|
+
|
|
146
|
+
def add_timers(self, timer_names: str | list[str]) -> None:
|
|
147
|
+
for timer in timer_names:
|
|
148
|
+
assert timer not in self.timers, f"Timer '{timer}' is already defined."
|
|
149
|
+
self.timers[timer] = devtools.Timer(timer, dp=6, verbose=False)
|
|
150
|
+
|
|
151
|
+
def show_timer_report(
|
|
152
|
+
self,
|
|
153
|
+
) -> None:
|
|
154
|
+
log.info("===== ICON4Py timer report =====")
|
|
155
|
+
table_titles = (
|
|
156
|
+
f"|{'timer name':^30}|"
|
|
157
|
+
f"{'no. of times called':^23}|"
|
|
158
|
+
f"{'mean time (s)':^23}|"
|
|
159
|
+
f"{'std. deviation (s)':^23}|"
|
|
160
|
+
f"{'min time (s)':^23}|"
|
|
161
|
+
f"{'max time (s)':^23}|"
|
|
162
|
+
)
|
|
163
|
+
log.info(table_titles)
|
|
164
|
+
log.info("-" * len(table_titles))
|
|
165
|
+
for timer_name, timer in self.timers.items():
|
|
166
|
+
times = []
|
|
167
|
+
for r in timer.results:
|
|
168
|
+
if not r.finish:
|
|
169
|
+
r.capture()
|
|
170
|
+
times.append(r.elapsed())
|
|
171
|
+
if len(times) > 0:
|
|
172
|
+
log.info(
|
|
173
|
+
f"|{timer_name:^30}|"
|
|
174
|
+
f"{len(times):^23}|"
|
|
175
|
+
f"{statistics.mean(times):^23.8f}|"
|
|
176
|
+
f"{statistics.stdev(times) if len(times) > 1 else 0:^23.8f}|"
|
|
177
|
+
f"{min(times):^23.8f}|"
|
|
178
|
+
f"{max(times):^23.8f}|"
|
|
179
|
+
)
|
|
180
|
+
else:
|
|
181
|
+
log.info(
|
|
182
|
+
f"|{timer_name:^30}|{'not started':^23}|{'':^23}|{'':^23}|{'':^23}|{'':^23}|"
|
|
183
|
+
)
|