def shp2pol(shpfile, outdir): """ Converts a polygon shape file to a *.pol file Uses the first polygon in the file and the filename as the polygon name """ XY, name = readShpPoly(shpfile) xy = XY[0] numverts = xy.shape[0] polynameext = os.path.basename(shpfile) polyname, ext = os.path.splitext(polynameext) outfile = '%s/%s.pol' % (outdir, polyname) print 'Writing polygon to: %s...' % outfile f = open(outfile, 'w') f.write('POLYGON_NAME\n') f.write('%s\n' % polyname) f.write('NUMBER_OF_VERTICES\n') f.write('%d\n' % numverts) for ii in range(numverts): f.write('%6.10f %6.10f\n' % (xy[ii, 0], xy[ii, 1])) f.close() print 'Done.'
def shp2pol(shpfile,outdir): """ Converts a polygon shape file to a *.pol file Uses the first polygon in the file and the filename as the polygon name """ XY, name = readShpPoly(shpfile) xy = XY[0] numverts = xy.shape[0] polynameext = os.path.basename(shpfile) polyname,ext = os.path.splitext(polynameext) outfile = '%s/%s.pol'%(outdir,polyname) print 'Writing polygon to: %s...'%outfile f = open(outfile,'w') f.write('POLYGON_NAME\n') f.write('%s\n'%polyname) f.write('NUMBER_OF_VERTICES\n') f.write('%d\n'%numverts) for ii in range(numverts): f.write('%6.10f %6.10f\n'%(xy[ii,0],xy[ii,1])) f.close() print 'Done.'
def setAgeSource(self,shpfile): """ Sets the age source term using a polygon shapefile """ # Read the shapefile XY,tmp = readShpPoly(shpfile,FIELDNAME=None) if len(XY)<1: raise Exception, ' could not find any polygons in shapefile: %s'%shpfile for xpoly in XY: xycells = np.asarray([self.xv,self.yv]) #ind1 = nxutils.points_inside_poly(xycells.T,xpoly) ind1 = inpolygon(xycells.T,xpoly) # Sets all vertical layers for now... self.agesource[:,ind1] = 1.
def calc_agebin(binfile, ncfile, polyfile, ntout): """ Calculate the from a binary file and save to netcdf """ # Load the polygon from a shapefile xypoly, field = readShpPoly(polyfile) # Load the binary file object PTM = PtmBin(binfile) # Count the number of particles from the first time step time, pdata = PTM.read_timestep() N = pdata.shape[0] tsec = othertime.SecondsSince(PTM.time) dt = tsec[1] - tsec[0] # Initialize the age particle object Age = ParticleAge(xypoly[0], N) # Loop through outctr = ntout ncctr = 0 for tt in range(PTM.nt - 1): # Read the current time step time, pdata = PTM.read_timestep(ts=tt) # Update the age variable Age.update_age(pdata['x'][:, 0], pdata['x'][:, 1], pdata['x'][:, 2], dt) # Write to netcdf if outctr == ntout: Age.write_nc(time, ncctr, ncfile=ncfile) ncctr += 1 outctr = 0 outctr += 1 print 'Done.'
def calc_agebin(binfile,ncfile,polyfile,ntout): """ Calculate the from a binary file and save to netcdf """ # Load the polygon from a shapefile xypoly,field = readShpPoly(polyfile) # Load the binary file object PTM = PtmBin(binfile) # Count the number of particles from the first time step time,pdata = PTM.read_timestep() N = pdata.shape[0] tsec = othertime.SecondsSince(PTM.time) dt = tsec[1] - tsec[0] # Initialize the age particle object Age = ParticleAge(xypoly[0],N) # Loop through outctr = ntout ncctr=0 for tt in range(PTM.nt-1): # Read the current time step time,pdata = PTM.read_timestep(ts=tt) # Update the age variable Age.update_age(pdata['x'][:,0],pdata['x'][:,1],pdata['x'][:,2],dt) # Write to netcdf if outctr==ntout: Age.write_nc(time,ncctr,ncfile=ncfile) ncctr+=1 outctr=0 outctr+=1 print 'Done.'
def modifyBCmarker(suntanspath,bcfile): """ Modifies SUNTANS boundary markers with a shapefile The shapefile must contain polygons with the integer-type field "marker" """ print '#######################################################' print ' Modifying the boundary markers for grid in folder:' print ' %s'%suntanspath # Load the grid into an object grd = sunpy.Grid(suntanspath) # Find the edge points xe = np.mean(grd.xp[grd.edges],axis=1) ye = np.mean(grd.yp[grd.edges],axis=1) # Read the shapefile if not bcfile==None: XY,newmarker = readShpPoly(bcfile,FIELDNAME='marker') if len(XY)<1: print 'Error - could not find any polygons with the field name "marker" in shapefile: %s'%bcfile return XY,edge_id = readShpPoly(bcfile,FIELDNAME='edge_id') if len(XY)<1: print 'Error - could not find any polygons with the field name "edge_id" in shapefile: %s'%bcfile return else: XY=[] newmarker=[] edge_id=[] # Plot before updates #plt.figure() #grd.plotBC() #plt.plot(XY[0][:,0],XY[0][:,1],'m',linewidth=2) #plt.show() # Reset all markers to one (closed) ind0 = grd.mark>0 grd.mark[ind0]=1 # Find the points inside each of the polygon and assign new bc grd.edge_id = grd.mark*0 # Flag to identify linked edges/segments (marker=4 only) for xpoly, bctype,segmentID in zip(XY,newmarker,edge_id): ind0 = grd.mark>0 edges = np.asarray([xe[ind0],ye[ind0]]) mark = grd.mark[ind0] #ind1 = nxutils.points_inside_poly(edges.T,xpoly) ind1 = inpolygon(edges.T,xpoly) if bctype==4: eflag = grd.edge_id[ind0] eflag[ind1]=segmentID grd.edge_id[ind0]=eflag bctype=2 mark[ind1]=bctype grd.mark[ind0]=mark # Save the new markers to edges.dat edgefile = suntanspath+'/edges.dat' grd.saveEdges(edgefile) print 'Updated markers written to: %s'%(edgefile) # Plot the markers plt.figure() grd.plotBC() if len(XY)>0: plt.plot(XY[0][:,0],XY[0][:,1],'m',linewidth=2) figfile = suntanspath+'/BoundaryMarkerTypes.pdf' plt.savefig(figfile) print 'Marker plot saved to: %s'%(figfile) print 'Done.' print '#######################################################'
def create_gmsh_geo(shpfile,scalefile,geofile,startpoly=0,ndmin=8,scalefac=1.0,\ r=1.08,lcmax=2000.0,sigmoid=0): """ Generate a gmsh *.geo file using a boundary from a shpfile Inputs: --- - shpfile : a polygon shapefile with the domain boundaries. Make sure that the first polygon is the outer ring. If not change 'startpoly' parameter. - scalefile : a line shapefile with field 'scale' specifying the target grid resolution for that region. - geofile: output geo ascii file. *Optional* - startpoly [default=0] - the index of the outer polygon in the shapefile. - ndmin [default=8] - the minimum range of the scale = ndmin*scale - r : expansion factor - lcmax [default=2000] - the maximum grid cell size. """ # Load the polygon shape file xy,field = readShpPoly(shpfile,FIELDNAME='FID') # Load the scale shape file xyscale,scale = readShpPointLine(scalefile,FIELDNAME='scale') # Load the 'embed' flag to see if the scale layer should be embedded #try: # exyscale,embed = readShpPointLine(scalefile,FIELDNAME='embed') #except: # print 'Warning - could not find "embed" field in shapefile. Setting embed = 0.' # embed = [ss*0 for ss in scale] exyscale,embed = readShpPointLine(scalefile,FIELDNAME='embed') if embed == []: embed = [ss*0 for ss in scale] ## output geo and svg file fgeo = open(geofile,'w') fgeo.write("""IP = newp; IL = newl; IS = news; IF = newf; """ ) ip = 0 # Point counter il = 0 # Line counter rp = 0 lines=[] for loop in xy: firstp = ip for p in range(loop.shape[0]): rp = rp + 1 fgeo.write("Point(IP + %i) = {%.16e, %.16e, %.16e}; // %i\n" % (ip, loop[p,0], loop[p,1], 0., rp -1)) ip = ip + 1 fgeo.write("BSpline(IL + %i) = {IP + %i : IP + %i, IP + %i};\n" % (il, firstp, ip - 1, firstp)) il = il + 1 lines.append(il-1) # Create the surface polygon fgeo.write('\n//%s\n//Surface Polygon Definition\n//%s\n\n'%(72*'#',72*'#')) surfstart=il fgeo.write("Line Loop(IL + %i) = {IL + %s};\n" % (il,startpoly) ) il += 1 for ll in lines: if ll != startpoly: fgeo.write("Line Loop(IL + %i) = {IL + %s};\n" % (il,ll) ) il += 1 surfend = il - 1 fgeo.write("Plane Surface(IL + %i) = {IL + %i : IL + %i};\n"%(il,surfstart,surfend)) fgeo.write('Physical Surface("Ocean") = {IL + %i};\n'%il) surface_id = il # Keep this to embed lines into il += 1 # Create the grid scale lines and fields fgeo.write('\n//%s\n//Grid Scale Definition\n//%s\n\n'%(72*'#',72*'#')) slines=[] # Reference to scale lines for loop,ss,ee in zip(xyscale,scale,embed): firstp = ip ss *= scalefac # Applies scale factor for p in range(loop.shape[0]): rp = rp + 1 #fgeo.write("Point(IP + %i) = {%.16e, %.16e, %.16e}; // %i\n" % (ip, loop[p,0], loop[p,1], 0., rp -1)) fgeo.write("Point(IP + %i) = {%.16e, %.16e, %.16e,%.16e}; // %i\n" % (ip, loop[p,0], loop[p,1], 0., rp -1,float(ss))) ip = ip + 1 if ee: #fgeo.write("BSpline(IL + %i) = {IP + %i : IP + %i};\n" % (il, firstp, ip - 1)) fgeo.write("Spline(IL + %i) = {IP + %i : IP + %i};\n" % (il, firstp, ip - 1)) # Embed this line in the main surface so that cells are aligned fgeo.write("Line{IL + %i} In Surface{IL + %i};\n"%(il,surface_id)) else: # Don't embed (can set as BSpline) fgeo.write("BSpline(IL + %i) = {IP + %i : IP + %i};\n" % (il, firstp, ip - 1)) slines.append(il) il = il + 1 ifield = 0 # Field counter fids = [] ii=0 for ss,line in zip(scale,slines): fgeo.write("Field[IF + %i] = Attractor;\n"%ifield) fgeo.write("Field[IF + %i].EdgesList = {IL + %i};\n"%(ifield,line)) nodesperedge = get_nnodes_from_line(xyscale[ii],2.0*float(ss)) fgeo.write("Field[IF + %i].NNodesByEdge = %i;\n"%(ifield,nodesperedge)) ifield+=1 fgeo.write("Field[IF + %i] = Threshold;\n"%ifield) # Find the maximum distance Nk = np.log(lcmax/ss)/np.log(r) print ss,Nk lmin = float(ndmin)*float(ss) lmax = lmin + Nk * ss fgeo.write("Field[IF + %i].DistMax = %6.2f;\n"%(ifield,lmax)) fgeo.write("Field[IF + %i].DistMin = %6.2f;\n"%(ifield,lmin)) fgeo.write("Field[IF + %i].IField = IF + %i;\n"%(ifield,ifield-1)) fgeo.write("Field[IF + %i].LcMax = %6.2f;\n"%(ifield,lcmax)) fgeo.write("Field[IF + %i].LcMin = %6.2f;\n"%(ifield,float(ss))) fgeo.write("Field[IF + %i].Sigmoid = %d;\n"%(ifield,sigmoid)) fids.append(ifield) ifield+=1 ii+=1 fieldlist = '{' for ff in fids: fieldlist += 'IF + %d, '%ff fieldlist = fieldlist[:-2]+'}' fgeo.write("Field[IF + %i] = Min;\n"%ifield) fgeo.write("Field[IF + %i].FieldsList = %s;\n"%(ifield,fieldlist)) fgeo.write("Background Field = IF + %i;\n"%ifield) # Set Quad options by default fgeo.write("Mesh.CharacteristicLengthMax=%.16e;//Max cell size\n"%lcmax) fgeo.write("Mesh.RecombineAll=0;//recombine all defined surfaces\n") fgeo.write("Mesh.Algorithm=6;//front\n") fgeo.write("Mesh.Smoothing=10;//10 smoothing steps\n") fgeo.write("Mesh.Remove4Triangles = 1;\n") fgeo.close() print 'Complete. GMSH geo file written to:\n\t %s'%geofile