480 lines
15 KiB
Python
480 lines
15 KiB
Python
|
|
# -*- coding: utf-8
|
|||
|
|
# This script is the PyLaGriT version of LaGriT tutorial example at
|
|||
|
|
# https://lanl.github.io/LaGriT/pages/tutorial/stratigraphy/index.html.
|
|||
|
|
# Written by Guoyan Jiang (gyjiang@whu.edu.cn) with technical support
|
|||
|
|
# from Dylan Harp (dharp@lanl.gov) and Terry Miller (tamiller@lanl.gov).
|
|||
|
|
|
|||
|
|
# Import PyLaGriT class from pylagrit module
|
|||
|
|
from pylagrit import PyLaGriT
|
|||
|
|
import numpy
|
|||
|
|
|
|||
|
|
# Variables
|
|||
|
|
maxX = 4000 # Max value in x direction
|
|||
|
|
maxY = 4000 # Max value in y direction
|
|||
|
|
maxZ = 3000 # Max value in z direction
|
|||
|
|
numX = 51 # Number of points in x direction
|
|||
|
|
numY = 51 # Number of points in y direction
|
|||
|
|
numZ = 26 # Number of points in z direction
|
|||
|
|
|
|||
|
|
# Create PyLaGriT object
|
|||
|
|
# This assumes that pylagritrc is being used so that lagrit_exe option does not need to be specified
|
|||
|
|
lg = PyLaGriT()
|
|||
|
|
|
|||
|
|
#********************************************
|
|||
|
|
# 01 Built HEX Mesh
|
|||
|
|
#********************************************
|
|||
|
|
# Create mesh object
|
|||
|
|
mo = lg.create_hex()
|
|||
|
|
mo.createpts_brick_xyz((numX, numY, numZ), (0,0,0), (maxX, maxY, maxZ))
|
|||
|
|
|
|||
|
|
# Save the mesh object
|
|||
|
|
mo.dump('tmp_hex_01.inp')
|
|||
|
|
|
|||
|
|
# Set vertices (imt) and cells (itetlcr) to 1
|
|||
|
|
mo.setatt('imt', 1)
|
|||
|
|
mo.setatt('itetclr', 1)
|
|||
|
|
|
|||
|
|
# Set node type from connectivity of mesh
|
|||
|
|
mo.resetpts_itp()
|
|||
|
|
|
|||
|
|
#********************************************
|
|||
|
|
# 02 Use pset’s to identify (for setting boundary conditions,
|
|||
|
|
# initial conditions, etc.) a set of vertices on the top
|
|||
|
|
# surface of the mesh
|
|||
|
|
#********************************************
|
|||
|
|
# Create a pset named p_top, which contains all nodes (stride = 1 0 0)
|
|||
|
|
# where the node’s Z value (zic) is greater than or equal to (ge) the top of the mesh (maxZ)
|
|||
|
|
pset0 = mo.pset_attribute('zic', maxZ, 'ge', (1,0,0), 'p_top')
|
|||
|
|
|
|||
|
|
# Define three cylindrical objects
|
|||
|
|
pset1 = mo.pset_geom((0,0,-1), (1100,360,10000), (1500,1500,0), 'rtz', (1,0,0), 'p_circle1')
|
|||
|
|
pset2 = mo.pset_geom((0,0,-1), (1100,360,10000), (2500,2500,0), 'rtz', (1,0,0), 'p_circle2')
|
|||
|
|
pset3 = mo.pset_geom((0,0,-1), (1100,360,10000), (2500,1500,0), 'rtz', (1,0,0), 'p_circle3')
|
|||
|
|
|
|||
|
|
# Intersect four psets, points belonging to the union of all given sets are preserved into the pset p_region
|
|||
|
|
pset4 = mo.pset_inter([pset0, pset1, pset2, pset3], 'p_region')
|
|||
|
|
|
|||
|
|
# Map psets to an attribute
|
|||
|
|
mo.addatt('id_top_region', vtype='vint', rank='scalar') # Creat a node-based attribute id_top_region within the mesh object
|
|||
|
|
mo.setatt('id_top_region', 1) #Fill the entire attribute with 1
|
|||
|
|
pset1.setatt('id_top_region', 2) #Color all nodes in the pset p_circle1 with the value 2
|
|||
|
|
pset2.setatt('id_top_region', 3)
|
|||
|
|
pset3.setatt('id_top_region', 4)
|
|||
|
|
pset4.setatt('id_top_region', 5)
|
|||
|
|
|
|||
|
|
# Release the psets from memory
|
|||
|
|
pset0.delete()
|
|||
|
|
pset1.delete()
|
|||
|
|
pset2.delete()
|
|||
|
|
pset3.delete()
|
|||
|
|
pset4.delete()
|
|||
|
|
|
|||
|
|
#********************************************
|
|||
|
|
# 03 Build some surfaces to define stratigraphy.
|
|||
|
|
# In a real model, the surfaces would come from some geologic framework model
|
|||
|
|
# and would define geologic or hydro-geologic horizons and topography.
|
|||
|
|
#********************************************
|
|||
|
|
mosurf1 = lg.create_qua() # Create the top surface
|
|||
|
|
p1 = (-20, -20, 1000)
|
|||
|
|
p2 = (4020, -20, 1500)
|
|||
|
|
p3 = (4020, 4020, 2500)
|
|||
|
|
p4 = (-20, 4020, 500)
|
|||
|
|
pts = [p1, p2, p3, p4]
|
|||
|
|
nnodes = (numX, numY, 1)
|
|||
|
|
mosurf1.quadxy(nnodes, pts)
|
|||
|
|
#mosurf1.paraview()
|
|||
|
|
mosurf1.minmax_xyz()
|
|||
|
|
mosurf1.dump('tmp_surf1_quad.inp')
|
|||
|
|
|
|||
|
|
mosurf2 = lg.create_qua() # Create the bottom surface
|
|||
|
|
p1 = (-20, -20, 1800)
|
|||
|
|
p2 = (4020, -20, 2100)
|
|||
|
|
p3 = (4020, 4020, 2800)
|
|||
|
|
p4 = (-20, 4020, 800)
|
|||
|
|
pts = [p1, p2, p3, p4]
|
|||
|
|
nnodes = (numX, numY, 1)
|
|||
|
|
mosurf2.quadxy(nnodes, pts)
|
|||
|
|
#mosurf2.paraview()
|
|||
|
|
mosurf2.minmax_xyz()
|
|||
|
|
mosurf2.dump('tmp_surf2_quad.inp')
|
|||
|
|
|
|||
|
|
#********************************************
|
|||
|
|
# 04 Use the surfaces to define regions and set
|
|||
|
|
# vertex and cell ids
|
|||
|
|
#********************************************
|
|||
|
|
# Define Regions
|
|||
|
|
sf1 = mosurf1.surface('sf1')
|
|||
|
|
sf2 = mosurf2.surface('sf2')
|
|||
|
|
|
|||
|
|
r1 = mo.region('le ' + str(sf1))
|
|||
|
|
r2 = mo.region('gt ' + str(sf1) + ' and ' + 'le ' + str(sf2))
|
|||
|
|
r3 = mo.region('gt ' + str(sf2))
|
|||
|
|
|
|||
|
|
mosurf1.delete()
|
|||
|
|
mosurf2.delete()
|
|||
|
|
|
|||
|
|
# Create Eltsets and PSets from Regions
|
|||
|
|
pset1 = mo.pset_region(r1)
|
|||
|
|
pset2 = mo.pset_region(r2)
|
|||
|
|
pset3 = mo.pset_region(r3)
|
|||
|
|
|
|||
|
|
eltset1 = mo.eltset_region(r1)
|
|||
|
|
eltset2 = mo.eltset_region(r2)
|
|||
|
|
eltset3 = mo.eltset_region(r3)
|
|||
|
|
|
|||
|
|
#Set Attributes from Eltsets and PSets
|
|||
|
|
pset1.setatt('imt', 1)
|
|||
|
|
pset2.setatt('imt', 2)
|
|||
|
|
pset3.setatt('imt', 3)
|
|||
|
|
|
|||
|
|
eltset1.setatt('itetclr', 1)
|
|||
|
|
eltset2.setatt('itetclr', 2)
|
|||
|
|
eltset3.setatt('itetclr', 3)
|
|||
|
|
|
|||
|
|
#********************************************
|
|||
|
|
# 05 Build a fault surface and define stratigraphy
|
|||
|
|
# on each side of the fault
|
|||
|
|
#********************************************
|
|||
|
|
# Create fault surface and surfaces to either side of fault
|
|||
|
|
mosurf1_fminus = lg.create_qua()
|
|||
|
|
p1 = (-20, -20, 1000)
|
|||
|
|
p2 = (4020, -20, 1500)
|
|||
|
|
p3 = (4020, 4020, 2500)
|
|||
|
|
p4 = (-20, 4020, 500)
|
|||
|
|
pts = [p1, p2, p3, p4]
|
|||
|
|
nnodes = (numX, numY, 1)
|
|||
|
|
mosurf1_fminus .quadxy(nnodes, pts)
|
|||
|
|
#mosurf1_fminus .paraview()
|
|||
|
|
mosurf1_fminus .minmax_xyz()
|
|||
|
|
mosurf1_fminus .dump('tmp_s1_fm.inp')
|
|||
|
|
|
|||
|
|
mosurf2_fminus = lg.create_qua()
|
|||
|
|
p1 = (-20, -20, 1800)
|
|||
|
|
p2 = (4020, -20, 2100)
|
|||
|
|
p3 = (4020, 4020, 2800)
|
|||
|
|
p4 = (-20, 4020, 800)
|
|||
|
|
pts = [p1, p2, p3, p4]
|
|||
|
|
nnodes = (numX, numY, 1)
|
|||
|
|
mosurf2_fminus.quadxy(nnodes, pts)
|
|||
|
|
#mosurf2_fminus.paraview()
|
|||
|
|
mosurf2_fminus.minmax_xyz()
|
|||
|
|
mosurf2_fminus.dump('tmp_s2_fm.inp')
|
|||
|
|
|
|||
|
|
mosurf1_fplus = lg.create_qua()
|
|||
|
|
p1 = (-20, -20, 1400)
|
|||
|
|
p2 = (4020, -20, 1900)
|
|||
|
|
p3 = (4020, 4020, 2900)
|
|||
|
|
p4 = (-20, 4020, 900)
|
|||
|
|
pts = [p1, p2, p3, p4]
|
|||
|
|
nnodes = (numX, numY, 1)
|
|||
|
|
mosurf1_fplus.quadxy(nnodes, pts)
|
|||
|
|
#mosurf1_fplus.paraview()
|
|||
|
|
mosurf1_fplus.minmax_xyz()
|
|||
|
|
mosurf1_fplus.dump('mosurf1_fplus.inp')
|
|||
|
|
|
|||
|
|
mosurf2_fplus = lg.create_qua()
|
|||
|
|
p1 = (-20, -20, 2200)
|
|||
|
|
p2 = (4020, -20, 2500)
|
|||
|
|
p3 = (4020, 4020, 3200)
|
|||
|
|
p4 = (-20, 4020, 1200)
|
|||
|
|
pts = [p1, p2, p3, p4]
|
|||
|
|
nnodes = (numX, numY, 1)
|
|||
|
|
mosurf2_fplus.quadxy(nnodes, pts)
|
|||
|
|
#mosurf2_fplus.paraview()
|
|||
|
|
mosurf2_fplus.minmax_xyz()
|
|||
|
|
mosurf2_fplus.dump('mosurf2_fplus.inp')
|
|||
|
|
|
|||
|
|
mosurf_fault = lg.create_qua()
|
|||
|
|
p1 = (-20, -20, -1.e4)
|
|||
|
|
p2 = (4020, -20, -1.e4)
|
|||
|
|
p3 = (4020, 4020, 1.e4)
|
|||
|
|
p4 = (-20, 4020, 1.e4)
|
|||
|
|
pts = [p1, p2, p3, p4]
|
|||
|
|
nnodes = (numX, numY, 1)
|
|||
|
|
mosurf_fault.quadxy(nnodes, pts)
|
|||
|
|
#mosurf_fault.paraview()
|
|||
|
|
mosurf_fault.minmax_xyz()
|
|||
|
|
mosurf_fault.dump('mosurf_fault.inp')
|
|||
|
|
|
|||
|
|
# Define geometry of hydrostratigraphic model
|
|||
|
|
sf1_fm = mosurf1_fminus.surface('sf1_fm')
|
|||
|
|
sf2_fm = mosurf2_fminus.surface('sf2_fm')
|
|||
|
|
sf1_fp = mosurf1_fplus.surface('sf1_fp')
|
|||
|
|
sf2_fp = mosurf2_fplus.surface('sf2_fp')
|
|||
|
|
sf_f = mosurf_fault.surface('sf_f')
|
|||
|
|
|
|||
|
|
r1_fm = mo.region('le ' + str(sf1_fm) + ' and ' + 'le ' + str(sf_f))
|
|||
|
|
r2_fm = mo.region('gt ' + str(sf1_fm) + ' and ' + 'le ' + str(sf2_fm) + ' and ' + 'le ' + str(sf_f))
|
|||
|
|
r3_fm = mo.region('gt ' + str(sf2_fm) + ' and ' + 'le ' + str(sf_f))
|
|||
|
|
r1_fp = mo.region('le ' + str(sf1_fp) + ' and ' + 'gt ' + str(sf_f))
|
|||
|
|
r2_fp = mo.region('gt ' + str(sf1_fp) + ' and ' + 'le ' + str(sf2_fp) + ' and ' + 'gt ' + str(sf_f))
|
|||
|
|
r3_fp = mo.region('gt ' + str(sf2_fp) + ' and ' + 'gt ' + str(sf_f))
|
|||
|
|
|
|||
|
|
mosurf1_fminus.delete()
|
|||
|
|
mosurf2_fminus.delete()
|
|||
|
|
mosurf1_fplus.delete()
|
|||
|
|
mosurf2_fplus.delete()
|
|||
|
|
mosurf_fault.delete()
|
|||
|
|
|
|||
|
|
# Set fault node and element materials
|
|||
|
|
pset1_fm = mo.pset_region(r1_fm)
|
|||
|
|
pset2_fm = mo.pset_region(r2_fm)
|
|||
|
|
pset3_fm = mo.pset_region(r3_fm)
|
|||
|
|
pset1_fp = mo.pset_region(r1_fp)
|
|||
|
|
pset2_fp = mo.pset_region(r2_fp)
|
|||
|
|
pset3_fp = mo.pset_region(r3_fp)
|
|||
|
|
|
|||
|
|
eltset1_fm = mo.eltset_region(r1_fm)
|
|||
|
|
eltset2_fm = mo.eltset_region(r2_fm)
|
|||
|
|
eltset3_fm = mo.eltset_region(r3_fm)
|
|||
|
|
eltset1_fp = mo.eltset_region(r1_fp)
|
|||
|
|
eltset2_fp = mo.eltset_region(r2_fp)
|
|||
|
|
eltset3_fp = mo.eltset_region(r3_fp)
|
|||
|
|
|
|||
|
|
#Set Attributes from Eltsets and PSets
|
|||
|
|
mo.setatt('imt', 7)
|
|||
|
|
mo.setatt('itetclr', 7)
|
|||
|
|
|
|||
|
|
pset1_fm.setatt('imt', 1)
|
|||
|
|
pset2_fm.setatt('imt', 2)
|
|||
|
|
pset3_fm.setatt('imt', 3)
|
|||
|
|
pset1_fp.setatt('imt', 4)
|
|||
|
|
pset2_fp.setatt('imt', 5)
|
|||
|
|
pset3_fp.setatt('imt', 6)
|
|||
|
|
|
|||
|
|
eltset1_fm.setatt('itetclr', 1)
|
|||
|
|
eltset2_fm.setatt('itetclr', 2)
|
|||
|
|
eltset3_fm.setatt('itetclr', 3)
|
|||
|
|
eltset1_fp.setatt('itetclr', 4)
|
|||
|
|
eltset2_fp.setatt('itetclr', 5)
|
|||
|
|
eltset3_fp.setatt('itetclr', 6)
|
|||
|
|
|
|||
|
|
#********************************************
|
|||
|
|
# 06 Define a polyline and truncate the exterior boundary of the mesh with the polyline
|
|||
|
|
#********************************************
|
|||
|
|
# Read boundary polygon file
|
|||
|
|
mobndry = lg.read('basin_bnd_ply_rescale.inp')
|
|||
|
|
|
|||
|
|
# Extrude the polyline into a vertical surface
|
|||
|
|
mofence = mobndry.extrude(3200, 'const', 'volume', [0, 0, -1])
|
|||
|
|
|
|||
|
|
mobndry.minmax_xyz()
|
|||
|
|
mofence.minmax_xyz()
|
|||
|
|
|
|||
|
|
# Translate the extrusion to make it cover the vertical extent of the hex mesh
|
|||
|
|
mofence.trans((0, 0, -3100), (0, 0 ,0))
|
|||
|
|
|
|||
|
|
mofence.minmax_xyz()
|
|||
|
|
#mofence.paraview()
|
|||
|
|
#mofence.dump('3D_vertical_surface.inp')
|
|||
|
|
#mo.dump('cube.inp')
|
|||
|
|
|
|||
|
|
# Truncate mesh
|
|||
|
|
sf_bndry = mofence.surface('sf_bndry')
|
|||
|
|
r_bndry = mo.region('ge ' + str(sf_bndry))
|
|||
|
|
pset_bndry = mo.pset_region(r_bndry)
|
|||
|
|
|
|||
|
|
mobndry.delete()
|
|||
|
|
mofence.delete()
|
|||
|
|
|
|||
|
|
# Method 1: Only remove a cell if ALL vertices are outside
|
|||
|
|
e_delete1 = pset_bndry.eltset('exclusive')
|
|||
|
|
|
|||
|
|
# Method 2: Remove a cell if the centroid (average of all vertices) is outside
|
|||
|
|
e_delete2 = mo.eltset_region(r_bndry)
|
|||
|
|
|
|||
|
|
# Method 3: Remove a cell if one or more vertices are outside
|
|||
|
|
e_delete3 = pset_bndry.eltset('inclusive')
|
|||
|
|
|
|||
|
|
#mo.addatt('id_in_out_bndry', vtype='vint', rank='scalar', length='nelements')
|
|||
|
|
mo.add_element_attribute('id_in_out_bndry', vtype='vint')
|
|||
|
|
mo.setatt('id_in_out_bndry', 4) #Fill the entire attribute with 4
|
|||
|
|
e_delete3.setatt('id_in_out_bndry', 3)
|
|||
|
|
e_delete2.setatt('id_in_out_bndry', 2)
|
|||
|
|
e_delete1.setatt('id_in_out_bndry', 1)
|
|||
|
|
|
|||
|
|
eltset4 = mo.eltset_attribute('id_in_out_bndry', 4, 'eq')
|
|||
|
|
eltset3 = mo.eltset_attribute('id_in_out_bndry', 3, 'eq')
|
|||
|
|
#eltset2 = mo.eltset_attribute('id_in_out_bndry', 2, 'eq')
|
|||
|
|
#eltset1 = mo.eltset_attribute('id_in_out_bndry', 1, 'eq')
|
|||
|
|
|
|||
|
|
mo.rmpoint_eltset(eltset4, False, False)
|
|||
|
|
mo.rmpoint_eltset(eltset3, True, True)
|
|||
|
|
|
|||
|
|
#********************************************
|
|||
|
|
# 07 Refine the mesh around the fault
|
|||
|
|
#********************************************
|
|||
|
|
f_zone = mo.intersect_elements(sf_f, 'f_zone')
|
|||
|
|
fz_i = mo.eltset_attribute('f_zone', 0, 'gt') #Non-zero indicates intersection
|
|||
|
|
fz_i.refine()
|
|||
|
|
|
|||
|
|
mo.delatt('f_zone')
|
|||
|
|
|
|||
|
|
mo.status (brief=True)
|
|||
|
|
|
|||
|
|
#sf_f.delete()
|
|||
|
|
#sf1_fm.delete()
|
|||
|
|
#sf2_fm.delete()
|
|||
|
|
#sf1_fp.delete()
|
|||
|
|
#sf1_fp.delete()
|
|||
|
|
#sf_bndry.delete()
|
|||
|
|
|
|||
|
|
#********************************************
|
|||
|
|
# 08 Insert a couple of 'wells' by refining the mesh and identifying a line of nodes
|
|||
|
|
# that will be the well source/sink for boundary conditions.
|
|||
|
|
#********************************************
|
|||
|
|
Well1X = 1234.56
|
|||
|
|
Well1Y = 1987.65
|
|||
|
|
Well2X = 2243.21
|
|||
|
|
Well2Y = 1212.34
|
|||
|
|
Radius = 25
|
|||
|
|
NRadius = 2
|
|||
|
|
|
|||
|
|
#Well 1
|
|||
|
|
mowell1 = lg.create_tet()
|
|||
|
|
mowell1.createpts_rtz((NRadius, 9, numZ), (0, 0, 3100), (Radius, 360, 1500)) #Create a cylindrical point cloud
|
|||
|
|
|
|||
|
|
mowell1.filter() # Filter (delete) points that are too close ( default distance <=1.e-16) or duplicate points
|
|||
|
|
mowell1.rmpoint_compress() # Remove all marked nodes and correct the itet array
|
|||
|
|
mowell1.setatt('imt', 1)
|
|||
|
|
|
|||
|
|
mowell1.connect() # Connect the point cloud
|
|||
|
|
mowell1.resetpts_itp()
|
|||
|
|
mowell1.minmax_xyz()
|
|||
|
|
|
|||
|
|
mowell1.trans((0, 0, 0), (Well1X, Well1Y, 0))
|
|||
|
|
mowell1.minmax_xyz()
|
|||
|
|
#mowell1.paraview()
|
|||
|
|
mowell1.dump('tmp_well1.inp')
|
|||
|
|
|
|||
|
|
#Well 2
|
|||
|
|
mowell2 = lg.create_tet()
|
|||
|
|
mowell2.createpts_rtz((NRadius, 9, numZ), (0, 0, 3100), (Radius, 360, 2200))
|
|||
|
|
|
|||
|
|
mowell2.filter()
|
|||
|
|
mowell2.rmpoint_compress()
|
|||
|
|
mowell2.setatt('imt', 1)
|
|||
|
|
|
|||
|
|
mowell2.connect()
|
|||
|
|
mowell2.resetpts_itp()
|
|||
|
|
mowell2.minmax_xyz()
|
|||
|
|
|
|||
|
|
mowell2.trans((0, 0, 0), (Well2X, Well2Y, 0))
|
|||
|
|
mowell2.minmax_xyz()
|
|||
|
|
#mowell2.paraview()
|
|||
|
|
mowell2.dump('tmp_well2.inp')
|
|||
|
|
|
|||
|
|
# Join the two distinct wells into a single mesh object
|
|||
|
|
mowells = lg.merge([mowell1, mowell2])
|
|||
|
|
mowells.dump('tmp_wells.inp')
|
|||
|
|
#mowells.paraview()
|
|||
|
|
|
|||
|
|
# Refine the mo around the wells
|
|||
|
|
# First pass refinement
|
|||
|
|
w_zone = mo.intersect_elements(mowells, 'w_zone')
|
|||
|
|
wz_i = mo.eltset_attribute('w_zone', 0, 'gt') #Non-zero indicates intersection
|
|||
|
|
wz_i.refine()
|
|||
|
|
mo.setatt('w_zone', 0)
|
|||
|
|
#wz_i.delete()
|
|||
|
|
|
|||
|
|
# Second pass refinement
|
|||
|
|
w_zone = mo.intersect_elements(mowells, 'w_zone')
|
|||
|
|
wz_i = mo.eltset_attribute('w_zone', 0, 'gt') #Non-zero indicates intersection
|
|||
|
|
wz_i.refine()
|
|||
|
|
mo.setatt('w_zone', 0)
|
|||
|
|
#wz_i.delete()
|
|||
|
|
|
|||
|
|
mohex = mo.grid2grid_tree_to_fe() #Quadtree or octree grid to grid
|
|||
|
|
|
|||
|
|
#mo.status (brief=True)
|
|||
|
|
|
|||
|
|
# Identify the column of vertices closest to the well center.
|
|||
|
|
#Well1
|
|||
|
|
mo_pts1 = lg.create()
|
|||
|
|
mo_pts1.createpts_rtz((2, 2, 1000), (0, 0, 3100), (Radius, 360, 2200))
|
|||
|
|
mo_pts1.trans((0, 0, 0), (Well1X, Well1Y, 0))
|
|||
|
|
|
|||
|
|
#Well2
|
|||
|
|
mo_pts2 = lg.create()
|
|||
|
|
mo_pts2.createpts_rtz((2, 2, 1000), (0, 0, 3100), (Radius, 360, 2200))
|
|||
|
|
mo_pts2.trans((0, 0, 0), (Well2X, Well2Y, 0))
|
|||
|
|
|
|||
|
|
mo_pts = lg.merge([mo_pts1, mo_pts2])
|
|||
|
|
mo_pts.filter()
|
|||
|
|
mo_pts.rmpoint_compress()
|
|||
|
|
|
|||
|
|
# Compute a distance field attribute
|
|||
|
|
mo.compute_distance(mo_pts, option='distance_field', attname='dfield_well')
|
|||
|
|
|
|||
|
|
mo_pts1.delete()
|
|||
|
|
mo_pts2.delete()
|
|||
|
|
mo_pts.delete()
|
|||
|
|
mowell1.delete()
|
|||
|
|
mowell2.delete()
|
|||
|
|
mowells.delete()
|
|||
|
|
|
|||
|
|
# Describe all nodes within 32, 16, 8, 4, 2 and 1 meters of the wells.
|
|||
|
|
pwell = mo.pset_attribute('dfield_well', 1.0, 'le', (1,0,0), 'pwell1')
|
|||
|
|
pwell.dump('zone_radius_01.0.zone')
|
|||
|
|
|
|||
|
|
pwell = mo.pset_attribute('dfield_well', 2.0, 'le', (1,0,0), 'pwell2')
|
|||
|
|
pwell.dump('zone_radius_02.0.zone')
|
|||
|
|
|
|||
|
|
pwell = mo.pset_attribute('dfield_well', 4.0, 'le', (1,0,0), 'pwell4')
|
|||
|
|
pwell.dump('zone_radius_04.0.zone')
|
|||
|
|
|
|||
|
|
pwell = mo.pset_attribute('dfield_well', 8.0, 'le', (1,0,0), 'pwell8')
|
|||
|
|
pwell.dump('zone_radius_08.0.zone')
|
|||
|
|
|
|||
|
|
pwell = mo.pset_attribute('dfield_well', 16.0, 'le', (1,0,0), 'pwell16')
|
|||
|
|
pwell.dump('zone_radius_16.0.zone')
|
|||
|
|
|
|||
|
|
pwell = mo.pset_attribute('dfield_well', 32.0, 'le', (1,0,0), 'pwell32')
|
|||
|
|
pwell.dump('zone_radius_32.0.zone')
|
|||
|
|
|
|||
|
|
mo.dump('Hex_mesh.inp')
|
|||
|
|
|
|||
|
|
#********************************************
|
|||
|
|
# 09 Convert hex mesh to tet mesh
|
|||
|
|
#********************************************
|
|||
|
|
motet = mohex.copypts()
|
|||
|
|
motet.setatt('imt', 1)
|
|||
|
|
motet.setatt('itp', 0)
|
|||
|
|
motet.connect(option1='check_interface')
|
|||
|
|
motet.resetpts_itp()
|
|||
|
|
|
|||
|
|
motet.interpolate_voronoi('imt', mohex, 'imt')
|
|||
|
|
motet.interpolate_map('itetclr', mohex, 'itetclr')
|
|||
|
|
|
|||
|
|
#Remove all nodes and elements with imt and itetclr values of 7
|
|||
|
|
motet.rmmat(7)
|
|||
|
|
#pset7 = motet.pset_attribute('imt', 7, 'eq', (1,0,0), 'pset7')
|
|||
|
|
#motet.rmpoint_pset(pset7)
|
|||
|
|
#eltset7 = motet.eltset_attribute('itetclr', 7, 'eq')
|
|||
|
|
#motet.rmpoint_eltset(eltset7, True, True)
|
|||
|
|
|
|||
|
|
motet.rmpoint_compress()
|
|||
|
|
motet.resetpts_itp()
|
|||
|
|
|
|||
|
|
# Visualize connected mesh using ParaView
|
|||
|
|
# This assumes that pylagritrc is being used so that exe option does not need to be specified
|
|||
|
|
#motet.paraview()
|
|||
|
|
|
|||
|
|
motet.dump('Tet_mesh.inp')
|
|||
|
|
|
|||
|
|
#********************************************
|
|||
|
|
# 10 Write tet mesh files for FEHM
|
|||
|
|
# FEHM uses node based materials and properties
|
|||
|
|
#********************************************
|
|||
|
|
#motet.resetpts_parent()
|
|||
|
|
motet.filter()
|
|||
|
|
motet.rmpoint_compress()
|
|||
|
|
motet.resetpts_itp()
|
|||
|
|
motet.minmax('imt')
|
|||
|
|
motet.setatt('itetclr', 1)
|
|||
|
|
#motet. tri_mesh_output_prep()
|
|||
|
|
motet.dump_fehm('Example3')
|
|||
|
|
|
|||
|
|
|
|||
|
|
|