mirror of
https://github.com/wassname/simpeg.git
synced 2026-07-15 11:26:09 +08:00
Merge branch 'dev' into Dom_Dev
This commit is contained in:
@@ -0,0 +1,416 @@
|
||||
import numpy as np, os
|
||||
from SimPEG import Utils
|
||||
|
||||
class TensorMeshIO(object):
|
||||
|
||||
@classmethod
|
||||
def readUBC(TensorMesh, fileName):
|
||||
"""
|
||||
Read UBC GIF 3DTensor mesh and generate 3D Tensor mesh in simpegTD
|
||||
|
||||
Input:
|
||||
:param fileName, path to the UBC GIF mesh file
|
||||
|
||||
Output:
|
||||
:param SimPEG TensorMesh object
|
||||
"""
|
||||
|
||||
# Interal function to read cell size lines for the UBC mesh files.
|
||||
def readCellLine(line):
|
||||
for seg in line.split():
|
||||
if '*' in seg:
|
||||
st = seg
|
||||
sp = seg.split('*')
|
||||
re = np.array(sp[0],dtype=int)*(' ' + sp[1])
|
||||
line = line.replace(st,re.strip())
|
||||
return np.array(line.split(),dtype=float)
|
||||
|
||||
# Read the file as line strings, remove lines with comment = !
|
||||
msh = np.genfromtxt(fileName,delimiter='\n',dtype=np.str,comments='!')
|
||||
|
||||
# Fist line is the size of the model
|
||||
sizeM = np.array(msh[0].split(),dtype=float)
|
||||
# Second line is the South-West-Top corner coordinates.
|
||||
x0 = np.array(msh[1].split(),dtype=float)
|
||||
# Read the cell sizes
|
||||
h1 = readCellLine(msh[2])
|
||||
h2 = readCellLine(msh[3])
|
||||
h3temp = readCellLine(msh[4])
|
||||
h3 = h3temp[::-1] # Invert the indexing of the vector to start from the bottom.
|
||||
# Adjust the reference point to the bottom south west corner
|
||||
x0[2] = x0[2] - np.sum(h3)
|
||||
# Make the mesh
|
||||
tensMsh = TensorMesh([h1,h2,h3],x0)
|
||||
return tensMsh
|
||||
|
||||
@classmethod
|
||||
def readVTK(TensorMesh, fileName):
|
||||
"""
|
||||
Read VTK Rectilinear (vtr xml file) and return SimPEG Tensor mesh and model
|
||||
|
||||
Input:
|
||||
:param vtrFileName, path to the vtr model file to write to
|
||||
|
||||
Output:
|
||||
:return SimPEG TensorMesh object
|
||||
:return SimPEG model dictionary
|
||||
|
||||
"""
|
||||
# Import
|
||||
from vtk import vtkXMLRectilinearGridReader as vtrFileReader
|
||||
from vtk.util.numpy_support import vtk_to_numpy
|
||||
|
||||
# Read the file
|
||||
vtrReader = vtrFileReader()
|
||||
vtrReader.SetFileName(fileName)
|
||||
vtrReader.Update()
|
||||
vtrGrid = vtrReader.GetOutput()
|
||||
# Sort information
|
||||
hx = np.abs(np.diff(vtk_to_numpy(vtrGrid.GetXCoordinates())))
|
||||
xR = vtk_to_numpy(vtrGrid.GetXCoordinates())[0]
|
||||
hy = np.abs(np.diff(vtk_to_numpy(vtrGrid.GetYCoordinates())))
|
||||
yR = vtk_to_numpy(vtrGrid.GetYCoordinates())[0]
|
||||
zD = np.diff(vtk_to_numpy(vtrGrid.GetZCoordinates()))
|
||||
# Check the direction of hz
|
||||
if np.all(zD < 0):
|
||||
hz = np.abs(zD[::-1])
|
||||
zR = vtk_to_numpy(vtrGrid.GetZCoordinates())[-1]
|
||||
else:
|
||||
hz = np.abs(zD)
|
||||
zR = vtk_to_numpy(vtrGrid.GetZCoordinates())[0]
|
||||
x0 = np.array([xR,yR,zR])
|
||||
|
||||
# Make the SimPEG object
|
||||
tensMsh = TensorMesh([hx,hy,hz],x0)
|
||||
|
||||
# Grap the models
|
||||
models = {}
|
||||
for i in np.arange(vtrGrid.GetCellData().GetNumberOfArrays()):
|
||||
modelName = vtrGrid.GetCellData().GetArrayName(i)
|
||||
if np.all(zD < 0):
|
||||
modFlip = vtk_to_numpy(vtrGrid.GetCellData().GetArray(i))
|
||||
tM = tensMsh.r(modFlip,'CC','CC','M')
|
||||
modArr = tensMsh.r(tM[:,:,::-1],'CC','CC','V')
|
||||
else:
|
||||
modArr = vtk_to_numpy(vtrGrid.GetCellData().GetArray(i))
|
||||
models[modelName] = modArr
|
||||
|
||||
# Return the data
|
||||
return tensMsh, models
|
||||
|
||||
def writeVTK(mesh, fileName, models=None):
|
||||
"""
|
||||
Makes and saves a VTK rectilinear file (vtr) for a simpeg Tensor mesh and model.
|
||||
|
||||
Input:
|
||||
:param str, path to the output vtk file
|
||||
:param mesh, SimPEG TensorMesh object - mesh to be transfer to VTK
|
||||
:param models, dictionary of numpy.array - Name('s) and array('s). Match number of cells
|
||||
|
||||
"""
|
||||
# Import
|
||||
from vtk import vtkRectilinearGrid as rectGrid, vtkXMLRectilinearGridWriter as rectWriter, VTK_VERSION
|
||||
from vtk.util.numpy_support import numpy_to_vtk
|
||||
|
||||
# Deal with dimensionalities
|
||||
if mesh.dim >= 1:
|
||||
vX = mesh.vectorNx
|
||||
xD = mesh.nNx
|
||||
yD,zD = 1,1
|
||||
vY, vZ = np.array([0,0])
|
||||
if mesh.dim >= 2:
|
||||
vY = mesh.vectorNy
|
||||
yD = mesh.nNy
|
||||
if mesh.dim == 3:
|
||||
vZ = mesh.vectorNz
|
||||
zD = mesh.nNz
|
||||
# Use rectilinear VTK grid.
|
||||
# Assign the spatial information.
|
||||
vtkObj = rectGrid()
|
||||
vtkObj.SetDimensions(xD,yD,zD)
|
||||
vtkObj.SetXCoordinates(numpy_to_vtk(vX,deep=1))
|
||||
vtkObj.SetYCoordinates(numpy_to_vtk(vY,deep=1))
|
||||
vtkObj.SetZCoordinates(numpy_to_vtk(vZ,deep=1))
|
||||
|
||||
# Assign the model('s) to the object
|
||||
if models is not None:
|
||||
for item in models.iteritems():
|
||||
# Convert numpy array
|
||||
vtkDoubleArr = numpy_to_vtk(item[1],deep=1)
|
||||
vtkDoubleArr.SetName(item[0])
|
||||
vtkObj.GetCellData().AddArray(vtkDoubleArr)
|
||||
# Set the active scalar
|
||||
vtkObj.GetCellData().SetActiveScalars(models.keys()[0])
|
||||
# vtkObj.Update()
|
||||
|
||||
# Check the extension of the fileName
|
||||
ext = os.path.splitext(fileName)[1]
|
||||
if ext is '':
|
||||
fileName = fileName + '.vtr'
|
||||
elif ext not in '.vtr':
|
||||
raise IOError('{:s} is an incorrect extension, has to be .vtr')
|
||||
# Write the file.
|
||||
vtrWriteFilter = rectWriter()
|
||||
if float(VTK_VERSION.split('.')[0]) >=6:
|
||||
vtrWriteFilter.SetInputData(vtkObj)
|
||||
else:
|
||||
vtuWriteFilter.SetInput(vtuObj)
|
||||
vtrWriteFilter.SetFileName(fileName)
|
||||
vtrWriteFilter.Update()
|
||||
|
||||
|
||||
def readModelUBC(mesh, fileName):
|
||||
"""
|
||||
Read UBC 3DTensor mesh model and generate 3D Tensor mesh model in simpeg
|
||||
|
||||
Input:
|
||||
:param fileName, path to the UBC GIF mesh file to read
|
||||
:param mesh, TensorMesh object, mesh that coresponds to the model
|
||||
|
||||
Output:
|
||||
:return numpy array, model with TensorMesh ordered
|
||||
"""
|
||||
f = open(fileName, 'r')
|
||||
model = np.array(map(float, f.readlines()))
|
||||
f.close()
|
||||
model = np.reshape(model, (mesh.nCz, mesh.nCx, mesh.nCy), order = 'F')
|
||||
model = model[::-1,:,:]
|
||||
model = np.transpose(model, (1, 2, 0))
|
||||
model = Utils.mkvc(model)
|
||||
return model
|
||||
|
||||
def writeModelUBC(mesh, fileName, model):
|
||||
"""
|
||||
Writes a model associated with a SimPEG TensorMesh
|
||||
to a UBC-GIF format model file.
|
||||
|
||||
:param str fileName: File to write to
|
||||
:param simpeg.Mesh.TensorMesh mesh: The mesh
|
||||
:param numpy.ndarray model: The model
|
||||
"""
|
||||
|
||||
# Reshape model to a matrix
|
||||
modelMat = mesh.r(model,'CC','CC','M')
|
||||
# Transpose the axes
|
||||
modelMatT = modelMat.transpose((2,0,1))
|
||||
# Flip z to positive down
|
||||
modelMatTR = Utils.mkvc(modelMatT[::-1,:,:])
|
||||
|
||||
np.savetxt(fileName, modelMatTR.ravel())
|
||||
|
||||
def writeUBC(mesh, fileName, models=None):
|
||||
"""
|
||||
Writes a SimPEG TensorMesh to a UBC-GIF format mesh file.
|
||||
|
||||
:param str fileName: File to write to
|
||||
:param simpeg.Mesh.TensorMesh mesh: The mesh
|
||||
|
||||
"""
|
||||
assert mesh.dim == 3
|
||||
s = ''
|
||||
s += '%i %i %i\n' %tuple(mesh.vnC)
|
||||
origin = mesh.x0 + np.array([0,0,mesh.hz.sum()]) # Have to it in the same operation or use mesh.x0.copy(), otherwise the mesh.x0 is updated.
|
||||
origin.dtype = float
|
||||
|
||||
s += '%.2f %.2f %.2f\n' %tuple(origin)
|
||||
s += ('%.2f '*mesh.nCx+'\n')%tuple(mesh.hx)
|
||||
s += ('%.2f '*mesh.nCy+'\n')%tuple(mesh.hy)
|
||||
s += ('%.2f '*mesh.nCz+'\n')%tuple(mesh.hz[::-1])
|
||||
f = open(fileName, 'w')
|
||||
f.write(s)
|
||||
f.close()
|
||||
|
||||
if models is None: return
|
||||
assert type(models) is dict, 'models must be a dict'
|
||||
for key in models:
|
||||
assert type(key) is str, 'The dict key is a file name'
|
||||
mesh.writeModelUBC(key, models[key])
|
||||
|
||||
class TreeMeshIO(object):
|
||||
|
||||
def writeUBC(mesh, fileName, models=None):
|
||||
"""
|
||||
Write UBC ocTree mesh and model files from a simpeg ocTree mesh and model.
|
||||
|
||||
:param str fileName: File to write to
|
||||
:param simpeg.Mesh.TreeMesh mesh: The mesh
|
||||
:param dictionary models: The models in a dictionary, where the keys is the name of the of the model file
|
||||
"""
|
||||
|
||||
# Calculate information to write in the file.
|
||||
# Number of cells in the underlying mesh
|
||||
nCunderMesh = np.array([h.size for h in mesh.h],dtype=np.int64)
|
||||
# The top-south-west most corner of the mesh
|
||||
tswCorn = mesh.x0 + np.array([0,0,np.sum(mesh.h[2])])
|
||||
# Smallest cell size
|
||||
smallCell = np.array([h.min() for h in mesh.h])
|
||||
# Number of cells
|
||||
nrCells = mesh.nC
|
||||
|
||||
## Extract iformation about the cells.
|
||||
# cell pointers
|
||||
cellPointers = np.array([c._pointer for c in mesh])
|
||||
# cell with
|
||||
cellW = np.array([ mesh._levelWidth(i) for i in cellPointers[:,-1] ])
|
||||
# Need to shift the pointers to work with UBC indexing
|
||||
# UBC Octree indexes always the top-left-close (top-south-west) corner first and orders the cells in z(top-down),x,y vs x,y,z(bottom-up).
|
||||
# Shift index up by 1
|
||||
ubcCellPt = cellPointers[:,0:-1].copy() + np.array([1.,1.,1.])
|
||||
# Need reindex the z index to be from the top-left-close corner and to be from the global top.
|
||||
ubcCellPt[:,2] = ( nCunderMesh[-1] + 2) - (ubcCellPt[:,2] + cellW)
|
||||
|
||||
# Reorder the ubcCellPt
|
||||
ubcReorder = np.argsort(ubcCellPt.view(','.join(3*['float'])),axis=0,order=['f2','f1','f0'])[:,0]
|
||||
# Make a array with the pointers and the withs, that are order in the ubc ordering
|
||||
indArr = np.concatenate((ubcCellPt[ubcReorder,:],cellW[ubcReorder].reshape((-1,1)) ),axis=1)
|
||||
|
||||
## Write the UBC octree mesh file
|
||||
with open(fileName,'w') as mshOut:
|
||||
mshOut.write('{:.0f} {:.0f} {:.0f}\n'.format(nCunderMesh[0],nCunderMesh[1],nCunderMesh[2]))
|
||||
mshOut.write('{:.4f} {:.4f} {:.4f}\n'.format(tswCorn[0],tswCorn[1],tswCorn[2]))
|
||||
mshOut.write('{:.3f} {:.3f} {:.3f}\n'.format(smallCell[0],smallCell[1],smallCell[2]))
|
||||
mshOut.write('{:.0f} \n'.format(nrCells))
|
||||
np.savetxt(mshOut,indArr,fmt='%i')
|
||||
|
||||
## Print the models
|
||||
# Assign the model('s) to the object
|
||||
if models is not None:
|
||||
# indUBCvector = np.argsort(cX0[np.argsort(np.concatenate((cX0[:,0:2],cX0[:,2:3].max() - cX0[:,2:3]),axis=1).view(','.join(3*['float'])),axis=0,order=('f2','f1','f0'))[:,0]].view(','.join(3*['float'])),axis=0,order=('f2','f1','f0'))[:,0]
|
||||
for item in models.iteritems():
|
||||
# Save the data
|
||||
np.savetxt(item[0],item[1][ubcReorder],fmt='%3.5e')
|
||||
|
||||
@classmethod
|
||||
def readUBC(TreeMesh, meshFile):
|
||||
"""
|
||||
Read UBC 3D OcTree mesh and/or modelFiles
|
||||
|
||||
Input:
|
||||
:param str meshFile: path to the UBC GIF OcTree mesh file to read
|
||||
|
||||
Output:
|
||||
:return SimPEG.Mesh.TreeMesh mesh: The octree mesh
|
||||
:return list of ndarray's: models as a list of numpy array's
|
||||
"""
|
||||
|
||||
## Read the file lines
|
||||
fileLines = np.genfromtxt(meshFile,dtype=str,delimiter='\n')
|
||||
# Extract the data
|
||||
nCunderMesh = np.array(fileLines[0].split(),dtype=float)
|
||||
# I think this is the case?
|
||||
if np.unique(nCunderMesh).size >1:
|
||||
raise Exception('SimPEG TreeMeshes have the same number of cell in all directions')
|
||||
tswCorn = np.array(fileLines[1].split(),dtype=float)
|
||||
smallCell = np.array(fileLines[2].split(),dtype=float)
|
||||
nrCells = np.array(fileLines[3].split(),dtype=float)
|
||||
# Read the index array
|
||||
indArr = np.genfromtxt(fileLines[4::],dtype=np.int)
|
||||
|
||||
## Calculate simpeg parameters
|
||||
h1,h2,h3 = [np.ones(nr)*sz for nr,sz in zip(nCunderMesh,smallCell)]
|
||||
x0 = tswCorn - np.array([0,0,np.sum(h3)])
|
||||
# Need to convert the index array to a points list that complies with SimPEG TreeMesh.
|
||||
# Shift to start at 0
|
||||
simpegCellPt = indArr[:,0:-1].copy()
|
||||
simpegCellPt[:,2] = ( nCunderMesh[-1] + 2) - (simpegCellPt[:,2] + indArr[:,3])
|
||||
# Need reindex the z index to be from the bottom-left-close corner and to be from the global bottom.
|
||||
simpegCellPt = simpegCellPt - np.array([1.,1.,1.])
|
||||
|
||||
# Calculate the cell level
|
||||
simpegLevel = np.log2(np.min(nCunderMesh)) - np.log2(indArr[:,3])
|
||||
# Make a pointer matrix
|
||||
simpegPointers = np.concatenate((simpegCellPt,simpegLevel.reshape((-1,1))),axis=1)
|
||||
|
||||
## Make the tree mesh
|
||||
mesh = TreeMesh([h1,h2,h3],x0)
|
||||
mesh._cells = set([mesh._index(p) for p in simpegPointers.tolist()])
|
||||
|
||||
# Figure out the reordering
|
||||
mesh._simpegReorderUBC = np.argsort(np.array([mesh._index(i) for i in simpegPointers.tolist()]))
|
||||
# mesh._simpegReorderUBC = np.argsort((np.array([[1,1,1,-1]])*simpegPointers).view(','.join(4*['float'])),axis=0,order=['f3','f2','f1','f0'])[:,0]
|
||||
|
||||
return mesh
|
||||
|
||||
|
||||
def readModelUBC(mesh, fileName):
|
||||
"""
|
||||
Read UBC OcTree model and get vector
|
||||
|
||||
Input:
|
||||
:param fileName, path to the UBC GIF model file to read
|
||||
|
||||
Output:
|
||||
:return numpy array, OcTree model
|
||||
"""
|
||||
|
||||
if type(fileName) is list:
|
||||
out = {}
|
||||
for f in fileName:
|
||||
out[f] = mesh.readModelUBC(f)
|
||||
return out
|
||||
|
||||
assert hasattr(mesh, '_simpegReorderUBC'), 'The file must have been loaded from a UBC format.'
|
||||
assert mesh.dim == 3
|
||||
|
||||
modList = []
|
||||
modArr = np.loadtxt(fileName)
|
||||
if len(modArr.shape) == 1:
|
||||
modList.append(modArr[mesh._simpegReorderUBC])
|
||||
else:
|
||||
modList.append(modArr[mesh._simpegReorderUBC,:])
|
||||
return modList
|
||||
|
||||
def writeVTK(mesh, fileName, models=None):
|
||||
"""
|
||||
Function to write a VTU file from a SimPEG TreeMesh and model.
|
||||
"""
|
||||
import vtk
|
||||
from vtk import vtkXMLUnstructuredGridWriter as Writer, VTK_VERSION
|
||||
from vtk.util.numpy_support import numpy_to_vtk, numpy_to_vtkIdTypeArray
|
||||
|
||||
if str(type(mesh)).split()[-1][1:-2] not in 'SimPEG.Mesh.TreeMesh.TreeMesh':
|
||||
raise IOError('mesh is not a SimPEG TreeMesh.')
|
||||
|
||||
# Make the data parts for the vtu object
|
||||
# Points
|
||||
mesh.number()
|
||||
ptsMat = mesh._gridN + mesh.x0
|
||||
|
||||
vtkPts = vtk.vtkPoints()
|
||||
vtkPts.SetData(numpy_to_vtk(ptsMat,deep=True))
|
||||
# Cells
|
||||
cellConn = np.array([c.nodes for c in mesh],dtype=np.int64)
|
||||
|
||||
cellsMat = np.concatenate((np.ones((cellConn.shape[0],1),dtype=np.int64)*cellConn.shape[1],cellConn),axis=1).ravel()
|
||||
cellsArr = vtk.vtkCellArray()
|
||||
cellsArr.SetNumberOfCells(cellConn.shape[0])
|
||||
cellsArr.SetCells(cellConn.shape[0],numpy_to_vtkIdTypeArray(cellsMat,deep=True))
|
||||
|
||||
# Make the object
|
||||
vtuObj = vtk.vtkUnstructuredGrid()
|
||||
vtuObj.SetPoints(vtkPts)
|
||||
vtuObj.SetCells(vtk.VTK_VOXEL,cellsArr)
|
||||
# Add the level of refinement as a cell array
|
||||
cellSides = np.array([np.array(vtuObj.GetCell(i).GetBounds()).reshape((3,2)).dot(np.array([-1, 1])) for i in np.arange(vtuObj.GetNumberOfCells())])
|
||||
uniqueLevel, indLevel = np.unique(np.prod(cellSides,axis=1),return_inverse=True)
|
||||
refineLevelArr = numpy_to_vtk(indLevel.max() - indLevel,deep=1)
|
||||
refineLevelArr.SetName('octreeLevel')
|
||||
vtuObj.GetCellData().AddArray(refineLevelArr)
|
||||
# Assign the model('s) to the object
|
||||
if models is not None:
|
||||
for item in models.iteritems():
|
||||
# Convert numpy array
|
||||
vtkDoubleArr = numpy_to_vtk(item[1],deep=1)
|
||||
vtkDoubleArr.SetName(item[0])
|
||||
vtuObj.GetCellData().AddArray(vtkDoubleArr)
|
||||
|
||||
# Make the writer
|
||||
vtuWriteFilter = Writer()
|
||||
if float(VTK_VERSION.split('.')[0]) >=6:
|
||||
vtuWriteFilter.SetInputData(vtuObj)
|
||||
else:
|
||||
vtuWriteFilter.SetInput(vtuObj)
|
||||
vtuWriteFilter.SetFileName(fileName)
|
||||
# Write the file
|
||||
vtuWriteFilter.Update()
|
||||
|
||||
+559
-558
File diff suppressed because it is too large
Load Diff
+59
-123
@@ -100,11 +100,12 @@ except Exception, e:
|
||||
|
||||
from InnerProducts import InnerProducts
|
||||
from TensorMesh import TensorMesh, BaseTensorMesh
|
||||
from MeshIO import TreeMeshIO
|
||||
import time
|
||||
|
||||
MAX_BITS = 20
|
||||
|
||||
class TreeMesh(BaseTensorMesh, InnerProducts):
|
||||
class TreeMesh(BaseTensorMesh, InnerProducts, TreeMeshIO):
|
||||
|
||||
_meshType = 'TREE'
|
||||
|
||||
@@ -564,15 +565,18 @@ class TreeMesh(BaseTensorMesh, InnerProducts):
|
||||
return [p - (p % mod) for p in pointer[:-1]] + [pointer[-1]-1]
|
||||
|
||||
def _cellN(self, p):
|
||||
"""Node location [x,y(,z)] of a single cell, closest to origin, given a pointer."""
|
||||
p = self._asPointer(p)
|
||||
return [hi[:p[ii]].sum() for ii, hi in enumerate(self.h)]
|
||||
|
||||
def _cellH(self, p):
|
||||
"""Widths of a single cell given a pointer."""
|
||||
p = self._asPointer(p)
|
||||
w = self._levelWidth(p[-1])
|
||||
return [hi[p[ii]:p[ii]+w].sum() for ii, hi in enumerate(self.h)]
|
||||
|
||||
def _cellC(self, p):
|
||||
"""Cell center of a single cell (without origin correction), given a pointer."""
|
||||
return (np.array(self._cellH(p))/2.0 + self._cellN(p)).tolist()
|
||||
|
||||
def _levelWidth(self, level):
|
||||
@@ -827,8 +831,10 @@ class TreeMesh(BaseTensorMesh, InnerProducts):
|
||||
def _numberCells(self, force=False):
|
||||
if not self.__dirtyCells__ and not force: return
|
||||
self._cc2i = dict()
|
||||
self._i2cc = dict()
|
||||
for ii, c in enumerate(sorted(self._cells)):
|
||||
self._cc2i[c] = ii
|
||||
self._i2cc[ii] = c
|
||||
self.__dirtyCells__ = False
|
||||
|
||||
def _numberNodes(self, force=False):
|
||||
@@ -1704,9 +1710,9 @@ class TreeMesh(BaseTensorMesh, InnerProducts):
|
||||
"Construct the averaging operator on cell faces to cell centers."
|
||||
if getattr(self, '_aveF2CC', None) is None:
|
||||
if self.dim == 2:
|
||||
self._aveF2CC = 1./self.dim*sp.hstack([self.aveFx2CC, self.aveFy2CC])
|
||||
self._aveF2CC = 1./self.dim*sp.hstack([self.aveFx2CC, self.aveFy2CC]).tocsr()
|
||||
elif self.dim == 3:
|
||||
self._aveF2CC = 1./self.dim*sp.hstack([self.aveFx2CC, self.aveFy2CC, self.aveFz2CC])
|
||||
self._aveF2CC = 1./self.dim*sp.hstack([self.aveFx2CC, self.aveFy2CC, self.aveFz2CC]).tocsr()
|
||||
return self._aveF2CC
|
||||
|
||||
@property
|
||||
@@ -1714,9 +1720,9 @@ class TreeMesh(BaseTensorMesh, InnerProducts):
|
||||
"Construct the averaging operator on cell faces to cell centers."
|
||||
if getattr(self, '_aveF2CCV', None) is None:
|
||||
if self.dim == 2:
|
||||
self._aveF2CCV = sp.block_diag([self.aveFx2CC, self.aveFy2CC])
|
||||
self._aveF2CCV = sp.block_diag([self.aveFx2CC, self.aveFy2CC]).tocsr()
|
||||
elif self.dim == 3:
|
||||
self._aveF2CCV = sp.block_diag([self.aveFx2CC, self.aveFy2CC, self.aveFz2CC])
|
||||
self._aveF2CCV = sp.block_diag([self.aveFx2CC, self.aveFy2CC, self.aveFz2CC]).tocsr()
|
||||
return self._aveF2CCV
|
||||
|
||||
@property
|
||||
@@ -2218,6 +2224,25 @@ class TreeMesh(BaseTensorMesh, InnerProducts):
|
||||
if showIt: plt.show()
|
||||
return tuple(out)
|
||||
|
||||
def __len__(self): return self.nC
|
||||
|
||||
def __getitem__(self, key):
|
||||
if isinstance( key, slice ) :
|
||||
#Get the start, stop, and step from the slice
|
||||
return [self[ii] for ii in xrange(*key.indices(len(self)))]
|
||||
elif isinstance( key, int ) :
|
||||
if key < 0 : #Handle negative indices
|
||||
key += len( self )
|
||||
if key >= len( self ) :
|
||||
raise IndexError, "The index (%d) is out of range."%key
|
||||
|
||||
self._numberCells() # no-op if numbered
|
||||
index = self._i2cc[key]
|
||||
pointer = self._asPointer(index)
|
||||
return Cell(self, index, pointer)
|
||||
else:
|
||||
raise TypeError, "Invalid argument type."
|
||||
|
||||
|
||||
class Cell(object):
|
||||
def __init__(self, mesh, index, pointer):
|
||||
@@ -2225,6 +2250,35 @@ class Cell(object):
|
||||
self._index = index
|
||||
self._pointer = pointer
|
||||
|
||||
@property
|
||||
def nodes(self):
|
||||
"""The node index in _gridN (this may include hanging nodes)."""
|
||||
M = self.mesh
|
||||
M._numberNodes()
|
||||
p = self._pointer
|
||||
i = self._index
|
||||
w = M._levelWidth(p[-1])
|
||||
|
||||
if M.dim == 2:
|
||||
n = [
|
||||
i,
|
||||
M._index([ p[0] + w, p[1] , p[2]]),
|
||||
M._index([ p[0] , p[1]+ w, p[2]]),
|
||||
M._index([ p[0] + w, p[1]+ w, p[2]]),
|
||||
]
|
||||
elif self.dim == 3:
|
||||
n = [
|
||||
i,
|
||||
M._index([ p[0] + w, p[1] , p[2] ,p[3]]),
|
||||
M._index([ p[0] , p[1] + w, p[2] ,p[3]]),
|
||||
M._index([ p[0] + w, p[1] + w, p[2] ,p[3]]),
|
||||
M._index([ p[0] , p[1] , p[2] + w,p[3]]),
|
||||
M._index([ p[0] + w, p[1] , p[2] + w,p[3]]),
|
||||
M._index([ p[0] , p[1] + w, p[2] + w,p[3]]),
|
||||
M._index([ p[0] + w, p[1] + w, p[2] + w,p[3]]),
|
||||
]
|
||||
return [M._n2i[_] for _ in n]
|
||||
|
||||
@property
|
||||
def center(self):
|
||||
if getattr(self, '_center', None) is None:
|
||||
@@ -2282,121 +2336,3 @@ class NotBalancedException(TreeException):
|
||||
pass
|
||||
class CellLookUpException(TreeException):
|
||||
pass
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib
|
||||
from mpl_toolkits.mplot3d import Axes3D
|
||||
import matplotlib.colors as colors
|
||||
import matplotlib.cm as cmx
|
||||
|
||||
def topo(x):
|
||||
return np.sin(x*(2.*np.pi))*0.3 + 0.5
|
||||
|
||||
def function(cell):
|
||||
r = cell.center - np.array([0.5]*len(cell.center))
|
||||
dist = np.sqrt(r.dot(r))
|
||||
# dist2 = np.abs(cell.center[-1] - topo(cell.center[0]))
|
||||
|
||||
# dist = min([dist1,dist2])
|
||||
# if dist < 0.05:
|
||||
# return 5
|
||||
if dist < 0.1:
|
||||
return 5
|
||||
if dist < 0.2:
|
||||
return 4
|
||||
if dist < 0.4:
|
||||
return 3
|
||||
return 2
|
||||
|
||||
# T = TreeMesh([[(1,128)],[(1,128)],[(1,128)]],levels=7)
|
||||
# T = TreeMesh([128,128,128])
|
||||
# T = TreeMesh([64,64],levels=6)
|
||||
T = TreeMesh([4,4,4])
|
||||
# T = TreeMesh([[(1,128)],[(1,128)]],levels=7)
|
||||
# T.refine(lambda xc:2, balance=False)
|
||||
# T._index([0,0,0])
|
||||
# T._pointer(0)
|
||||
|
||||
|
||||
# tic = time.time()
|
||||
T.refine(function)#, balance=False)
|
||||
# print time.time() - tic
|
||||
# print T.nC
|
||||
T.plotSlice(np.log(T.vol))#np.random.rand(T.nC))
|
||||
|
||||
plt.show()
|
||||
blah
|
||||
|
||||
# T.plotImage(np.arange(len(T.vol)),showIt=True)
|
||||
|
||||
# print T.getFaceInnerProduct()
|
||||
# print T.gridFz
|
||||
|
||||
|
||||
# T._refineCell([8,0,1])
|
||||
# T._refineCell([8,0,2])
|
||||
# T._refineCell([12,0,2])
|
||||
# T._refineCell([8,4,2])
|
||||
# T._refineCell([6,0,3])
|
||||
# T._refineCell([8,8,1])
|
||||
# T._refineCell([0,0,0,1])
|
||||
# T.__dirty__ = True
|
||||
|
||||
|
||||
# print T.gridFx.shape[0], T.nFx
|
||||
|
||||
|
||||
|
||||
ax = plt.subplot(211)
|
||||
ax.spy(T.edgeCurl)
|
||||
|
||||
# print Mesh.TensorMesh([2,2,2]).edgeCurl.todense()
|
||||
# print T.edgeCurl.todense()
|
||||
# print Mesh.TensorMesh([2,2,2]).edgeCurl.todense() - T.edgeCurl.todense()
|
||||
# print T.gridEy - Mesh.TensorMesh([2,2,2]).gridEy
|
||||
|
||||
# print T.edge
|
||||
# T.plotGrid(ax=ax)
|
||||
|
||||
# R = deflationMatrix(T._facesX, T._hangingFx, T._fx2i)
|
||||
# print R
|
||||
|
||||
ax = plt.subplot(212)#, projection='3d')
|
||||
ax.spy(Mesh.TensorMesh([2,2,2]).edgeCurl)
|
||||
|
||||
# ax = plt.subplot(313)
|
||||
# ax.spy(T.faceDiv[:,:T.nFx] * R)
|
||||
|
||||
|
||||
# T.balance()
|
||||
# T.plotGrid(ax=ax)
|
||||
|
||||
# cx = T._getNextCell([0,0,1],direction=0,positive=True)
|
||||
# print cx
|
||||
# # print [T._asPointer(_) for _ in cx]
|
||||
# cx = T._getNextCell([8,0,3],direction=0,positive=False)
|
||||
# print T._asPointer(cx)
|
||||
# cx = T._getNextCell([8,8,1],direction=1,positive=False)
|
||||
# print cx, #[T._asPointer(_) for _ in cx]
|
||||
# cm = T._getNextCell([64,80,4],direction=0,positive=False)
|
||||
# cy = T._getNextCell([64,80,4],direction=1,positive=True)
|
||||
# cp = T._getNextCell([64,80,4],direction=1,positive=False)
|
||||
|
||||
# ax.plot( T._cellN([4,0,1])[0],T._cellN([4,0,1])[1], 'yd')
|
||||
# ax.plot( T._cellN(cx)[0],T._cellN(cx)[1], 'ys')
|
||||
# ax.plot( T._cellN(cm)[0],T._cellN(cm)[1], 'ys')
|
||||
# ax.plot( T._cellN(cy)[0],T._cellN(cy)[1], 'ys')
|
||||
# ax.plot( T._cellN(cp[0])[0],T._cellN(cp[0])[1], 'ys')
|
||||
# ax.plot( T._cellN(cp[1])[0],T._cellN(cp[1])[1], 'ys')
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# print T.nN
|
||||
|
||||
plt.show()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user