Since I am familar with the blockMesh utility and GIS, I decided to try another approach. Using ArcGIS I converted the point cloud first to a TIN and then a DEM. A DEM is essentially a regular matrix of elevations and which makes it very easy to work with as opposed to a randomly spaced point cloud. I then exported the DEM to an ASCII DEM. Finally I wrote a PYTHON script to read the ASCII DEM and write out the blockMeshDict file. The script can be found below. Currently the script requires to user to specify the number of rows and columns as well as the cell size however these could also be read from the ASCII DEM header. The script is nice in that it is easy to make modifications to extract subsets. For example I have a version used to extract a 2D slice of the bed.
There is one issue with the code to be aware of. The code treats each centroid of the DEM as a vertex in the blockMesh which is not quite correct. This may or may not be an issue depending on your problem, but can be corrected. If I get around to correcting this I will post the code.
Here is an image of the mesh I was able to generate for my point cloud:
''' Created on May 10, 2013 @author: Patrick Grover ''' from numpy import * # note that matrix starts at 1,1 and goes up to numrows,numcols def getvertex(row, col, numrows): index = numrows*(col-1) + row return index def getBlock(row, col, numrows,numcols, blockSettings): retval = "\thex (" retval = retval + str(getvertex(row,col,numrows)-1) + " " retval = retval + str(getvertex(row+1,col,numrows)-1) + " " retval = retval + str(getvertex(row+1,col+1,numrows)-1) + " " retval = retval + str(getvertex(row,col+1,numrows)-1) + " " numvertices = numrows*numcols retval = retval + str(getvertex(row,col,numrows) + numvertices-1) + " " retval = retval + str(getvertex(row+1,col,numrows) + numvertices-1) + " " retval = retval + str(getvertex(row+1,col+1,numrows) + numvertices-1) + " " retval = retval + str(getvertex(row,col+1,numrows) + numvertices-1) + ") " retval = retval + blockSettings return retval def getTopWall(row, col, numrows,numcols): numvertices = numrows*numcols retval = "(" + str(getvertex(row,col,numrows) + numvertices-1) + " " retval = retval + str(getvertex(row,col+1,numrows) + numvertices-1) + " " retval = retval + str(getvertex(row+1,col+1,numrows) + numvertices-1) + " " retval = retval + str(getvertex(row+1,col,numrows) + numvertices-1) + ") " return retval def getBottomWall(row, col, numrows,numcols): retval = "(" + str(getvertex(row,col,numrows) -1) + " " retval = retval + str(getvertex(row+1,col,numrows) -1) + " " retval = retval + str(getvertex(row+1,col+1,numrows)-1 ) + " " retval = retval + str(getvertex(row,col+1,numrows)-1 ) + ") " return retval def getInlet(row, col, numrows,numcols): numvertices = numrows*numcols retval = "(" + str(getvertex(row,col,numrows)-1) + " " retval = retval + str(getvertex(row,col,numrows)+ numvertices-1) + " " retval = retval + str(getvertex(row+1,col,numrows) + numvertices-1) + " " retval = retval + str(getvertex(row+1,col,numrows) -1) retval = retval + ") " return retval def getOutlet(row, col, numrows,numcols): numvertices = numrows*numcols retval = "(" + str(getvertex(row,col,numrows)-1) + " " retval = retval + str(getvertex(row+1,col,numrows) -1) + " " retval = retval + str(getvertex(row+1,col,numrows) + numvertices-1) + " " retval = retval + str(getvertex(row,col,numrows) + numvertices-1) retval = retval + ") " return retval def getLeftWall(row, col, numrows,numcols): numvertices = numrows*numcols retval = "(" + str(getvertex(row,col,numrows)-1) + " " retval = retval + str(getvertex(row,col+1,numrows)-1) + " " retval = retval + str(getvertex(row,col+1,numrows) + numvertices-1) + " " retval = retval + str(getvertex(row,col,numrows) + numvertices-1) retval = retval + ") " return retval def getRightWall(row, col, numrows,numcols): numvertices = numrows*numcols retval = "(" + str(getvertex(row,col,numrows)-1) + " " retval = retval + str(getvertex(row,col,numrows)+ numvertices-1) + " " retval = retval + str(getvertex(row,col+1,numrows) + numvertices-1) + " " retval = retval + str(getvertex(row,col+1,numrows)-1) retval = retval + ") " return retval #-------------------------------------------------------------------------------- # BlockMesh Parameters # Manually set these. Could read these from the ASCII header. depth = 2.0 numrows = 67 numcols = 1000 cellsize = 0.03 # Meshing details - describes the mesh blockSettings = "(2 1 20) simpleGrading (1 1 10)\n"
# Input ASCII DEM
asciiFilePath = '/home/geeko/working/GIS/dunes_3cm_67x1000.asc' # Path to the blockMeshDict
blockMeshPath = "/home/geeko/working/BlockMesh/TestMesh2/constant/polyMesh/blockMeshDict" # Read in ASCII file data = genfromtxt(asciiFilePath,delimiter=' ',skiprows=6,unpack=True, filling_values=-9999) print data fo= open(blockMeshPath,'w') fo.write("FoamFile\n{version\t2.0;\n\tformat\tascii;\n\tclass\tdictionary;\n\tobject\tblockMeshDict;\n}\n\n") fo.write("convertToMeters 1.0;\n\n") # Write out vertices fo.write("vertices\n") fo.write("(\n") for y in range(0,numcols): for x in range(0,numrows): #print "x= " + str(x) + "y= " + str(y) if data[y,x]==-9999: print "!!!!!!!!!!!!!!!! Error!!!!!!!!!!!!!!!!!!!!!" #fo.write("( " + str(x*cellsize) + " " + str(y*cellsize) + " " + str(data[numrows-y-1,x]) + ")\n") fo.write("( " + str(x*cellsize) + " " + str(y*cellsize) + " " + str(data[y-1,x]) + ")\n") for y in range(0,numcols): for x in range(0,numrows): fo.write("( " + str(x*cellsize) + " " + str(y*cellsize) + " " + str(depth) + ")\n") fo.write(");\n") # Write out blocks fo.write("blocks\n") fo.write("(\n") for row in range (1,numrows): for col in range(1,numcols): fo.write(getBlock(row, col, numrows,numcols, blockSettings)) fo.write(");\n") fo.close #edges fo.write("edges\n") fo.write("(\n") fo.write(");\n"); # Boundaries fo.write("boundary\n") fo.write("(\n") # Top Wall fo.write("\ttopWall\n") fo.write("\t{\n") fo.write("\ttype symmetryPlane;\n") fo.write("\tfaces\n") fo.write("\t(\n") for row in range (1,numrows): for col in range(1,numcols): fo.write("\t\t" + getTopWall(row, col, numrows,numcols) + "\n") fo.write("\t);\n") fo.write("\t}\n") # getBottomWall fo.write("\tbottomWall\n") fo.write("\t{\n") fo.write("\ttype wall;\n") fo.write("\tfaces\n") fo.write("\t(\n") for row in range (1,numrows): for col in range(1,numcols): fo.write("\t\t" + getBottomWall(row, col, numrows,numcols) + "\n") fo.write("\t);\n") fo.write("\t}\n") # Inlet fo.write("\tinlet\n") fo.write("\t{\n") fo.write("\ttype patch;\n") #fo.write("\ttype cyclic;\n") #fo.write("\tneighbourPatch outlet;\n") fo.write("\tfaces\n") fo.write("\t(\n") for row in range(1,numrows): fo.write("\t\t" + getInlet(row, 1, numrows,numcols) + "\n") fo.write("\t);\n") fo.write("\t}\n") # Outlet fo.write("\toutlet\n") fo.write("\t{\n") fo.write("\ttype patch;\n") #fo.write("\ttype cyclic;\n") #fo.write("\tneighbourPatch inlet;\n") fo.write("\tfaces\n") fo.write("\t(\n") for row in range(1,numrows): fo.write("\t\t" + getOutlet(row, numcols, numrows,numcols) + "\n") fo.write("\t);\n") fo.write("\t}\n") # Front and Back fo.write("\tfrontAndBack\n") fo.write("\t{\n") fo.write("\ttype empty;\n") fo.write("\tfaces\n") fo.write("\t(\n") fo.write("\t// Left side\n") for col in range (1,numcols): fo.write("\t\t" + getLeftWall(1, col, numrows,numcols) + "\n") fo.write("\t// Right side\n") for col in range (1,numcols): fo.write("\t\t" + getRightWall(numrows, col, numrows,numcols) + "\n") fo.write("\t);\n") fo.write("\t}\n") fo.write(");\n") #mergePatchPairs fo.write("mergePatchPairs\n") fo.write("(\n") fo.write(");\n"); print "Done!"
Thanks. I have problems in the generation of .xyz file or ASCII file. It will be very grateful if you can further explain details of ArcMap.
ReplyDelete