Source code for pyww3.grid

import os

from dataclasses import dataclass
from textwrap import dedent as dtxt

from .ww3 import WW3Base
from .utils import (bool_to_str, verify_runpath, verify_ww3_file)


[docs]@dataclass class WW3GRid(WW3Base): """This class abstracts the program ww3_grid. It is an extension of the class :class:`pyww3.ww3.WW3Base()`. """ runpath: str grid_name: str grid_nml: str grid_type: str grid_coord: str grid_clos: str EXE = "ww3_grid" output: str = "ww3_grid.nml" spectrum_xfr: int = 1.1 spectrum_freq1: int = 0.04118 spectrum_nk: int = 32 spectrum_nth: int = 24 spectrum_thoff: int = 0 run_fldry: bool = False run_flcx: bool = True run_flcy: bool = True run_flcth: bool = True run_flck: bool = True run_flsou: bool = True timesteps_dtmax: float = 480. timesteps_dtxy: float = 160. timesteps_dtkth: float = 240. timesteps_dtmin: float = 10. grid_zlim: float = 0. grid_dmin: float = 0. rect_nx: int = 0 rect_ny: int = 0 rect_sx: float = 0.0 rect_sy: float = 0.0 rect_sf: float = 1. rect_x0: float = 0. rect_y0: float = 0. rect_sf0: float = 1. curv_nx: int = 0 curv_ny: int = 0 curv_xcoord_sf: float = 1. curv_xcoord_off: float = 0. curv_xcoord_filename: str = "" curv_xcoord_idf: int = 21 curv_xcoord_idla: int = 1 curv_xcoord_idfm: int = 1 curv_xcoord_format: str = "(....)" curv_ycoord_sf: float = 1. curv_ycoord_off: float = 0. curv_ycoord_filename: str = "" curv_ycoord_idf: int = 22 curv_ycoord_idla: int = 1 curv_ycoord_idfm: int = 1 curv_ycoord_format: str = "(....)" unst_sf: float = 1. unst_filename: str = "" unst_idla: int = 20 unst_idfm: int = 1 unst_format: int = "(20f10.2)" unst_ugobcfile: str = "" depth_sf: float = 1. depth_filename: str = "" depth_idf: int = 50 depth_dla: int = 1 depth_dfm: int = 1 depth_format: str = "(....)" mask_filename: str = "" mask_idf: int = 60 mask_idla: int = 1 mask_idfm: int = 1 mask_format: str = "(....)" obst_sf: float = 1. obst_filename: str = "" obst_idf: int = 70 obst_idla: int = 1 obst_idfm: int = 1 obst_format: str = "(....)" slope_sf: float = 1. slope_filename: str = "" slope_idf: int = 80 slope_idla: int = 1 slope_idfm: int = 1 slope_format: str = "(....)" sed_sf: float = 1. sed_filename: str = "" sed_idfm: int = 90 sed_idla: int = 1 sed_idfm: int = 1 sed_format: str = "(....)" def __post_init__(self): # verify if all files are valid verify_runpath(self.runpath) # check if grid_nml exists verify_ww3_file(self.runpath, self.grid_nml) self.__setattr__("grid_nml", os.path.basename(self.grid_nml)) grid_types = ["RECT", "CURV", "UNST"] if self.grid_type not in grid_types: error = "grid_type type must be: {}".format(",".join(grid_types)) raise ValueError(error) coord_types = ["SPHE", "CART"] if self.grid_coord not in coord_types: error = "grid_coord type must be: {}".format(",".join(grid_types)) raise ValueError(error) clos_types = ["NONE", "SMPL", "TRPL"] if self.grid_clos not in clos_types: error = "grid_clos type must be: {}".format(",".join(grid_types)) raise ValueError(error) # check if required data exists if self.depth_filename: verify_ww3_file(self.runpath, self.depth_filename) self.__setattr__("depth_filename", os.path.basename(self.depth_filename)) if self.mask_filename: verify_ww3_file(self.runpath, self.mask_filename) self.__setattr__("mask_filename", os.path.basename(self.mask_filename)) if self.obst_filename: verify_ww3_file(self.runpath, self.obst_filename) self.__setattr__("obst_filename", os.path.basename(self.obst_filename)) if self.slope_filename: verify_ww3_file(self.runpath, self.slope_filename) self.__setattr__("slope_filename", os.path.basename(self.slope_filename)) if self.sed_filename: verify_ww3_file(self.runpath, self.sed_filename) self.__setattr__("sed_filename", os.path.basename(self.sed_filename)) # unstructured grid data if self.unst_filename: verify_ww3_file(self.runpath, self.unst_filename) self.__setattr__("unst_filename", os.path.basename(self.unst_filename)) # curvlinear grid data if self.curv_xcoord_filename: verify_ww3_file(self.runpath, self.curv_xcoord_filename) self.__setattr__("curv_xcoord_filename", os.path.basename(self.curv_xcoord_filename)) if self.curv_ycoord_filename: verify_ww3_file(self.runpath, self.curv_ycoord_filename) self.__setattr__("curv_ycoord_filename", os.path.basename(self.curv_ycoord_filename)) self.__setattr__("text", self.populate_namelist()) # NOTE: I am doing this this way instead of reading it from a file # because f-strings in a file allow for arbitrary code execution, # and are thefore a security issue. Writting everything here at # least controls what is being executed.
[docs] def populate_namelist(self): """Create the namelist text using NOAA's latest template.""" txt = dtxt(f"""\ ! -------------------------------------------------------------------- ! ! WAVEWATCH III - ww3_grid.nml - Grid pre-processing ! ! -------------------------------------------------------------------- ! ! -------------------------------------------------------------------- ! ! Define the spectrum parameterization via SPECTRUM_NML namelist ! ! * namelist must be terminated with / ! * definitions & defaults: ! SPECTRUM%XFR = 0. ! frequency increment ! SPECTRUM%FREQ1 = 0. ! first frequency (Hz) ! SPECTRUM%NK = 0 ! number of frequencies (wavenumbers) ! SPECTRUM%NTH = 0 ! number of direction bins ! SPECTRUM%THOFF = 0. ! relative offset of first direction [-0.5,0.5] ! -------------------------------------------------------------------- ! &SPECTRUM_NML SPECTRUM%XFR = {self.spectrum_xfr} SPECTRUM%FREQ1 = {self.spectrum_freq1} SPECTRUM%NK = {self.spectrum_nk} SPECTRUM%NTH = {self.spectrum_nth} SPECTRUM%THOFF = {self.spectrum_thoff} / ! -------------------------------------------------------------------- ! ! Define the run parameterization via RUN_NML namelist ! ! * namelist must be terminated with / ! * definitions & defaults: ! RUN%FLDRY = F ! dry run (I/O only, no calculation) ! RUN%FLCX = F ! x-component of propagation ! RUN%FLCY = F ! y-component of propagation ! RUN%FLCTH = F ! direction shift ! RUN%FLCK = F ! wavenumber shift ! RUN%FLSOU = F ! source terms ! -------------------------------------------------------------------- ! &RUN_NML RUN%FLDRY = {bool_to_str(self.run_fldry).upper()} RUN%FLCX = {bool_to_str(self.run_flcx).upper()} RUN%FLCY = {bool_to_str(self.run_flcy).upper()} RUN%FLCTH = {bool_to_str(self.run_flcth).upper()} RUN%FLCK = {bool_to_str(self.run_flck).upper()} RUN%FLSOU = {bool_to_str(self.run_flsou).upper()} / ! -------------------------------------------------------------------- ! ! Define the timesteps parameterization via TIMESTEPS_NML namelist ! ! * It is highly recommended to set up time steps which are multiple ! between them. ! ! * The first time step to calculate is the maximum CFL time step ! which depend on the lowest frequency FREQ1 previously set up and the ! lowest spatial grid resolution in meters DXY. ! reminder : 1 degree=60minutes // 1minute=1mile // 1mile=1.852km ! The formula for the CFL time is : ! Tcfl = DXY / (G / (FREQ1*4*Pi) ) with the constants Pi=3,14 and G=9.8m/s²; ! DTXY ~= 90% Tcfl ! DTMAX ~= 3 * DTXY (maximum global time step limit) ! ! * The refraction time step depends on how strong can be the current velocities ! on your grid : ! DTKTH ~= DTMAX / 2 ! in case of no or light current velocities ! DTKTH ~= DTMAX / 10 ! in case of strong current velocities ! ! * The source terms time step is usually defined between 5s and 60s. ! A common value is 10s. ! DTMIN ~= 10 ! ! * namelist must be terminated with / ! * definitions & defaults: ! TIMESTEPS%DTMAX = 0. ! maximum global time step (s) ! TIMESTEPS%DTXY = 0. ! maximum CFL time step for x-y (s) ! TIMESTEPS%DTKTH = 0. ! maximum CFL time step for k-th (s) ! TIMESTEPS%DTMIN = 0. ! minimum source term time step (s) ! -------------------------------------------------------------------- ! &TIMESTEPS_NML TIMESTEPS%DTMAX = {self.timesteps_dtmax} TIMESTEPS%DTXY = {self.timesteps_dtxy} TIMESTEPS%DTKTH = {self.timesteps_dtkth} TIMESTEPS%DTMIN = {self.timesteps_dtmin} / ! -------------------------------------------------------------------- ! ! Define the grid to preprocess via GRID_NML namelist ! ! * the tunable parameters for source terms, propagation schemes, and ! numerics are read using namelists. ! * Any namelist found in the folowing sections is temporarily written ! to param.scratch, and read from there if necessary. ! * The order of the namelists is immaterial. ! * Namelists not needed for the given switch settings will be skipped ! automatically ! ! * grid type can be : ! 'RECT' : rectilinear ! 'CURV' : curvilinear ! 'UNST' : unstructured (triangle-based) ! ! * coordinate system can be : ! 'SPHE' : Spherical (degrees) ! 'CART' : Cartesian (meters) ! ! * grid closure can only be applied in spherical coordinates ! ! * grid closure can be : ! 'NONE' : No closure is applied ! 'SMPL' : Simple grid closure. Grid is periodic in the ! : i-index and wraps at i=NX+1. In other words, ! : (NX+1,J) => (1,J). A grid with simple closure ! : may be rectilinear or curvilinear. ! 'TRPL' : Tripole grid closure : Grid is periodic in the ! : i-index and wraps at i=NX+1 and has closure at ! : j=NY+1. In other words, (NX+1,J<=NY) => (1,J) ! : and (I,NY+1) => (NX-I+1,NY). Tripole ! : grid closure requires that NX be even. A grid ! : with tripole closure must be curvilinear. ! ! * The coastline limit depth is the value which distinguish the sea ! points to the land points. All the points with depth values (ZBIN) ! greater than this limit (ZLIM) will be considered as excluded points ! and will never be wet points, even if the water level grows over. ! It can only overwrite the status of a sea point to a land point. ! The value must have a negative value under the mean sea level ! ! * The minimum water depth allowed to compute the model is the absolute ! depth value (DMIN) used in the model if the input depth is lower to ! avoid the model to blow up. ! ! * namelist must be terminated with / ! * definitions & defaults: ! GRID%NAME = 'unset' ! grid name (30 char) ! GRID%NML = 'namelists.nml' ! namelists filename ! GRID%TYPE = 'unset' ! grid type ! GRID%COORD = 'unset' ! coordinate system ! GRID%CLOS = 'unset' ! grid closure ! ! GRID%ZLIM = 0. ! coastline limit depth (m) ! GRID%DMIN = 0. ! abs. minimum water depth (m) ! -------------------------------------------------------------------- ! &GRID_NML GRID%NAME = '{self.grid_name}' GRID%NML = '{self.grid_nml}' GRID%TYPE = '{self.grid_type}' GRID%COORD = '{self.grid_coord}' GRID%CLOS = '{self.grid_clos}' GRID%ZLIM = {self.grid_zlim} GRID%DMIN = {self.grid_dmin} / ! -------------------------------------------------------------------- ! ! Define the rectilinear grid type via RECT_NML namelist ! - only for RECT grids - ! ! * The minimum grid size is 3x3. ! ! * If the grid increments SX and SY are given in minutes of arc, the scaling ! factor SF must be set to 60. to provide an increment factor in degree. ! ! * If CSTRG='SMPL', then SX is forced to 360/NX. ! ! * value <= value_read / scale_fac ! ! * namelist must be terminated with / ! * definitions & defaults: ! RECT%NX = 0 ! number of points along x-axis ! RECT%NY = 0 ! number of points along y-axis ! ! RECT%SX = 0. ! grid increment along x-axis ! RECT%SY = 0. ! grid increment along y-axis ! RECT%SF = 1. ! scaling division factor for x-y axis ! ! RECT%X0 = 0. ! x-coordinate of lower-left corner (deg) ! RECT%Y0 = 0. ! y-coordinate of lower-left corner (deg) ! RECT%SF0 = 1. ! scaling division factor for x0,y0 coord ! -------------------------------------------------------------------- ! &RECT_NML RECT%NX = {self.rect_nx} RECT%NY = {self.rect_ny} RECT%SX = {self.rect_sx} RECT%SY = {self.rect_sy} RECT%SF = {self.rect_sf} RECT%X0 = {self.rect_x0} RECT%Y0 = {self.rect_y0} RECT%SF0 = {self.rect_sf0} / ! -------------------------------------------------------------------- ! ! Define the curvilinear grid type via CURV_NML namelist ! - only for CURV grids - ! ! * The minimum grid size is 3x3. ! ! * If CSTRG='SMPL', then SX is forced to 360/NX. ! ! * value <= scale_fac * value_read + add_offset ! ! * IDLA : Layout indicator : ! 1 : Read line-by-line bottom to top. (default) ! 2 : Like 1, single read statement. ! 3 : Read line-by-line top to bottom. ! 4 : Like 3, single read statement. ! * IDFM : format indicator : ! 1 : Free format. (default) ! 2 : Fixed format. ! 3 : Unformatted. ! * FORMAT : element format to read : ! '(....)' : auto detected (default) ! '(f10.6)' : float type ! ! * Example : ! IDF SF OFF IDLA IDFM FORMAT FILENAME ! 21 0.25 -0.5 3 1 '(....)' 'x.inp' ! 22 0.25 0.5 3 1 '(....)' 'y.inp' ! ! * namelist must be terminated with / ! * definitions & defaults: ! CURV%NX = 0 ! number of points along x-axis ! CURV%NY = 0 ! number of points along y-axis ! ! CURV%XCOORD%SF = 1. ! x-coord scale factor ! CURV%XCOORD%OFF = 0. ! x-coord add offset ! CURV%XCOORD%FILENAME = 'unset' ! x-coord filename ! CURV%XCOORD%IDF = 21 ! x-coord file unit number ! CURV%XCOORD%IDLA = 1 ! x-coord layout indicator ! CURV%XCOORD%IDFM = 1 ! x-coord format indicator ! CURV%XCOORD%FORMAT = '(....)' ! x-coord formatted read format ! ! CURV%YCOORD%SF = 1. ! y-coord scale factor ! CURV%YCOORD%OFF = 0. ! y-coord add offset ! CURV%YCOORD%FILENAME = 'unset' ! y-coord filename ! CURV%YCOORD%IDF = 22 ! y-coord file unit number ! CURV%YCOORD%IDLA = 1 ! y-coord layout indicator ! CURV%YCOORD%IDFM = 1 ! y-coord format indicator ! CURV%YCOORD%FORMAT = '(....)' ! y-coord formatted read format ! -------------------------------------------------------------------- ! &CURV_NML CURV%NX = {self.curv_nx} CURV%NY = {self.curv_ny} CURV%XCOORD%SF = {self.curv_xcoord_sf} CURV%XCOORD%OFF = {self.curv_xcoord_off} CURV%XCOORD%FILENAME = {self.curv_xcoord_filename} CURV%XCOORD%IDF = {self.curv_xcoord_idf} CURV%XCOORD%IDLA = {self.curv_xcoord_idla} CURV%XCOORD%IDFM = {self.curv_xcoord_idfm} CURV%XCOORD%FORMAT = '{self.curv_xcoord_format}' CURV%YCOORD%SF = {self.curv_ycoord_sf} CURV%YCOORD%OFF = {self.curv_ycoord_off} CURV%YCOORD%FILENAME = {self.curv_ycoord_filename} CURV%YCOORD%IDF = {self.curv_ycoord_idf} CURV%YCOORD%IDLA = {self.curv_ycoord_idla} CURV%YCOORD%IDFM = {self.curv_ycoord_idfm} CURV%YCOORD%FORMAT = '{self.curv_ycoord_format}' / ! -------------------------------------------------------------------- ! ! Define the unstructured grid type via UNST_NML namelist ! - only for UNST grids - ! ! * The minimum grid size is 3x3. ! ! * &MISC namelist must be removed ! ! * The depth value must have negative values under the mean sea level ! ! * The map value must be set as : ! -2 : Excluded boundary point (covered by ice) ! -1 : Excluded sea point (covered by ice) ! 0 : Excluded land point ! 1 : Sea point ! 2 : Active boundary point ! 3 : Excluded grid point ! 7 : Ice point ! ! * the file must be a GMESH grid file containing node and element lists. ! ! * Extra open boundary list file with UGOBCFILE in namelist &UNST ! An example is given in regtest ww3_tp2.7 ! ! * value <= scale_fac * value_read ! ! * IDLA : Layout indicator : ! 1 : Read line-by-line bottom to top. (default) ! 2 : Like 1, single read statement. ! 3 : Read line-by-line top to bottom. ! 4 : Like 3, single read statement. ! * IDFM : format indicator : ! 1 : Free format. (default) ! 2 : Fixed format. ! 3 : Unformatted. ! * FORMAT : element format to read : ! '(....)' : auto detected (default) ! '(f10.6)' : float type ! ! * Example : ! IDF SF IDLA IDFM FORMAT FILENAME ! 20 -1. 4 2 '(20f10.2)' 'ngug.msh' ! ! * namelist must be terminated with / ! * definitions & defaults: ! UNST%SF = 1. ! unst scale factor ! UNST%FILENAME = 'unset' ! unst filename ! UNST%IDF = 20 ! unst file unit number ! UNST%IDLA = 1 ! unst layout indicator ! UNST%IDFM = 1 ! unst format indicator ! UNST%FORMAT = '(....)' ! unst formatted read format ! ! UNST%UGOBCFILE = 'unset' ! additional boundary list file ! -------------------------------------------------------------------- ! &UNST_NML UNST%SF = {self.unst_sf} UNST%FILENAME = '{self.unst_filename}' UNST%IDLA = {self.unst_idla} UNST%IDFM = {self.unst_idfm} UNST%FORMAT = '{self.unst_format}' UNST%UGOBCFILE = {self.unst_ugobcfile} / ! -------------------------------------------------------------------- ! ! Define the spherical multiple-cell grid via SMC_NML namelist ! - only for SMC grids - ! ! * SMC cell 'MCELS' and face 'ISIDE & JSIDE' arrays ! and obstruction ratio 'SUBTR'. ! ! * The input boundary cell file 'BUNDY' is only needed when NBISMC > 0. ! Boundary cell id list file (unit 35) is only required if boundary ! cell number entered above is non-zero. The cell id number should be ! the sequential number in the cell array (unit 31) S625MCels.dat. ! ! * Extra cell and face arrays for Arctic part if switch ARC is selected. ! ! * Example : ! IDF IDLA IDFM FORMAT FILENAME ! 31 1 1 '(....)' 'S6125MCels.dat' ! 32 1 1 '(....)' 'S6125ISide.dat' ! 33 1 1 '(....)' 'S6125JSide.dat' ! 34 1 1 '(....)' 'SMC25Subtr.dat' ! 35 1 1 '(....)' 'S6125Bundy.dat' ! 36 1 1 '(....)' 'S6125MBArc.dat' ! 37 1 1 '(....)' 'S6125AISid.dat' ! 38 1 1 '(....)' 'S6125AJSid.dat' ! ! * namelist must be terminated with / ! * definitions & defaults: ! SMC%MCELS%FILENAME = 'unset' ! MCels filename ! SMC%MCELS%IDF = 31 ! MCels file unit number ! SMC%MCELS%IDLA = 1 ! MCels layout indicator ! SMC%MCELS%IDFM = 1 ! MCels format indicator ! SMC%MCELS%FORMAT = '(....)' ! MCels formatted read format ! ! SMC%ISIDE%FILENAME = 'unset' ! ISide filename ! SMC%ISIDE%IDF = 32 ! ISide file unit number ! SMC%ISIDE%IDLA = 1 ! ISide layout indicator ! SMC%ISIDE%IDFM = 1 ! ISide format indicator ! SMC%ISIDE%FORMAT = '(....)' ! ISide formatted read format ! ! SMC%JSIDE%FILENAME = 'unset' ! JSide filename ! SMC%JSIDE%IDF = 33 ! JSide file unit number ! SMC%JSIDE%IDLA = 1 ! JSide layout indicator ! SMC%JSIDE%IDFM = 1 ! JSide format indicator ! SMC%JSIDE%FORMAT = '(....)' ! JSide formatted read format ! ! SMC%SUBTR%FILENAME = 'unset' ! Subtr filename ! SMC%SUBTR%IDF = 34 ! Subtr file unit number ! SMC%SUBTR%IDLA = 1 ! Subtr layout indicator ! SMC%SUBTR%IDFM = 1 ! Subtr format indicator ! SMC%SUBTR%FORMAT = '(....)' ! Subtr formatted read format ! ! SMC%BUNDY%FILENAME = 'unset' ! Bundy filename ! SMC%BUNDY%IDF = 35 ! Bundy file unit number ! SMC%BUNDY%IDLA = 1 ! Bundy layout indicator ! SMC%BUNDY%IDFM = 1 ! Bundy format indicator ! SMC%BUNDY%FORMAT = '(....)' ! Bundy formatted read format ! ! SMC%MBARC%FILENAME = 'unset' ! MBArc filename ! SMC%MBARC%IDF = 36 ! MBArc file unit number ! SMC%MBARC%IDLA = 1 ! MBArc layout indicator ! SMC%MBARC%IDFM = 1 ! MBArc format indicator ! SMC%MBARC%FORMAT = '(....)' ! MBArc formatted read format ! ! SMC%AISID%FILENAME = 'unset' ! AISid filename ! SMC%AISID%IDF = 37 ! AISid file unit number ! SMC%AISID%IDLA = 1 ! AISid layout indicator ! SMC%AISID%IDFM = 1 ! AISid format indicator ! SMC%AISID%FORMAT = '(....)' ! AISid formatted read format ! ! SMC%AJSID%FILENAME = 'unset' ! AJSid filename ! SMC%AJSID%IDF = 38 ! AJSid file unit number ! SMC%AJSID%IDLA = 1 ! AJSid layout indicator ! SMC%AJSID%IDFM = 1 ! AJSid format indicator ! SMC%AJSID%FORMAT = '(....)' ! AJSid formatted read format ! -------------------------------------------------------------------- ! !&SMC_NML ! NOT SUPPORTED. REQUIRES USER INPUT. !/ ! -------------------------------------------------------------------- ! ! Define the depth to preprocess via DEPTH_NML namelist ! - for RECT and CURV grids - ! ! * if no obstruction subgrid, need to set &MISC FLAGTR = 0 ! ! * The depth value must have negative values under the mean sea level ! ! * value <= value_read * scale_fac ! ! * IDLA : Layout indicator : ! 1 : Read line-by-line bottom to top. (default) ! 2 : Like 1, single read statement. ! 3 : Read line-by-line top to bottom. ! 4 : Like 3, single read statement. ! * IDFM : format indicator : ! 1 : Free format. (default) ! 2 : Fixed format. ! 3 : Unformatted. ! * FORMAT : element format to read : ! '(....)' : auto detected (default) ! '(f10.6)' : float type ! ! * Example : ! IDF SF IDLA IDFM FORMAT FILENAME ! 50 0.001 1 1 '(....)' 'GLOB-30M.bot' ! ! * namelist must be terminated with / ! * definitions & defaults: ! DEPTH%SF = 1. ! scale factor ! DEPTH%FILENAME = 'unset' ! filename ! DEPTH%IDF = 50 ! file unit number ! DEPTH%IDLA = 1 ! layout indicator ! DEPTH%IDFM = 1 ! format indicator ! DEPTH%FORMAT = '(....)' ! formatted read format ! -------------------------------------------------------------------- ! &DEPTH_NML DEPTH%SF = {self.depth_sf} DEPTH%FILENAME = '{self.depth_filename}' DEPTH%IDF = {self.depth_idf} DEPTH%IDLA = {self.depth_dla} DEPTH%IDFM = {self.depth_dfm} DEPTH%FORMAT = '{self.depth_format}' / ! -------------------------------------------------------------------- ! ! Define the point status map via MASK_NML namelist ! - only for RECT and CURV grids - ! ! * If no mask defined, INBOUND can be used to set active boundaries ! ! * IDLA : Layout indicator : ! 1 : Read line-by-line bottom to top. (default) ! 2 : Like 1, single read statement. ! 3 : Read line-by-line top to bottom. ! 4 : Like 3, single read statement. ! * IDFM : format indicator : ! 1 : Free format. (default) ! 2 : Fixed format. ! 3 : Unformatted. ! * FORMAT : element format to read : ! '(....)' : auto detected (default) ! '(f10.6)' : float type ! ! * Example : ! IDF IDLA IDFM FORMAT FILENAME ! 60 1 1 '(....)' 'GLOB-30M.mask' ! ! * The legend for the input map is : ! -2 : Excluded boundary point (covered by ice) ! -1 : Excluded sea point (covered by ice) ! 0 : Excluded land point ! 1 : Sea point ! 2 : Active boundary point ! 3 : Excluded grid point ! 7 : Ice point ! ! * namelist must be terminated with / ! * definitions & defaults: ! MASK%FILENAME = 'unset' ! filename ! MASK%IDF = 60 ! file unit number ! MASK%IDLA = 1 ! layout indicator ! MASK%IDFM = 1 ! format indicator ! MASK%FORMAT = '(....)' ! formatted read format ! -------------------------------------------------------------------- ! &MASK_NML MASK%FILENAME = '{self.mask_filename}' MASK%IDF = {self.mask_idf} MASK%IDLA = {self.mask_idla} MASK%IDFM = {self.mask_idfm} MASK%FORMAT = '{self.mask_format}' / ! -------------------------------------------------------------------- ! ! Define the obstruction map via OBST_NML namelist ! - only for RECT and CURV grids - ! ! * only used if &MISC FLAGTR = 1 in param.nml ! (transparencies at cell boundaries) ! or if &MISC FLAGTR = 2 in param.nml ! (transparencies at cell centers) ! or if &MISC FLAGTR = 3 in param.nml ! (transparencies at cell boundaries with cont. ice) ! or if &MISC FLAGTR = 4 in param.nml ! (transparencies at cell centers with cont. ice) ! ! * value <= value_read * scale_fac ! ! * IDLA : Layout indicator : ! 1 : Read line-by-line bottom to top. (default) ! 2 : Like 1, single read statement. ! 3 : Read line-by-line top to bottom. ! 4 : Like 3, single read statement. ! * IDFM : format indicator : ! 1 : Free format. (default) ! 2 : Fixed format. ! 3 : Unformatted. ! * FORMAT : element format to read : ! '(....)' : auto detected (default) ! '(f10.6)' : float type ! ! * Example : ! IDF SF IDLA IDFM FORMAT FILENAME ! 70 0.0001 1 1 '(....)' 'GLOB-30M.obst' ! ! * If the file unit number equals 10, then the data is read from this ! file. The data must follow the above record. No comment lines are ! allowed within the data input. ! ! * In the case of unstructured grids, no obstruction file can be added ! ! * namelist must be terminated with / ! * definitions & defaults: ! OBST%SF = 1. ! scale factor ! OBST%FILENAME = 'unset' ! filename ! OBST%IDF = 70 ! file unit number ! OBST%IDLA = 1 ! layout indicator ! OBST%IDFM = 1 ! format indicator ! OBST%FORMAT = '(....)' ! formatted read format ! -------------------------------------------------------------------- ! &OBST_NML OBST%SF = {self.obst_sf} OBST%FILENAME = '{self.obst_filename}' OBST%IDF = {self.obst_idf} OBST%IDLA = {self.obst_idla} OBST%IDFM = {self.obst_idfm} OBST%FORMAT = '{self.obst_format}' / ! -------------------------------------------------------------------- ! ! Define the reflexion slope map via SLOPE_NML namelist ! - only for RECT and CURV grids - ! ! * only used if &REF1 REFMAP = 2 defined in param.nml ! ! * value <= value_read * scale_fac ! ! * IDLA : Layout indicator : ! 1 : Read line-by-line bottom to top. (default) ! 2 : Like 1, single read statement. ! 3 : Read line-by-line top to bottom. ! 4 : Like 3, single read statement. ! * IDFM : format indicator : ! 1 : Free format. (default) ! 2 : Fixed format. ! 3 : Unformatted. ! * FORMAT : element format to read : ! '(....)' : auto detected (default) ! '(f10.6)' : float type ! ! * Example : ! IDF SF IDLA IDFM FORMAT FILENAME ! 80 0.0001 1 1 '(....)' 'GLOB-30M.slope' ! ! * In the case of unstructured grids, no sed file can be added ! ! * namelist must be terminated with / ! * definitions & defaults: ! SLOPE%SF = 1. ! scale factor ! SLOPE%FILENAME = 'unset' ! filename ! SLOPE%IDF = 80 ! file unit number ! SLOPE%IDLA = 1 ! layout indicator ! SLOPE%IDFM = 1 ! format indicator ! SLOPE%FORMAT = '(....)' ! formatted read format ! -------------------------------------------------------------------- ! &SLOPE_NML SLOPE%SF = {self.slope_sf} SLOPE%FILENAME = '{self.slope_filename}' SLOPE%IDF = {self.slope_idf} SLOPE%IDLA = {self.slope_idla} SLOPE%IDFM = {self.slope_idfm} SLOPE%FORMAT = '{self.slope_format}' / ! -------------------------------------------------------------------- ! ! Define the sedimentary bottom map via SED_NML namelist ! ! * only used if &SBT4 SEDMAPD50 = T defined in param.nml ! ! * value <= value_read * scale_fac ! ! * IDLA : Layout indicator : ! 1 : Read line-by-line bottom to top. (default) ! 2 : Like 1, single read statement. ! 3 : Read line-by-line top to bottom. ! 4 : Like 3, single read statement. ! * IDFM : format indicator : ! 1 : Free format. (default) ! 2 : Fixed format. ! 3 : Unformatted. ! * FORMAT : element format to read : ! '(....)' : auto detected (default) ! '(f10.6)' : float type ! ! * Example : ! IDF SF IDLA IDFM FORMAT FILENAME ! 90 1. 1 2 '(f10.6)' 'SED.txt' ! ! * In the case of unstructured grids, no sed file can be added ! ! * namelist must be terminated with / ! * definitions & defaults: ! SED%SF = 1. ! scale factor ! SED%FILENAME = 'unset' ! filename ! SED%IDF = 90 ! file unit number ! SED%IDLA = 1 ! layout indicator ! SED%IDFM = 1 ! format indicator ! SED%FORMAT = '(....)' ! formatted read format ! -------------------------------------------------------------------- ! &SED_NML SED%SF = {self.sed_sf} SED%FILENAME = '{self.sed_filename}' SED%IDFM = {self.sed_idfm} SED%IDLA = {self.sed_idla} SED%IDFM = {self.sed_idfm} SED%FORMAT = '{self.sed_format}' / ! -------------------------------------------------------------------- ! ! Define the input boundary points via INBND_COUNT_NML and ! INBND_POINT_NML namelist ! - for RECT, CURV and UNST grids - ! ! * If no mask defined, INBOUND can be used ! ! * If the actual input data is not defined in the actual wave model run ! the initial conditions will be applied as constant boundary conditions. ! ! * The number of points is defined by INBND_COUNT ! ! * The points must start from index 1 to N ! ! * Each line contains: ! Discrete grid counters (IX,IY) of the active point and a ! connect flag. If this flag is true, and the present and previous ! point are on a grid line or diagonal, all intermediate points ! are also defined as boundary points. ! ! * Included point : ! grid points from segment data ! Defines as lines identifying points at which ! input boundary conditions are to be defined. ! ! * namelist must be terminated with / ! * definitions & defaults: ! INBND_COUNT%N_POINT = 0 ! number of segments ! ! INBND_POINT(I)%X_INDEX = 0 ! x index included point ! INBND_POINT(I)%Y_INDEX = 0 ! y index included point ! INBND_POINT(I)%CONNECT = F ! connect flag ! ! OR ! INBND_POINT(I) = 0 0 F ! included point ! -------------------------------------------------------------------- ! !&INBND_COUNT_NML ! NOT SUPPORTED. REQUIRES USER INPUT. !/ !&INBND_POINT_NML ! NOT SUPPORTED. REQUIRES USER INPUT. !/ ! -------------------------------------------------------------------- ! ! Define the excluded points and bodies via EXCL_COUNT_NML, EXCL_POINT_NML ! and EXCL_BODY_NML namelist ! - only for RECT and CURV grids - ! ! * If no mask defined, EXCL can NOT be used ! ! * The number of points and bodies are defined by EXCL_COUNT ! ! * The points and bodies must start from index 1 to N ! ! * Each line contains: ! Discrete grid counters (IX,IY) of the active point and a ! connect flag. If this flag is true, and the present and previous ! point are on a grid line or diagonal, all intermediate points ! are also defined as boundary points. ! ! * Excluded point : ! grid points from segment data ! Defined as lines identifying points at which ! input boundary conditions are to be excluded. ! ! * Excluded body: ! Define a point in a closed body of sea points to remove the ! entire body of sea points. ! ! * namelist must be terminated with / ! * definitions & defaults: ! EXCL_COUNT%N_POINT = 0 ! number of segments ! EXCL_COUNT%N_BODY = 0 ! number of bodies ! ! EXCL_POINT(J)%X_INDEX = 0 ! x index excluded point ! EXCL_POINT(J)%Y_INDEX = 0 ! y index excluded point ! EXCL_POINT(J)%CONNECT = F ! connect flag ! ! EXCL_BODY(K)%X_INDEX = 0 ! x index excluded body ! EXCL_BODY(K)%Y_INDEX = 0 ! y index excluded body ! OR ! EXCL_POINT(J) = 0 0 F ! excluded point ! EXCL_BODY(K) = 0 0 ! excluded body ! -------------------------------------------------------------------- ! !&EXCL_COUNT_NML ! NOT SUPPORTED. REQUIRES USER INPUT. !/ !&EXCL_POINT_NML ! NOT SUPPORTED. REQUIRES USER INPUT. !/ !&EXCL_BODY_NML ! NOT SUPPORTED. REQUIRES USER INPUT. !/ ! -------------------------------------------------------------------- ! ! Define the output boundary points via OUTBND_COUNT_NML and ! OUTBND_LINE_NML namelist ! - only for RECT and CURV grids - ! ! * It will creates a nest file with output boundaries for a inner grid. ! The prefered way to do it is to use ww3_bounc program. ! ! * These do not need to be defined for data transfer between grids in ! the multi grid driver. ! ! * The number of lines are defined by OUTBND_COUNT ! ! * The lines must start from index 1 to N ! ! * Output boundary points are defined as a number of straight lines, ! defined by its starting point (X0,Y0), increments (DX,DY) and number ! of points. A negative number of points starts a new output file. ! ! * Example for spherical grid in degrees : ! '1.75 1.50 0.25 -0.10 3' ! '2.25 1.50 -0.10 0.00 -6' ! '0.10 0.10 0.10 0.00 -10' ! ! * namelist must be terminated with / ! * definitions & defaults: ! OUTBND_COUNT%N_LINE = 0 ! number of lines ! ! OUTBND_LINE(I)%X0 = 0. ! x index start point ! OUTBND_LINE(I)%Y0 = 0. ! y index start point ! OUTBND_LINE(I)%DX = 0. ! x-along increment ! OUTBND_LINE(I)%DY = 0. ! y-along increment ! OUTBND_LINE(I)%NP = 0 ! number of points ! OR ! OUTBND_LINE(I) = 0. 0. 0. 0. 0 ! included lines ! -------------------------------------------------------------------- ! !&OUTBND_COUNT_NML ! NOT SUPPORTED. REQUIRES USER INPUT. !/ !&OUTBND_LINE_NML ! NOT SUPPORTED. REQUIRES USER INPUT. !/ ! -------------------------------------------------------------------- ! ! WAVEWATCH III - end of namelist ! ! -------------------------------------------------------------------- !""") return txt
# def to_file(self): # """Write namelist text to file ww3_ounf.nml.""" # if os.path.isfile(os.path.join(self.runpath, self.output)): # os.remove(os.path.join(self.runpath, self.output)) # with open(os.path.join(self.runpath, self.output), 'w') as f: # f.write(self.text) # def run(self): # """Run the program ww3_grid.""" # res = run(self.runpath, self.EXE) # self.__setattr__("returncode", res.returncode) # self.__setattr__("stdout", res.stdout) # self.__setattr__("stderr", res.stderr) # def update_text(self, block: str, action: str = "add", index: int = -1): # """Update namelist block in the text with an action.""" # # add case # if action.lower().startswith("a"): # newtext = add_namelist_block(self.text, block, index) # # remove case # else: # newtext = remove_namelist_block(self.text, block) # # update class attribute # self.__setattr__("text", newtext)