def make_mesh(): opts = jigsawpy.jigsaw_jig_t() # jigsaw data structures geom = jigsawpy.jigsaw_msh_t() mesh = jigsawpy.jigsaw_msh_t() opts.geom_file = "tmp/geom.msh" # setup jigsaw files opts.jcfg_file = "tmp/opts.jig" opts.mesh_file = "out/mesh.msh" geom.mshID = "ellipsoid-mesh" # a simple "unit" sphere geom.radii = np.ones(+3) jigsawpy.savemsh(opts.geom_file, geom) opts.verbosity = +1 # setup user-defined opt opts.optm_iter = +512 opts.optm_qtol = +1.E-08 opts.optm_kern = "odt+dqdx" # opts.optm_kern = "cvt+dqdx" ttic = time.time() jigsawpy.cmd.icosahedron(opts, 6, mesh) # mesh with n bisections # keep = mesh.tria3["IDtag"] == +1 # only keep single face? # mesh.tria3 = mesh.tria3[keep] ttoc = time.time() print("CPUSEC =", (ttoc - ttic)) jigsawpy.savevtk("mesh.vtk", mesh) # to open in paraview... return
def _write_to_file(self, out_format, out_file, hfun_collector, crs): _logger.info(f"Writing for file ({out_format}) ...") # NOTE: Combined mesh from collector is always in EPSG:4326 jig_hfun = hfun_collector.msh_t() dst_crs = CRS.from_user_input(crs) if jig_hfun.crs != dst_crs: _logger.info(f"Reprojecting hfun to ({crs}) ...") utils.reproject(jig_hfun, dst_crs) # TODO: Check for correct extension on out_file if out_format in ("jigsaw", "vtk"): if out_format == "jigsaw": savemsh(out_file, jig_hfun) elif out_format == "vtk": savevtk(out_file, jig_hfun) elif out_format in ['2dm', 'sms']: # TODO: How to specify crs in 2dm file? mesh = Mesh(jig_hfun) mesh.write(out_file, format='2dm') else: raise NotImplementedError( f"Output type {out_format} is not supported") _logger.info("Done")
def _run_cmdsaw(self): msg = f'_run_cmdsaw()' self.logger.debug(msg) # init tmpfiles self.logger.debug(f'init tmpfiles') mesh_file = tempfile.NamedTemporaryFile(prefix=tmpdir, suffix='.msh') hmat_file = tempfile.NamedTemporaryFile(prefix=tmpdir, suffix='.msh') geom_file = tempfile.NamedTemporaryFile(prefix=tmpdir, suffix='.msh') jcfg_file = tempfile.NamedTemporaryFile(prefix=tmpdir, suffix='.jig') # dump data to tempfiles jigsawpy.savemsh(hmat_file.name, self.hfun) jigsawpy.savemsh(geom_file.name, self.geom) # init opts opts = jigsaw_jig_t() opts.mesh_file = mesh_file.name opts.hfun_file = hmat_file.name opts.geom_file = geom_file.name opts.jcfg_file = jcfg_file.name # additional configuration options opts.verbosity = self.verbosity opts.mesh_dims = +2 # NOTE: Hardcoded value opts.hfun_scal = 'absolute' opts.optm_tria = True # NOTE: Hardcoded value opts.optm_qlim = self.optm_qlim if self.hmin_is_absolute_limit: opts.hfun_hmin = self.hmin else: opts.hfun_hmin = np.min(self.hfun.value) if self.hmax_is_absolute_limit: opts.hfun_hmax = self.hmax else: opts.hfun_hmax = np.max(self.hfun.value) # init outputmesh mesh = jigsaw_msh_t() # call jigsaw self.logger.debug('call cmdsaw') jigsawpy.cmd.jigsaw(opts, mesh) # cleanup temporary files for tmpfile in (mesh_file, hmat_file, geom_file, jcfg_file): del (tmpfile) self.__output_mesh = mesh
def geom(self): """ This is the global geom """ try: name = self.__geom_tmpfile.name geom = jigsaw_msh_t() loadmsh(name, geom) return geom except AttributeError: # jigsawpy.msh_t.jigsaw_msh_t if isinstance(self._geom, jigsaw_msh_t): self._logger.debug('self.geom:AttributeError:jigsaw_msh_t') self._geom.edge2 = geomesh.utils.edge2_from_msh_t(self._geom) geom = self._geom elif isinstance(self._geom, (Polygon, MultiPolygon)): msg = 'self.geom:AttributeError:(Polygon, MultiPolygon)' self._logger.debug(msg) geom = self._get_geom_from_shapely() # RasterCollection elif isinstance( self._geom, ( geomesh.Raster, geomesh.RasterCollection ) ): msg = 'self.geom:AttributeError:(Raster, RasterCollection)' self._logger.debug(msg) geom = self._get_geom_from_raster() else: self._logger.debug('self.geom:AttributeError:Undefined') msg = f"Undefined handler for geom type {self._geom}" raise NotImplementedError(msg) tmpfile = tempfile.NamedTemporaryFile( prefix=geomesh.tmpdir, suffix='.msh') savemsh(tmpfile.name, geom) self.__geom_tmpfile = tmpfile # spherical mesh if self._radii is not None: geom.radii = self._radii geom.mshID = self._mshID return geom
def jigsaw_driver(cellWidth, lon, lat): ''' A function for building a jigsaw mesh Parameters ---------- cellWidth : ndarray The size of each cell in the resulting mesh as a function of space lon, lat : ndarray The lon. and lat. of each point in the cellWidth array ''' # Authors # ------- # Mark Petersen, Phillip Wolfram, Xylar Asay-Davis # setup files for JIGSAW opts = jigsawpy.jigsaw_jig_t() opts.geom_file = 'mesh.msh' opts.jcfg_file = 'mesh.jig' opts.mesh_file = 'mesh-MESH.msh' opts.hfun_file = 'mesh-HFUN.msh' # save HFUN data to file hmat = jigsawpy.jigsaw_msh_t() hmat.mshID = 'ELLIPSOID-GRID' hmat.xgrid = numpy.radians(lon) hmat.ygrid = numpy.radians(lat) hmat.value = cellWidth jigsawpy.savemsh(opts.hfun_file, hmat) # define JIGSAW geometry geom = jigsawpy.jigsaw_msh_t() geom.mshID = 'ELLIPSOID-MESH' geom.radii = 6371.*numpy.ones(3, float) jigsawpy.savemsh(opts.geom_file, geom) # build mesh via JIGSAW! mesh = jigsawpy.jigsaw_msh_t() opts.hfun_scal = 'absolute' opts.hfun_hmax = float("inf") opts.hfun_hmin = 0.0 opts.mesh_dims = +2 # 2-dim. simplexes opts.optm_qlim = 0.9375 opts.verbosity = +1 jigsawpy.cmd.jigsaw(opts)
def jigsaw_gen_icos_grid(basename="mesh", level=4): # setup files for JIGSAW opts = jig.jigsaw_jig_t() icos = jig.jigsaw_msh_t() geom = jig.jigsaw_msh_t() opts.geom_file = basename + '.msh' opts.jcfg_file = basename + '.jig' opts.mesh_file = basename + '-MESH.msh' geom.mshID = "ellipsoid-mesh" geom.radii = np.full(3, 1.000E+000, dtype=geom.REALS_t) jig.savemsh(opts.geom_file, geom) opts.hfun_hmax = +1. opts.mesh_dims = +2 # 2-dim. simplexes opts.optm_iter = +512 opts.optm_qtol = +1.0E-06 jig.cmd.icosahedron(opts, level, icos) return opts.mesh_file
def setspac(): spac_ocn = 30. # regional ocn. km spac_1_m = 2. # sqrt(H) ocn. km spac_lnd = 45. # global land km spac_wbd = 5. # watershed km spac_pfz = 2. # PFZ km elev_pfz = 25. # PFZ elev. thresh dhdx_lim = 0.0625 # |dH/dx| thresh fade_pos = [-75.2316, 39.1269] fade_len = 700. fade_gap = 350. spac = jigsawpy.jigsaw_msh_t() opts = jigsawpy.jigsaw_jig_t() poly = jigsawpy.jigsaw_msh_t() opts.jcfg_file = os.path.join(TDIR, "opts.jig") opts.hfun_file = os.path.join(TDIR, "spac.msh") #------------------------------------ define spacing pattern print("BUILDING MESH SPAC.") print("Loading elevation assets...") data = nc.Dataset( os.path.join("data", "etopo_gebco", "etopo_gebco_tiled.nc"), "r") zlev = np.array(data.variables["z"]) spac.mshID = "ellipsoid-grid" # use elev. grid spac.radii = np.full(+3, FULL_SPHERE_RADIUS, dtype=spac.REALS_t) spac.xgrid = np.array(data.variables["x"][:], dtype=spac.REALS_t) spac.ygrid = np.array(data.variables["y"][:], dtype=spac.REALS_t) spac.xgrid *= np.pi / +180. spac.ygrid *= np.pi / +180. xgrd, ygrd = np.meshgrid(spac.xgrid, spac.ygrid) grid = np.concatenate( ( # to [x, y] list xgrd.reshape((xgrd.size, +1)), ygrd.reshape((ygrd.size, +1))), axis=+1) #------------------------------------ global ocn ec-60-to-30 print("Compute global ocean h(x)...") vals = \ mdt.EC_CellWidthVsLat(spac.ygrid * 180. / np.pi) vals = np.reshape(vals, (spac.ygrid.size, 1)) spac.value = np.array(np.tile(vals, (1, spac.xgrid.size)), dtype=spac.REALS_t) #------------------------------------ region ocn "eddy" halo filename = os.path.join("data", "na_ocean_halo", "na_ocean_halo.geojson") loadgeo(filename, poly) poly.point["coord"] *= np.pi / +180. mask, _ = inpoly2(grid, poly.point["coord"], poly.edge2["index"]) mask = np.reshape(mask, spac.value.shape) mask = np.logical_and(mask, zlev <= +0.0) spac.value[mask] = \ np.minimum(spac_ocn, spac.value[mask]) #------------------------------------ coastal ocn heuristics mask = zlev <= +0.0 hval = np.sqrt(np.maximum(-zlev, +0.0)) hval = np.maximum(spac_1_m, hval / np.sqrt(+1.0) / spac_1_m) dist = sphdist(FULL_SPHERE_RADIUS, grid[:, 0], grid[:, 1], fade_pos[0] * np.pi / 180., fade_pos[1] * np.pi / 180.) dist = np.reshape(dist, spac.value.shape) hval = blender(hval, spac.value, dist, fade_len, fade_gap) spac.value[mask] = \ np.minimum(hval[mask], spac.value[mask]) #------------------------------------ global lnd const. = 45 print("Compute global land h(x)...") halo = +9 # filter islands zmed = median_filter(zlev, size=halo, mode="wrap") spac.value[zmed >= 0.0] = spac_lnd #------------------------------------ push watershed(s) = 5. print("Compute watersheds h(x)...") shed = np.full((grid.shape[0]), False, dtype=bool) filename = os.path.join("data", "NHD_H_0204_HU4_Shape", "Shape", "WBDHU4.shp") loadshp(filename, poly) poly.point["coord"] *= np.pi / +180. mask, _ = inpoly2(grid, poly.point["coord"], poly.edge2["index"]) shed[mask] = True filename = os.path.join("data", "NHD_H_0205_HU4_Shape", "Shape", "WBDHU4.shp") loadshp(filename, poly) poly.point["coord"] *= np.pi / +180. mask, _ = inpoly2(grid, poly.point["coord"], poly.edge2["index"]) shed[mask] = True filename = os.path.join("data", "NHD_H_0206_HU4_Shape", "Shape", "WBDHU4.shp") loadshp(filename, poly) poly.point["coord"] *= np.pi / +180. mask, _ = inpoly2(grid, poly.point["coord"], poly.edge2["index"]) shed[mask] = True filename = os.path.join("data", "NHD_H_0207_HU4_Shape", "Shape", "WBDHU4.shp") loadshp(filename, poly) poly.point["coord"] *= np.pi / +180. mask, _ = inpoly2(grid, poly.point["coord"], poly.edge2["index"]) shed[mask] = True filename = os.path.join("data", "NHD_H_0208_HU4_Shape", "Shape", "WBDHU4.shp") loadshp(filename, poly) poly.point["coord"] *= np.pi / +180. mask, _ = inpoly2(grid, poly.point["coord"], poly.edge2["index"]) shed[mask] = True shed = np.reshape(shed, spac.value.shape) spac.value[shed] = \ np.minimum(spac_wbd, spac.value[shed]) #------------------------------------ partially flooded zone mask = np.logical_and(shed, zlev < elev_pfz) spac.value[mask] = \ np.minimum(spac_pfz, spac.value[mask]) #------------------------------------ push |DH/DX| threshold print("Impose |DH/DX| threshold...") spac.slope = np.full(spac.value.shape, dhdx_lim, dtype=spac.REALS_t) jigsawpy.savemsh(opts.hfun_file, spac, "precision = 9") jigsawpy.cmd.marche(opts, spac) spac.slope = \ np.empty((+0), dtype=spac.REALS_t) return spac
def jigsaw_driver(cellWidth, x, y, on_sphere=True, geom_points=None, geom_edges=None): ''' A function for building a jigsaw mesh Parameters ---------- cellWidth : ndarray The size of each cell in the resulting mesh as a function of space x, y : ndarray The x and y coordinates of each point in the cellWidth array (lon and lat for spherical mesh) on_sphere : logical Whether this mesh is spherical or planar geom_points : list of point coordinates for bounding polygon for planar mesh geom_edges : list of edges between points in geom_points that define the bounding polygon ''' # Authors # ------- # Mark Petersen, Phillip Wolfram, Xylar Asay-Davis # setup files for JIGSAW opts = jigsawpy.jigsaw_jig_t() opts.geom_file = 'mesh.msh' opts.jcfg_file = 'mesh.jig' opts.mesh_file = 'mesh-MESH.msh' opts.hfun_file = 'mesh-HFUN.msh' # save HFUN data to file hmat = jigsawpy.jigsaw_msh_t() if on_sphere: hmat.mshID = 'ELLIPSOID-GRID' hmat.xgrid = numpy.radians(x) hmat.ygrid = numpy.radians(y) else: hmat.mshID = 'EUCLIDEAN-GRID' hmat.xgrid = x hmat.ygrid = y hmat.value = cellWidth jigsawpy.savemsh(opts.hfun_file, hmat) # define JIGSAW geometry geom = jigsawpy.jigsaw_msh_t() if on_sphere: geom.mshID = 'ELLIPSOID-MESH' geom.radii = 6371. * numpy.ones(3, float) else: geom.mshID = 'EUCLIDEAN-MESH' geom.vert2 = geom_points geom.edge2 = geom_edges #geom.edge2.index = geom_edges print(geom_points) jigsawpy.savemsh(opts.geom_file, geom) # build mesh via JIGSAW! mesh = jigsawpy.jigsaw_msh_t() opts.hfun_scal = 'absolute' opts.hfun_hmax = float("inf") opts.hfun_hmin = 0.0 opts.mesh_dims = +2 # 2-dim. simplexes opts.optm_qlim = 0.9375 opts.verbosity = +1 jigsawpy.cmd.jigsaw(opts)
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 waves_mesh(cfg): pwd = os.getcwd() src_path = pwd dst_path = pwd opts = jigsawpy.jigsaw_jig_t() hfun = jigsawpy.jigsaw_msh_t() mesh = jigsawpy.jigsaw_msh_t() init = jigsawpy.jigsaw_msh_t() #------------------------------------ setup files for JIGSAW opts.geom_file = \ str(Path(dst_path)/"geom.msh") # GEOM file opts.jcfg_file = \ str(Path(dst_path)/"jcfg.jig") # JCFG file opts.hfun_file = \ str(Path(dst_path)/"hfun.msh") # HFUN file opts.mesh_file = \ str(Path(dst_path)/"mesh.msh") # MESH file opts.init_file = \ str(Path(dst_path)/"init.msh") # INIT file #------------------------------------ define JIGSAW geometry if cfg['coastlines']: print('Defining coastline geometry') create_coastline_geometry(cfg['shpfiles'], opts.geom_file, cfg['sphere_radius']) else: geom = jigsawpy.jigsaw_msh_t() geom.mshID = 'ELLIPSOID-MESH' geom.radii = cfg['sphere_radius'] * np.ones(3, float) jigsawpy.savemsh(opts.geom_file, geom) #------------------------------------ define mesh size function print('Defining mesh size function') lon_min = -180.0 lon_max = 180.0 dlon = cfg['hfun_grid_spacing'] nlon = int((lon_max - lon_min) / dlon) + 1 lat_min = -90.0 lat_max = 90.0 nlat = int((lat_max - lat_min) / dlon) + 1 dlat = cfg['hfun_grid_spacing'] xlon = np.linspace(lon_min, lon_max, nlon) ylat = np.linspace(lat_min, lat_max, nlat) print(' hfun grid dimensions: {}, {}'.format(xlon.size, ylat.size)) define_hfunction.depth_threshold_refined = cfg['depth_threshold_refined'] define_hfunction.distance_threshold_refined = cfg[ 'distance_threshold_refined'] define_hfunction.depth_threshold_global = cfg['depth_threshold_global'] define_hfunction.distance_threshold_global = cfg[ 'distance_threshold_global'] define_hfunction.refined_res = cfg['refined_res'] define_hfunction.maxres = cfg['maxres'] hfunction = define_hfunction.cell_widthVsLatLon(xlon, ylat, cfg['shpfiles'], cfg['sphere_radius'], cfg['ocean_mesh']) hfunction = hfunction / km hfun.mshID = "ellipsoid-grid" hfun.radii = np.full(3, cfg['sphere_radius'], dtype=jigsawpy.jigsaw_msh_t.REALS_t) hfun.xgrid = np.radians(xlon) hfun.ygrid = np.radians(ylat) hfun.value = hfunction.astype(jigsawpy.jigsaw_msh_t.REALS_t) #------------------------------------ specify JIGSAW initial conditions print('Specifying initial fixed coordinate locations') create_initial_points(cfg['ocean_mesh'], xlon, ylat, hfunction, cfg['sphere_radius'], opts.init_file) jigsawpy.loadmsh(opts.init_file, init) jigsawpy.savevtk(str(Path(dst_path) / "init.vtk"), init) #------------------------------------ set HFUN grad.-limiter print('Limiting mesh size function gradients') hfun.slope = np.full( # |dH/dx| limits hfun.value.shape, cfg['hfun_slope_lim'], dtype=hfun.REALS_t) jigsawpy.savemsh(opts.hfun_file, hfun) jigsawpy.cmd.marche(opts, 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.mesh_eps1 = +.67 # relax edge error opts.mesh_rad2 = +1.2 opts.optm_qlim = +9.5E-01 # tighter opt. tol opts.optm_iter = +32 opts.optm_qtol = +1.0E-05 opts.verbosity = 2 #jigsawpy.cmd.tetris(opts, 3, mesh) jigsawpy.cmd.jigsaw(opts, mesh) if cfg['coastlines']: segment.segment(mesh) #------------------------------------ save mesh for Paraview print("Writing ex_h.vtk file.") jigsawpy.savevtk(str(Path(dst_path) / "_hfun.vtk"), hfun) jigsawpy.savevtk(str(Path(dst_path) / "waves_mesh.vtk"), mesh) jigsawpy.savemsh(str(Path(dst_path) / "waves_mesh.msh"), mesh) #------------------------------------ convert mesh to MPAS format jigsaw_to_netcdf(msh_filename='waves_mesh.msh', output_name='waves_mesh_triangles.nc', on_sphere=True, sphere_radius=cfg['sphere_radius']) write_netcdf( convert(xarray.open_dataset('waves_mesh_triangles.nc'), dir='./', logger=None), 'waves_mesh.nc') #------------------------------------ cull mesh to ocean bounary if os.path.exists('./cull_waves_mesh'): f = open('cull_waves_mesh.nml', 'w') f.write('&inputs\n') f.write(" waves_mesh_file = 'waves_mesh.nc'\n") f.write(" ocean_mesh_file = '" + cfg['ocean_mesh'] + "'\n") f.write("/\n") f.write('&output\n') f.write(" waves_mesh_culled_vtk = 'waves_mesh_culled.vtk'\n") f.write(" waves_mesh_culled_gmsh = 'waves_mesh_culled.msh'\n") f.write("/\n") f.close() subprocess.call('./cull_waves_mesh', shell=True) #------------------------------------ output ocean mesh polygons subprocess.call('paraview_vtk_field_extractor.py -f ' + cfg['ocean_mesh'] + ' --ignore_time -v areaCell -o ' + cfg['ocean_mesh'] + '.vtk', shell=True) 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(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 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_3_(src_path, dst_path): # DEMO-3: generate multi-resolution spacing, via local refi- # nement 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() hraw = jigsawpy.jigsaw_msh_t() hlim = 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.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) hraw.mshID = "ellipsoid-grid" hraw.radii = geom.radii hraw.xgrid = topo.xgrid * np.pi / 180. hraw.ygrid = topo.ygrid * np.pi / 180. hfn0 = +150. # global spacing hfn2 = +33. # adapt. spacing hfn3 = +67. # arctic spacing hraw.value = np.sqrt(np.maximum(-topo.value, 0.0)) hraw.value = \ np.maximum(hraw.value, hfn2) hraw.value = \ np.minimum(hraw.value, hfn3) mask = hraw.ygrid < 40. * np.pi / 180. hraw.value[mask] = hfn0 #------------------------------------ set HFUN grad.-limiter hlim = copy.copy(hraw) hlim.slope = np.full( # |dH/dx| limits topo.value.shape, +0.050, dtype=hlim.REALS_t) jigsawpy.savemsh(opts.hfun_file, hlim) jigsawpy.cmd.marche(opts, hlim) #------------------------------------ save mesh for Paraview print("Saving to ../cache/case_3a.vtk") jigsawpy.savevtk(os.path.join(dst_path, "case_3a.vtk"), hraw) print("Saving to ../cache/case_3b.vtk") jigsawpy.savevtk(os.path.join(dst_path, "case_3b.vtk"), hlim) 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_7_(src_path, dst_path): # DEMO-7: generate a multi-part mesh of the (contiguous) USA # using state boundaries to partition the mesh. A local # stereographic projection is employed. The domain is meshed # using uniform resolution. opts = jigsawpy.jigsaw_jig_t() geom = jigsawpy.jigsaw_msh_t() mesh = jigsawpy.jigsaw_msh_t() proj = jigsawpy.jigsaw_prj_t() #------------------------------------ setup files for JIGSAW opts.geom_file = \ os.path.join(dst_path, "geom.msh") opts.jcfg_file = \ os.path.join(dst_path, "us48.jig") opts.mesh_file = \ os.path.join(dst_path, "mesh.msh") #------------------------------------ define JIGSAW geometry jigsawpy.loadmsh(os.path.join(src_path, "us48.msh"), geom) xmin = np.min(geom.point["coord"][:, 0]) ymin = np.min(geom.point["coord"][:, 1]) xmax = np.max(geom.point["coord"][:, 0]) ymax = np.max(geom.point["coord"][:, 1]) geom.point["coord"][:, :] *= np.pi / 180. proj.prjID = 'stereographic' proj.radii = +6.371E+003 proj.xbase = \ +0.500 * (xmin + xmax) * np.pi / 180. proj.ybase = \ +0.500 * (ymin + ymax) * np.pi / 180. jigsawpy.project(geom, proj, "fwd") jigsawpy.savemsh(opts.geom_file, geom) #------------------------------------ make mesh using JIGSAW opts.hfun_hmax = .005 opts.mesh_dims = +2 # 2-dim. simplexes opts.mesh_eps1 = +1 / 6. ttic = time.time() jigsawpy.cmd.jigsaw(opts, mesh) ttoc = time.time() print("CPUSEC =", (ttoc - ttic)) 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))) #------------------------------------ save mesh for Paraview print("Saving to ../cache/case_7a.vtk") jigsawpy.savevtk(os.path.join(dst_path, "case_7a.vtk"), mesh) return
def jigsaw_gen_sph_grid(cellWidth, x, y, earth_radius=6371.0e3, basename="mesh"): """ A function for building a jigsaw spherical mesh Parameters ---------- cellWidth : ndarray The size of each cell in the resulting mesh as a function of space x, y : ndarray The x and y coordinates of each point in the cellWidth array (lon and lat for spherical mesh) on_sphere : logical, optional Whether this mesh is spherical or planar earth_radius : float, optional Earth radius in meters """ # Authors # ------- #by P. Peixoto in Dec 2021 # based on MPAS-Tools file from Mark Petersen, Phillip Wolfram, Xylar Asay-Davis # setup files for JIGSAW opts = jig.jigsaw_jig_t() opts.geom_file = basename + '.msh' opts.jcfg_file = basename + '.jig' opts.mesh_file = basename + '-MESH.msh' opts.hfun_file = basename + '-HFUN.msh' # save HFUN data to file hmat = jig.jigsaw_msh_t() hmat.mshID = 'ELLIPSOID-GRID' hmat.xgrid = np.radians(x) hmat.ygrid = np.radians(y) hmat.value = cellWidth jig.savemsh(opts.hfun_file, hmat) # define JIGSAW geometry geom = jig.jigsaw_msh_t() geom.mshID = 'ELLIPSOID-MESH' geom.radii = earth_radius * 1e-3 * np.ones(3, float) jig.savemsh(opts.geom_file, geom) # build mesh via JIGSAW! opts.hfun_scal = 'absolute' opts.hfun_hmax = float("inf") opts.hfun_hmin = 0.0 opts.mesh_dims = +2 # 2-dim. simplexes opts.mesh_iter = 500000 opts.optm_qlim = 0.9375 opts.optm_qtol = 1.0e-6 opts.optm_iter = 500000 opts.verbosity = +1 jig.savejig(opts.jcfg_file, opts) #Call jigsaw process = subprocess.call(['jigsaw', opts.jcfg_file]) return opts.mesh_file
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 ex_9(): # DEMO-9: generate a 2-dim. grid for the Australian coastal # region, using scaled ocean-depth as a mesh-resolution # heuristic. A local stereographic projection is employed. 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() mesh = jigsawpy.jigsaw_msh_t() msph = jigsawpy.jigsaw_msh_t() hmat = jigsawpy.jigsaw_msh_t() proj = jigsawpy.jigsaw_prj_t() #------------------------------------ setup files for JIGSAW opts.geom_file = \ os.path.join(dst_path, "proj.msh") opts.jcfg_file = \ os.path.join(dst_path, "aust.jig") opts.mesh_file = \ os.path.join(dst_path, "mesh.msh") opts.hfun_file = \ os.path.join(dst_path, "spac.msh") #------------------------------------ define JIGSAW geometry jigsawpy.loadmsh(os.path.join(src_path, "aust.msh"), geom) jigsawpy.loadmsh(os.path.join(src_path, "topo.msh"), topo) xmin = np.min(geom.point["coord"][:, 0]) ymin = np.min(geom.point["coord"][:, 1]) xmax = np.max(geom.point["coord"][:, 0]) ymax = np.max(geom.point["coord"][:, 1]) zlev = topo.value xmsk = np.logical_and(topo.xgrid > xmin, topo.xgrid < xmax) ymsk = np.logical_and(topo.ygrid > ymin, topo.ygrid < ymax) zlev = zlev[:, xmsk] zlev = zlev[ymsk, :] #------------------------------------ define spacing pattern hmat.mshID = "ellipsoid-grid" hmat.radii = np.full(+3, +6371.0, dtype=jigsawpy.jigsaw_msh_t.REALS_t) hmat.xgrid = \ topo.xgrid[xmsk] * np.pi / 180. hmat.ygrid = \ topo.ygrid[ymsk] * np.pi / 180. hmin = +1.0E+01 hmax = +1.0E+02 hmat.value = \ np.sqrt(np.maximum(-zlev, 0.)) / 0.5 hmat.value = \ np.maximum(hmat.value, hmin) hmat.value = \ np.minimum(hmat.value, hmax) hmat.slope = np.full(hmat.value.shape, +0.1500, dtype=jigsawpy.jigsaw_msh_t.REALS_t) #------------------------------------ do stereographic proj. geom.point["coord"][:, :] *= np.pi / 180. proj.prjID = 'stereographic' proj.radii = +6.371E+003 proj.xbase = \ +0.500 * (xmin + xmax) * np.pi / 180. proj.ybase = \ +0.500 * (ymin + ymax) * np.pi / 180. jigsawpy.project(geom, proj, "fwd") jigsawpy.project(hmat, proj, "fwd") jigsawpy.savemsh(opts.geom_file, geom) jigsawpy.savemsh(opts.hfun_file, hmat) #------------------------------------ set HFUN grad.-limiter 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.mesh_eps1 = +1.0E+00 # relax edge error opts.optm_iter = +32 opts.optm_qtol = +1.0E-05 jigsawpy.cmd.jigsaw(opts, mesh) #------------------------------------ do stereographic proj. msph = copy.deepcopy(mesh) jigsawpy.project(msph, proj, "inv") radii = np.full(+3, proj.radii, dtype=jigsawpy.jigsaw_msh_t.REALS_t) msph.vert3 = np.zeros((msph.vert2.size), dtype=jigsawpy.jigsaw_msh_t.VERT3_t) msph.vert3["coord"] = \ jigsawpy.S2toR3( radii, msph.point["coord"]) msph.vert2 = None #------------------------------------ save mesh for Paraview print("Saving to ../cache/case_9a.vtk") jigsawpy.savevtk(os.path.join(dst_path, "case_9a.vtk"), mesh) print("Saving to ../cache/case_9b.vtk") jigsawpy.savevtk(os.path.join(dst_path, "case_9b.vtk"), hmat) print("Saving to ../cache/case_9c.vtk") jigsawpy.savevtk(os.path.join(dst_path, "case_9c.vtk"), msph) return
nobj, last = \ coreshp(data, nset, eset, nobj, last) mesh.vert2 = np.concatenate(nset, axis=0) mesh.edge2 = np.concatenate(eset, axis=0) return if (__name__ == "__main__"): parser = argparse.ArgumentParser( description=__doc__, formatter_class=argparse.RawTextHelpFormatter) parser.add_argument( "--src_file", dest="src_file", type=str, required=True, help="Input shape file to load") parser.add_argument( "--dst_file", dest="dst_file", type=str, required=True, help="Output .msh file to save") args = parser.parse_args() mesh = jigsaw_msh_t() loadshp(name=args.src_file, mesh=mesh) savemsh(name=args.dst_file, mesh=mesh)
def setspac(): spac_wbd = 2.5 # watershed km spac_pfz = 1. # PFZ km elev_pfz = 25. # PFZ elev. thresh dhdx_lim = 0.0625 # |dH/dx| thresh bbox = [-77.5, 37.5, -72.5, 42.5] spac = jigsawpy.jigsaw_msh_t() opts = jigsawpy.jigsaw_jig_t() poly = jigsawpy.jigsaw_msh_t() geom = GEOM[0] opts.jcfg_file = os.path.join(TDIR, "opts.jig") opts.hfun_file = os.path.join(TDIR, "spac.msh") #------------------------------------ define spacing pattern print("BUILDING MESH SPAC.") print("Loading elevation assets...") data = nc.Dataset(os.path.join( "data", "etopo_gebco", "etopo_gebco_tiled.nc"), "r") zlev = np.array(data.variables["z"]) spac.mshID = "ellipsoid-grid" # use elev. grid spac.radii = np.full( +3, FULL_SPHERE_RADIUS, dtype=spac.REALS_t) spac.xgrid = np.array( data.variables["x"][:], dtype=spac.REALS_t) spac.ygrid = np.array( data.variables["y"][:], dtype=spac.REALS_t) xmsk = np.logical_and.reduce(( spac.xgrid >= bbox[0] - 1., spac.xgrid <= bbox[2] + 1. )) ymsk = np.logical_and.reduce(( spac.ygrid >= bbox[1] - 1., spac.ygrid <= bbox[3] + 1. )) spac.xgrid = spac.xgrid[xmsk] # only bbox part spac.ygrid = spac.ygrid[ymsk] zlev = zlev[:, xmsk] zlev = zlev[ymsk, :] spac.xgrid *= np.pi / +180. spac.ygrid *= np.pi / +180. xgrd, ygrd = np.meshgrid(spac.xgrid, spac.ygrid) spac.value = +10. * np.ones( (spac.ygrid.size, spac.xgrid.size)) grid = np.concatenate(( # to [x, y] list xgrd.reshape((xgrd.size, +1)), ygrd.reshape((ygrd.size, +1))), axis=+1) #------------------------------------ push watershed spacing print("Compute watersheds h(x)...") shed = np.full( (grid.shape[0]), False, dtype=bool) filename = os.path.join( "data", "NHD_H_0204_HU4_Shape", "Shape", "WBDHU4.shp") loadshp(filename, poly) poly.point["coord"] *= np.pi / +180. mask, _ = inpoly2( grid, poly.point["coord"], poly.edge2["index"]) shed[mask] = True shed = np.reshape(shed, spac.value.shape) spac.value[shed] = \ np.minimum(spac_wbd, spac.value[shed]) #------------------------------------ partially flooded zone mask = np.logical_and(shed, zlev < elev_pfz) spac.value[mask] = \ np.minimum(spac_pfz, spac.value[mask]) #------------------------------------ push |DH/DX| threshold print("Impose |DH/DX| threshold...") spac.slope = np.full( spac.value.shape, dhdx_lim, dtype=spac.REALS_t) jigsawpy.savemsh(opts.hfun_file, spac, "precision = 9") jigsawpy.cmd.marche(opts, spac) spac.slope = \ np.empty((+0), dtype=spac.REALS_t) #------------------------------------ proj. to local 2-plane proj = jigsawpy.jigsaw_prj_t() proj.prjID = "stereographic" proj.radii = FULL_SPHERE_RADIUS proj.xbase = PROJ_CENTRE[0] * np.pi / +180. proj.ybase = PROJ_CENTRE[1] * np.pi / +180. jigsawpy.project(spac, proj, "fwd") SPAC[0] = spac # save a "pointer" return spac
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 case_5_(src_path, dst_path): opts = jigsawpy.jigsaw_jig_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, "airfoil.msh") opts.jcfg_file = \ os.path.join(dst_path, "airfoil.jig") opts.mesh_file = \ os.path.join(dst_path, "airfoil.msh") opts.hfun_file = \ os.path.join(dst_path, "spacing.msh") #------------------------------------ compute HFUN over GEOM jigsawpy.loadmsh(opts.geom_file, geom) xgeo = geom.vert2["coord"][:, 0] ygeo = geom.vert2["coord"][:, 1] xpos = np.linspace(xgeo.min(), xgeo.max(), 80) ypos = np.linspace(ygeo.min(), ygeo.max(), 40) xmat, ymat = np.meshgrid(xpos, ypos) fun1 = \ +0.1 * (xmat - .40) ** 2 + \ +2.0 * (ymat - .55) ** 2 fun2 = \ +0.7 * (xmat - .75) ** 2 + \ +0.7 * (ymat - .45) ** 2 hfun = np.minimum(fun1, fun2) hmin = 0.01 hmax = 0.10 hfun = 0.4 * np.maximum(np.minimum(hfun, hmax), hmin) hmat.mshID = "euclidean-grid" hmat.ndims = +2 hmat.xgrid = np.array(xpos, dtype=hmat.REALS_t) hmat.ygrid = np.array(ypos, dtype=hmat.REALS_t) hmat.value = np.array(hfun, dtype=hmat.REALS_t) jigsawpy.savemsh(opts.hfun_file, 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_kern = "delfront" # DELFRONT kernel opts.mesh_dims = +2 opts.geom_feat = True opts.mesh_top1 = True jigsawpy.cmd.jigsaw(opts, mesh) print("Saving case_5a.vtk file.") jigsawpy.savevtk(os.path.join(dst_path, "case_5a.vtk"), hmat) print("Saving case_5b.vtk file.") jigsawpy.savevtk(os.path.join(dst_path, "case_5b.vtk"), mesh) return
def case_6_(src_path, dst_path): # DEMO-6: generate a 2-dim. grid for the Australian coastal # region, using scaled ocean-depth as a mesh-resolution # heuristic. A local stereographic projection is employed. 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() proj = jigsawpy.jigsaw_prj_t() #------------------------------------ setup files for JIGSAW opts.geom_file = \ os.path.join(dst_path, "geom.msh") opts.jcfg_file = \ os.path.join(dst_path, "aust.jig") opts.mesh_file = \ os.path.join(dst_path, "mesh.msh") opts.hfun_file = \ os.path.join(dst_path, "spac.msh") #------------------------------------ define JIGSAW geometry jigsawpy.loadmsh(os.path.join(src_path, "aust.msh"), geom) jigsawpy.loadmsh(os.path.join(src_path, "topo.msh"), topo) xmin = np.min(geom.point["coord"][:, 0]) ymin = np.min(geom.point["coord"][:, 1]) xmax = np.max(geom.point["coord"][:, 0]) ymax = np.max(geom.point["coord"][:, 1]) zlev = topo.value xmsk = np.logical_and(topo.xgrid > xmin, topo.xgrid < xmax) ymsk = np.logical_and(topo.ygrid > ymin, topo.ygrid < ymax) zlev = zlev[:, xmsk] zlev = zlev[ymsk, :] #------------------------------------ define spacing pattern hmat.mshID = "ellipsoid-grid" hmat.radii = np.full(+3, +6371.0, dtype=jigsawpy.jigsaw_msh_t.REALS_t) hmat.xgrid = \ topo.xgrid[xmsk] * np.pi / 180. hmat.ygrid = \ topo.ygrid[ymsk] * np.pi / 180. hmin = +1.0E+01 hmax = +1.0E+02 hmat.value = \ np.sqrt(np.maximum(-zlev, 0.)) / 0.5 hmat.value = \ np.maximum(hmat.value, hmin) hmat.value = \ np.minimum(hmat.value, hmax) hmat.slope = np.full(hmat.value.shape, +0.1500, dtype=jigsawpy.jigsaw_msh_t.REALS_t) #------------------------------------ do stereographic proj. geom.point["coord"][:, :] *= np.pi / 180. proj.prjID = 'stereographic' proj.radii = +6.371E+003 proj.xbase = \ +0.500 * (xmin + xmax) * np.pi / 180. proj.ybase = \ +0.500 * (ymin + ymax) * np.pi / 180. jigsawpy.project(geom, proj, "fwd") jigsawpy.project(hmat, proj, "fwd") jigsawpy.savemsh(opts.geom_file, geom) jigsawpy.savemsh(opts.hfun_file, hmat) #------------------------------------ set HFUN grad.-limiter 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.mesh_eps1 = +1. ttic = time.time() jigsawpy.cmd.jigsaw(opts, mesh) ttoc = time.time() print("CPUSEC =", (ttoc - ttic)) 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))) #------------------------------------ save mesh for Paraview print("Saving to ../cache/case_6a.vtk") jigsawpy.savevtk(os.path.join(dst_path, "case_6a.vtk"), mesh) print("Saving to ../cache/case_6b.vtk") jigsawpy.savevtk(os.path.join(dst_path, "case_6b.vtk"), hmat) return
def _write_to_file(self, out_format, out_file, multi_polygon, crs): _logger.info(f"Writing for file ({out_format}) ...") # TODO: Check for correct extension on out_file if out_format == "shapefile": gdf = gpd.GeoDataFrame({'geometry': multi_polygon}, crs=self._calc_crs) if not crs.equals(self._calc_crs): _logger.info(f"Project from {self._calc_crs.to_string()} to" f" {crs.to_string()} ...") gdf = gdf.to_crs(crs) gdf.to_file(out_file) elif out_format == "feather": gdf = gpd.GeoDataFrame({'geometry': multi_polygon}, crs=self._calc_crs) if not crs.equals(self._calc_crs): _logger.info(f"Project from {self._calc_crs.to_string()} to" f" {crs.to_string()} ...") gdf = gdf.to_crs(crs) gdf.to_feather(out_file) elif out_format in ("jigsaw", "vtk"): if not crs.equals(self._calc_crs): _logger.info(f"Project from {self._calc_crs.to_string()} to" f" {crs.to_string()} ...") transformer = Transformer.from_crs(self._calc_crs, crs, always_xy=True) multi_polygon = ops.transform(transformer.transform, multi_polygon) msh = jigsaw_msh_t() msh.ndims = +2 msh.mshID = 'euclidean-mesh' coords = [] edges = [] for polygon in multi_polygon: self._linearring_to_vert_edge(coords, edges, polygon.exterior) for interior in polygon.interiors: self._linearring_to_vert_edge(coords, edges, interior) msh.vert2 = np.array([(i, 0) for i in coords], dtype=jigsaw_msh_t.VERT2_t) msh.edge2 = np.array([(i, 0) for i in edges], dtype=jigsaw_msh_t.EDGE2_t) if out_format == "jigsaw": savemsh(out_file, msh) elif out_format == "vtk": savevtk(out_file, msh) else: raise NotImplementedError( f"Output type {out_format} is not supported") _logger.info("Done")
def jigsaw_driver(cellWidth, x, y, on_sphere=True, earth_radius=6371.0e3, geom_points=None, geom_edges=None, logger=None): """ A function for building a jigsaw mesh Parameters ---------- cellWidth : ndarray The size of each cell in the resulting mesh as a function of space x, y : ndarray The x and y coordinates of each point in the cellWidth array (lon and lat for spherical mesh) on_sphere : logical, optional Whether this mesh is spherical or planar earth_radius : float, optional Earth radius in meters geom_points : ndarray, optional list of point coordinates for bounding polygon for planar mesh geom_edges : ndarray, optional list of edges between points in geom_points that define the bounding polygon logger : logging.Logger, optional A logger for the output if not stdout """ # Authors # ------- # Mark Petersen, Phillip Wolfram, Xylar Asay-Davis # setup files for JIGSAW opts = jigsawpy.jigsaw_jig_t() opts.geom_file = 'mesh.msh' opts.jcfg_file = 'mesh.jig' opts.mesh_file = 'mesh-MESH.msh' opts.hfun_file = 'mesh-HFUN.msh' # save HFUN data to file hmat = jigsawpy.jigsaw_msh_t() if on_sphere: hmat.mshID = 'ELLIPSOID-GRID' hmat.xgrid = numpy.radians(x) hmat.ygrid = numpy.radians(y) else: hmat.mshID = 'EUCLIDEAN-GRID' hmat.xgrid = x hmat.ygrid = y hmat.value = cellWidth jigsawpy.savemsh(opts.hfun_file, hmat) # define JIGSAW geometry geom = jigsawpy.jigsaw_msh_t() if on_sphere: geom.mshID = 'ELLIPSOID-MESH' geom.radii = earth_radius * 1e-3 * numpy.ones(3, float) else: geom.mshID = 'EUCLIDEAN-MESH' geom.vert2 = geom_points geom.edge2 = geom_edges jigsawpy.savemsh(opts.geom_file, geom) # build mesh via JIGSAW! opts.hfun_scal = 'absolute' opts.hfun_hmax = float("inf") opts.hfun_hmin = 0.0 opts.mesh_dims = +2 # 2-dim. simplexes opts.optm_qlim = 0.9375 opts.verbosity = +1 savejig(opts.jcfg_file, opts) check_call(['jigsaw', opts.jcfg_file], logger=logger)
def ex_7(): # DEMO-7: setup simple piecewise linear geometry definitions 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() geom = jigsawpy.jigsaw_msh_t() mesh = jigsawpy.jigsaw_msh_t() #------------------------------------ setup files for JIGSAW opts.geom_file = \ os.path.join(src_path, "pslg.msh") opts.jcfg_file = \ os.path.join(dst_path, "pslg.jig") opts.mesh_file = \ os.path.join(dst_path, "mesh.msh") #------------------------------------ define JIGSAW geometry geom.mshID = "euclidean-mesh" geom.ndims = +2 geom.vert2 = np.array( [ # list of xy "node" coordinate ((0, 0), 0), # outer square ((9, 0), 0), ((9, 9), 0), ((0, 9), 0), ((4, 4), 0), # inner square ((5, 4), 0), ((5, 5), 0), ((4, 5), 0) ], dtype=geom.VERT2_t) geom.edge2 = np.array( [ # list of "edges" between vert ((0, 1), 0), # outer square ((1, 2), 0), ((2, 3), 0), ((3, 0), 0), ((4, 5), 0), # inner square ((5, 6), 0), ((6, 7), 0), ((7, 4), 0) ], dtype=geom.EDGE2_t) jigsawpy.savemsh(opts.geom_file, geom) #------------------------------------ make mesh using JIGSAW opts.hfun_scal = "absolute" opts.hfun_hmax = +2.5E-01 # uniform at 0.250 opts.mesh_dims = +2 # 2-dim. simplexes opts.geom_feat = True # do sharp feature opts.mesh_top1 = True # preserve 1-topo. 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 print("Saving to ../cache/case_7a.vtk") jigsawpy.savevtk(os.path.join(dst_path, "case_7a.vtk"), mesh) return
def runjgsw(mesh_path, make_bool, projector): """ RUNJGSW: main call to JIGSAW to build the triangulation. MESH-PATH should point to a user-defined mesh directory, containing the COMPOSE.py template. Firstly, MESH-PATH/COMPOSE.py is called to build user-defined geometry, initial conditions, mesh spacing and mesh configuration information. The boolean flags MAKE-BOOL control whether mesh information is built from scratch, or if an exitsing an existing file is to be used. For example, setting MAKE-BOOL.SPAC = FALSE relies on an existing spacing pattern be available in MESH-PATH/tmp/. This information is written to MESH-PATH/tmp/ to be accessed by subsequent calls to JIGSAW. Finally, JIGSAW is run to build the triangular mesh, calling either the multi-level (TETRIS) or single-level (JIGSAW) algorithms. Cells are assigned ID-tags via the polygon/regions defined in GEOM.BOUNDS. Returns full-dimensional and 2d-projected msh_t objects. """ # Authors: Darren Engwirda mesh = jigsawpy.jigsaw_msh_t() mprj = jigsawpy.jigsaw_msh_t() gprj = jigsawpy.jigsaw_msh_t() #------------------------------------ setup via user COMPOSE base = \ mesh_path.replace(os.path.sep, ".") if (make_bool.geom): geom = getattr(import_module( base + ".compose"), "setgeom")() if (make_bool.spac): spac = getattr(import_module( base + ".compose"), "setspac")() if (make_bool.init): init = getattr(import_module( base + ".compose"), "setinit")() if (make_bool.opts): opts = getattr(import_module( base + ".compose"), "setopts")() #------------------------------------ setup files for JIGSAW opts.geom_file = os.path.join( mesh_path, "tmp", "geom.msh") opts.jcfg_file = os.path.join( mesh_path, "tmp", "opts.jig") opts.init_file = os.path.join( mesh_path, "tmp", "init.msh") opts.hfun_file = os.path.join( mesh_path, "tmp", "spac.msh") opts.mesh_file = os.path.join( mesh_path, "tmp", "mesh.msh") opts.hfun_tags = "precision = 9" # less float prec. jigsawpy.savemsh(opts.geom_file, geom, opts.geom_tags) jigsawpy.savemsh(opts.hfun_file, spac, opts.hfun_tags) jigsawpy.savemsh(opts.init_file, init, opts.init_tags) #------------------------------------ make mesh using JIGSAW if (not hasattr(opts, "bisection")): opts.bisection = +0 if (opts.bisection < +0): # bisect heuristic rbar = np.mean(geom.radii) hbar = np.mean(spac.value) nlev = round(math.log2( rbar / math.sin(.4 * math.pi) / hbar) ) nlev = nlev - 1 ttic = time.time() jigsawpy.cmd.tetris(opts, nlev - 0, mesh) ttoc = time.time() print("CPUSEC =", (ttoc - ttic)) print("BISECT =", +nlev) elif (opts.bisection > +0): # bisect specified nlev = opts.bisection ttic = time.time() jigsawpy.cmd.tetris(opts, nlev - 0, mesh) ttoc = time.time() print("CPUSEC =", (ttoc - ttic)) print("BISECT =", +nlev) else: # do non-recursive ttic = time.time() jigsawpy.cmd.jigsaw(opts, mesh) ttoc = time.time() print("CPUSEC =", (ttoc - ttic)) #------------------------------------ form local projections gprj = copy.deepcopy(geom) # local 2d objects mprj = copy.deepcopy(mesh) if (mesh.vert3.size > +0): project(geom, mesh, gprj, mprj, projector) #------------------------------------ assign IDtag's to cell if (geom.bound is not None and geom.bound.size > +0): # tags per polygon imin = np.amin(geom.bound["IDtag"]) imax = np.amax(geom.bound["IDtag"]) for itag in range( imin + 0, imax + 1): tagcell(geom, mesh, gprj, mprj, itag) #------------------------------------ check mesh for quality 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.savevtk(os.path.join( mesh_path, "out", "geom.vtk"), geom) jigsawpy.savevtk(os.path.join( mesh_path, "out", "spac.vtk"), spac) jigsawpy.savevtk(os.path.join( mesh_path, "out", "init.vtk"), init) jigsawpy.savevtk(os.path.join( mesh_path, "out", "mesh.vtk"), mesh) jigsawpy.savevtk(os.path.join( mesh_path, "out", "geom_prj.vtk"), gprj) jigsawpy.savevtk(os.path.join( mesh_path, "out", "mesh_prj.vtk"), mprj) return geom, gprj, mesh, mprj
def case_6_(src_path, dst_path): # DEMO-6: generate a multi-part mesh of the (contiguous) USA # using state boundaries to partition the mesh. A local # stereographic projection is employed. The domain is meshed # using uniform resolution. opts = jigsawpy.jigsaw_jig_t() geom = jigsawpy.jigsaw_msh_t() mesh = jigsawpy.jigsaw_msh_t() proj = jigsawpy.jigsaw_prj_t() #------------------------------------ setup files for JIGSAW opts.geom_file = \ os.path.join(src_path, "proj.msh") opts.jcfg_file = \ os.path.join(dst_path, "us48.jig") opts.mesh_file = \ os.path.join(dst_path, "mesh.msh") #------------------------------------ define JIGSAW geometry jigsawpy.loadmsh(os.path.join(src_path, "us48.msh"), geom) xmin = np.min(geom.point["coord"][:, 0]) ymin = np.min(geom.point["coord"][:, 1]) xmax = np.max(geom.point["coord"][:, 0]) ymax = np.max(geom.point["coord"][:, 1]) geom.point["coord"][:, :] *= np.pi / 180. proj.prjID = 'stereographic' proj.radii = +6.371E+003 proj.xbase = \ +0.500 * (xmin + xmax) * np.pi / 180. proj.ybase = \ +0.500 * (ymin + ymax) * np.pi / 180. jigsawpy.project(geom, proj, "fwd") jigsawpy.savemsh(opts.geom_file, geom) #------------------------------------ make mesh using JIGSAW opts.hfun_hmax = .005 opts.mesh_dims = +2 # 2-dim. simplexes opts.mesh_eps1 = +1 / 6. jigsawpy.cmd.jigsaw(opts, mesh) #------------------------------------ save mesh for Paraview print("Saving to ../cache/case_6a.vtk") jigsawpy.savevtk(os.path.join(dst_path, "case_6a.vtk"), mesh) return