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)
예제 #2
0
 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)
예제 #3
0
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.")
예제 #4
0
 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])))
예제 #5
0
 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])
예제 #6
0
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)
예제 #7
0
 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.]))
예제 #8
0
 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)
예제 #9
0
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)
예제 #10
0
 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)
예제 #11
0
 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)
예제 #12
0
 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.
             ])))
예제 #13
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)
예제 #15
0
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()
예제 #16
0
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)
예제 #17
0
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"
예제 #18
0
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)
예제 #19
0
 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.)
예제 #20
0
 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.)
예제 #21
0
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")
예제 #22
0
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)
예제 #23
0
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)
예제 #24
0
def convert_mesh(args):
    mesh = read_mesh(args.input)
    write_mesh(mesh, args.output, proj4=args.proj4)