Skip to content

Commit 5c84f97

Browse files
committed
use click parse argument, add checking of open boundary name
1 parent 3dcb153 commit 5c84f97

1 file changed

Lines changed: 92 additions & 13 deletions

File tree

schimpy/bctide.py

Lines changed: 92 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,25 @@
77
88
"""
99
from schimpy.schism_yaml import load
10-
from schimpy.schism_mesh import SchismMeshGr3Reader
10+
from schimpy.schism_mesh import SchismMeshGr3Reader, BoundaryType
1111
import numbers
12+
import numpy as np
13+
import click
1214

1315

1416
__all__ = ["load_boundary"]
1517

1618

19+
@click.command(
20+
help=(
21+
"The tool create SCHISM bctide inputs by reading a number of open boundary condition yaml and mesh \
22+
from a main input yaml \n\n"
23+
"Example:\n"
24+
" bctide bctide_main.yaml\n "
25+
)
26+
)
27+
@click.argument('main_yaml', type=click.Path(exists=True))
28+
1729
def load_main_input(main_yaml):
1830
""" read in main yaml file which contians the grid topology and
1931
boundary condtion yaml files, this input file looks like below
@@ -34,27 +46,53 @@ class and write out the SCHISM boundary condition btdides input file.
3446

3547
mesh_in = main_yaml_dict["mesh"]["mesh_inputfile"]
3648
sr = SchismMeshGr3Reader()
49+
3750
hgrid = sr.read(mesh_in)
38-
open_boundary_grd = None
51+
open_boundary_segments = None
3952
if "open_boundaries" in main_yaml_dict["mesh"].keys():
40-
open_boundary_grd = main_yaml_dict["mesh"]["open_boundaries"]
53+
open_boundary_segments = main_yaml_dict["mesh"]["open_boundaries"]
4154

4255
bctides_dic = main_yaml_dict["bctides"]
4356
for bctides_key in bctides_dic.keys():
4457
bctides_yaml = bctides_dic[bctides_key]
45-
by = load_boundary(hgrid,bctides_yaml,open_boundary_grd)
58+
by = load_boundary(hgrid,bctides_yaml,open_boundary_segments)
4659
by.write_bctides(bctides_key)
4760

48-
def load_boundary(hgrid,fn,open_boundary_grid):
49-
return boundary(hgrid,fn,open_boundary_grid)
61+
def update_mesh_open_boundaries(mesh, segments):
62+
"""Overtide mesh open boundaries with linestrings from segments dict
63+
borrowed from schism_setup.py
64+
segments: dict containing "linestrings" key
65+
"""
66+
mesh.clear_boundaries()
67+
boundary_only = True
68+
linestrings = segments.get("linestrings")
69+
if linestrings is None:
70+
raise ValueError("Linestrings is required for open boundaries specification")
71+
for item in linestrings:
72+
name = item.get("name")
73+
if name is None:
74+
name = item.get("Name")
75+
p = np.array(item["coordinates"])
76+
start = mesh.find_closest_nodes(p[0], 1, boundary_only)
77+
end = mesh.find_closest_nodes(p[1], 1, boundary_only)
78+
path = mesh._build_boundary_node_string(start, end, boundary_only)
79+
comment = '! Open boundary "%s"' % name
80+
mesh.add_boundary(path, BoundaryType.OPEN, comment)
81+
mesh.fill_land_and_island_boundaries()
82+
83+
84+
85+
86+
def load_boundary(hgrid,fn,open_boundary_segments):
87+
return boundary(hgrid,fn,open_boundary_segments)
5088

5189

5290
class boundary(object):
5391
"""
5492
A class to generate boundary condition input file for SCHISM
5593
"""
5694

57-
def __init__(self, hgrid,bc_yaml=None,boundary_grid=None):
95+
def __init__(self, hgrid,bc_yaml=None,boundary_segments=None):
5896
""" initialize the boundary condition from yaml file"""
5997

6098
main_id = "bctides"
@@ -73,7 +111,25 @@ def __init__(self, hgrid,bc_yaml=None,boundary_grid=None):
73111

74112
## if boundary grid is provided, use it to override the hgrid boundary
75113
## grid
76-
self.boundary_grid = boundary_grid
114+
self.boundary_segments = boundary_segments
115+
if self.boundary_segments is not None:
116+
## also check if the number of open boundaries and names match
117+
## with bctides open boundaries
118+
num_boundary_segments = len(self.boundary_segments["linestrings"])
119+
if num_boundary_segments != len(self.open_boundaries):
120+
raise ValueError(
121+
"number of boundary segments from included open_boundary yaml does not match number of open boundaries in bctides YAML: %s vs %s"
122+
% (num_boundary_segments, len(self.open_boundaries))
123+
)
124+
for i in range(num_boundary_segments):
125+
bname_yaml = self.open_boundaries[i]["name"]
126+
bname_segment = self.boundary_segments["linestrings"][i]["name"]
127+
if bname_yaml != bname_segment:
128+
raise ValueError(
129+
"boundary name mismatch between included open_boundary YAML and bctides YAML: %s vs %s"
130+
% (bname_yaml, bname_segment)
131+
)
132+
update_mesh_open_boundaries(self.hgrid, self.boundary_segments)
77133

78134
self.elev_type = {
79135
"elev.th": 1,
@@ -197,14 +253,38 @@ def write_bctides(self, bctides_file):
197253

198254

199255
hgrid = self.hgrid
256+
257+
258+
hgrd_open_boundaries = list(
259+
boundary
260+
for boundary in hgrid.boundaries
261+
if boundary.btype == BoundaryType.OPEN
262+
)
200263

201-
if len(hgrid.boundaries) < len(self.open_boundaries):
264+
if len(hgrd_open_boundaries) != len(self.open_boundaries):
202265
raise ValueError(
203-
"boundary YAML has more number of openbounary than model hgrid, YAML:%s hgrid:%s"
204-
% (len(self.open_boundaries), len(hgrid.boundaries))
266+
"boundary YAML has different number of openbounary than model hgrid, YAML:%s hgrid:%s"
267+
% (len(self.open_boundaries), len(hgrd_open_boundaries))
205268
)
206269
else:
207270
num_open_boundaries = len(self.open_boundaries)
271+
## check to make sure all open_boundaries name match
272+
## with hgrid boundary names
273+
for i in range(num_open_boundaries):
274+
bname_yaml = self.open_boundaries[i]["name"]
275+
if hgrd_open_boundaries[i].comment is None:
276+
print("Warning: hgrid boundary %s has no name, skipping boundary name check" % i)
277+
continue ## skip if hgrid boundary name is empty
278+
bname_hgrid = hgrd_open_boundaries[i].comment.strip().split('"')[1]
279+
## if bname in hgrid is empty, skip the check
280+
if bname_hgrid == "":
281+
continue
282+
if bname_yaml != bname_hgrid:
283+
raise ValueError(
284+
"boundary name mismatch between YAML and hgrid: %s vs %s"
285+
% (bname_yaml, bname_hgrid)
286+
)
287+
208288
num_tracer_mod = 0
209289
tracer_mods = []
210290
tracer_mod_pos = {}
@@ -519,8 +599,7 @@ def write_bctides(self, bctides_file):
519599

520600

521601
if __name__ == "__main__":
522-
bcyaml = "bctides_main.yaml"
523-
by = load_main_input(bcyaml)
602+
by = load_main_input()
524603

525604

526605

0 commit comments

Comments
 (0)