initial upload
This commit is contained in:
194
PyLaGriT/examples/ideas_mesh/ideas_mesh.py
Executable file
194
PyLaGriT/examples/ideas_mesh/ideas_mesh.py
Executable file
@@ -0,0 +1,194 @@
|
||||
import optparse
|
||||
import shutil, distutils.dir_util, os, sys, glob
|
||||
|
||||
import numpy
|
||||
import math
|
||||
import matplotlib.pyplot as plt
|
||||
from pylagrit import PyLaGriT
|
||||
|
||||
#
|
||||
# Create parser and options
|
||||
#
|
||||
p = optparse.OptionParser()
|
||||
p.add_option('--dem-file', help='DEM data file name including path', type='string', dest='dem_filename' )
|
||||
p.add_option('--exo-file', help='Exodus II mesh output including path', type='string', dest='exo_filename')
|
||||
p.add_option('--dry-run', help='Show commands and diagnostics but no execution', default=False, dest='dry_run', action='store_true')
|
||||
p.add_option('--plot', help='Show commands and diagnostics but no execution', default=False, dest='plot', action='store_true')
|
||||
#
|
||||
(opts,args) = p.parse_args()
|
||||
|
||||
print(opts.dem_filename)
|
||||
print(opts.dry_run)
|
||||
|
||||
# Input: DEM data
|
||||
dem_file_fullname=opts.dem_filename
|
||||
dem_file_noext, dem_file_ext=os.path.splitext(opts.dem_filename)
|
||||
dem_file_base=os.path.basename(opts.dem_filename).rstrip(dem_file_ext)
|
||||
dem_file_path=os.path.dirname(opts.dem_filename)
|
||||
|
||||
# Output: Exodus II mesh
|
||||
exo_file_fullname=opts.exo_filename
|
||||
exo_file_noext, exo_file_ext=os.path.splitext(opts.exo_filename)
|
||||
exo_file_base=os.path.basename(opts.exo_filename).rstrip(exo_file_ext)
|
||||
exo_file_path=os.path.dirname(opts.exo_filename)
|
||||
|
||||
# Output: XML region specifications for the new mesh
|
||||
xml_file_fullname=exo_file_path+exo_file_base+'.xml'
|
||||
|
||||
# DEM parsing
|
||||
#
|
||||
with open(dem_file_fullname) as dem_header:
|
||||
for line in dem_header:
|
||||
if ("ncols" in line):
|
||||
nx=int(line.split()[1])
|
||||
elif ("nrows" in line):
|
||||
ny=int(line.split()[1])
|
||||
elif ("xllcorner" in line):
|
||||
xll_corner=float(line.split()[1])
|
||||
elif ("yllcorner" in line):
|
||||
yll_corner=float(line.split()[1])
|
||||
elif ("cellsize" in line):
|
||||
dx=float(line.split()[1])
|
||||
dy=dx
|
||||
elif ("NODATA_value" in line):
|
||||
no_data_value=int(line.split()[1])
|
||||
break
|
||||
|
||||
print(nx, ny, xll_corner, yll_corner, dx, dy, no_data_value)
|
||||
dem_header.close()
|
||||
|
||||
d = numpy.flipud(numpy.genfromtxt(dem_file_fullname,skip_header=6))
|
||||
#plt.matshow(d)
|
||||
|
||||
# Create mesh based on ncols and nrows in file, could automatically read
|
||||
x = numpy.linspace(xll_corner,dx*(nx-1),nx)
|
||||
y = numpy.linspace(yll_corner,dy*(ny-1),ny)
|
||||
|
||||
x=numpy.arange(xll_corner,dx*nx,dx)
|
||||
y=numpy.arange(yll_corner,dy*ny,dy)
|
||||
|
||||
xx, yy = numpy.meshgrid(x,y)
|
||||
|
||||
# Write avs file
|
||||
fh = open(dem_file_base+'.avs','w')
|
||||
# Find number of data values and write avs header
|
||||
N = numpy.where(numpy.isnan(d)==False)[0].shape[0]
|
||||
fh.write(str(N)+' 0 0 0 0\n')
|
||||
# Collect data into avs format
|
||||
# JDM: Not sure if this should be nx*ny?
|
||||
davs = numpy.zeros([nx*ny,4])
|
||||
ind = 0
|
||||
for i,row in enumerate(d):
|
||||
for j,v in enumerate(row):
|
||||
davs[ind,:] = [ind + 1, xx[i,j], yy[i,j], v]
|
||||
ind += 1
|
||||
# Write data to avs file
|
||||
numpy.savetxt(fh,davs,fmt=['%4d','%.1lf','%.1lf','%.8lf'])
|
||||
fh.close()
|
||||
|
||||
# Crank up pylagrit
|
||||
lg = PyLaGriT()
|
||||
# Read in elevations in avs fromat
|
||||
m = lg.read(dem_file_base+'.avs')
|
||||
# Take a look, change paraview exe
|
||||
# Will need to use glyph filter to view points
|
||||
#m.paraview(exe='paraview')
|
||||
|
||||
# Copy z values over to attribute
|
||||
m.addatt('z_save',vtype='vdouble',rank='scalar')
|
||||
m.copyatt('zic','z_save')
|
||||
# Not sure why this has to be done, but not data elements don't get removed otherwise
|
||||
m.setatt('zic',0.)
|
||||
|
||||
# Create connected quad mesh surface
|
||||
m2 = lg.create()
|
||||
#m2.createpts_xyz((nx,ny,1),[xx.min(),yy.min(),0.],[xx.max(),yy.max(),0],rz_switch=[1,1,1],connect=True)
|
||||
m2.createpts_xyz((nx,ny,1),[xx.min(),yy.min(),0.],[xx.max(),yy.max(),0],rz_switch=[1,1,1])
|
||||
# Create temporary z value attribute
|
||||
m2.addatt('z_save',vtype='vdouble',rank='scalar')
|
||||
# Interpolate elevations to z_save
|
||||
m2.interpolate_voronoi('z_save',m,'z_save')
|
||||
# Find nodes associated with nodata
|
||||
pdel = m2.pset_attribute('z_save',-9999)
|
||||
# Create element set from these nodes and remove elements
|
||||
edel = pdel.eltset()
|
||||
m2.rmpoint_eltset(edel)
|
||||
# Copy temp z values over to actual a values
|
||||
#m2.copyatt('z_save','zic')
|
||||
# Take a look to make sure everything is ok
|
||||
#m2.paraview(exe='paraview')
|
||||
|
||||
|
||||
|
||||
m3 = m2.copypts(elem_type='triplane')
|
||||
m3.connect()
|
||||
# To lazy to add to pylagrit now, and don't know how to make it intuitive
|
||||
# Creates edge_max element attribute containing max edge length
|
||||
m3.sendline('quality/edge_max/y')
|
||||
# Query created attribute
|
||||
#m3.printatt('edgemax')
|
||||
m3.minmax('edgemax')
|
||||
# Figure out max desired edge length
|
||||
max_edge = numpy.sqrt(dx**2+dy**2)
|
||||
# Identify elements with longer edges
|
||||
edel = m3.eltset_attribute('edgemax',max_edge*2.05,'gt')
|
||||
m3.rmpoint_eltset(edel)
|
||||
|
||||
#m3 = m2.grid2grid_quadtotri2()
|
||||
#m3=m2
|
||||
# Create temporary z value attribute
|
||||
m3.addatt('z_save',vtype='vdouble',rank='scalar')
|
||||
# Interpolate elevations to z_save
|
||||
m3.interpolate_voronoi('z_save',m,'z_save')
|
||||
|
||||
# Find nodes associated with nodata
|
||||
pdel = m3.pset_attribute('z_save',-9999)
|
||||
# Create element set from these nodes and remove elements
|
||||
edel = pdel.eltset()
|
||||
m3.rmpoint_eltset(edel)
|
||||
# Copy temp z values over to actual a values
|
||||
m3.copyatt('z_save','zic')
|
||||
# Take a look to make sure everything is ok
|
||||
#m2.paraview(exe='paraview')
|
||||
|
||||
# Create top surface avs
|
||||
m3.dump('top.inp')
|
||||
## Subtract 1 from z values of top and dump into bottom surface avs
|
||||
m3.math('sub',1,'zic',cmosrc=m3)
|
||||
m3.dump('mid.inp')
|
||||
m3.setatt('zic',0.0)
|
||||
m3.dump('bot.inp')
|
||||
|
||||
# Stack the layers in a new mesh object
|
||||
stack = lg.create()
|
||||
stack.stack_layers('avs',['bot.inp 1','mid.inp 1,3','top.inp 1,0'],flip_opt=True)
|
||||
stack_hex = stack.stack_fill()
|
||||
# Automatically create face sets based on normal vectors and layer id
|
||||
#fs = stack_hex.create_boundary_facesets(base_name='faceset_bounds',stacked_layers=True)
|
||||
#fs = stack_hex.create_boundary_facesets(base_name='faceset_bounds',stacked_layers=False)
|
||||
# Diagnostic
|
||||
#stack_hex.sendline('quality volume itetclr')
|
||||
|
||||
# Write exo file with boundary facesets
|
||||
#stack_hex.dump_exo(exo_file_fullname,facesets=fs.values())
|
||||
stack_hex.dump_exo(exo_file_fullname)
|
||||
|
||||
# Write region and faceset identifier file for ats_xml
|
||||
matnames = {10000:'computational domain peat'}
|
||||
facenames = {1:'bottom face',
|
||||
2:'surface',
|
||||
3:'front',
|
||||
4:'right',
|
||||
5:'back',
|
||||
6:'left'}
|
||||
|
||||
# Dump ats style xml for mesh, can provide options for other schemas easily also
|
||||
#stack_hex.dump_ats_xml(xml_file_fullname,exo_file_fullname,matnames=matnames,facenames=facenames)
|
||||
stack_hex.dump_ats_xml(xml_file_fullname,exo_file_fullname,matnames=matnames,facenames=facenames)
|
||||
|
||||
# Take a look
|
||||
if opts.plot:
|
||||
stack_hex.paraview(exe='/Applications/paraview.app/Contents/MacOS/paraview')
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user