def interpolate_hotstart_w_args(args): """ Interpolate hotstart.in with the given arguments """ mesh_in = read_mesh(args.hgrid_in, args.vgrid_in) hotstart_in = read_hotstart(mesh_in) mesh_out = read_mesh(args.hgrid_out, args.vgrid_out) return interpolate_hotstart(mesh_in, hotstart_in, mesh_out)
def test_schism_mesh_gr3_writer(self): fpath_mesh = self.fpath_mesh mesh = read_mesh(fpath_mesh) fpath_mesh_out = os.path.join(os.path.dirname(__file__), "testdata/meshout.gr3") write_mesh(mesh, fpath_mesh_out, write_boundary=True) meshout = read_mesh(fpath_mesh_out) self.assertEqual(meshout.n_nodes(), 112) self.assertEqual(meshout.n_elems(), 135) self.assertEqual(meshout.n_boundaries(), 3) if os.path.exists(fpath_mesh_out): os.remove(fpath_mesh_out)
def main(): """ main function for CLI """ parser = create_arg_parser() args = parser.parse_args() fpath_mesh_in = args.meshinput if not os.path.exists(fpath_mesh_in): raise ValueError('The given input file not found') fpath_mesh_out = args.meshoutput skewness = args.skewness if skewness is not None: if skewness < 0.: raise ValueError('Skewness must be bigger than zero') minangle = args.minangle maxangle = args.maxangle if minangle is not None: minangle = np.pi * minangle / 180. if maxangle is not None: maxangle = np.pi * maxangle / 180. if skewness is None and minangle is None and maxangle is None: raise ValueError('No splitting criteria are given') mesh = schism_mesh.read_mesh(fpath_mesh_in) elems_to_split = sets.Set() n_elems_ori = mesh.n_elems() if skewness is not None: for elem_i, elem in enumerate(mesh.elems): if len(elem) == 4: # split skew = calculate_skewness(mesh.nodes[elem]) if skew > skewness: # split elems_to_split.add(elem_i) if minangle is not None or maxangle is not None: for elem_i, elem in enumerate(mesh.elems): if len(elem) == 4: angles = calculate_internal_angles(mesh.nodes[elem]) if minangle is not None: angle_min = angles.min() if angle_min < minangle: elems_to_split.add(elem_i) if maxangle is not None: angle_max = angles.max() if angle_max > maxangle: elems_to_split.add(elem_i) print("Found %d quad element(s) to spilt." % len(elems_to_split)) if len(elems_to_split) < 1: print("No element to split.") return print("Start splitting...") split_quad(mesh, elems_to_split) print("Writing output file...") schism_mesh.write_mesh(mesh, fpath_mesh_out) if args.prop is not None: fpath_prop = args.prop write_prop(elems_to_split, n_elems_ori, fpath_prop) print("Done.")
def test_schism_mesh_sms_reader(self): fpath_mesh = os.path.join(self.testdata_dir, 'testmesh.2dm') mesh = read_mesh(fpath_mesh) self.assertEqual(mesh.n_nodes(), 112) self.assertEqual(mesh.n_elems(), 135) self.assertTrue(np.allclose(mesh.node(0), np.array([0., 100., 0.]))) self.assertTrue(np.array_equal(mesh.elem(0), np.array([2, 0, 4])))
def test_find_two_neigboring_node_paths(self): path = self.fpath_mesh mesh = read_mesh(path) # Tri area line_segment = (31.0, 69.0, 39.0, 101.0) up_path, down_path = mesh.find_two_neighboring_node_paths(line_segment) self.assertListEqual(up_path, [32, 25, 19, 14]) self.assertListEqual(down_path, [24, 18, 13, 9]) # Quad area line_segment = (69.0, 69.0, 101.0, 61.0) up_path, down_path = mesh.find_two_neighboring_node_paths(line_segment) self.assertListEqual(up_path, [64, 73, 82, 90]) self.assertListEqual(down_path, [56, 65, 74, 83]) # Mixed area line_segment = (-1.0, 1.0, 101.0, 9.0) up_path, down_path = mesh.find_two_neighboring_node_paths(line_segment) self.assertListEqual(up_path, [52, 60, 68, 76, 84, 91, 97, 102, 106, 109, 111]) self.assertListEqual(down_path, [44, 53, 61, 69, 77, 85, 92, 98, 103, 107, 110]) # Ill-defined, tri line_segment = (31.0, 71.0, 39.0, 101.0) up_path, down_path = mesh.find_two_neighboring_node_paths(line_segment) self.assertListEqual(up_path, [25, 19, 14]) self.assertListEqual(down_path, [24, 18, 13, 9]) # Ill-defined, quad line_segment = (71.0, 69.0, 101.0, 61.0) up_path, down_path = mesh.find_two_neighboring_node_paths(line_segment) self.assertListEqual(up_path, [73, 82, 90]) self.assertListEqual(down_path, [65, 74, 83]) # Diagonal corner cut line_segment = (82., -3, 103., 18.) up_path, down_path = mesh.find_two_neighboring_node_paths(line_segment) self.assertListEqual(up_path, [109, 111, 110]) self.assertListEqual(down_path, [106, 103, 107, 104, 108])
def cut_mesh(fpath_gr3_in, lines, fpath_gr3_out, cut_side='left'): """ Remove elements of a mesh in one side of cutting polyline segments. A mesh is read in from a gr3, and a result mesh is written in another gr3 file. A user needs to be careful that line segments forms a closed division. Otherwise, all elements would be deleted. Parameters ---------- fpath_gr3_in Filename of the input grid in gr3 lines: array-like An array of coordinates of line segments specifying the location of cuts fpath_gr3_out Filename of the output grid in gr3 cut_side: str, optional If cut_side is 'left,' which is default, the left side of cutting lines when one sees the second point from the first point of a line will be removed. If this value is 'right,' the right side will be removed. """ s = read_mesh(fpath_gr3_in) lines = np.array(lines).reshape(-1, 4) print("{} line(s) to cut found".format(lines.shape[0])) if cut_side == 'right': # Switch ordering lines = np.hstack((lines[:, 2:], lines[:, :2])) s.trim_to_left_of_mesh(lines) write_mesh(s, fpath_gr3_out)
def test_schism_mesh_centroids(self): fpath_mesh = self.fpath_mesh mesh = read_mesh(fpath_mesh) centroids = mesh.centroids() np.testing.assert_almost_equal(centroids[0, :], np.array([6.66666667, 96.66666667])) np.testing.assert_almost_equal(centroids[60, :], np.array([75., 45.]))
def test_read_hotstart(self): """ Check values from a hotstart """ fpath_mesh = os.path.join( os.path.dirname(__file__), 'testdata/schism_hotstart/simple_triquad/hgrid1.gr3') fpath_vmesh = os.path.join( os.path.dirname(__file__), 'testdata/schism_hotstart/simple_triquad/vgrid1.in') mesh = read_mesh(fpath_mesh, fpath_vmesh) fpath_hotstart = os.path.join( os.path.dirname(__file__), 'testdata/schism_hotstart/simple_triquad/hotstart1_elev0.in') hotstart = read_hotstart(mesh, fpath_hotstart) desired = np.array([[0., 10., 35.], [0., 10., 35.], [0., 10., 35.], [0., 10., 35.], [0., 10., 35.], [0., 10., 35.], [0., 10., 35.], [0., 10., 35.], [0., 10., 35.], [0., 10., 35.], [0., 10., 32.5]]) np.testing.assert_allclose(hotstart.elems[0], desired) desired = np.array([[0., 0., 10., 35.], [0., 0., 10., 35.], [0., 0., 10., 35.], [0., 0., 10., 35.], [0., 0., 10., 35.], [0., 0., 10., 35.], [0., 0., 10., 35.], [0., 0., 10., 35.], [0., 0., 10., 35.], [0., 0., 10., 35.], [0., 0., 10., 30.]]) np.testing.assert_allclose(hotstart.sides[0], desired) desired = np.array([[10., 35., 10., 35., 0., 0., 0., 0., 0., 0., 0.], [10., 35., 10., 35., 0., 0., 0., 0., 0., 0., 0.], [10., 35., 10., 35., 0., 0., 0., 0., 0., 0., 0.], [10., 35., 10., 35., 0., 0., 0., 0., 0., 0., 0.], [10., 35., 10., 35., 0., 0., 0., 0., 0., 0., 0.], [10., 35., 10., 35., 0., 0., 0., 0., 0., 0., 0.], [10., 35., 10., 35., 0., 0., 0., 0., 0., 0., 0.], [10., 35., 10., 35., 0., 0., 0., 0., 0., 0., 0.], [10., 35., 10., 35., 0., 0., 0., 0., 0., 0., 0.], [10., 35., 10., 35., 0., 0., 0., 0., 0., 0., 0.], [10., 30., 10., 30., 0., 0., 0., 0., 0., 0., 0.]]) np.testing.assert_allclose(hotstart.nodes[0], desired)
def main(): """ Just a main function """ parser = create_arg_parser() args = parser.parse_args() mesh = read_mesh(args.hgrid, args.vgrid) print(mesh.vmesh.n_vert_levels()) n_levels = mesh.vmesh.n_vert_levels() - np.array(mesh.vmesh.kbps) write_mesh(mesh, args.output, node_attr=n_levels)
def test_schism_mesh_gr3_reader_wo_vgrid(self): path = self.fpath_mesh mesh = read_mesh(path) self.assertEqual(mesh.n_nodes(), 112) self.assertEqual(mesh.n_elems(), 135) # Boundaries self.assertEqual(mesh.n_boundaries(), 3) self.assertEqual(mesh.n_boundaries(btype=BoundaryType.OPEN), 1) self.assertEqual(mesh.n_boundaries(btype=BoundaryType.LAND), 2) self.assertEqual(mesh.n_total_boundary_nodes(BoundaryType.OPEN), 11)
def test_build_z(self): fpath_mesh = os.path.join(self.dir_cur, 'testdata/testmesh/testmesh.gr3') fpath_vmesh = os.path.join(self.dir_cur, 'testdata/testmesh/vgrid.in') mesh = read_mesh(fpath_mesh, fpath_vmesh) z = mesh.build_z() desired = np.arange(-100.0, 0.1, 10.0) np.testing.assert_allclose(z[0], desired) node_i = 5 desired = np.full((mesh.vmesh.n_vert_levels(), ), -80.0) desired[2:] = np.arange(-80.0, 0.1, 10.0) np.testing.assert_allclose(z[node_i], desired)
def test_schism_mesh_gr3_reader_w_vgrid_sz(self): fpath_mesh = self.fpath_mesh fpath_vmesh = self.fpath_vmesh_sz mesh = read_mesh(fpath_mesh, fpath_vmesh) self.assertEqual(mesh.vmesh.param['nvrt'], 12) self.assertEqual(mesh.vmesh.param['kz'], 2) self.assertEqual(mesh.vmesh.param['h_s'], 80.) self.assertEqual(mesh.vmesh.param['h_c'], 5.0) self.assertTrue( np.allclose( mesh.vmesh.sigma, np.array([ -1.00, -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1, 0. ])))
def create_schism_setup(fname, logger=None): """ Read a mesh and return a SCHISM input set-up instance. Parameters ---------- fname: str Returns ------- SCHISM input set-up instance """ s = SchismSetup(logger) # Read the grid if not os.path.exists(fname): raise Exception("Grid file not found: {}".format(fname)) s.mesh = read_mesh(fname) return s
def test_interpolate_hotstart_simple_triquad_self(self): """ Interpolating to the same grid should yield the same hotstart """ mesh_in = read_mesh( os.path.join(self.test_dir, 'simple_triquad/hgrid1.gr3'), os.path.join(self.test_dir, 'simple_triquad/vgrid1.in')) hotstart_base = read_hotstart( mesh_in, os.path.join(self.test_dir, 'simple_triquad/hotstart1_elev0.in')) hotstart_new = interpolate_hotstart(mesh_in, hotstart_base, mesh_in) # np.testing.assert_allclose(hotstart_base.nodes, hotstart_new.nodes) # np.testing.assert_allclose(hotstart_base.elems, hotstart_new.elems, atol=1e-100) # np.testing.assert_allclose(hotstart_base.sides, hotstart_new.sides, atol=1e-100) # np.testing.assert_allclose(hotstart_base.nodes_elev, hotstart_new.nodes_elev, atol=1e-100) # np.testing.assert_allclose(hotstart_base.nodes_dry, hotstart_new.nodes_dry) # np.testing.assert_allclose(hotstart_base.elems_dry, hotstart_new.elems_dry) # np.testing.assert_allclose(hotstart_base.sides_dry, hotstart_new.sides_dry) self.assertEqual(hotstart_base, hotstart_new)
def plot_vgrid(hgrid_file, vgrid_file, vgrid0_file, eta, transectfiles): from lsc2 import default_num_layers, plot_mesh from schism_vertical_mesh import * import matplotlib.pylab as plt import os.path as ospath mesh = read_mesh(hgrid_file) x = mesh.nodes[:, 0:2] vmesh0 = read_vmesh(vgrid0_file) vmesh1 = read_vmesh(vgrid_file) h0 = mesh.nodes[:, 2] depth = eta + h0 zcor0 = vmesh0.build_z(mesh, eta)[:, ::-1] zcor1 = vmesh1.build_z(mesh, eta)[:, ::-1] for transectfile in transectfiles: base = ospath.splitext(ospath.basename(transectfile))[0] transect = np.loadtxt(transectfile, skiprows=1, delimiter=",") #transx = transect[:,1:3] path = [] transx = transect[:, 1:3] for p in range(transx.shape[0]): path.append(mesh.find_closest_nodes(transx[p, :])) #ndx1 = mesh.find_closest_nodes(transx[-1,:]) #path = mesh.shortest_path(ndx0,ndx1) #zcorsub = zcor[path,:] xx = x[path] xpath = np.zeros(xx.shape[0]) for i in range(1, len(path)): dist = np.linalg.norm(xx[i, :] - xx[i - 1, :]) xpath[i] = xpath[i - 1] + dist fig, (ax0, ax1) = plt.subplots(2, 1) #,sharex=True,sharey=True) plt.title(transectfile) #plot_mesh(ax0,xpath,zcor0[path,:],0,len(xpath),c="0.5",linewidth=2) plot_mesh(ax0, xpath, zcor0[path, :], 0, len(xpath), c="red") plot_mesh(ax1, xpath, zcor1[path, :], 0, len(xpath), c="blue") ax0.plot(xpath, -h0[path], linewidth=2, c="black") ax1.plot(xpath, -h0[path], linewidth=2, c="black") plt.savefig(ospath.join("images", base + ".png")) plt.show()
def grid_opt_with_args(args): """ Optimize grid with arguments parsed by argparse """ with open(args.optparam) as f: opt_param = schism_yaml.load(f) mesh = read_mesh(args.filename, nodestring_option='land') with open(args.demfile, 'r') as f: demfiles = schism_yaml.load(f) # dir = os.path.dirname(args.demfile) # demfiles_full = [os.path.join(dir, fname) for fname in demfiles] logger = init_logger() kwargs = { 'mesh': mesh, 'demfiles': demfiles, # demfiles_full, 'na_fill': args.na_fill, 'logger': logger } optimizer = GridOptimizer(**kwargs) optimized = optimizer.optimize(opt_param) fpath_output = args.optfile write_mesh(mesh, fpath_output, node_attr=-optimized)
def vgrid_gen(hgrid, vgrid_out, eta, minmaxlayerfile, ngen, maxiter, theta, b, hc, dx2fac=20.0, curvewgt=100.0, foldwgt=20., foldfrac=0.35, archive_nlayer=None, nlayer_gr3=None): from numlayer import tabu_numlayer from lsc2 import default_num_layers from vgrid_opt2 import * print("Reading the mesh ") mesh = read_mesh(hgrid) h0 = mesh.nodes[:, 2] depth = eta + h0 if archive_nlayer == 'out': print("Reading the polygons...") polygons = read_polygons(minmaxlayerfile) minlayer = np.ones_like(h0, dtype='int') #minlayer[:] = 8 # todo need polygons maxlayer = np.ones_like(h0, dtype='int') * 10000 dztarget = np.full_like(h0, 100., dtype='d') #maxlayer[:] = 31 print("Assign min/max layers to nodes based on polygons...") for polygon in polygons: box = [polygon.bounds[i] for i in (0, 2, 1, 3)] candidates = mesh.find_nodes_in_box(box) n_layers_min = int(polygon.prop['minlayer']) n_layers_max = int(polygon.prop['maxlayer']) dz0 = float(polygon.prop['dz_target']) for node_i in candidates: if polygon.intersects(mesh.nodes[node_i, :2]): minlayer[node_i] = n_layers_min maxlayer[node_i] = n_layers_max dztarget[node_i] = dz0 if np.any(np.isnan(minlayer)): print(np.where(np.isnan(minlayer))) raise ValueError('Nan value in minlayer') print("Creating vertical grid...") #meshsmooth = read_mesh("hgrid_depth_smooth.gr3") hsmooth = mesh.nodes[:, 2] etazero = 0. assert len(hsmooth) == len(h0) # todo: was eta and h0 dztarget = dztarget * 0 + 1. dztarget = 0.6 + 0.4 * (hsmooth - 12.) / (22. - 12.) dztarget = np.minimum(1.0, dztarget) dztarget = np.maximum(0.65, dztarget) #dztarget2 = np.minimum(1.3,0.65+0.65*(2.-hsmooth)) #dztarget[hsmooth<2.] = dztarget2[hsmooth<2.] nlayer_default = default_num_layers(eta, hsmooth, minlayer, maxlayer, dztarget) #print nlayer_default #nlayer = deap_numlayer(depth,mesh.edges,nlayer_default,minlayer,ngen) nlayer = tabu_numlayer(depth, mesh.edges, nlayer_default, minlayer, maxlayer, ngen) print depth.shape print nlayer.shape if archive_nlayer == "out": print "writing out number of layers" write_mesh(mesh, nlayer_gr3.replace(".gr3", "_default.gr3"), node_attr=nlayer_default) write_mesh(mesh, nlayer_gr3, node_attr=nlayer) write_mesh(mesh, nlayer_gr3.replace(".gr3", "_dztarget.gr3"), node_attr=dztarget) elif archive_nlayer == "in": nlayer_mesh = read_mesh(nlayer_gr3) dztarget = read_mesh(nlayer_gr3.replace(".gr3", "_dztarget.gr3")).nodes[:, 2] nlayer = nlayer_mesh.nodes[:, 2].astype('i') if long(nlayer_mesh.n_nodes()) != long(mesh.n_nodes()): raise ValueError( "NLayer gr3 file (%s)\nhas %s nodes, hgrid file (%s) has %s" % (nlayer_gr3, nlayer_mesh.n_nodes(), hgrid, mesh.n_nodes())) #print("Reading the polygons for dz_target...") #polygons = read_polygons(minmaxlayerfile) #dztarget = np.full_like(h0, np.nan, dtype='d') #maxlayer[:] = 31 #print("Assign dz_target to nodes based on polygons...") #for polygon in polygons: # box = [polygon.bounds[i] for i in (0, 2, 1, 3)] # candidates = mesh.find_nodes_in_box(box) # dz0 = float(polygon.prop['dz_target']) # for node_i in candidates: # if polygon.intersects(mesh.nodes[node_i, :2]): # dztarget[node_i] = dz0 else: raise ValueError("archive_nlayer must be one of 'out', 'in' or None") #np.savez("savevar.npz",nlayer,nlayer_default,depth,h0) sigma, nlayer_revised = gen_sigma(nlayer, dztarget, eta, h0, theta, b, hc, mesh=mesh) print "sigma shape" print sigma.shape nlayer = nlayer_revised nlevel = nlayer + 1 #fsigma = flip_sigma(sigma) #print fsigma[0,:] vmesh = SchismLocalVerticalMesh(flip_sigma(sigma)) vgrid0 = vgrid_out.replace(".in", "_int.in") write_vmesh(vmesh, vgrid0) # Gradient based stuff nodes = mesh.nodes edges = mesh.edges x = nodes[:, 0:2] # x positions for xsect. These have no analog in 3D sidelen2 = np.sum((x[edges[:, 1], :] - x[edges[:, 0], :])**2., axis=1) #nodemasked = (depth < 0.75) #| (nlayer <= 2) #todo hardwire was 0.75 nodemasked = (depth < 0.75) #| (nlayer <= 2) sidemasked = nodemasked[edges[:, 0]] | nodemasked[edges[:, 1]] gradmat = gradient_matrix(mesh, sidelen2, sidemasked) print "Nodes excluded: %s" % np.sum(nodemasked) print "Sides excluded: %s" % np.sum(sidemasked) zcor = vmesh.build_z(mesh, eta)[:, ::-1] # todo: test this #zcor[depth < 0., :] = np.nan # todo: why is kbps-1 so common? What does it mean and why the funny offset nvlevel = (vmesh.n_vert_levels() - vmesh.kbps) #nvlevel[depth<0] = 0 nlayer, ndx = index_interior(zcor, nodemasked, nvlevel) xvar = zcor[ndx >= 0].flatten() xvarbase = xvar.copy() zcorold = zcor.copy() zmin = np.nanmin(zcorold, axis=1) deptharr = np.tile(zmin, (zcorold.shape[1], 1)).T zcorold = np.where(np.isnan(zcorold), deptharr, zcorold) do_opt = False if do_opt: curvewgt = np.zeros_like(zcorold) + curvewgt #todo: hardwire #bigcurvewgt = 4 #for iii in range(zcor.shape[0]): # nlev = nlayer[iii]+1 # curvewgt[iii,0:nlev]+=np.maximum(np.linspace(bigcurvewgt-nlev,bigcurvewgt-nlev,nlev),1) # todo ata = laplace2(mesh, nodemasked, sidemasked) href_hess, grad_hess, laplace_hess = hess_base( xvar, zcorold, mesh, nlayer, ndx, eta, depth, gradmat, sidelen2, nodemasked, sidemasked, ata, dx2fac, curvewgt, foldwgt, foldfrac) zcor1 = mesh_opt(zcorold, mesh, nlayer, ndx, eta, depth, gradmat, sidelen2, nodemasked, sidemasked, ata, dx2fac, curvewgt, foldwgt, foldfrac, href_hess, grad_hess, laplace_hess) else: zcor1 = zcorold sigma1 = z_sigma(zcor1) nlevel = nlayer + 1 for i in range(len(depth)): nlev = nlevel[i] if depth[i] <= 0: sigma1[i, 0:nlev] = np.linspace(0, -1.0, nlev) sigma1[i, nlev:] = np.nan vmesh1 = SchismLocalVerticalMesh(flip_sigma(sigma1)) print("Writing vgrid.in output file...") write_vmesh(vmesh1, vgrid_out) print "Done"
def bay_delta_hotstart_with_cdec_stations(args): """ Create a hotstart file with USGS cruise data and CDEC data If CDEC data is not given, a constant salinity is set Parameters ---------- args: namespace command line arguments parsed by argparse """ logger = init_logger('bay_delta_hotstart') generator = HotstartGenerator(logger=logger) fpath_mesh = args.hgrid fpath_vgrid = args.vgrid fpath_elev_polygons = args.elev fpath_usgs_cruise = args.usgs_data fpath_usgs_cruise_stations = args.usgs_station fpath_cdec_data = args.cdec_data fpath_cdec_stations = args.cdec_station fpath_estuary_polygons = args.estuary fpath_hotstart = args.hotstart polygons_estuary = read_polygons(fpath_estuary_polygons) if fpath_elev_polygons is not None: polygons_elev = read_polygons(fpath_elev_polygons) else: polygons_elev = None usgs_stations = read_stations(fpath_usgs_cruise_stations) usgs_data = read_station_data(fpath_usgs_cruise) for row in usgs_data: if 'station number' in row: row['id'] = row['station number'] del row['station number'] if fpath_cdec_stations is not None: cdec_stations = read_stations(fpath_cdec_stations) else: cdec_stations = None if fpath_cdec_data is not None: cdec_data = read_station_data(fpath_cdec_data) else: cdec_data = None # Load mesh information if not os.path.exists(fpath_mesh): logger.error("A mesh file not found: %s", fpath_mesh) raise ValueError("A mesh file not found") if not os.path.exists(fpath_vgrid): logger.error("A vertical mesh file not found: %s", fpath_vgrid) raise ValueError("A vertical mesh file not found") logger.info("Reading a mesh...") mesh = read_mesh(fpath_mesh, fpath_vgrid) logger.info("Setting up initializers...") # Salinity ocean_salt = args.ocean_salt if cdec_data is not None: generator.gen_salt = \ RegionalInitializer(mesh, polygons_estuary, {'default': ocean_salt, 'bay': NearestNeighborInitializer(mesh, usgs_stations, usgs_data, 'salinity'), 'delta': NearestNeighborInitializer(mesh, cdec_stations, cdec_data, 'salinity'), }) else: delta_salt = args.delta_salt generator.gen_salt = \ RegionalInitializer(mesh, polygons_estuary, {'default': ocean_salt, 'bay': NearestNeighborInitializer(mesh, usgs_stations, usgs_data, 'salinity'), 'delta': delta_salt }) # Temperature generator.gen_temp = RegionalInitializer(mesh, polygons_estuary, {'default': 12., 'bay': NearestNeighborInitializer(mesh, usgs_stations, usgs_data, 'temperature'), 'delta': 10.5 }) # Elevation if polygons_elev is not None: generator.gen_elev = RegionalInitializer(mesh, polygons_elev, {'default': 0.96, 'ccfb': 0.525}) else: generator.gen_elev = None # Create hotstart file logger.info("Start creating a hotstart file...") generator.create_hotstart(mesh, fpath_hotstart)
def test_schism_mesh_edge_len(self): fpath_mesh = self.fpath_mesh mesh = read_mesh(fpath_mesh) edge_lens = mesh.edge_len() self.assertAlmostEqual(edge_lens[0], 14.14213562) self.assertAlmostEqual(edge_lens[1], 10.)
def test_schism_mesh_areas(self): fpath_mesh = self.fpath_mesh mesh = read_mesh(fpath_mesh) areas = mesh.areas() self.assertEqual(areas[0], 50.) self.assertEqual(areas[60], 100.)
def vgrid_gen(hgrid, vgrid_out, eta, minmaxlayerfile, archive_nlayer=None, nlayer_gr3=None): from lsc2 import default_num_layers meshfun = BilinearMeshDensity() dummydepth = np.linspace(0, 14, 15) dummyk = np.linspace(0, 14, 15) dummyout = meshfun.depth(dummyk, dummydepth, 0.) print("Reading the mesh ") mesh = read_mesh(hgrid) h0 = mesh.nodes[:, 2] places_on = np.array( [[626573.490000, 4260349.590000], [626635.000000, 4260391.7]], dtype='d') dists_on = np.min(scipy.spatial.distance.cdist(mesh.nodes[:, 0:2], places_on), axis=1) print(np.where(dists_on < 100)) depth = eta + h0 print("Reading the polygons...") polygons = read_polygons(minmaxlayerfile) minlayer = np.ones_like(h0, dtype='int') #minlayer[:] = 8 # todo need polygons maxlayer = np.ones_like(h0, dtype='int') * 10000 dztarget = np.full_like(h0, 100., dtype='d') print("Assign min/max layers to nodes based on polygons...") for polygon in polygons: box = [polygon.bounds[i] for i in (0, 2, 1, 3)] candidates = mesh.find_nodes_in_box(box) n_layers_min = int(polygon.prop['minlayer']) n_layers_max = int(polygon.prop['maxlayer']) dz0 = float(polygon.prop['dz_target']) for node_i in candidates: if polygon.intersects(mesh.nodes[node_i, :2]): minlayer[node_i] = n_layers_min maxlayer[node_i] = n_layers_max dztarget[node_i] = dz0 if np.any(np.isnan(minlayer)): print((np.where(np.isnan(minlayer)))) raise ValueError('Nan value in minlayer') if archive_nlayer == 'out': dztarget = 0. #todo: these will ruin the code if fix_minmax: minlayer = minlayer * 0 + fixed_min maxlayer = maxlayer * 0 + fixed_max #np.max(maxlayer) xdummy = 0. nlayer_default = default_num_layers(xdummy, eta, h0, minlayer, maxlayer, dztarget, meshfun) nlayer = nlayer_default if archive_nlayer == "out": print("writing out number of layers") write_mesh(mesh, nlayer_gr3.replace(".gr3", "_default.gr3"), node_attr=nlayer_default) write_mesh(mesh, nlayer_gr3, node_attr=nlayer) #write_mesh(mesh,nlayer_gr3.replace(".gr3","_dztarget.gr3"),node_attr=dztarget) elif archive_nlayer == "in": nlayer_mesh = read_mesh(nlayer_gr3) #dztarget=read_mesh(nlayer_gr3.replace(".gr3","_dztarget.gr3")).nodes[:,2] nlayer = nlayer_mesh.nodes[:, 2].astype('i') if int(nlayer_mesh.n_nodes()) != int(mesh.n_nodes()): raise ValueError( "NLayer gr3 file (%s)\nhas %s nodes, hgrid file (%s) has %s" % (nlayer_gr3, nlayer_mesh.n_nodes(), hgrid, mesh.n_nodes())) else: raise ValueError("archive_nlayer must be one of 'out', 'in' or None") # inclusion of minlayer and maxlayer has to do with experiment regenerating # layers after smoothing # this will ruin code generally, and if the experiment goes well we need to make sure this is available when archive_nlayer="in" if fix_minmax: minlayer = nlayer * 0 + fixed_min maxlayer = nlayer * 0 + fixed_max #np.max(maxlayer) sigma2, nlayer_revised = gen_sigma(nlayer, minlayer, maxlayer, eta, h0, mesh, meshfun) print("Returned nlayer revised: {}".format(np.max(nlayer_revised))) nlayer = nlayer_revised nlevel = nlayer + 1 vmesh = SchismLocalVerticalMesh(flip_sigma(sigma2)) #vgrid0 = vgrid_out.replace(".in", "_int.in") #write_vmesh(vmesh, vgrid0) #vmesh1 = SchismLocalVerticalMesh(flip_sigma(sigma1)) print("Writing vgrid.in output file...") write_vmesh(vmesh, vgrid_out) print("Done")
def example(): import schism_mesh dx2fac = 10. #1000. curvewgt = 100. #0.01 # 0.05 #0.05 #0.05 #0.03 #800000 foldwgt = 22. #1.e3 foldfrac = 0.35 maxiter = 200 #gr3name = "gg_cut.gr3" gr3name = "victoria.gr3" #gr3name= "hgrid.gr3" mesh = schism_mesh.read_mesh(gr3name) nodes = mesh.nodes edges = mesh.edges x = nodes[:, 0:2] # x positions for xsect. These have no analog in 3D h0 = nodes[:, 2] # nominal depth, as in hgrid.gr3 nx = x.shape[0] sidelen2 = np.sum((x[edges[:, 1], :] - x[edges[:, 0], :])**2., axis=1) eta = 1.0 # Reference height at which assessed. Aim on the high side minlayer = 4 maxlayer = 8 maxlayer = np.zeros(nx, 'i') + maxlayer maxlevel = maxlayer + 1 depth = eta + h0 theta = 2 b = 0. hc = 0 nlayer_default = default_num_layers(eta, h0, minlayer, maxlayer) nlayer = deap_numlayer(depth, mesh.edges, nlayer_default, float(minlayer)) nodemasked = depth < 1.0 sidemasked = nodemasked[edges[:, 0]] | nodemasked[edges[:, 1]] gradmat = gradient_matrix(mesh, sidelen2, sidemasked) print("Nodes excluded: %s" % np.sum(nodemasked)) print("Sides excluded: %s" % np.sum(sidemasked)) sigma = gen_sigma(nlayer, eta, h0, theta, b, hc) zcor = sigma_z(sigma, eta, h0) nlayer, ndx = index_interior(zcor, nodemasked) ata = laplace2(mesh, nodemasked, sidemasked) xvar = zcor[ndx >= 0].flatten() xvarbase = xvar.copy() zcorold = zcor.copy() zmin = np.nanmin(zcorold, axis=1) deptharr = np.tile(zmin, (zcorold.shape[1], 1)).T zcorold = np.where(np.isnan(zcorold), deptharr, zcorold) href_hess, grad_hess, laplace_hess = hess_base(xvar, zcorold, mesh, nlayer, ndx, eta, depth, gradmat, sidelen2, nodemasked, sidemasked, ata, dx2fac, curvewgt, foldwgt, foldfrac) zcor2 = mesh_opt(zcorold, mesh, nlayer, ndx, eta, depth, gradmat, sidelen2, nodemasked, sidemasked, ata, dx2fac, curvewgt, foldwgt, foldfrac, href_hess, grad_hess, laplace_hess)
def test_gradients(): import schism_mesh dx2fac = 0.0 #1000. curvewgt = 0.02 #0.01 # 0.05 #0.05 #0.05 #0.03 #800000 foldwgt = 1.e3 foldfrac = 0.5 maxiter = 4000 gr3name = "test.gr3" delta = 1e-6 mesh = schism_mesh.read_mesh(gr3name) nodes = mesh.nodes edges = mesh.edges x = nodes[:, 0:2] # x positions for xsect. These have no analog in 3D h0 = nodes[:, 2] # nominal depth, as in hgrid.gr3 nx = x.shape[0] sidelen2 = np.sum((x[edges[:, 1], :] - x[edges[:, 0], :])**2., axis=1) eta = 1.0 # Reference height at which assessed. Aim on the high side minlayer = 3 maxlayer = 6 maxlayer = np.zeros(nx, 'i') + maxlayer maxlevel = maxlayer + 1 depth = eta + h0 theta = 2 b = 0. hc = 0 nodemasked = depth < 1.0 sidemasked = nodemasked[edges[:, 0]] & nodemasked[edges[:, 1]] gradmat = gradient_matrix(mesh, sidelen2, sidemasked) print("Nodes excluded: %s" % np.sum(nodemasked)) print("Sides excluded: %s" % np.sum(sidemasked)) #sigma = gen_sigma(nlayer,eta,h0,theta,b,hc) # todo: this has excluded node, but not side zcor = np.array([[1.0, -0.2, np.nan, np.nan, np.nan], [1.0, -0.3, -1.8, np.nan, np.nan], [1.0, -0.1, -1.2, -2.3, np.nan], [1.0, -0.2, -1.4, -2.6, -3.8], [1.0, -0.1, -1.2, -2.3, np.nan], [1.0, 0.8, 0.6, 0.4, np.nan]]) #todo: nlayer is being calculated several times nlayer, ndx = index_interior(zcor, nodemasked) assert np.all(nlayer == [1, 2, 3, 4, 3, 3]) #this is a 2D quantity ata = laplace2(mesh, nodemasked, sidemasked) xvar = zcor[ndx >= 0].flatten() xvarbase = xvar.copy() zcorold = zcor.copy() zmin = np.nanmin(zcorold, axis=1) deptharr = np.tile(zmin, (zcorold.shape[1], 1)).T zcorold = np.where(np.isnan(zcorold), deptharr, zcorold) curvewgt = np.zeros_like(zcorold) + curvewgt curvewgt[2, :] = 0.1 curvewgt[3:, 0:2] = 0.2 href_hess, grad_hess, laplace_hess = hess_base(xvar, zcorold, mesh, nlayer, ndx, eta, depth, gradmat, sidelen2, nodemasked, sidemasked, ata, dx2fac, curvewgt, foldwgt, foldfrac) xvar[5] = -2.8 xvar[6] = 0.8 xvar[7] = 0.5 obj1 = meshobj(xvar, zcorold, mesh, nlayer, ndx, eta, depth, gradmat, sidelen2, nodemasked, sidemasked, ata, dx2fac, curvewgt, foldwgt, foldfrac, href_hess, grad_hess, laplace_hess) grad1 = meshgrad(xvar, zcorold, mesh, nlayer, ndx, eta, depth, gradmat, sidelen2, nodemasked, sidemasked, ata, dx2fac, curvewgt, foldwgt, foldfrac, href_hess, grad_hess, laplace_hess) print("calc hessian") big_hess = grad_hess + href_hess + laplace_hess print(big_hess) xvarbase = xvar.copy() numgrad = np.zeros(8) for i in range(8): xvar = xvarbase.copy() xvar[i] += delta obj2 = meshobj(xvar, zcorold, mesh, nlayer, ndx, eta, depth, gradmat, sidelen2, nodemasked, sidemasked, ata, dx2fac, curvewgt, foldwgt, foldfrac, href_hess, grad_hess, laplace_hess) grad2 = meshgrad(xvar, zcorold, mesh, nlayer, ndx, eta, depth, gradmat, sidelen2, nodemasked, sidemasked, ata, dx2fac, curvewgt, foldwgt, foldfrac, href_hess, grad_hess, laplace_hess) numgrad[i] = (obj2 - obj1) / delta print("num hessian (%s)" % i) print((grad2 - grad1) / delta) xvar = xvarbase.copy() p = np.array([0., 0., 0., 0., 0., 0., 0., 0.]) jtest = 7 p[jtest] = 1. hessp = meshessp(xvar, p, zcorold, mesh, nlayer, ndx, eta, depth, gradmat, sidelen2, nodemasked, sidemasked, ata, dx2fac, curvewgt, foldwgt, foldfrac, href_hess, grad_hess, laplace_hess) print("\n**hessian element [%s]" % jtest) print(hessp) print("\ngradient") print(numgrad) print(grad1)
def convert_mesh(args): mesh = read_mesh(args.input) write_mesh(mesh, args.output, proj4=args.proj4)