コード例 #1
0
ファイル: ptm_tools.py プロジェクト: mrayson/soda
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.'
コード例 #2
0
ファイル: ptm_tools.py プロジェクト: rustychris/soda
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.')
コード例 #3
0
ファイル: sunboundary.py プロジェクト: mrayson/soda
    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.
コード例 #4
0
ファイル: ptm_tools.py プロジェクト: rustychris/soda
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.')
コード例 #5
0
ファイル: ptm_tools.py プロジェクト: mrayson/soda
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.'
コード例 #6
0
ファイル: sunboundary.py プロジェクト: mrayson/soda
def modifyBCmarker(suntanspath, bcfile, saveplot=False):
    """
    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
    if saveplot:
        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 '#######################################################'
コード例 #7
0
def create_gmsh_geo(shpfile, scalefile, geofile,
    startpoly=0, ndmin=8, scalefac=1.0,\
    r=1.08, lcmax=2000.0, sigmoid=0,\
    linetype='BSpline'):
    """
    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.
        - sigmoid [default=0]
        - linetype - 'BSpline' or 'Line'
    """
    # 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

            if linetype == 'Line' and ip > 1:
                fgeo.write("Line(IL + %i) = {IP + %i , IP + %i};\n" % \
                        (il, ip-2, ip-1))
                il = il + 1
                lines.append(il - 1)

        if linetype == 'BSpline':
            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("%s(IL + %i) = {IP + %i : IP + %i};\n" %
                       (linetpye, 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("%s(IL + %i) = {IP + %i : IP + %i};\n" %
                       (linetype, 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)
コード例 #8
0
ファイル: gmsh.py プロジェクト: mrayson/soda
def create_gmsh_geo(shpfile, scalefile, geofile, 
    startpoly=0, ndmin=8, scalefac=1.0,\
    r=1.08, lcmax=2000.0, sigmoid=0,\
    linetype='BSpline'):
    """
    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.
        - sigmoid [default=0]
        - linetype - 'BSpline' or 'Line'
    """
    # 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

            if linetype == 'Line' and ip > 1:
                fgeo.write("Line(IL + %i) = {IP + %i , IP + %i};\n" % \
                        (il, ip-2, ip-1))
                il = il + 1
                lines.append(il-1)

                
        
        if linetype =='BSpline':
            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("%s(IL + %i) = {IP + %i : IP + %i};\n" % (linetpye,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("%s(IL + %i) = {IP + %i : IP + %i};\n" % (linetype,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