def project(geom, mesh, gprj, mprj, pmid): """ PROJECT: projection of GEOM/MESH objects to a 2d. plane. Modifies GPRJ, MPRJ objects "inplace". """ # Authors: Darren Engwirda proj = jigsawpy.jigsaw_prj_t() mprj.point = np.full( mesh.point.size, +0, dtype=mprj.VERT2_t) mprj.point["coord"] = \ jigsawpy.R3toS2( geom.radii, mesh.point["coord"]) proj.prjID = "stereographic" proj.radii = np.mean(geom.radii) proj.xbase = pmid[0] * np.pi / +180. proj.ybase = pmid[1] * np.pi / +180. jigsawpy.project(gprj, proj, "fwd") jigsawpy.project(mprj, proj, "fwd") return
def zipnear(init, geom, spac, near=10.0): """ ZIPNEAR: "zip" nodes / cells in INIT. that are "too near" to geometry features. Here, "too near" means they lie within NEAR * H(x) of objects in GEOM. where H(x) is the spacing distribution defined via SPAC. The INIT. object is modified in-place. """ # Authors: Darren Engwirda #------------------------------------ subdiv. geom. for H(x) divgeom(geom, spac) #------------------------------------ find dist. to geometry tree = spatial.cKDTree(jigsawpy.S2toR3(geom.radii, geom.point["coord"])) dmax = np.max(spac.value) * near dist, _ = tree.query(init.point["coord"], eps=0.0, distance_upper_bound=dmax) apos = jigsawpy.R3toS2(geom.radii, init.point["coord"][:]) #------------------------------------ zip init. if too close hfun = interpolate.RectBivariateSpline(spac.ygrid, spac.xgrid, spac.value) hval = hfun(apos[:, 1], apos[:, 0], grid=False) keep = dist >= hval * near #------------------------------------ re-index init. for zip if (init.edge2 is not None and init.edge2.size > +0): mask = np.logical_and.reduce( (keep[init.edge2["index"][:, 0]], keep[init.edge2["index"][:, 1]])) init.edge2 = init.edge2[mask] if (init.tria3 is not None and init.tria3.size > +0): mask = np.logical_and.reduce( (keep[init.tria3["index"][:, 0]], keep[init.tria3["index"][:, 1]], keep[init.tria3["index"][:, 2]])) init.tria3 = init.tria3[mask] zipmesh(init) return
def R3toS2(radii, E3): """ R3TOS2: return the LON-LAT coord's associated with a set of points in R^3. A (geocentric) projection is first done to ensure the points lie on the ellipsoidal surface, with the projected points then transformed to [LON,LAT] pairs. """ # Authors: Darren Engwirda PP = .5 * E3 ax = PP[:, 0]**1 / radii[0]**1 ay = PP[:, 1]**1 / radii[1]**1 az = PP[:, 2]**1 / radii[2]**1 aa = ax**2 + ay**2 + az**2 bx = PP[:, 0]**2 / radii[0]**2 by = PP[:, 1]**2 / radii[1]**2 bz = PP[:, 2]**2 / radii[2]**2 bb = bx * 2. + by * 2. + bz * 2. cx = PP[:, 0]**1 / radii[0]**1 cy = PP[:, 1]**1 / radii[1]**1 cz = PP[:, 2]**1 / radii[2]**1 cc = cx**2 + cy**2 + cz**2 cc = cc - 1.0 ts = bb * bb - 4. * aa * cc ok = ts >= .0 AA = aa[ok] BB = bb[ok] CC = cc[ok] TS = ts[ok] t1 = (-BB + np.sqrt(TS)) / AA / 2.0 t2 = (-BB - np.sqrt(TS)) / AA / 2.0 tt = np.maximum(t1, t2) P3 = np.zeros(E3.shape, dtype=float) P3[ok, 0] = (1. + tt) * PP[ok, 0] P3[ok, 1] = (1. + tt) * PP[ok, 1] P3[ok, 2] = (1. + tt) * PP[ok, 2] return jigsawpy.R3toS2(radii, P3)
def case_2_(src_path, dst_path): # DEMO-2: generate a regionally-refined global grid with a # high-resolution 37.5km patch embedded in a uniform 150km # background grid. opts = jigsawpy.jigsaw_jig_t() topo = jigsawpy.jigsaw_msh_t() geom = jigsawpy.jigsaw_msh_t() hfun = jigsawpy.jigsaw_msh_t() mesh = jigsawpy.jigsaw_msh_t() #------------------------------------ setup files for JIGSAW opts.geom_file = \ os.path.join(src_path, "eSPH.msh") opts.jcfg_file = \ os.path.join(dst_path, "eSPH.jig") opts.mesh_file = \ os.path.join(dst_path, "mesh.msh") opts.hfun_file = \ os.path.join(dst_path, "spac.msh") #------------------------------------ define JIGSAW geometry geom.mshID = "ellipsoid-mesh" geom.radii = np.full(3, 6.371E+003, dtype=geom.REALS_t) jigsawpy.savemsh(opts.geom_file, geom) #------------------------------------ define spacing pattern hfun.mshID = "ellipsoid-grid" hfun.radii = geom.radii hfun.xgrid = np.linspace(-1. * np.pi, +1. * np.pi, 360) hfun.ygrid = np.linspace(-.5 * np.pi, +.5 * np.pi, 180) xmat, ymat = \ np.meshgrid(hfun.xgrid, hfun.ygrid) hfun.value = +150. - 112.5 * np.exp(-(+1.5 * (xmat + 1.0)**2 + +1.5 * (ymat - 0.5)**2)**4) jigsawpy.savemsh(opts.hfun_file, hfun) #------------------------------------ make mesh using JIGSAW opts.hfun_scal = "absolute" opts.hfun_hmax = float("inf") # null HFUN limits opts.hfun_hmin = float(+0.00) opts.mesh_dims = +2 # 2-dim. simplexes opts.optm_qlim = +9.5E-01 # tighter opt. tol opts.optm_iter = +32 opts.optm_qtol = +1.0E-05 jigsawpy.cmd.tetris(opts, 3, mesh) scr2 = jigsawpy.triscr2( # "quality" metric mesh.point["coord"], mesh.tria3["index"]) #------------------------------------ save mesh for Paraview jigsawpy.loadmsh(os.path.join(src_path, "topo.msh"), topo) #------------------------------------ a very rough land mask apos = jigsawpy.R3toS2(geom.radii, mesh.point["coord"][:]) apos = apos * 180. / np.pi zfun = interpolate.RectBivariateSpline(topo.ygrid, topo.xgrid, topo.value) mesh.value = zfun(apos[:, 1], apos[:, 0], grid=False) cell = mesh.tria3["index"] zmsk = \ mesh.value[cell[:, 0]] + \ mesh.value[cell[:, 1]] + \ mesh.value[cell[:, 2]] zmsk = zmsk / +3.0 mesh.tria3 = mesh.tria3[zmsk < +0.] print("Saving to ../cache/case_2a.vtk") jigsawpy.savevtk(os.path.join(dst_path, "case_2a.vtk"), mesh) print("Saving to ../cache/case_2b.vtk") jigsawpy.savevtk(os.path.join(dst_path, "case_2b.vtk"), hfun) return
def case_2_(src_path, dst_path): # DEMO-2: generate a regionally-refined global grid with a # high-resolution 37.5km patch embedded in a uniform 150km # background grid. opts = jigsawpy.jigsaw_jig_t() topo = jigsawpy.jigsaw_msh_t() geom = jigsawpy.jigsaw_msh_t() hfun = jigsawpy.jigsaw_msh_t() mesh = jigsawpy.jigsaw_msh_t() #------------------------------------ setup files for JIGSAW opts.geom_file = \ os.path.join(dst_path, "geom.msh") opts.jcfg_file = \ os.path.join(dst_path, "opts.jig") opts.mesh_file = \ os.path.join(dst_path, "mesh.msh") opts.hfun_file = \ os.path.join(dst_path, "spac.msh") #------------------------------------ define JIGSAW geometry geom.mshID = "ellipsoid-mesh" geom.radii = np.full(3, 6.371E+003, dtype=geom.REALS_t) jigsawpy.savemsh(opts.geom_file, geom) #------------------------------------ define spacing pattern hfun.mshID = "ellipsoid-grid" hfun.radii = geom.radii hfun.xgrid = np.linspace(-1. * np.pi, +1. * np.pi, 360) hfun.ygrid = np.linspace(-.5 * np.pi, +.5 * np.pi, 180) xmat, ymat = \ np.meshgrid(hfun.xgrid, hfun.ygrid) hfun.value = +150. - 112.5 * np.exp(-(+1.5 * (xmat + 1.0)**2 + +1.5 * (ymat - 0.5)**2)**4) jigsawpy.savemsh(opts.hfun_file, hfun) #------------------------------------ make mesh using JIGSAW opts.hfun_scal = "absolute" opts.hfun_hmax = float("inf") # null HFUN limits opts.hfun_hmin = float(+0.00) opts.mesh_dims = +2 # 2-dim. simplexes opts.optm_qlim = +9.5E-01 # tighter opt. tol opts.optm_iter = +32 opts.optm_qtol = +1.0E-05 # opts.optm_kern = "cvt+dqdx" rbar = np.mean(geom.radii) # bisect heuristic hbar = np.mean(hfun.value) nlev = round(math.log2(rbar / math.sin(.4 * math.pi) / hbar)) ttic = time.time() jigsawpy.cmd.tetris(opts, nlev - 1, mesh) ttoc = time.time() print("CPUSEC =", (ttoc - ttic)) print("BISECT =", +nlev) cost = jigsawpy.triscr2( # quality metrics! mesh.point["coord"], mesh.tria3["index"]) print("TRISCR =", np.min(cost), np.mean(cost)) cost = jigsawpy.pwrscr2(mesh.point["coord"], mesh.power, mesh.tria3["index"]) print("PWRSCR =", np.min(cost), np.mean(cost)) tbad = jigsawpy.centre2(mesh.point["coord"], mesh.power, mesh.tria3["index"]) print("OBTUSE =", +np.count_nonzero(np.logical_not(tbad))) ndeg = jigsawpy.trideg2(mesh.point["coord"], mesh.tria3["index"]) print("TOPOL. =", +np.count_nonzero(ndeg == +6) / ndeg.size) #------------------------------------ save mesh for Paraview jigsawpy.loadmsh(os.path.join(src_path, "topo.msh"), topo) #------------------------------------ a very rough land mask apos = jigsawpy.R3toS2(geom.radii, mesh.point["coord"][:]) apos = apos * 180. / np.pi zfun = interpolate.RectBivariateSpline(topo.ygrid, topo.xgrid, topo.value) mesh.value = zfun(apos[:, 1], apos[:, 0], grid=False) cell = mesh.tria3["index"] zmsk = \ mesh.value[cell[:, 0]] + \ mesh.value[cell[:, 1]] + \ mesh.value[cell[:, 2]] zmsk = zmsk / +3.0 mesh.tria3 = mesh.tria3[zmsk < +0.] print("Saving to ../cache/case_2a.vtk") jigsawpy.savevtk(os.path.join(dst_path, "case_2a.vtk"), mesh) print("Saving to ../cache/case_2b.vtk") jigsawpy.savevtk(os.path.join(dst_path, "case_2b.vtk"), hfun) return
def case_4_(src_path, dst_path): # DEMO-4: generate a multi-resolution mesh, via local refin- # ement along coastlines and shallow ridges. Global grid # resolution is 150KM, background resolution is 67KM and the # min. adaptive resolution is 33KM. opts = jigsawpy.jigsaw_jig_t() topo = jigsawpy.jigsaw_msh_t() geom = jigsawpy.jigsaw_msh_t() mesh = jigsawpy.jigsaw_msh_t() hmat = jigsawpy.jigsaw_msh_t() #------------------------------------ setup files for JIGSAW opts.geom_file = \ os.path.join(src_path, "eSPH.msh") opts.jcfg_file = \ os.path.join(dst_path, "eSPH.jig") opts.mesh_file = \ os.path.join(dst_path, "mesh.msh") opts.hfun_file = \ os.path.join(dst_path, "spac.msh") #------------------------------------ define JIGSAW geometry geom.mshID = "ellipsoid-mesh" geom.radii = np.full(3, 6.371E+003, dtype=geom.REALS_t) jigsawpy.savemsh(opts.geom_file, geom) #------------------------------------ define spacing pattern jigsawpy.loadmsh(os.path.join(src_path, "topo.msh"), topo) hmat.mshID = "ellipsoid-grid" hmat.radii = geom.radii hmat.xgrid = topo.xgrid * np.pi / 180. hmat.ygrid = topo.ygrid * np.pi / 180. hfn0 = +150. # global spacing hfn2 = +33. # adapt. spacing hfn3 = +67. # arctic spacing hmat.value = np.sqrt(np.maximum(-topo.value, 0.0)) hmat.value = \ np.maximum(hmat.value, hfn2) hmat.value = \ np.minimum(hmat.value, hfn3) mask = hmat.ygrid < 40. * np.pi / 180. hmat.value[mask] = hfn0 #------------------------------------ set HFUN grad.-limiter hmat.slope = np.full( # |dH/dx| limits topo.value.shape, +0.050, dtype=hmat.REALS_t) jigsawpy.savemsh(opts.hfun_file, hmat) jigsawpy.cmd.marche(opts, hmat) #------------------------------------ make mesh using JIGSAW opts.hfun_scal = "absolute" opts.hfun_hmax = float("inf") # null HFUN limits opts.hfun_hmin = float(+0.00) opts.mesh_dims = +2 # 2-dim. simplexes opts.optm_qlim = +9.5E-01 # tighter opt. tol opts.optm_iter = +32 opts.optm_qtol = +1.0E-05 jigsawpy.cmd.tetris(opts, 3, mesh) scr2 = jigsawpy.triscr2( # "quality" metric mesh.point["coord"], mesh.tria3["index"]) #------------------------------------ save mesh for Paraview apos = jigsawpy.R3toS2(geom.radii, mesh.point["coord"][:]) apos = apos * 180. / np.pi zfun = interpolate.RectBivariateSpline(topo.ygrid, topo.xgrid, topo.value) mesh.value = zfun(apos[:, 1], apos[:, 0], grid=False) cell = mesh.tria3["index"] zmsk = \ mesh.value[cell[:, 0]] + \ mesh.value[cell[:, 1]] + \ mesh.value[cell[:, 2]] zmsk = zmsk / +3.0 mesh.tria3 = mesh.tria3[zmsk < +0.] print("Saving to ../cache/case_4a.vtk") jigsawpy.savevtk(os.path.join(dst_path, "case_4a.vtk"), mesh) print("Saving to ../cache/case_4b.vtk") jigsawpy.savevtk(os.path.join(dst_path, "case_4b.vtk"), hmat) return
def getInitialMesh(topofile, meshfile, spacefile, outfile, dst_path, hfn): t0 = process_time() opts = jigsawpy.jigsaw_jig_t() topo = jigsawpy.jigsaw_msh_t() geom = jigsawpy.jigsaw_msh_t() mesh = jigsawpy.jigsaw_msh_t() hmat = jigsawpy.jigsaw_msh_t() jigsawpy.loadmsh(topofile, topo) print("Load topography grid (%0.02f seconds)" % (process_time() - t0)) t0 = process_time() opts.geom_file = os.path.join(dst_path, "topology.msh") opts.jcfg_file = os.path.join(dst_path, "config.jig") opts.mesh_file = meshfile opts.hfun_file = spacefile geom.mshID = "ellipsoid-mesh" geom.radii = np.full(3, 6.371e003, dtype=geom.REALS_t) jigsawpy.savemsh(opts.geom_file, geom) hmat.mshID = "ellipsoid-grid" hmat.radii = geom.radii hmat.xgrid = topo.xgrid * np.pi / 180.0 hmat.ygrid = topo.ygrid * np.pi / 180.0 # Set HFUN gradient-limiter hmat.value = np.full(topo.value.shape, hfn[0], dtype=hmat.REALS_t) hmat.value[topo.value > -1000] = hfn[1] hmat.value[topo.value > 0] = hfn[2] hmat.slope = np.full(topo.value.shape, +0.050, dtype=hmat.REALS_t) jigsawpy.savemsh(opts.hfun_file, hmat) jigsawpy.cmd.marche(opts, hmat) print("Build space function (%0.02f seconds)" % (process_time() - t0)) t0 = process_time() opts.hfun_scal = "absolute" opts.hfun_hmax = float("inf") # null HFUN limits opts.hfun_hmin = float(+0.00) opts.mesh_dims = +2 # 2-dim. simplexes opts.optm_qlim = +9.5e-01 # tighter opt. tol opts.optm_iter = +32 opts.optm_qtol = +1.0e-05 jigsawpy.cmd.tetris(opts, 3, mesh) print("Perform triangulation (%0.02f seconds)" % (process_time() - t0)) t0 = process_time() apos = jigsawpy.R3toS2(geom.radii, mesh.point["coord"][:]) apos = apos * 180.0 / np.pi zfun = interpolate.RectBivariateSpline(topo.ygrid, topo.xgrid, topo.value) mesh.value = zfun(apos[:, 1], apos[:, 0], grid=False) jigsawpy.savevtk(outfile, mesh) jigsawpy.savemsh(opts.mesh_file, mesh) print("Get unstructured mesh (%0.02f seconds)" % (process_time() - t0)) return
def ex_3(): # DEMO-3: generate a grid based on the "HR" spacing pattern, # developed by the FESOM team at AWI. dst_path = \ os.path.abspath( os.path.dirname(__file__)) src_path = \ os.path.join(dst_path, "..", "files") dst_path = \ os.path.join(dst_path, "..", "cache") opts = jigsawpy.jigsaw_jig_t() topo = jigsawpy.jigsaw_msh_t() geom = jigsawpy.jigsaw_msh_t() hfun = jigsawpy.jigsaw_msh_t() mesh = jigsawpy.jigsaw_msh_t() #------------------------------------ setup files for JIGSAW opts.geom_file = \ os.path.join(src_path, "eSPH.msh") opts.jcfg_file = \ os.path.join(dst_path, "eSPH.jig") opts.mesh_file = \ os.path.join(dst_path, "mesh.msh") opts.hfun_file = \ os.path.join(dst_path, "spac.msh") #------------------------------------ define JIGSAW geometry geom.mshID = "ellipsoid-mesh" geom.radii = np.full( 3, 6.371E+003, dtype=geom.REALS_t) jigsawpy.savemsh(opts.geom_file, geom) #------------------------------------ define spacing pattern jigsawpy.loadmsh(os.path.join( src_path, "f_hr.msh"), hfun) hfun.value = +3. * hfun.value # for fast example jigsawpy.savemsh(opts.hfun_file, hfun) #------------------------------------ make mesh using JIGSAW opts.hfun_scal = "absolute" opts.hfun_hmax = float("inf") # null HFUN limits opts.hfun_hmin = float(+0.00) opts.mesh_dims = +2 # 2-dim. simplexes opts.optm_qlim = +9.5E-01 # tighter opt. tol opts.optm_iter = +32 opts.optm_qtol = +1.0E-05 jigsawpy.cmd.jigsaw(opts, mesh) #------------------------------------ save mesh for Paraview jigsawpy.loadmsh(os.path.join( src_path, "topo.msh"), topo) #------------------------------------ a very rough land mask apos = jigsawpy.R3toS2( geom.radii, mesh.point["coord"][:]) apos = apos * 180. / np.pi zfun = interpolate.RectBivariateSpline( topo.ygrid, topo.xgrid, topo.value) mesh.value = zfun( apos[:, 1], apos[:, 0], grid=False) cell = mesh.tria3["index"] zmsk = \ mesh.value[cell[:, 0]] + \ mesh.value[cell[:, 1]] + \ mesh.value[cell[:, 2]] zmsk = zmsk / +3.0 mesh.tria3 = mesh.tria3[zmsk < +0.] print("Saving to ../cache/case_3a.vtk") jigsawpy.savevtk(os.path.join( dst_path, "case_3a.vtk"), mesh) print("Saving to ../cache/case_3b.vtk") jigsawpy.savevtk(os.path.join( dst_path, "case_3b.vtk"), hfun) return
def case_5_(src_path, dst_path): # DEMO-5: generate struct. icosahedral and cubedsphere grids opts = jigsawpy.jigsaw_jig_t() topo = jigsawpy.jigsaw_msh_t() geom = jigsawpy.jigsaw_msh_t() icos = jigsawpy.jigsaw_msh_t() cube = jigsawpy.jigsaw_msh_t() #------------------------------------ setup files for JIGSAW opts.geom_file = \ os.path.join(dst_path, "geom.msh") opts.jcfg_file = \ os.path.join(dst_path, "opts.jig") opts.mesh_file = \ os.path.join(dst_path, "mesh.msh") #------------------------------------ define JIGSAW geometry geom.mshID = "ellipsoid-mesh" geom.radii = np.full(3, 1.000E+000, dtype=geom.REALS_t) jigsawpy.savemsh(opts.geom_file, geom) #------------------------------------ make mesh using JIGSAW opts.hfun_hmax = +1. opts.mesh_dims = +2 # 2-dim. simplexes opts.optm_iter = +512 opts.optm_qtol = +1.0E-06 # opts.optm_kern = "cvt+dqdx" ttic = time.time() jigsawpy.cmd.icosahedron(opts, +6, icos) ttoc = time.time() print("CPUSEC =", (ttoc - ttic)) ttic = time.time() jigsawpy.cmd.cubedsphere(opts, +6, cube) ttoc = time.time() print("CPUSEC =", (ttoc - ttic)) #------------------------------------ save mesh for Paraview jigsawpy.loadmsh(os.path.join(src_path, "topo.msh"), topo) #------------------------------------ a very rough land mask zfun = interpolate.RectBivariateSpline(topo.ygrid, topo.xgrid, topo.value) apos = jigsawpy.R3toS2(geom.radii, icos.point["coord"][:]) apos = apos * 180. / np.pi icos.value = zfun(apos[:, 1], apos[:, 0], grid=False) cell = icos.tria3["index"] zmsk = \ icos.value[cell[:, 0]] + \ icos.value[cell[:, 1]] + \ icos.value[cell[:, 2]] zmsk = zmsk / +3.0 icos.tria3 = icos.tria3[zmsk < +0.] print("Saving to ../cache/case_5a.vtk") jigsawpy.savevtk(os.path.join(dst_path, "case_5a.vtk"), icos) #------------------------------------ a very rough land mask apos = jigsawpy.R3toS2(geom.radii, cube.point["coord"][:]) apos = apos * 180. / np.pi cube.value = zfun(apos[:, 1], apos[:, 0], grid=False) cell = cube.quad4["index"] zmsk = \ cube.value[cell[:, 0]] + \ cube.value[cell[:, 1]] + \ cube.value[cell[:, 2]] + \ cube.value[cell[:, 3]] zmsk = zmsk / +4.0 cube.quad4 = cube.quad4[zmsk < +0.] print("Saving to ../cache/case_5b.vtk") jigsawpy.savevtk(os.path.join(dst_path, "case_5b.vtk"), cube) return
def case_1_(src_path, dst_path): # DEMO-1: generate a uniform resolution (150KM) global grid. opts = jigsawpy.jigsaw_jig_t() topo = jigsawpy.jigsaw_msh_t() geom = jigsawpy.jigsaw_msh_t() mesh = jigsawpy.jigsaw_msh_t() #------------------------------------ setup files for JIGSAW opts.geom_file = \ os.path.join(src_path, "eSPH.msh") opts.jcfg_file = \ os.path.join(dst_path, "eSPH.jig") opts.mesh_file = \ os.path.join(dst_path, "mesh.msh") #------------------------------------ define JIGSAW geometry geom.mshID = "ellipsoid-mesh" geom.radii = np.full( 3, 6.371E+003, dtype=geom.REALS_t) jigsawpy.savemsh(opts.geom_file, geom) #------------------------------------ make mesh using JIGSAW opts.hfun_scal = "absolute" opts.hfun_hmax = +150. # uniform at 150km opts.mesh_dims = +2 # 2-dim. simplexes opts.optm_qlim = +9.5E-01 # tighter opt. tol opts.optm_iter = +32 opts.optm_qtol = +1.0E-05 jigsawpy.cmd.tetris(opts, 3, mesh) scr2 = jigsawpy.triscr2( # "quality" metric mesh.point["coord"], mesh.tria3["index"]) #------------------------------------ save mesh for Paraview jigsawpy.loadmsh(os.path.join( src_path, "topo.msh"), topo) #------------------------------------ a very rough land mask apos = jigsawpy.R3toS2( geom.radii, mesh.point["coord"][:]) apos = apos * 180. / np.pi zfun = interpolate.RectBivariateSpline( topo.ygrid, topo.xgrid, topo.value) mesh.value = zfun( apos[:, 1], apos[:, 0], grid=False) cell = mesh.tria3["index"] zmsk = \ mesh.value[cell[:, 0]] + \ mesh.value[cell[:, 1]] + \ mesh.value[cell[:, 2]] zmsk = zmsk / +3.0 mesh.tria3 = mesh.tria3[zmsk < +0.] print("Saving to ../cache/case_1a.vtk") jigsawpy.savevtk(os.path.join( dst_path, "case_1a.vtk"), mesh) return
def unstMesh(esph, infile, hfn0=100.0, hfn1=30.0, hfn2=15, tmp="tmp/"): opts = jigsawpy.jigsaw_jig_t() topo = jigsawpy.jigsaw_msh_t() geom = jigsawpy.jigsaw_msh_t() mesh = jigsawpy.jigsaw_msh_t() hmat = jigsawpy.jigsaw_msh_t() opts.geom_file = esph opts.jcfg_file = os.path.join(tmp, "topo.jig") opts.mesh_file = os.path.join(tmp, "mesh.msh") opts.hfun_file = os.path.join(tmp, "spac.msh") # define JIGSAW geometry geom.mshID = "ellipsoid-mesh" geom.radii = np.full(3, 6.371e003, dtype=geom.REALS_t) jigsawpy.savemsh(opts.geom_file, geom) # define spacing pattern jigsawpy.loadmsh(infile, topo) hmat.mshID = "ellipsoid-grid" hmat.radii = geom.radii hmat.xgrid = topo.xgrid * np.pi / 180.0 hmat.ygrid = topo.ygrid * np.pi / 180.0 # Define grid resolution for each elevation domain hmat.value = np.full(topo.value.shape, hfn0, dtype=hmat.REALS_t) hmat.value[topo.value > -1000.0] = hfn1 hmat.value[topo.value > 0.0] = hfn2 # Set HFUN gradient-limiter hmat.slope = np.full(topo.value.shape, +0.025, dtype=hmat.REALS_t) jigsawpy.savemsh(opts.hfun_file, hmat) jigsawpy.cmd.marche(opts, hmat) # Make mesh using JIGSAW opts.hfun_scal = "absolute" opts.hfun_hmax = float("inf") # null HFUN limits opts.hfun_hmin = float(+0.00) opts.mesh_dims = +2 # 2-dim. simplexes opts.optm_qlim = +9.5e-01 # tighter opt. tol opts.optm_iter = +32 opts.optm_qtol = +1.0e-05 jigsawpy.cmd.tetris(opts, 4, mesh) scr2 = jigsawpy.triscr2( # "quality" metric mesh.point["coord"], mesh.tria3["index"]) apos = jigsawpy.R3toS2(geom.radii, mesh.point["coord"][:]) apos = apos * 180.0 / np.pi zfun = interpolate.RectBivariateSpline(topo.ygrid, topo.xgrid, topo.value) mesh.value = zfun(apos[:, 1], apos[:, 0], grid=False) coords = (mesh.vert3["coord"] / 6.371e003) * 6378137.0 del scr2 return coords, mesh.tria3["index"], mesh.value
def case_4_(src_path, dst_path): # DEMO-4: generate a multi-resolution mesh, via local refin- # ement along coastlines and shallow ridges. Global grid # resolution is 150KM, background resolution is 67KM and the # min. adaptive resolution is 33KM. opts = jigsawpy.jigsaw_jig_t() topo = jigsawpy.jigsaw_msh_t() geom = jigsawpy.jigsaw_msh_t() mesh = jigsawpy.jigsaw_msh_t() hmat = jigsawpy.jigsaw_msh_t() #------------------------------------ setup files for JIGSAW opts.geom_file = \ os.path.join(dst_path, "geom.msh") opts.jcfg_file = \ os.path.join(dst_path, "opts.jig") opts.mesh_file = \ os.path.join(dst_path, "mesh.msh") opts.hfun_file = \ os.path.join(dst_path, "spac.msh") #------------------------------------ define JIGSAW geometry geom.mshID = "ellipsoid-mesh" geom.radii = np.full(3, 6.371E+003, dtype=geom.REALS_t) jigsawpy.savemsh(opts.geom_file, geom) #------------------------------------ define spacing pattern jigsawpy.loadmsh(os.path.join(src_path, "topo.msh"), topo) hmat.mshID = "ellipsoid-grid" hmat.radii = geom.radii hmat.xgrid = topo.xgrid * np.pi / 180. hmat.ygrid = topo.ygrid * np.pi / 180. hfn0 = +150. # global spacing hfn2 = +33. # adapt. spacing hfn3 = +67. # arctic spacing hmat.value = np.sqrt(np.maximum(-topo.value, 0.0)) hmat.value = \ np.maximum(hmat.value, hfn2) hmat.value = \ np.minimum(hmat.value, hfn3) mask = hmat.ygrid < 40. * np.pi / 180. hmat.value[mask] = hfn0 #------------------------------------ set HFUN grad.-limiter hmat.slope = np.full( # |dH/dx| limits topo.value.shape, +0.050, dtype=hmat.REALS_t) jigsawpy.savemsh(opts.hfun_file, hmat) jigsawpy.cmd.marche(opts, hmat) #------------------------------------ make mesh using JIGSAW opts.hfun_scal = "absolute" opts.hfun_hmax = float("inf") # null HFUN limits opts.hfun_hmin = float(+0.00) opts.mesh_dims = +2 # 2-dim. simplexes opts.optm_qlim = +9.5E-01 # tighter opt. tol opts.optm_iter = +32 opts.optm_qtol = +1.0E-05 # opts.optm_kern = "cvt+dqdx" rbar = np.mean(geom.radii) # bisect heuristic hbar = np.mean(hmat.value) nlev = round(math.log2(rbar / math.sin(.4 * math.pi) / hbar)) ttic = time.time() jigsawpy.cmd.tetris(opts, nlev - 1, mesh) ttoc = time.time() print("CPUSEC =", (ttoc - ttic)) print("BISECT =", +nlev) cost = jigsawpy.triscr2( # quality metrics! mesh.point["coord"], mesh.tria3["index"]) print("TRISCR =", np.min(cost), np.mean(cost)) cost = jigsawpy.pwrscr2(mesh.point["coord"], mesh.power, mesh.tria3["index"]) print("PWRSCR =", np.min(cost), np.mean(cost)) tbad = jigsawpy.centre2(mesh.point["coord"], mesh.power, mesh.tria3["index"]) print("OBTUSE =", +np.count_nonzero(np.logical_not(tbad))) ndeg = jigsawpy.trideg2(mesh.point["coord"], mesh.tria3["index"]) print("TOPOL. =", +np.count_nonzero(ndeg == +6) / ndeg.size) #------------------------------------ save mesh for Paraview apos = jigsawpy.R3toS2(geom.radii, mesh.point["coord"][:]) apos = apos * 180. / np.pi zfun = interpolate.RectBivariateSpline(topo.ygrid, topo.xgrid, topo.value) mesh.value = zfun(apos[:, 1], apos[:, 0], grid=False) cell = mesh.tria3["index"] zmsk = \ mesh.value[cell[:, 0]] + \ mesh.value[cell[:, 1]] + \ mesh.value[cell[:, 2]] zmsk = zmsk / +3.0 mesh.tria3 = mesh.tria3[zmsk < +0.] print("Saving to ../cache/case_4a.vtk") jigsawpy.savevtk(os.path.join(dst_path, "case_4a.vtk"), mesh) print("Saving to ../cache/case_4b.vtk") jigsawpy.savevtk(os.path.join(dst_path, "case_4b.vtk"), hmat) return
def case_1_(src_path, dst_path): # DEMO-1: generate a uniform resolution (150KM) global grid. opts = jigsawpy.jigsaw_jig_t() topo = jigsawpy.jigsaw_msh_t() geom = jigsawpy.jigsaw_msh_t() mesh = jigsawpy.jigsaw_msh_t() #------------------------------------ setup files for JIGSAW opts.geom_file = \ os.path.join(dst_path, "geom.msh") opts.jcfg_file = \ os.path.join(dst_path, "opts.jig") opts.mesh_file = \ os.path.join(dst_path, "mesh.msh") #------------------------------------ define JIGSAW geometry geom.mshID = "ellipsoid-mesh" geom.radii = np.full(3, 6.371E+003, dtype=geom.REALS_t) jigsawpy.savemsh(opts.geom_file, geom) #------------------------------------ make mesh using JIGSAW opts.hfun_scal = "absolute" opts.hfun_hmax = +150. # uniform at 150km opts.mesh_dims = +2 # 2-dim. simplexes opts.optm_qlim = +9.5E-01 # tighter opt. tol opts.optm_iter = +32 opts.optm_qtol = +1.0E-05 # opts.optm_kern = "cvt+dqdx" rbar = np.mean(geom.radii) # bisect heuristic nlev = round(math.log2(rbar / math.sin(.4 * math.pi) / opts.hfun_hmax)) ttic = time.time() jigsawpy.cmd.tetris(opts, nlev - 1, mesh) ttoc = time.time() print("CPUSEC =", (ttoc - ttic)) print("BISECT =", +nlev) cost = jigsawpy.triscr2( # quality metrics! mesh.point["coord"], mesh.tria3["index"]) print("TRISCR =", np.min(cost), np.mean(cost)) cost = jigsawpy.pwrscr2(mesh.point["coord"], mesh.power, mesh.tria3["index"]) print("PWRSCR =", np.min(cost), np.mean(cost)) tbad = jigsawpy.centre2(mesh.point["coord"], mesh.power, mesh.tria3["index"]) print("OBTUSE =", +np.count_nonzero(np.logical_not(tbad))) ndeg = jigsawpy.trideg2(mesh.point["coord"], mesh.tria3["index"]) print("TOPOL. =", +np.count_nonzero(ndeg == +6) / ndeg.size) #------------------------------------ save mesh for Paraview jigsawpy.loadmsh(os.path.join(src_path, "topo.msh"), topo) #------------------------------------ a very rough land mask apos = jigsawpy.R3toS2(geom.radii, mesh.point["coord"][:]) apos = apos * 180. / np.pi zfun = interpolate.RectBivariateSpline(topo.ygrid, topo.xgrid, topo.value) mesh.value = zfun(apos[:, 1], apos[:, 0], grid=False) cell = mesh.tria3["index"] zmsk = \ mesh.value[cell[:, 0]] + \ mesh.value[cell[:, 1]] + \ mesh.value[cell[:, 2]] zmsk = zmsk / +3.0 mesh.tria3 = mesh.tria3[zmsk < +0.] print("Saving to ../cache/case_1a.vtk") jigsawpy.savevtk(os.path.join(dst_path, "case_1a.vtk"), mesh) return