wrfrun 0.2.0__py3-none-any.whl → 0.3.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.
- wrfrun/__init__.py +8 -3
- wrfrun/cli.py +69 -29
- wrfrun/core/__init__.py +27 -10
- wrfrun/core/_config.py +308 -0
- wrfrun/core/_constant.py +236 -0
- wrfrun/core/_exec_db.py +105 -0
- wrfrun/core/_namelist.py +287 -0
- wrfrun/core/_record.py +178 -0
- wrfrun/core/_resource.py +172 -0
- wrfrun/core/base.py +132 -406
- wrfrun/core/core.py +196 -0
- wrfrun/core/error.py +28 -2
- wrfrun/core/replay.py +10 -96
- wrfrun/core/server.py +52 -27
- wrfrun/core/type.py +171 -0
- wrfrun/data.py +304 -139
- wrfrun/extension/goos_sst/__init__.py +2 -2
- wrfrun/extension/goos_sst/core.py +9 -14
- wrfrun/extension/goos_sst/res/__init__.py +0 -1
- wrfrun/extension/goos_sst/utils.py +50 -44
- wrfrun/extension/littler/core.py +105 -88
- wrfrun/extension/utils.py +4 -3
- wrfrun/log.py +117 -0
- wrfrun/model/__init__.py +11 -7
- wrfrun/model/constants.py +52 -0
- wrfrun/model/palm/__init__.py +30 -0
- wrfrun/model/palm/core.py +145 -0
- wrfrun/model/palm/namelist.py +33 -0
- wrfrun/model/plot.py +99 -119
- wrfrun/model/type.py +116 -0
- wrfrun/model/utils.py +9 -20
- wrfrun/model/wrf/__init__.py +4 -9
- wrfrun/model/wrf/core.py +246 -161
- wrfrun/model/wrf/exec_wrap.py +13 -12
- wrfrun/model/wrf/geodata.py +116 -100
- wrfrun/model/wrf/log.py +103 -0
- wrfrun/model/wrf/namelist.py +90 -73
- wrfrun/model/wrf/plot.py +102 -0
- wrfrun/model/wrf/scheme.py +108 -52
- wrfrun/model/wrf/utils.py +39 -25
- wrfrun/model/wrf/vtable.py +35 -3
- wrfrun/plot/__init__.py +20 -0
- wrfrun/plot/wps.py +90 -73
- wrfrun/res/__init__.py +103 -5
- wrfrun/res/config/config.template.toml +8 -0
- wrfrun/res/config/palm.template.toml +23 -0
- wrfrun/run.py +105 -77
- wrfrun/scheduler/__init__.py +1 -0
- wrfrun/scheduler/lsf.py +3 -2
- wrfrun/scheduler/pbs.py +3 -2
- wrfrun/scheduler/script.py +17 -5
- wrfrun/scheduler/slurm.py +3 -2
- wrfrun/scheduler/utils.py +14 -2
- wrfrun/utils.py +88 -199
- wrfrun/workspace/__init__.py +8 -5
- wrfrun/workspace/core.py +20 -12
- wrfrun/workspace/palm.py +137 -0
- wrfrun/workspace/wrf.py +16 -15
- wrfrun-0.3.0.dist-info/METADATA +240 -0
- wrfrun-0.3.0.dist-info/RECORD +78 -0
- wrfrun/core/config.py +0 -923
- wrfrun/model/base.py +0 -14
- wrfrun-0.2.0.dist-info/METADATA +0 -68
- wrfrun-0.2.0.dist-info/RECORD +0 -62
- {wrfrun-0.2.0.dist-info → wrfrun-0.3.0.dist-info}/WHEEL +0 -0
- {wrfrun-0.2.0.dist-info → wrfrun-0.3.0.dist-info}/entry_points.txt +0 -0
wrfrun/model/wrf/core.py
CHANGED
|
@@ -24,22 +24,31 @@ from os.path import abspath, basename, exists
|
|
|
24
24
|
from shutil import copyfile, move, rmtree
|
|
25
25
|
from typing import Optional, Union
|
|
26
26
|
|
|
27
|
-
from wrfrun.core import ExecutableBase, FileConfigDict, InputFileError, NamelistIDError
|
|
28
|
-
from wrfrun.
|
|
27
|
+
from wrfrun.core import WRFRUN, ExecutableBase, ExecutableDB, FileConfigDict, InputFileError, NamelistIDError
|
|
28
|
+
from wrfrun.log import logger
|
|
29
29
|
from wrfrun.workspace.wrf import get_wrf_workspace_path
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
|
|
31
|
+
from ..constants import NamelistName
|
|
32
|
+
from .namelist import (
|
|
33
|
+
get_ungrib_out_dir_path,
|
|
34
|
+
get_ungrib_out_prefix,
|
|
35
|
+
prepare_dfi_namelist,
|
|
36
|
+
prepare_wps_namelist,
|
|
37
|
+
prepare_wrf_namelist,
|
|
38
|
+
prepare_wrfda_namelist,
|
|
39
|
+
set_metgrid_fg_names,
|
|
40
|
+
set_ungrib_out_prefix,
|
|
41
|
+
)
|
|
32
42
|
from .utils import process_after_ndown, reconcile_namelist_metgrid
|
|
33
43
|
from .vtable import VtableFiles
|
|
34
|
-
from ..base import NamelistName
|
|
35
44
|
|
|
36
45
|
|
|
37
46
|
def _check_and_prepare_namelist():
|
|
38
47
|
"""
|
|
39
|
-
This function check if namelists needed by WPS/WRF have been loaded
|
|
40
|
-
|
|
48
|
+
This function check if namelists needed by WPS/WRF have been loaded.
|
|
49
|
+
If not, call :doc:`preparation function </api/model.wrf.namelist>` to load them.
|
|
41
50
|
"""
|
|
42
|
-
wrfrun_config =
|
|
51
|
+
wrfrun_config = WRFRUN.config
|
|
43
52
|
if not wrfrun_config.check_namelist("wps"):
|
|
44
53
|
prepare_wps_namelist()
|
|
45
54
|
|
|
@@ -65,7 +74,7 @@ class GeoGrid(ExecutableBase):
|
|
|
65
74
|
:type core_num: int
|
|
66
75
|
"""
|
|
67
76
|
if isinstance(core_num, int) and core_num <= 0:
|
|
68
|
-
logger.warning(
|
|
77
|
+
logger.warning("`core_num` should be greater than 0")
|
|
69
78
|
core_num = None
|
|
70
79
|
|
|
71
80
|
if core_num is None:
|
|
@@ -78,7 +87,14 @@ class GeoGrid(ExecutableBase):
|
|
|
78
87
|
mpi_cmd = "mpirun"
|
|
79
88
|
mpi_core_num = core_num
|
|
80
89
|
|
|
81
|
-
super().__init__(
|
|
90
|
+
super().__init__(
|
|
91
|
+
name="geogrid",
|
|
92
|
+
cmd="./geogrid.exe",
|
|
93
|
+
work_path=get_wrf_workspace_path("wps"),
|
|
94
|
+
mpi_use=mpi_use,
|
|
95
|
+
mpi_cmd=mpi_cmd,
|
|
96
|
+
mpi_core_num=mpi_core_num,
|
|
97
|
+
)
|
|
82
98
|
|
|
83
99
|
self.geogrid_tbl_file = geogrid_tbl_file
|
|
84
100
|
|
|
@@ -91,48 +107,46 @@ class GeoGrid(ExecutableBase):
|
|
|
91
107
|
1. Namelist settings.
|
|
92
108
|
2. Path of custom TBL file.
|
|
93
109
|
"""
|
|
94
|
-
self.custom_config.update(
|
|
95
|
-
{
|
|
96
|
-
"namelist": WRFRUNConfig.get_namelist("wps"),
|
|
97
|
-
"geogrid_tbl_file": self.geogrid_tbl_file
|
|
98
|
-
}
|
|
99
|
-
)
|
|
110
|
+
self.custom_config.update({"namelist": WRFRUN.config.get_namelist("wps"), "geogrid_tbl_file": self.geogrid_tbl_file})
|
|
100
111
|
|
|
101
112
|
def load_custom_config(self):
|
|
102
113
|
"""
|
|
103
114
|
Load custom configs.
|
|
104
115
|
"""
|
|
105
|
-
|
|
116
|
+
WRFRUN.config.update_namelist(self.custom_config["namelist"], "wps")
|
|
106
117
|
self.geogrid_tbl_file = self.custom_config["geogrid_tbl_file"]
|
|
107
118
|
|
|
108
119
|
def before_exec(self):
|
|
109
|
-
|
|
110
|
-
|
|
120
|
+
WRFRUN.config.check_wrfrun_context(True)
|
|
121
|
+
WRFRUN.config.WRFRUN_WORK_STATUS = "geogrid"
|
|
111
122
|
|
|
112
|
-
if not
|
|
123
|
+
if not WRFRUN.config.IS_IN_REPLAY:
|
|
113
124
|
if self.geogrid_tbl_file is not None:
|
|
114
125
|
tbl_file: FileConfigDict = {
|
|
115
|
-
"file_path": self.geogrid_tbl_file,
|
|
116
|
-
"
|
|
126
|
+
"file_path": self.geogrid_tbl_file,
|
|
127
|
+
"save_path": f"{get_wrf_workspace_path('wps')}/geogrid",
|
|
128
|
+
"save_name": "GEOGRID.TBL",
|
|
129
|
+
"is_data": False,
|
|
130
|
+
"is_output": False,
|
|
117
131
|
}
|
|
118
132
|
self.add_input_files(tbl_file)
|
|
119
133
|
|
|
120
134
|
super().before_exec()
|
|
121
135
|
|
|
122
|
-
|
|
136
|
+
WRFRUN.config.write_namelist(f"{get_wrf_workspace_path('wps')}/{NamelistName.WPS}", "wps")
|
|
123
137
|
|
|
124
138
|
# print debug logs
|
|
125
139
|
logger.debug("Namelist settings of 'geogrid':")
|
|
126
|
-
logger.debug(
|
|
140
|
+
logger.debug(WRFRUN.config.get_namelist("wps"))
|
|
127
141
|
|
|
128
142
|
def after_exec(self):
|
|
129
|
-
if not
|
|
143
|
+
if not WRFRUN.config.IS_IN_REPLAY:
|
|
130
144
|
self.add_output_files(save_path=self._log_save_path, startswith="geogrid.log", outputs=NamelistName.WPS)
|
|
131
145
|
self.add_output_files(save_path=self._output_save_path, startswith="geo_em")
|
|
132
146
|
|
|
133
147
|
super().after_exec()
|
|
134
148
|
|
|
135
|
-
logger.info(f"All geogrid output files have been copied to {
|
|
149
|
+
logger.info(f"All geogrid output files have been copied to {WRFRUN.config.parse_resource_uri(self._output_save_path)}")
|
|
136
150
|
|
|
137
151
|
|
|
138
152
|
class LinkGrib(ExecutableBase):
|
|
@@ -149,7 +163,11 @@ class LinkGrib(ExecutableBase):
|
|
|
149
163
|
"""
|
|
150
164
|
self._link_grib_input_path = "./input_grib_data_dir"
|
|
151
165
|
|
|
152
|
-
super().__init__(
|
|
166
|
+
super().__init__(
|
|
167
|
+
name="link_grib",
|
|
168
|
+
cmd=["./link_grib.csh", f"{self._link_grib_input_path}/*", "."],
|
|
169
|
+
work_path=get_wrf_workspace_path("wps"),
|
|
170
|
+
)
|
|
153
171
|
self.grib_dir_path = grib_dir_path
|
|
154
172
|
|
|
155
173
|
def generate_custom_config(self):
|
|
@@ -161,8 +179,7 @@ class LinkGrib(ExecutableBase):
|
|
|
161
179
|
self.class_config["class_args"] = (self.grib_dir_path,)
|
|
162
180
|
|
|
163
181
|
def before_exec(self):
|
|
164
|
-
if not
|
|
165
|
-
|
|
182
|
+
if not WRFRUN.config.IS_IN_REPLAY:
|
|
166
183
|
logger.debug(f"Input data are: {self.grib_dir_path}")
|
|
167
184
|
_grib_dir_path = abspath(self.grib_dir_path)
|
|
168
185
|
|
|
@@ -171,7 +188,7 @@ class LinkGrib(ExecutableBase):
|
|
|
171
188
|
raise FileNotFoundError(f"GRIB file directory not found: {_grib_dir_path}")
|
|
172
189
|
|
|
173
190
|
save_path = f"{get_wrf_workspace_path('wps')}/{self._link_grib_input_path}"
|
|
174
|
-
save_path =
|
|
191
|
+
save_path = WRFRUN.config.parse_resource_uri(save_path)
|
|
175
192
|
if exists(save_path):
|
|
176
193
|
rmtree(save_path)
|
|
177
194
|
|
|
@@ -179,7 +196,9 @@ class LinkGrib(ExecutableBase):
|
|
|
179
196
|
_file_config: FileConfigDict = {
|
|
180
197
|
"file_path": f"{_grib_dir_path}/{_file}",
|
|
181
198
|
"save_path": f"{get_wrf_workspace_path('wps')}/{self._link_grib_input_path}",
|
|
182
|
-
"save_name": _file,
|
|
199
|
+
"save_name": _file,
|
|
200
|
+
"is_data": True,
|
|
201
|
+
"is_output": False,
|
|
183
202
|
}
|
|
184
203
|
self.add_input_files(_file_config)
|
|
185
204
|
|
|
@@ -202,7 +221,7 @@ class UnGrib(ExecutableBase):
|
|
|
202
221
|
Defaults to ``input_data_path`` set in user's config file.
|
|
203
222
|
:type input_data_path: str
|
|
204
223
|
"""
|
|
205
|
-
super().__init__(name="ungrib", cmd="./ungrib.exe", work_path=get_wrf_workspace_path(
|
|
224
|
+
super().__init__(name="ungrib", cmd="./ungrib.exe", work_path=get_wrf_workspace_path("wps"))
|
|
206
225
|
|
|
207
226
|
self.vtable_file = vtable_file
|
|
208
227
|
self.input_data_path = input_data_path
|
|
@@ -214,7 +233,7 @@ class UnGrib(ExecutableBase):
|
|
|
214
233
|
Call :class:`LinkGrib` if needed.
|
|
215
234
|
"""
|
|
216
235
|
if self.input_data_path is None:
|
|
217
|
-
self.input_data_path =
|
|
236
|
+
self.input_data_path = WRFRUN.config.get_input_data_path()
|
|
218
237
|
|
|
219
238
|
LinkGrib(self.input_data_path)()
|
|
220
239
|
|
|
@@ -239,53 +258,50 @@ class UnGrib(ExecutableBase):
|
|
|
239
258
|
1. Namelist settings.
|
|
240
259
|
2. Path of used VTable file.
|
|
241
260
|
"""
|
|
242
|
-
self.custom_config.update(
|
|
243
|
-
{
|
|
244
|
-
"namelist": WRFRUNConfig.get_namelist("wps"),
|
|
245
|
-
"vtable_file": self.vtable_file
|
|
246
|
-
}
|
|
247
|
-
)
|
|
261
|
+
self.custom_config.update({"namelist": WRFRUN.config.get_namelist("wps"), "vtable_file": self.vtable_file})
|
|
248
262
|
|
|
249
263
|
def load_custom_config(self):
|
|
250
264
|
"""
|
|
251
265
|
Load custom configs.
|
|
252
266
|
"""
|
|
253
267
|
self.vtable_file = self.custom_config["vtable_file"]
|
|
254
|
-
|
|
268
|
+
WRFRUN.config.update_namelist(self.custom_config["namelist"], "wps")
|
|
255
269
|
|
|
256
270
|
def before_exec(self):
|
|
257
|
-
|
|
258
|
-
|
|
271
|
+
WRFRUN.config.check_wrfrun_context(True)
|
|
272
|
+
WRFRUN.config.WRFRUN_WORK_STATUS = "ungrib"
|
|
259
273
|
|
|
260
|
-
if not
|
|
274
|
+
if not WRFRUN.config.IS_IN_REPLAY:
|
|
261
275
|
if self.vtable_file is None:
|
|
262
276
|
self.vtable_file = VtableFiles.ERA_PL
|
|
263
277
|
|
|
264
278
|
_file_config: FileConfigDict = {
|
|
265
279
|
"file_path": self.vtable_file,
|
|
266
|
-
"save_path": get_wrf_workspace_path(
|
|
280
|
+
"save_path": get_wrf_workspace_path("wps"),
|
|
267
281
|
"save_name": "Vtable",
|
|
268
282
|
"is_data": False,
|
|
269
|
-
"is_output": False
|
|
283
|
+
"is_output": False,
|
|
270
284
|
}
|
|
271
285
|
self.add_input_files(_file_config)
|
|
272
286
|
|
|
273
287
|
super().before_exec()
|
|
274
288
|
|
|
275
|
-
|
|
289
|
+
WRFRUN.config.write_namelist(f"{get_wrf_workspace_path('wps')}/{NamelistName.WPS}", "wps")
|
|
276
290
|
|
|
277
291
|
# print debug logs
|
|
278
292
|
logger.debug("Namelist settings of 'ungrib':")
|
|
279
|
-
logger.debug(
|
|
293
|
+
logger.debug(WRFRUN.config.get_namelist("wps"))
|
|
280
294
|
|
|
281
295
|
def after_exec(self):
|
|
282
|
-
if not
|
|
283
|
-
self.add_output_files(
|
|
296
|
+
if not WRFRUN.config.IS_IN_REPLAY:
|
|
297
|
+
self.add_output_files(
|
|
298
|
+
output_dir=get_ungrib_out_dir_path(), save_path=self._output_save_path, startswith=get_ungrib_out_prefix()
|
|
299
|
+
)
|
|
284
300
|
self.add_output_files(save_path=self._log_save_path, outputs=["ungrib.log", "namelist.wps"])
|
|
285
301
|
|
|
286
302
|
super().after_exec()
|
|
287
303
|
|
|
288
|
-
logger.info(f"All ungrib output files have been copied to {
|
|
304
|
+
logger.info(f"All ungrib output files have been copied to {WRFRUN.config.parse_resource_uri(self._output_save_path)}")
|
|
289
305
|
|
|
290
306
|
def __call__(self):
|
|
291
307
|
self.call_link_grib()
|
|
@@ -298,7 +314,9 @@ class MetGrid(ExecutableBase):
|
|
|
298
314
|
``Executable`` of "metgrid.exe".
|
|
299
315
|
"""
|
|
300
316
|
|
|
301
|
-
def __init__(
|
|
317
|
+
def __init__(
|
|
318
|
+
self, geogrid_data_path: Optional[str] = None, ungrib_data_path: Optional[str] = None, core_num: Optional[int] = None
|
|
319
|
+
):
|
|
302
320
|
"""
|
|
303
321
|
``Executable`` of "metgrid.exe".
|
|
304
322
|
|
|
@@ -312,7 +330,7 @@ class MetGrid(ExecutableBase):
|
|
|
312
330
|
:type core_num: int
|
|
313
331
|
"""
|
|
314
332
|
if isinstance(core_num, int) and core_num <= 0:
|
|
315
|
-
logger.warning(
|
|
333
|
+
logger.warning("`core_num` should be greater than 0")
|
|
316
334
|
core_num = None
|
|
317
335
|
|
|
318
336
|
if core_num is None:
|
|
@@ -325,7 +343,14 @@ class MetGrid(ExecutableBase):
|
|
|
325
343
|
mpi_cmd = "mpirun"
|
|
326
344
|
mpi_core_num = core_num
|
|
327
345
|
|
|
328
|
-
super().__init__(
|
|
346
|
+
super().__init__(
|
|
347
|
+
name="metgrid",
|
|
348
|
+
cmd="./metgrid.exe",
|
|
349
|
+
work_path=get_wrf_workspace_path("wps"),
|
|
350
|
+
mpi_use=mpi_use,
|
|
351
|
+
mpi_cmd=mpi_cmd,
|
|
352
|
+
mpi_core_num=mpi_core_num,
|
|
353
|
+
)
|
|
329
354
|
|
|
330
355
|
self.geogrid_data_path = geogrid_data_path
|
|
331
356
|
self.ungrib_data_path = ungrib_data_path
|
|
@@ -341,7 +366,9 @@ class MetGrid(ExecutableBase):
|
|
|
341
366
|
:rtype: MetGrid
|
|
342
367
|
"""
|
|
343
368
|
if isinstance(fg_names, str):
|
|
344
|
-
fg_names = [
|
|
369
|
+
fg_names = [
|
|
370
|
+
fg_names,
|
|
371
|
+
]
|
|
345
372
|
fg_names = [basename(x) for x in fg_names]
|
|
346
373
|
set_metgrid_fg_names(fg_names)
|
|
347
374
|
return self
|
|
@@ -358,7 +385,7 @@ class MetGrid(ExecutableBase):
|
|
|
358
385
|
{
|
|
359
386
|
"geogrid_data_path": self.geogrid_data_path,
|
|
360
387
|
"ungrib_data_path": self.ungrib_data_path,
|
|
361
|
-
"namelist":
|
|
388
|
+
"namelist": WRFRUN.config.get_namelist("wps"),
|
|
362
389
|
}
|
|
363
390
|
)
|
|
364
391
|
|
|
@@ -368,50 +395,56 @@ class MetGrid(ExecutableBase):
|
|
|
368
395
|
"""
|
|
369
396
|
self.geogrid_data_path = self.custom_config["geogrid_data_path"]
|
|
370
397
|
self.ungrib_data_path = self.custom_config["ungrib_data_path"]
|
|
371
|
-
|
|
398
|
+
WRFRUN.config.update_namelist(self.custom_config["namelist"], "wps")
|
|
372
399
|
|
|
373
400
|
def before_exec(self):
|
|
374
|
-
|
|
375
|
-
|
|
401
|
+
WRFRUN.config.check_wrfrun_context(True)
|
|
402
|
+
WRFRUN.config.WRFRUN_WORK_STATUS = "metgrid"
|
|
376
403
|
|
|
377
|
-
if not
|
|
404
|
+
if not WRFRUN.config.IS_IN_REPLAY and not WRFRUN.config.FAKE_SIMULATION_MODE:
|
|
378
405
|
# check input of metgrid.exe
|
|
379
406
|
# try to search input files in the output path if workspace is clear.
|
|
380
|
-
file_list = listdir(
|
|
407
|
+
file_list = listdir(WRFRUN.config.parse_resource_uri(get_wrf_workspace_path("wps")))
|
|
381
408
|
|
|
382
409
|
if "geo_em.d01.nc" not in file_list:
|
|
383
|
-
|
|
384
410
|
if self.geogrid_data_path is None:
|
|
385
|
-
self.geogrid_data_path = f"{
|
|
386
|
-
geogrid_data_path =
|
|
411
|
+
self.geogrid_data_path = f"{WRFRUN.config.WRFRUN_OUTPUT_PATH}/geogrid"
|
|
412
|
+
geogrid_data_path = WRFRUN.config.parse_resource_uri(self.geogrid_data_path)
|
|
387
413
|
|
|
388
414
|
if not exists(geogrid_data_path) or "geo_em.d01.nc" not in listdir(geogrid_data_path):
|
|
389
|
-
logger.error(
|
|
390
|
-
|
|
415
|
+
logger.error(
|
|
416
|
+
"Can't find geogrid outputs in WPS_WORK_PATH and your outputs directory, which is essential to run metgrid"
|
|
417
|
+
)
|
|
418
|
+
raise FileNotFoundError(
|
|
419
|
+
"Can't find geogrid outputs in WPS_WORK_PATH and your outputs directory, which is essential to run metgrid"
|
|
420
|
+
)
|
|
391
421
|
|
|
392
422
|
else:
|
|
393
423
|
geogrid_file_list = [x for x in listdir(geogrid_data_path) if x.startswith("geo_em.d")]
|
|
394
424
|
for _file in geogrid_file_list:
|
|
395
425
|
_file_config = {
|
|
396
426
|
"file_path": f"{self.geogrid_data_path}/{_file}",
|
|
397
|
-
"save_path": get_wrf_workspace_path(
|
|
427
|
+
"save_path": get_wrf_workspace_path("wps"),
|
|
398
428
|
"save_name": _file,
|
|
399
429
|
"is_data": True,
|
|
400
|
-
"is_output": True
|
|
430
|
+
"is_output": True,
|
|
401
431
|
}
|
|
402
432
|
self.add_input_files(_file_config)
|
|
403
433
|
|
|
404
|
-
ungrib_output_dir =
|
|
434
|
+
ungrib_output_dir = WRFRUN.config.parse_resource_uri(get_ungrib_out_dir_path())
|
|
405
435
|
if basename(ungrib_output_dir) not in file_list or len(listdir(ungrib_output_dir)) == 0:
|
|
406
|
-
|
|
407
436
|
if self.ungrib_data_path is None:
|
|
408
|
-
self.ungrib_data_path = f"{
|
|
437
|
+
self.ungrib_data_path = f"{WRFRUN.config.WRFRUN_OUTPUT_PATH}/ungrib"
|
|
409
438
|
|
|
410
|
-
ungrib_data_path =
|
|
439
|
+
ungrib_data_path = WRFRUN.config.parse_resource_uri(self.ungrib_data_path)
|
|
411
440
|
|
|
412
441
|
if not exists(ungrib_data_path) or len(listdir(ungrib_data_path)) == 0:
|
|
413
|
-
logger.error(
|
|
414
|
-
|
|
442
|
+
logger.error(
|
|
443
|
+
"Can't find ungrib outputs in WPS_WORK_PATH and your outputs directory, which is essential to run metgrid"
|
|
444
|
+
)
|
|
445
|
+
raise FileNotFoundError(
|
|
446
|
+
"Can't find ungrib outputs in WPS_WORK_PATH and your outputs directory, which is essential to run metgrid"
|
|
447
|
+
)
|
|
415
448
|
|
|
416
449
|
else:
|
|
417
450
|
ungrib_file_list = [x for x in listdir(ungrib_data_path)]
|
|
@@ -421,26 +454,26 @@ class MetGrid(ExecutableBase):
|
|
|
421
454
|
"save_path": get_ungrib_out_dir_path(),
|
|
422
455
|
"save_name": _file,
|
|
423
456
|
"is_data": True,
|
|
424
|
-
"is_output": True
|
|
457
|
+
"is_output": True,
|
|
425
458
|
}
|
|
426
459
|
self.add_input_files(_file_config)
|
|
427
460
|
|
|
428
461
|
super().before_exec()
|
|
429
462
|
|
|
430
|
-
|
|
463
|
+
WRFRUN.config.write_namelist(f"{get_wrf_workspace_path('wps')}/{NamelistName.WPS}", "wps")
|
|
431
464
|
|
|
432
465
|
# print debug logs
|
|
433
466
|
logger.debug("Namelist settings of 'metgrid':")
|
|
434
|
-
logger.debug(
|
|
467
|
+
logger.debug(WRFRUN.config.get_namelist("wps"))
|
|
435
468
|
|
|
436
469
|
def after_exec(self):
|
|
437
|
-
if not
|
|
470
|
+
if not WRFRUN.config.IS_IN_REPLAY:
|
|
438
471
|
self.add_output_files(save_path=self._log_save_path, startswith="metgrid.log", outputs="namelist.wps")
|
|
439
472
|
self.add_output_files(save_path=self._output_save_path, startswith="met_em")
|
|
440
473
|
|
|
441
474
|
super().after_exec()
|
|
442
475
|
|
|
443
|
-
logger.info(f"All metgrid output files have been copied to {
|
|
476
|
+
logger.info(f"All metgrid output files have been copied to {WRFRUN.config.parse_resource_uri(self._output_save_path)}")
|
|
444
477
|
|
|
445
478
|
|
|
446
479
|
class Real(ExecutableBase):
|
|
@@ -459,7 +492,7 @@ class Real(ExecutableBase):
|
|
|
459
492
|
:type core_num: int
|
|
460
493
|
"""
|
|
461
494
|
if isinstance(core_num, int) and core_num <= 0:
|
|
462
|
-
logger.warning(
|
|
495
|
+
logger.warning("`core_num` should be greater than 0")
|
|
463
496
|
core_num = None
|
|
464
497
|
|
|
465
498
|
if core_num is None:
|
|
@@ -474,7 +507,14 @@ class Real(ExecutableBase):
|
|
|
474
507
|
|
|
475
508
|
_check_and_prepare_namelist()
|
|
476
509
|
|
|
477
|
-
super().__init__(
|
|
510
|
+
super().__init__(
|
|
511
|
+
name="real",
|
|
512
|
+
cmd="./real.exe",
|
|
513
|
+
work_path=get_wrf_workspace_path("wrf"),
|
|
514
|
+
mpi_use=mpi_use,
|
|
515
|
+
mpi_cmd=mpi_cmd,
|
|
516
|
+
mpi_core_num=mpi_core_num,
|
|
517
|
+
)
|
|
478
518
|
|
|
479
519
|
self.metgrid_data_path = metgrid_data_path
|
|
480
520
|
|
|
@@ -486,58 +526,53 @@ class Real(ExecutableBase):
|
|
|
486
526
|
2. Directory path of :class:`MetGrid` outputs.
|
|
487
527
|
"""
|
|
488
528
|
self.custom_config["metgrid_data_path"] = self.metgrid_data_path
|
|
489
|
-
self.custom_config.update(
|
|
490
|
-
{
|
|
491
|
-
"namelist": WRFRUNConfig.get_namelist("wrf"),
|
|
492
|
-
"metgrid_data_path": self.metgrid_data_path
|
|
493
|
-
}
|
|
494
|
-
)
|
|
529
|
+
self.custom_config.update({"namelist": WRFRUN.config.get_namelist("wrf"), "metgrid_data_path": self.metgrid_data_path})
|
|
495
530
|
|
|
496
531
|
def load_custom_config(self):
|
|
497
532
|
"""
|
|
498
533
|
Load custom configs.
|
|
499
534
|
"""
|
|
500
535
|
self.metgrid_data_path = self.custom_config["metgrid_data_path"]
|
|
501
|
-
|
|
536
|
+
WRFRUN.config.update_namelist(self.custom_config["namelist"], "wrf")
|
|
502
537
|
|
|
503
538
|
def before_exec(self):
|
|
504
|
-
|
|
505
|
-
|
|
539
|
+
WRFRUN.config.check_wrfrun_context(True)
|
|
540
|
+
WRFRUN.config.WRFRUN_WORK_STATUS = "real"
|
|
506
541
|
|
|
507
|
-
if not
|
|
542
|
+
if not WRFRUN.config.IS_IN_REPLAY and not WRFRUN.config.FAKE_SIMULATION_MODE:
|
|
508
543
|
if self.metgrid_data_path is None:
|
|
509
|
-
self.metgrid_data_path = f"{
|
|
544
|
+
self.metgrid_data_path = f"{WRFRUN.config.WRFRUN_OUTPUT_PATH}/metgrid"
|
|
510
545
|
|
|
511
|
-
metgrid_data_path =
|
|
546
|
+
metgrid_data_path = WRFRUN.config.parse_resource_uri(self.metgrid_data_path)
|
|
512
547
|
reconcile_namelist_metgrid(metgrid_data_path)
|
|
513
548
|
|
|
514
549
|
file_list = [x for x in listdir(metgrid_data_path) if x.startswith("met_em")]
|
|
515
550
|
for _file in file_list:
|
|
516
551
|
_file_config: FileConfigDict = {
|
|
517
552
|
"file_path": f"{self.metgrid_data_path}/{_file}",
|
|
518
|
-
"save_path": get_wrf_workspace_path(
|
|
553
|
+
"save_path": get_wrf_workspace_path("wrf"),
|
|
519
554
|
"save_name": _file,
|
|
520
555
|
"is_data": True,
|
|
521
|
-
"is_output": True
|
|
556
|
+
"is_output": True,
|
|
522
557
|
}
|
|
523
558
|
self.add_input_files(_file_config)
|
|
524
559
|
|
|
525
560
|
super().before_exec()
|
|
526
561
|
|
|
527
|
-
|
|
562
|
+
WRFRUN.config.write_namelist(f"{get_wrf_workspace_path('wrf')}/{NamelistName.WRF}", "wrf")
|
|
528
563
|
|
|
529
564
|
# print debug logs
|
|
530
565
|
logger.debug("Namelist settings of 'real':")
|
|
531
|
-
logger.debug(
|
|
566
|
+
logger.debug(WRFRUN.config.get_namelist("wrf"))
|
|
532
567
|
|
|
533
568
|
def after_exec(self):
|
|
534
|
-
if not
|
|
569
|
+
if not WRFRUN.config.IS_IN_REPLAY:
|
|
535
570
|
self.add_output_files(save_path=self._output_save_path, startswith=("wrfbdy", "wrfinput", "wrflow"))
|
|
536
571
|
self.add_output_files(save_path=self._log_save_path, startswith="rsl.", outputs="namelist.input")
|
|
537
572
|
|
|
538
573
|
super().after_exec()
|
|
539
574
|
|
|
540
|
-
logger.info(f"All real output files have been copied to {
|
|
575
|
+
logger.info(f"All real output files have been copied to {WRFRUN.config.parse_resource_uri(self._output_save_path)}")
|
|
541
576
|
|
|
542
577
|
|
|
543
578
|
class WRF(ExecutableBase):
|
|
@@ -545,7 +580,13 @@ class WRF(ExecutableBase):
|
|
|
545
580
|
``Executable`` of "wrf.exe".
|
|
546
581
|
"""
|
|
547
582
|
|
|
548
|
-
def __init__(
|
|
583
|
+
def __init__(
|
|
584
|
+
self,
|
|
585
|
+
input_file_dir_path: Optional[str] = None,
|
|
586
|
+
restart_file_dir_path: Optional[str] = None,
|
|
587
|
+
save_restarts=False,
|
|
588
|
+
core_num: Optional[int] = None,
|
|
589
|
+
):
|
|
549
590
|
"""
|
|
550
591
|
``Executable`` of "wrf.exe"
|
|
551
592
|
|
|
@@ -559,7 +600,7 @@ class WRF(ExecutableBase):
|
|
|
559
600
|
:type core_num: int
|
|
560
601
|
"""
|
|
561
602
|
if isinstance(core_num, int) and core_num <= 0:
|
|
562
|
-
logger.warning(
|
|
603
|
+
logger.warning("`core_num` should be greater than 0")
|
|
563
604
|
core_num = None
|
|
564
605
|
|
|
565
606
|
if core_num is None:
|
|
@@ -574,7 +615,14 @@ class WRF(ExecutableBase):
|
|
|
574
615
|
|
|
575
616
|
_check_and_prepare_namelist()
|
|
576
617
|
|
|
577
|
-
super().__init__(
|
|
618
|
+
super().__init__(
|
|
619
|
+
name="wrf",
|
|
620
|
+
cmd="./wrf.exe",
|
|
621
|
+
work_path=get_wrf_workspace_path("wrf"),
|
|
622
|
+
mpi_use=mpi_use,
|
|
623
|
+
mpi_cmd=mpi_cmd,
|
|
624
|
+
mpi_core_num=mpi_core_num,
|
|
625
|
+
)
|
|
578
626
|
|
|
579
627
|
self.input_file_dir_path = input_file_dir_path
|
|
580
628
|
self.restart_file_dir_path = restart_file_dir_path
|
|
@@ -592,7 +640,7 @@ class WRF(ExecutableBase):
|
|
|
592
640
|
{
|
|
593
641
|
"input_file_dir_path": self.input_file_dir_path,
|
|
594
642
|
"restart_file_dir_path": self.restart_file_dir_path,
|
|
595
|
-
"namelist":
|
|
643
|
+
"namelist": WRFRUN.config.get_namelist("wrf"),
|
|
596
644
|
}
|
|
597
645
|
)
|
|
598
646
|
|
|
@@ -602,30 +650,30 @@ class WRF(ExecutableBase):
|
|
|
602
650
|
"""
|
|
603
651
|
self.input_file_dir_path = self.custom_config["input_file_dir_path"]
|
|
604
652
|
self.restart_file_dir_path = self.custom_config["restart_file_dir_path"]
|
|
605
|
-
|
|
653
|
+
WRFRUN.config.update_namelist(self.custom_config["namelist"], "wrf")
|
|
606
654
|
|
|
607
655
|
def before_exec(self):
|
|
608
|
-
|
|
656
|
+
WRFRUN.config.check_wrfrun_context(True)
|
|
609
657
|
# help wrfrun to make sure the input file is from real or ndown.
|
|
610
|
-
last_work_status =
|
|
658
|
+
last_work_status = WRFRUN.config.WRFRUN_WORK_STATUS
|
|
611
659
|
if last_work_status not in ["real", "ndown"]:
|
|
612
660
|
last_work_status = ""
|
|
613
|
-
|
|
661
|
+
WRFRUN.config.WRFRUN_WORK_STATUS = "wrf"
|
|
614
662
|
|
|
615
|
-
if not
|
|
663
|
+
if not WRFRUN.config.IS_IN_REPLAY and not WRFRUN.config.FAKE_SIMULATION_MODE:
|
|
616
664
|
if self.input_file_dir_path is None:
|
|
617
665
|
if last_work_status == "":
|
|
618
666
|
# assume we already have outputs from real.exe.
|
|
619
|
-
self.input_file_dir_path = f"{
|
|
667
|
+
self.input_file_dir_path = f"{WRFRUN.config.WRFRUN_OUTPUT_PATH}/real"
|
|
620
668
|
is_output = False
|
|
621
669
|
else:
|
|
622
|
-
self.input_file_dir_path = f"{
|
|
670
|
+
self.input_file_dir_path = f"{WRFRUN.config.WRFRUN_OUTPUT_PATH}/{last_work_status}"
|
|
623
671
|
is_output = True
|
|
624
672
|
|
|
625
673
|
else:
|
|
626
674
|
is_output = False
|
|
627
675
|
|
|
628
|
-
input_file_dir_path =
|
|
676
|
+
input_file_dir_path = WRFRUN.config.parse_resource_uri(self.input_file_dir_path)
|
|
629
677
|
|
|
630
678
|
if exists(input_file_dir_path):
|
|
631
679
|
file_list = [x for x in listdir(input_file_dir_path) if x != "logs"]
|
|
@@ -633,19 +681,19 @@ class WRF(ExecutableBase):
|
|
|
633
681
|
for _file in file_list:
|
|
634
682
|
_file_config: FileConfigDict = {
|
|
635
683
|
"file_path": f"{self.input_file_dir_path}/{_file}",
|
|
636
|
-
"save_path": get_wrf_workspace_path(
|
|
684
|
+
"save_path": get_wrf_workspace_path("wrf"),
|
|
637
685
|
"save_name": _file,
|
|
638
686
|
"is_data": True,
|
|
639
|
-
"is_output": is_output
|
|
687
|
+
"is_output": is_output,
|
|
640
688
|
}
|
|
641
689
|
self.add_input_files(_file_config)
|
|
642
690
|
|
|
643
|
-
if
|
|
691
|
+
if WRFRUN.config.get_model_config("wrf")["restart_mode"]:
|
|
644
692
|
if self.restart_file_dir_path is None:
|
|
645
693
|
logger.error("You need to specify the restart file if you want to restart WRF.")
|
|
646
694
|
raise InputFileError("You need to specify the restart file if you want to restart WRF.")
|
|
647
695
|
|
|
648
|
-
restart_file_dir_path =
|
|
696
|
+
restart_file_dir_path = WRFRUN.config.parse_resource_uri(self.restart_file_dir_path)
|
|
649
697
|
|
|
650
698
|
if not exists(restart_file_dir_path):
|
|
651
699
|
logger.error(f"Restart files not found: {restart_file_dir_path}")
|
|
@@ -655,23 +703,23 @@ class WRF(ExecutableBase):
|
|
|
655
703
|
for _file in file_list:
|
|
656
704
|
_file_config: FileConfigDict = {
|
|
657
705
|
"file_path": f"{self.restart_file_dir_path}/{_file}",
|
|
658
|
-
"save_path": get_wrf_workspace_path(
|
|
706
|
+
"save_path": get_wrf_workspace_path("wrf"),
|
|
659
707
|
"save_name": _file,
|
|
660
708
|
"is_data": True,
|
|
661
|
-
"is_output": False
|
|
709
|
+
"is_output": False,
|
|
662
710
|
}
|
|
663
711
|
self.add_input_files(_file_config)
|
|
664
712
|
|
|
665
713
|
super().before_exec()
|
|
666
714
|
|
|
667
|
-
|
|
715
|
+
WRFRUN.config.write_namelist(f"{get_wrf_workspace_path('wrf')}/{NamelistName.WRF}", "wrf")
|
|
668
716
|
|
|
669
717
|
# print debug logs
|
|
670
718
|
logger.debug("Namelist settings of 'wrf':")
|
|
671
|
-
logger.debug(
|
|
719
|
+
logger.debug(WRFRUN.config.get_namelist("wrf"))
|
|
672
720
|
|
|
673
721
|
def after_exec(self):
|
|
674
|
-
if not
|
|
722
|
+
if not WRFRUN.config.IS_IN_REPLAY:
|
|
675
723
|
self.add_output_files(save_path=self._log_save_path, startswith="rsl.", outputs="namelist.input")
|
|
676
724
|
self.add_output_files(save_path=self._output_save_path, startswith="wrfout")
|
|
677
725
|
if self.save_restarts:
|
|
@@ -680,7 +728,7 @@ class WRF(ExecutableBase):
|
|
|
680
728
|
|
|
681
729
|
super().after_exec()
|
|
682
730
|
|
|
683
|
-
logger.info(f"All wrf output files have been copied to {
|
|
731
|
+
logger.info(f"All wrf output files have been copied to {WRFRUN.config.parse_resource_uri(self._output_save_path)}")
|
|
684
732
|
|
|
685
733
|
|
|
686
734
|
class DFI(ExecutableBase):
|
|
@@ -700,7 +748,7 @@ class DFI(ExecutableBase):
|
|
|
700
748
|
:type core_num: int
|
|
701
749
|
"""
|
|
702
750
|
if isinstance(core_num, int) and core_num <= 0:
|
|
703
|
-
logger.warning(
|
|
751
|
+
logger.warning("`core_num` should be greater than 0")
|
|
704
752
|
core_num = None
|
|
705
753
|
|
|
706
754
|
if core_num is None:
|
|
@@ -713,7 +761,14 @@ class DFI(ExecutableBase):
|
|
|
713
761
|
mpi_cmd = "mpirun"
|
|
714
762
|
mpi_core_num = core_num
|
|
715
763
|
|
|
716
|
-
super().__init__(
|
|
764
|
+
super().__init__(
|
|
765
|
+
name="dfi",
|
|
766
|
+
cmd="./wrf.exe",
|
|
767
|
+
work_path=get_wrf_workspace_path("wrf"),
|
|
768
|
+
mpi_use=mpi_use,
|
|
769
|
+
mpi_cmd=mpi_cmd,
|
|
770
|
+
mpi_core_num=mpi_core_num,
|
|
771
|
+
)
|
|
717
772
|
|
|
718
773
|
self.input_file_dir_path = input_file_dir_path
|
|
719
774
|
self.update_real_output = update_real_output
|
|
@@ -730,7 +785,7 @@ class DFI(ExecutableBase):
|
|
|
730
785
|
{
|
|
731
786
|
"input_file_dir_path": self.input_file_dir_path,
|
|
732
787
|
"update_real_output": self.update_real_output,
|
|
733
|
-
"namelist":
|
|
788
|
+
"namelist": WRFRUN.config.get_namelist("dfi"),
|
|
734
789
|
}
|
|
735
790
|
)
|
|
736
791
|
|
|
@@ -741,25 +796,25 @@ class DFI(ExecutableBase):
|
|
|
741
796
|
self.input_file_dir_path = self.custom_config["input_file_dir_path"]
|
|
742
797
|
self.update_real_output = self.custom_config["update_real_output"]
|
|
743
798
|
|
|
744
|
-
if not
|
|
799
|
+
if not WRFRUN.config.register_namelist_id("dfi"):
|
|
745
800
|
logger.error("Can't register namelist for DFI.")
|
|
746
801
|
raise NamelistIDError("Can't register namelist for DFI.")
|
|
747
|
-
|
|
802
|
+
WRFRUN.config.update_namelist(self.custom_config["namelist"], "dfi")
|
|
748
803
|
|
|
749
804
|
def before_exec(self):
|
|
750
|
-
|
|
751
|
-
|
|
805
|
+
WRFRUN.config.check_wrfrun_context(True)
|
|
806
|
+
WRFRUN.config.WRFRUN_WORK_STATUS = "dfi"
|
|
752
807
|
|
|
753
|
-
if not
|
|
808
|
+
if not WRFRUN.config.IS_IN_REPLAY and not WRFRUN.config.FAKE_SIMULATION_MODE:
|
|
754
809
|
# prepare config
|
|
755
810
|
if self.input_file_dir_path is None:
|
|
756
|
-
self.input_file_dir_path = f"{
|
|
811
|
+
self.input_file_dir_path = f"{WRFRUN.config.WRFRUN_OUTPUT_PATH}/real"
|
|
757
812
|
is_output = True
|
|
758
813
|
|
|
759
814
|
else:
|
|
760
815
|
is_output = False
|
|
761
816
|
|
|
762
|
-
input_file_dir_path =
|
|
817
|
+
input_file_dir_path = WRFRUN.config.parse_resource_uri(self.input_file_dir_path)
|
|
763
818
|
|
|
764
819
|
if exists(input_file_dir_path):
|
|
765
820
|
file_list = [x for x in listdir(input_file_dir_path) if x != "logs"]
|
|
@@ -767,36 +822,38 @@ class DFI(ExecutableBase):
|
|
|
767
822
|
for _file in file_list:
|
|
768
823
|
_file_config: FileConfigDict = {
|
|
769
824
|
"file_path": f"{self.input_file_dir_path}/{_file}",
|
|
770
|
-
"save_path": get_wrf_workspace_path(
|
|
825
|
+
"save_path": get_wrf_workspace_path("wrf"),
|
|
771
826
|
"save_name": _file,
|
|
772
827
|
"is_data": True,
|
|
773
|
-
"is_output": is_output
|
|
828
|
+
"is_output": is_output,
|
|
774
829
|
}
|
|
775
830
|
self.add_input_files(_file_config)
|
|
776
831
|
|
|
777
|
-
if not
|
|
832
|
+
if not WRFRUN.config.register_namelist_id("dfi"):
|
|
778
833
|
logger.error("Can't register namelist for DFI.")
|
|
779
834
|
raise NamelistIDError("Can't register namelist for DFI.")
|
|
780
835
|
|
|
781
836
|
prepare_dfi_namelist()
|
|
782
837
|
|
|
783
838
|
super().before_exec()
|
|
784
|
-
|
|
839
|
+
WRFRUN.config.write_namelist(f"{get_wrf_workspace_path('wrf')}/{NamelistName.WRF}", "dfi")
|
|
785
840
|
|
|
786
841
|
def after_exec(self):
|
|
787
|
-
if not
|
|
842
|
+
if not WRFRUN.config.IS_IN_REPLAY:
|
|
788
843
|
self.add_output_files(save_path=self._log_save_path, startswith="rsl.", outputs="namelist.input")
|
|
789
844
|
self.add_output_files(save_path=self._output_save_path, startswith="wrfinput_initialized_")
|
|
790
845
|
|
|
791
846
|
super().after_exec()
|
|
792
847
|
|
|
793
|
-
parsed_output_save_path =
|
|
794
|
-
if self.update_real_output and not
|
|
795
|
-
real_dir_path =
|
|
848
|
+
parsed_output_save_path = WRFRUN.config.parse_resource_uri(self._output_save_path)
|
|
849
|
+
if self.update_real_output and not WRFRUN.config.FAKE_SIMULATION_MODE:
|
|
850
|
+
real_dir_path = WRFRUN.config.parse_resource_uri(self.input_file_dir_path)
|
|
796
851
|
|
|
797
852
|
move(f"{real_dir_path}/wrfinput_d01", f"{real_dir_path}/wrfinput_d01_before_dfi")
|
|
798
853
|
copyfile(f"{parsed_output_save_path}/wrfinput_initialized_d01", f"{real_dir_path}/wrfinput_d01")
|
|
799
|
-
logger.info(
|
|
854
|
+
logger.info(
|
|
855
|
+
"Replace real.exe output 'wrfinput_d01' with outputs, old file has been renamed as 'wrfinput_d01_before_dfi'"
|
|
856
|
+
)
|
|
800
857
|
|
|
801
858
|
logger.info(f"All DFI output files have been copied to {parsed_output_save_path}")
|
|
802
859
|
|
|
@@ -806,7 +863,13 @@ class NDown(ExecutableBase):
|
|
|
806
863
|
``Executable`` of "ndown.exe".
|
|
807
864
|
"""
|
|
808
865
|
|
|
809
|
-
def __init__(
|
|
866
|
+
def __init__(
|
|
867
|
+
self,
|
|
868
|
+
wrfout_file_path: str,
|
|
869
|
+
real_output_dir_path: Optional[str] = None,
|
|
870
|
+
update_namelist=True,
|
|
871
|
+
core_num: Optional[int] = None,
|
|
872
|
+
):
|
|
810
873
|
"""
|
|
811
874
|
``Executable`` of "ndown.exe".
|
|
812
875
|
|
|
@@ -820,7 +883,7 @@ class NDown(ExecutableBase):
|
|
|
820
883
|
:type core_num: int
|
|
821
884
|
"""
|
|
822
885
|
if isinstance(core_num, int) and core_num <= 0:
|
|
823
|
-
logger.warning(
|
|
886
|
+
logger.warning("`core_num` should be greater than 0")
|
|
824
887
|
core_num = None
|
|
825
888
|
|
|
826
889
|
if core_num is None:
|
|
@@ -835,7 +898,14 @@ class NDown(ExecutableBase):
|
|
|
835
898
|
|
|
836
899
|
_check_and_prepare_namelist()
|
|
837
900
|
|
|
838
|
-
super().__init__(
|
|
901
|
+
super().__init__(
|
|
902
|
+
name="ndown",
|
|
903
|
+
cmd="./ndown.exe",
|
|
904
|
+
work_path=get_wrf_workspace_path("wrf"),
|
|
905
|
+
mpi_use=mpi_use,
|
|
906
|
+
mpi_cmd=mpi_cmd,
|
|
907
|
+
mpi_core_num=mpi_core_num,
|
|
908
|
+
)
|
|
839
909
|
|
|
840
910
|
self.wrfout_file_path = wrfout_file_path
|
|
841
911
|
self.real_output_dir_path = real_output_dir_path
|
|
@@ -855,7 +925,7 @@ class NDown(ExecutableBase):
|
|
|
855
925
|
{
|
|
856
926
|
"real_output_dir_path": self.real_output_dir_path,
|
|
857
927
|
"update_namelist": self.update_namelist,
|
|
858
|
-
"namelist":
|
|
928
|
+
"namelist": WRFRUN.config.get_namelist("wrf"),
|
|
859
929
|
}
|
|
860
930
|
)
|
|
861
931
|
|
|
@@ -865,18 +935,18 @@ class NDown(ExecutableBase):
|
|
|
865
935
|
"""
|
|
866
936
|
self.real_output_dir_path = self.custom_config["real_output_dir_path"]
|
|
867
937
|
self.update_namelist = self.custom_config["update_namelist"]
|
|
868
|
-
|
|
938
|
+
WRFRUN.config.update_namelist(self.custom_config["namelist"], "wrf")
|
|
869
939
|
|
|
870
940
|
def before_exec(self):
|
|
871
|
-
|
|
872
|
-
|
|
941
|
+
WRFRUN.config.check_wrfrun_context(True)
|
|
942
|
+
WRFRUN.config.WRFRUN_WORK_STATUS = "ndown"
|
|
873
943
|
|
|
874
944
|
# we need to make sure time_control.io_form_auxinput2 is 2.
|
|
875
945
|
# which means the format of input stream 2 is NetCDF.
|
|
876
|
-
|
|
946
|
+
WRFRUN.config.update_namelist({"time_control": {"io_form_auxinput2": 2}}, "wrf")
|
|
877
947
|
|
|
878
948
|
if self.real_output_dir_path is None:
|
|
879
|
-
self.real_output_dir_path = f"{
|
|
949
|
+
self.real_output_dir_path = f"{WRFRUN.config.WRFRUN_OUTPUT_PATH}/real"
|
|
880
950
|
is_output = True
|
|
881
951
|
|
|
882
952
|
else:
|
|
@@ -884,35 +954,39 @@ class NDown(ExecutableBase):
|
|
|
884
954
|
|
|
885
955
|
wrfndi_file_config: FileConfigDict = {
|
|
886
956
|
"file_path": f"{self.real_output_dir_path}/wrfinput_d02",
|
|
887
|
-
"save_path": get_wrf_workspace_path(
|
|
957
|
+
"save_path": get_wrf_workspace_path("wrf"),
|
|
888
958
|
"save_name": "wrfndi_d02",
|
|
889
959
|
"is_data": True,
|
|
890
|
-
"is_output": is_output
|
|
960
|
+
"is_output": is_output,
|
|
891
961
|
}
|
|
892
962
|
wrfout_file_config: FileConfigDict = {
|
|
893
963
|
"file_path": self.wrfout_file_path,
|
|
894
|
-
"save_path": get_wrf_workspace_path(
|
|
964
|
+
"save_path": get_wrf_workspace_path("wrf"),
|
|
895
965
|
"save_name": "wrfout_d01",
|
|
896
966
|
"is_data": True,
|
|
897
|
-
"is_output": False
|
|
967
|
+
"is_output": False,
|
|
898
968
|
}
|
|
899
969
|
|
|
900
970
|
self.add_input_files([wrfndi_file_config, wrfout_file_config])
|
|
901
971
|
|
|
902
972
|
super().before_exec()
|
|
903
973
|
|
|
904
|
-
|
|
974
|
+
WRFRUN.config.write_namelist(f"{get_wrf_workspace_path('wrf')}/{NamelistName.WRF}", "wrf")
|
|
905
975
|
|
|
906
976
|
def after_exec(self):
|
|
907
977
|
self.add_output_files(save_path=self._log_save_path, startswith="rsl.", outputs="namelist.input")
|
|
908
978
|
self.add_output_files(save_path=self._output_save_path, outputs=["wrfinput_d02", "wrfbdy_d02"])
|
|
909
979
|
# also save other outputs of real.exe, so WRF can directly use them.
|
|
910
|
-
self.add_output_files(
|
|
911
|
-
|
|
980
|
+
self.add_output_files(
|
|
981
|
+
output_dir=f"{WRFRUN.config.WRFRUN_OUTPUT_PATH}/real",
|
|
982
|
+
save_path=self._output_save_path,
|
|
983
|
+
startswith="wrflowinp_",
|
|
984
|
+
no_file_error=False,
|
|
985
|
+
)
|
|
912
986
|
|
|
913
987
|
super().after_exec()
|
|
914
988
|
|
|
915
|
-
parsed_output_save_path =
|
|
989
|
+
parsed_output_save_path = WRFRUN.config.parse_resource_uri(self._output_save_path)
|
|
916
990
|
|
|
917
991
|
move(f"{parsed_output_save_path}/wrfinput_d02", f"{parsed_output_save_path}/wrfinput_d01")
|
|
918
992
|
move(f"{parsed_output_save_path}/wrfbdy_d02", f"{parsed_output_save_path}/wrfbdy_d01")
|
|
@@ -923,11 +997,22 @@ class NDown(ExecutableBase):
|
|
|
923
997
|
process_after_ndown()
|
|
924
998
|
|
|
925
999
|
|
|
926
|
-
|
|
927
|
-
|
|
1000
|
+
def _exec_register_func(exec_db: ExecutableDB):
|
|
1001
|
+
"""
|
|
1002
|
+
Function to register ``Executable``.
|
|
1003
|
+
|
|
1004
|
+
:param exec_db: ``ExecutableDB`` instance.
|
|
1005
|
+
:type exec_db: ExecutableDB
|
|
1006
|
+
"""
|
|
1007
|
+
class_list = [GeoGrid, LinkGrib, UnGrib, MetGrid, Real, WRF, NDown]
|
|
1008
|
+
class_id_list = ["geogrid", "link_grib", "ungrib", "metgrid", "real", "wrf", "ndown"]
|
|
1009
|
+
|
|
1010
|
+
for _class, _id in zip(class_list, class_id_list):
|
|
1011
|
+
if not exec_db.is_registered(_id):
|
|
1012
|
+
exec_db.register_exec(_id, _class)
|
|
1013
|
+
|
|
1014
|
+
|
|
1015
|
+
WRFRUN.set_exec_db_register_func(_exec_register_func)
|
|
928
1016
|
|
|
929
|
-
for _class, _id in zip(class_list, class_id_list):
|
|
930
|
-
if not WRFRUNExecDB.is_registered(_id):
|
|
931
|
-
WRFRUNExecDB.register_exec(_id, _class)
|
|
932
1017
|
|
|
933
1018
|
__all__ = ["GeoGrid", "LinkGrib", "UnGrib", "MetGrid", "Real", "WRF", "DFI", "NDown"]
|