def _calcValue(self): Nfaces = self.mesh.numberOfFaces M = self.mesh._maxFacesPerCell dim = self.mesh.dim cellFaceIDs = self.mesh.cellFaceIDs faceNormalAreas = self.distanceVar._levelSetNormals * self.mesh._faceAreas cellFaceNormalAreas = numerix.array(MA.filled(numerix.take(faceNormalAreas, cellFaceIDs, axis=-1), 0)) norms = numerix.array(MA.filled(MA.array(self.mesh._cellNormals), 0)) alpha = numerix.dot(cellFaceNormalAreas, norms) alpha = numerix.where(alpha > 0, alpha, 0) alphasum = numerix.sum(alpha, axis=0) alphasum += (alphasum < 1e-100) * 1.0 alpha = alpha / alphasum phi = numerix.repeat(self.distanceVar[numerix.newaxis, ...], M, axis=0) alpha = numerix.where(phi > 0., 0, alpha) volumes = numerix.array(self.mesh.cellVolumes) alpha = alpha * volumes * norms value = numerix.zeros((dim, Nfaces), 'd') vector._putAdd(value, cellFaceIDs, alpha, mask=MA.getmask(MA.array(cellFaceIDs))) ## value = numerix.reshape(value, (dim, Nfaces, dim)) return -value / self.mesh._faceAreas
def _getDifferences(self, adjacentValues, cellValues, oldArray, cellToCellIDs, mesh): dAP = mesh._cellToCellDistances ## adjacentGradient = numerix.take(oldArray.grad, cellToCellIDs) adjacentGradient = numerix.take(oldArray.grad, mesh._cellToCellIDs, axis=-1) adjacentNormalGradient = numerix.dot(adjacentGradient, mesh._cellNormals) adjacentUpValues = cellValues + 2 * dAP * adjacentNormalGradient cellIDs = numerix.repeat(numerix.arange(mesh.numberOfCells)[numerix.newaxis, ...], mesh._maxFacesPerCell, axis=0) cellIDs = MA.masked_array(cellIDs, mask = MA.getmask(mesh._cellToCellIDs)) cellGradient = numerix.take(oldArray.grad, cellIDs, axis=-1) cellNormalGradient = numerix.dot(cellGradient, mesh._cellNormals) cellUpValues = adjacentValues - 2 * dAP * cellNormalGradient cellLaplacian = (cellUpValues + adjacentValues - 2 * cellValues) / dAP**2 adjacentLaplacian = (adjacentUpValues + cellValues - 2 * adjacentValues) / dAP**2 adjacentLaplacian = adjacentLaplacian.filled(0) cellLaplacian = cellLaplacian.filled(0) mm = numerix.where(cellLaplacian * adjacentLaplacian < 0., 0., numerix.where(abs(cellLaplacian) > abs(adjacentLaplacian), adjacentLaplacian, cellLaplacian)) return FirstOrderAdvectionTerm._getDifferences(self, adjacentValues, cellValues, oldArray, cellToCellIDs, mesh) - mm * dAP / 2.
def _calcValue_(self, alpha, id1, id2): cell1 = numerix.take(self.var, id1, axis=-1) cell2 = numerix.take(self.var, id2, axis=-1) return numerix.where((cell1 > 0) & (cell2 > 0), numerix.minimum(cell1, cell2), numerix.where((cell1 < 0) & (cell2 < 0), numerix.maximum(cell1, cell2), 0))
def _calcValue(self): """ Test case added because `and` was being used instead of bitwise `&`. >>> from fipy.meshes import Grid1D >>> mesh = Grid1D(nx = 3) >>> from fipy.variables.faceVariable import FaceVariable >>> P = FaceVariable(mesh = mesh, value = (1e-3, 1e+71, 1e-3, 1e-3)) >>> alpha = ExponentialConvectionTerm([1])._alpha(P) >>> print alpha [ 0.5 1. 0.5 0.5] """ eps = 1e-3 largeValue = 101.0 P = self.P.numericValue P = numerix.where(abs(P) < eps, eps, P) alpha = numerix.where(P > largeValue, (P - 1) / P, 0.5) Pmin = numerix.where(P > largeValue + 1, largeValue + 1, P) alpha = numerix.where((abs(Pmin) > eps) & (Pmin <= largeValue), ((Pmin - 1) * numerix.exp(Pmin) + 1) / (Pmin * (numerix.exp(Pmin) - 1)), alpha) return alpha
def __getRotationTensor(self, mesh): if not hasattr(self, 'rotationTensor'): rotationTensor = FaceVariable(mesh=mesh, rank=2) rotationTensor[:, 0] = self._getNormals(mesh) if mesh.dim == 2: rotationTensor[:, 1] = rotationTensor[:, 0].dot( (((0, 1), (-1, 0)))) elif mesh.dim == 3: epsilon = 1e-20 div = numerix.sqrt(1 - rotationTensor[2, 0]**2) flag = numerix.resize(div > epsilon, (mesh.dim, mesh.numberOfFaces)) rotationTensor[0, 1] = 1 rotationTensor[:, 1] = numerix.where( flag, rotationTensor[:, 0].dot( (((0, 1, 0), (-1, 0, 0), (0, 0, 0)))) / div, rotationTensor[:, 1]) rotationTensor[1, 2] = 1 rotationTensor[:, 2] = numerix.where( flag, rotationTensor[:, 0] * rotationTensor[2, 0] / div, rotationTensor[:, 2]) rotationTensor[2, 2] = -div self.rotationTensor = rotationTensor return self.rotationTensor
def _getRotationTensor(self, mesh): if not hasattr(self, 'rotationTensor'): from fipy.variables.faceVariable import FaceVariable rotationTensor = FaceVariable(mesh=mesh, rank=2) rotationTensor[:, 0] = self._getNormals(mesh) if mesh.getDim() == 2: rotationTensor[:,1] = rotationTensor[:,0].dot((((0, 1), (-1, 0)))) elif mesh.getDim() ==3: epsilon = 1e-20 div = numerix.sqrt(1 - rotationTensor[2,0]**2) flag = numerix.resize(div > epsilon, (mesh.getDim(), mesh._getNumberOfFaces())) rotationTensor[0, 1] = 1 rotationTensor[:, 1] = numerix.where(flag, rotationTensor[:,0].dot((((0, 1, 0), (-1, 0, 0), (0, 0, 0)))) / div, rotationTensor[:, 1]) rotationTensor[1, 2] = 1 rotationTensor[:, 2] = numerix.where(flag, rotationTensor[:,0] * rotationTensor[2,0] / div, rotationTensor[:, 2]) rotationTensor[2, 2] = -div self.rotationTensor = rotationTensor return self.rotationTensor
def _calcValuePy(self, eps, P): """ Test case added because `and` was being used instead of bitwise `&`. >>> from fipy.meshes.grid1D import Grid1D >>> mesh = Grid1D(nx = 3) >>> from fipy.variables.faceVariable import FaceVariable >>> P = FaceVariable(mesh = mesh, value = (1e-3, 1e+71, 1e-3, 1e-3)) >>> alpha = PowerLawConvectionTerm._Alpha(P) >>> print numerix.allclose(alpha, [ 0.5, 1., 0.5 , 0.5]) True """ P = numerix.where(abs(P) < eps, eps, P) alpha = numerix.where( P > 10., (P - 1.) / P, 0.5) tmp = (1. - P / 10.) tmpSqr = tmp * tmp alpha = numerix.where( (10. >= P) & (P > eps), ((P-1.) + tmpSqr*tmpSqr*tmp) / P, alpha) tmp = (1. + P / 10.) tmpSqr = tmp * tmp alpha = numerix.where((-eps > P) & (P >= -10.), (tmpSqr*tmpSqr*tmp - 1.) / P, alpha) alpha = numerix.where( P < -10., -1. / P, alpha) return PhysicalField(value = alpha)
def _orderVertices(vertexCoords, vertices): coordinates = numerix.take(vertexCoords, vertices, axis=1) centroid = numerix.add.reduce(coordinates, axis=1) / coordinates.shape[1] coordinates = coordinates - centroid[..., numerix.newaxis] coordinates = numerix.where(coordinates == 0, 1.e-10, coordinates) ## to prevent division by zero angles = numerix.arctan(coordinates[1] / coordinates[0]) + numerix.where(coordinates[0] < 0, numerix.pi, 0) ## angles go from -pi / 2 to 3*pi / 2 sortorder = numerix.argsort(angles) return numerix.take(vertices, sortorder)
def _calcValue_(self, alpha, id1, id2): cell1 = numerix.take(self.var,id1, axis=-1) cell2 = numerix.take(self.var,id2, axis=-1) return numerix.where((cell1 > 0) & (cell2 > 0), numerix.minimum(cell1, cell2), numerix.where((cell1 < 0) & (cell2 < 0), numerix.maximum(cell1, cell2), 0))
def _calcValue(self): eps = 1e-3 P = self.P alpha = numerix.where( P > 2., (P - 1) / P, 0.) alpha = numerix.where( numerix.logical_and(2. >= P, P >= -2.), 0.5, alpha) alpha = numerix.where( -2. > P, -1 / P, alpha) return alpha
def __init__(self, trenchDepth=None, trenchSpacing=None, boundaryLayerDepth=None, cellSize=None, aspectRatio=None, angle=0., communicator=parallelComm): """ `trenchDepth` - Depth of the trench. `trenchSpacing` - The distance between the trenches. `boundaryLayerDepth` - The depth of the hydrodynamic boundary layer. `cellSize` - The cell Size. `aspectRatio` - trenchDepth / trenchWidth `angle` - The angle for the taper of the trench. The trench mesh takes the parameters generally used to define a trench region and recasts then for the general `GapFillMesh`. """ heightBelowTrench = cellSize * 10. heightAboveTrench = trenchDepth / 1. fineRegionHeight = heightBelowTrench + trenchDepth + heightAboveTrench transitionHeight = fineRegionHeight * 3. domainWidth = trenchSpacing / 2. domainHeight = heightBelowTrench + trenchDepth + boundaryLayerDepth super(TrenchMesh, self).__init__(cellSize=cellSize, desiredDomainWidth=domainWidth, desiredDomainHeight=domainHeight, desiredFineRegionHeight=fineRegionHeight, transitionRegionHeight=transitionHeight, communicator=parallelComm) trenchWidth = trenchDepth / aspectRatio x, y = self.cellCenters Y = (y - (heightBelowTrench + trenchDepth / 2)) taper = numerix.tan(angle) * Y self.electrolyteMask = numerix.where(y > trenchDepth + heightBelowTrench, 1, numerix.where(y < heightBelowTrench, 0, numerix.where(x > trenchWidth / 2 + taper, 0, 1)))
def _orderVertices(vertexCoords, vertices): coordinates = numerix.take(vertexCoords, vertices) centroid = numerix.add.reduce(coordinates) / coordinates.shape[0] coordinates = coordinates - centroid # to prevent division by zero coordinates = numerix.where(coordinates == 0, 1.e-100, coordinates) # angles go from -pi / 2 to 3*pi / 2 angles = numerix.arctan(coordinates[:, 1] / coordinates[:, 0]) \ + numerix.where(coordinates[:, 0] < 0, numerix.pi, 0) sortorder = numerix.argsort(angles) return numerix.take(vertices, sortorder)
def _getGradient(self, normalGradient, gradUpwind): gradUpUpwind = -gradUpwind + 2 * normalGradient avg = 0.5 * (abs(gradUpwind) + abs(gradUpUpwind)) min3 = numerix.minimum( numerix.minimum(abs(2 * gradUpwind), abs(2 * gradUpUpwind)), avg) grad = numerix.where(gradUpwind * gradUpUpwind < 0., 0., numerix.where(gradUpUpwind > 0., min3, -min3)) return grad
def _getGradient(self, normalGradient, gradUpwind): gradUpUpwind = -gradUpwind + 2 * normalGradient avg = 0.5 * (abs(gradUpwind) + abs(gradUpUpwind)) min3 = numerix.minimum(numerix.minimum(abs(gradUpwind), abs(gradUpUpwind)), avg) grad = numerix.where(gradUpwind * gradUpUpwind < 0., 0., numerix.where(gradUpUpwind > 0., min3, -min3)) return grad
def _calcValue_(self, alpha, id1, id2): distance = numerix.array(self.var) cell1 = numerix.take(distance, id1) cell2 = numerix.take(distance, id2) return numerix.where(numerix.logical_or(cell1 < 0, cell2 < 0), 0, self.diffusionCoeff)
def _levelSetNormals(self): """ Return the face level set normals. >>> from fipy.meshes import Grid2D >>> from fipy.variables.faceVariable import FaceVariable >>> mesh = Grid2D(dx = .5, dy = .5, nx = 2, ny = 2) >>> distanceVariable = DistanceVariable(mesh = mesh, ... value = (-0.5, 0.5, 0.5, 1.5)) >>> v = 1 / numerix.sqrt(2) >>> answer = FaceVariable(mesh=mesh, ... value=((0, 0, v, v, 0, 0, 0, v, 0, 0, v, 0), ... (0, 0, v, v, 0, 0, 0, v, 0, 0, v, 0))) >>> print numerix.allclose(distanceVariable._levelSetNormals, answer) True """ faceGrad = self.grad.arithmeticFaceValue faceGradMag = numerix.array(faceGrad.mag) faceGradMag = numerix.where(faceGradMag > 1e-10, faceGradMag, 1e-10) faceGrad = numerix.array(faceGrad) ## set faceGrad zero on exteriorFaces exteriorFaces = self.mesh.exteriorFaces if len(exteriorFaces.value) > 0: faceGrad[..., exteriorFaces.value] = 0. return faceGrad / faceGradMag
def _interfaceNormals(self): """ Returns the normals on the boundary faces only, the other are set to zero. >>> from fipy.meshes import Grid2D >>> from fipy.variables.faceVariable import FaceVariable >>> mesh = Grid2D(dx = .5, dy = .5, nx = 2, ny = 2) >>> distanceVariable = DistanceVariable(mesh = mesh, ... value = (-0.5, 0.5, 0.5, 1.5)) >>> v = 1 / numerix.sqrt(2) >>> answer = FaceVariable(mesh=mesh, ... value=((0, 0, v, 0, 0, 0, 0, v, 0, 0, 0, 0), ... (0, 0, v, 0, 0, 0, 0, v, 0, 0, 0, 0))) >>> print numerix.allclose(distanceVariable._interfaceNormals, answer) True """ M = self.mesh.dim interfaceFlag = numerix.repeat(self._interfaceFlag[numerix.newaxis, ...], M, axis=0) return numerix.where(interfaceFlag, self._levelSetNormals, 0)
def _plot(self): var = self.vars[0] mesh = var.mesh U, V = var.numericValue U = numerix.take(U, self.indices) V = numerix.take(V, self.indices) ang = numerix.arctan2(V, U) mag = numerix.sqrt(U**2 + V**2) datamin, datamax = self._autoscale(vars=(mag,), datamin=self._getLimit('datamin'), datamax=self._getLimit('datamax')) mag = numerix.where(mag > datamax, datamax, mag) mag = numerix.ma.masked_array(mag, mag < datamin) if self.log: mag = numerix.log10(mag) mag = numerix.ma.masked_array(mag, numerix.isnan(mag)) U = mag * numerix.cos(ang) V = mag * numerix.sin(ang) self._quiver.set_UVC(U, V) self.axes.set_xlim(xmin=self._getLimit('xmin'), xmax=self._getLimit('xmax')) self.axes.set_ylim(ymin=self._getLimit('ymin'), ymax=self._getLimit('ymax'))
def _calcValue(self): flag = MA.filled( numerix.take(self.distanceVar._interfaceFlag, self.mesh.cellFaceIDs), 0) flag = numerix.sum(flag, axis=0) return numerix.where( numerix.logical_and(self.distanceVar.value > 0, flag > 0), 1, 0)
def _plot(self): var = self.vars[0] mesh = var.mesh U, V = var.numericValue U = numerix.take(U, self.indices) V = numerix.take(V, self.indices) ang = numerix.arctan2(V, U) mag = numerix.sqrt(U**2 + V**2) datamin, datamax = self._autoscale(vars=(mag, ), datamin=self._getLimit('datamin'), datamax=self._getLimit('datamax')) mag = numerix.where(mag > datamax, datamax, mag) mag = numerix.ma.masked_array(mag, mag < datamin) if self.log: mag = numerix.log10(mag) mag = numerix.ma.masked_array(mag, numerix.isnan(mag)) U = mag * numerix.cos(ang) V = mag * numerix.sin(ang) self._quiver.set_UVC(U, V) self.axes.set_xlim(xmin=self._getLimit('xmin'), xmax=self._getLimit('xmax')) self.axes.set_ylim(ymin=self._getLimit('ymin'), ymax=self._getLimit('ymax'))
def run(self): MayaviDaemon._viewers.append(self) mlab.clf() self.cellsource = self.setup_source(self.cellfname) self.has_cell, bounds = self._examine_data(source=self.cellsource, datatype="cell_data", bounds=zeros((0, 6), 'l')) self.facesource = self.setup_source(self.facefname) self.has_face, bounds = self._examine_data(source=self.facesource, datatype="point_data", bounds=bounds) boundsmin = bounds.min(axis=0) boundsmax = bounds.max(axis=0) bounds = (boundsmin[0], boundsmax[1], boundsmin[2], boundsmax[3], boundsmin[4], boundsmax[5]) self.bounds = where(self.bounds == array((None, )), bounds, self.bounds).astype(float) self.view_data() # Poll the lock file. self.timer = Timer(1000 / self.fps, self.poll_file)
def _calcValue_(self, alpha, id1, id2): cell1 = take(self.var, id1) cell2 = take(self.var, id2) delta = cell1 - cell2 eps = 1e-14 value = where(abs(delta) < eps, 1.0 / exp(delta), 0.0) delta = where(abs(delta) < eps, eps, delta) value = where((abs(delta) > eps) & (delta < 100), delta / (exp(delta) - 1), value) value *= exp(cell1) for bc in self.bcs: if isinstance(bc, FixedValue): value[bc.faces.value] = bc._value return value
def _calcValue(self): eps = self.eps P = self.P.numericValue P = numerix.where(abs(P) < eps, eps, P) alpha = numerix.where( P > 10., (P - 1.) / P, 0.5) tmp = (1. - P / 10.) tmpSqr = tmp * tmp alpha = numerix.where( (10. >= P) & (P > eps), ((P-1.) + tmpSqr*tmpSqr*tmp) / P, alpha) tmp = (1. + P / 10.) tmpSqr = tmp * tmp alpha = numerix.where((-eps > P) & (P >= -10.), (tmpSqr*tmpSqr*tmp - 1.) / P, alpha) alpha = numerix.where( P < -10., -1. / P, alpha) return PhysicalField(value = alpha)
def _calcValue_(self, alpha, id1, id2): cell1 = take(self.var,id1) cell2 = take(self.var,id2) delta = cell1 - cell2 eps = 1e-14 value = where(abs(delta) < eps, 1. / exp(delta), 0.) delta = where(abs(delta) < eps, eps, delta) value = where((abs(delta) > eps) & (delta < 100), delta / (exp(delta) - 1), value) value *= exp(cell1) for bc in self.bcs: if isinstance(bc, FixedValue): value[bc.faces.value] = bc._value return value
def _buildMatrix(self, var, SparseMatrix, boundaryConditions=(), dt=None, transientGeomCoeff=None, diffusionGeomCoeff=None): var, L, b = FaceTerm._buildMatrix( self, var, SparseMatrix, boundaryConditions=boundaryConditions, dt=dt, transientGeomCoeff=transientGeomCoeff, diffusionGeomCoeff=diffusionGeomCoeff) ## if var.rank != 1: mesh = var.mesh if (not hasattr(self, 'constraintL')) or (not hasattr( self, 'constraintB')): weight = self._getWeight(var, transientGeomCoeff, diffusionGeomCoeff) if 'implicit' in weight: alpha = weight['implicit']['cell 1 diag'] else: alpha = 0.0 alpha_constraint = numerix.where(var.faceGrad.constraintMask, 1.0, alpha) def divergence(face_value): return ( face_value * \ (var.faceGrad.constraintMask | var.arithmeticFaceValue.constraintMask) * \ self.coeff * mesh.exteriorFaces ).divergence * mesh.cellVolumes self.constraintL = divergence(alpha_constraint) dvar = (var.faceGrad * mesh._cellDistances * mesh.faceNormals).sum(axis=0) self.constraintB = divergence( (alpha_constraint - 1) * var.arithmeticFaceValue + (alpha - 1) * dvar * var.faceGrad.constraintMask) ids = self._reshapeIDs(var, numerix.arange(mesh.numberOfCells)) L.addAt( numerix.array(self.constraintL).ravel(), ids.ravel(), ids.swapaxes(0, 1).ravel()) b += numerix.reshape(self.constraintB.value, ids.shape).sum(0).ravel() return (var, L, b)
def run(self): MayaviDaemon._viewers.append(self) mlab.clf() bounds = zeros((0, 6), 'l') self.cellsource = self.setup_source(self.cellfname) if self.cellsource is not None: tmp = [out.cell_data.scalars for out in self.cellsource.outputs \ if out.cell_data.scalars is not None] self.has_cell_scalars = (len(tmp) > 0) tmp = [out.cell_data.vectors for out in self.cellsource.outputs \ if out.cell_data.vectors is not None] self.has_cell_vectors = (len(tmp) > 0) tmp = [out.cell_data.tensors for out in self.cellsource.outputs \ if out.cell_data.tensors is not None] self.has_cell_tensors = (len(tmp) > 0) bounds = concatenate((bounds, [out.bounds for out in self.cellsource.outputs]), axis=0) self.facesource = self.setup_source(self.facefname) if self.facesource is not None: tmp = [out.point_data.scalars for out in self.facesource.outputs \ if out.point_data.scalars is not None] self.has_face_scalars = (len(tmp) > 0) tmp = [out.point_data.vectors for out in self.facesource.outputs \ if out.point_data.vectors is not None] self.has_face_vectors = (len(tmp) > 0) tmp = [out.point_data.tensors for out in self.facesource.outputs \ if out.point_data.tensors is not None] self.has_face_tensors = (len(tmp) > 0) bounds = concatenate((bounds, [out.bounds for out in self.facesource.outputs]), axis=0) boundsmin = bounds.min(axis=0) boundsmax = bounds.max(axis=0) bounds = (boundsmin[0], boundsmax[1], boundsmin[2], boundsmax[3], boundsmin[4], boundsmax[5]) self.bounds = where(self.bounds == array((None,)), bounds, self.bounds).astype(float) self.view_data() # Poll the lock file. self.timer = Timer(1000 / self.fps, self.poll_file)
def _getDifferences(self, adjacentValues, cellValues, oldArray, cellToCellIDs, mesh): dAP = mesh._cellToCellDistances ## adjacentGradient = numerix.take(oldArray.grad, cellToCellIDs) adjacentGradient = numerix.take(oldArray.grad, mesh._cellToCellIDs, axis=-1) adjacentNormalGradient = numerix.dot(adjacentGradient, mesh._cellNormals) adjacentUpValues = cellValues + 2 * dAP * adjacentNormalGradient cellIDs = numerix.repeat(numerix.arange( mesh.numberOfCells)[numerix.newaxis, ...], mesh._maxFacesPerCell, axis=0) cellIDs = MA.masked_array(cellIDs, mask=MA.getmask(mesh._cellToCellIDs)) cellGradient = numerix.take(oldArray.grad, cellIDs, axis=-1) cellNormalGradient = numerix.dot(cellGradient, mesh._cellNormals) cellUpValues = adjacentValues - 2 * dAP * cellNormalGradient cellLaplacian = (cellUpValues + adjacentValues - 2 * cellValues) / dAP**2 adjacentLaplacian = (adjacentUpValues + cellValues - 2 * adjacentValues) / dAP**2 adjacentLaplacian = adjacentLaplacian.filled(0) cellLaplacian = cellLaplacian.filled(0) mm = numerix.where( cellLaplacian * adjacentLaplacian < 0., 0., numerix.where( abs(cellLaplacian) > abs(adjacentLaplacian), adjacentLaplacian, cellLaplacian)) return FirstOrderAdvectionTerm._getDifferences( self, adjacentValues, cellValues, oldArray, cellToCellIDs, mesh) - mm * dAP / 2.
def _calcFaceCellToCellNormals(self): faceCellCentersUp = numerix.take(self._cellCenters, self.faceCellIDs[1], axis=1) faceCellCentersDown = numerix.take(self._cellCenters, self.faceCellIDs[0], axis=1) faceCellCentersUp = numerix.where(MA.getmaskarray(faceCellCentersUp), self._faceCenters, faceCellCentersUp) diff = faceCellCentersDown - faceCellCentersUp mag = numerix.sqrt(numerix.sum(diff**2)) faceCellToCellNormals = diff / numerix.resize(mag, (self.dim, len(mag))) orientation = 1 - 2 * (numerix.dot(self.faceNormals, faceCellToCellNormals) < 0) return faceCellToCellNormals * orientation
def _calcFaceAreas(self): faceVertexIDs = MA.filled(self.faceVertexIDs, -1) substitute = numerix.repeat(faceVertexIDs[numerix.newaxis, 0], faceVertexIDs.shape[0], axis=0) faceVertexIDs = numerix.where(MA.getmaskarray(self.faceVertexIDs), substitute, faceVertexIDs) faceVertexCoords = numerix.take(self.vertexCoords, faceVertexIDs, axis=1) faceOrigins = numerix.repeat(faceVertexCoords[:,0], faceVertexIDs.shape[0], axis=0) faceOrigins = numerix.reshape(faceOrigins, MA.shape(faceVertexCoords)) faceVertexCoords = faceVertexCoords - faceOrigins left = range(faceVertexIDs.shape[0]) right = left[1:] + [left[0]] cross = numerix.sum(numerix.cross(faceVertexCoords, numerix.take(faceVertexCoords, right, 1), axis=0), 1) self.faceAreas = numerix.sqrtDot(cross, cross) / 2.
def _getDiagonalSign(self, transientGeomCoeff=None, diffusionGeomCoeff=None): if transientGeomCoeff is not None and diffusionGeomCoeff is not None: diagonalSign = numerix.where(numerix.array(numerix.all(transientGeomCoeff == 0, axis=-1)), numerix.array(2 * numerix.all(diffusionGeomCoeff[0] <= 0, axis=-1) - 1), numerix.array(2 * numerix.all(transientGeomCoeff >= 0, axis=-1) - 1)) elif transientGeomCoeff is not None: diagonalSign = 2 * numerix.all(transientGeomCoeff >= 0, axis=-1) - 1 elif diffusionGeomCoeff is not None: diagonalSign = 2 * numerix.all(diffusionGeomCoeff[0] <= 0, axis=-1) - 1 else: diagonalSign = 1 return diagonalSign
def setValue(self, value, unit=None, where=None): """ Set the value of the Variable. Can take a masked array. >>> a = Variable((1,2,3)) >>> a.setValue(5, where=(1, 0, 1)) >>> print a [5 2 5] >>> b = Variable((4,5,6)) >>> a.setValue(b, where=(1, 0, 1)) >>> print a [4 2 6] >>> print b [4 5 6] >>> a.setValue(3) >>> print a [3 3 3] >>> b = numerix.array((3,4,5)) >>> a.setValue(b) >>> a[:] = 1 >>> print b [3 4 5] >>> a.setValue((4,5,6), where=(1, 0)) Traceback (most recent call last): .... ValueError: shape mismatch: objects cannot be broadcast to a single shape """ if where is not None: tmp = numerix.empty(numerix.getShape(where), self.getsctype()) tmp[:] = value tmp = numerix.where(where, tmp, self.getValue()) else: if hasattr(value, 'copy'): tmp = value.copy() else: tmp = value value = self._makeValue(value=tmp, unit=unit, array=None) if numerix.getShape(self.value) == (): self.value.itemset(value) else: self.value[:] = value self._markFresh()
def _calcValue(self): """ Test case added because `and` was being used instead of bitwise `&`. >>> from fipy.meshes import Grid1D >>> mesh = Grid1D(nx = 3) >>> from fipy.variables.faceVariable import FaceVariable >>> P = FaceVariable(mesh = mesh, value = (1e-3, 1e+71, 1e-3, 1e-3)) >>> alpha = ExponentialConvectionTerm([1])._alpha(P) >>> print(alpha) [ 0.5 1. 0.5 0.5] """ eps = 1e-3 largeValue = 101.0 P = self.P.numericValue P = numerix.where(abs(P) < eps, eps, P) alpha = numerix.where(P > largeValue, (P - 1) / P, 0.5) Pmin = numerix.where(P > largeValue + 1, largeValue + 1, P) alpha = numerix.where((abs(Pmin) > eps) & (Pmin <= largeValue), ((Pmin - 1) * numerix.exp(Pmin) + 1) / (Pmin * (numerix.exp(Pmin) - 1)), alpha) return alpha
def _calcFaceAreas(self): faceVertexIDs = MA.filled(self.faceVertexIDs, -1) substitute = numerix.repeat(faceVertexIDs[numerix.newaxis, 0], faceVertexIDs.shape[0], axis=0) faceVertexIDs = numerix.where(MA.getmaskarray(self.faceVertexIDs), substitute, faceVertexIDs) faceVertexCoords = numerix.take(self.vertexCoords, faceVertexIDs, axis=1) faceOrigins = numerix.repeat(faceVertexCoords[:,0], faceVertexIDs.shape[0], axis=0) faceOrigins = numerix.reshape(faceOrigins, MA.shape(faceVertexCoords)) faceVertexCoords = faceVertexCoords - faceOrigins left = range(faceVertexIDs.shape[0]) right = left[1:] + [left[0]] cross = numerix.sum(numerix.cross(faceVertexCoords, numerix.take(faceVertexCoords, right, 1), axis=0), 1) return numerix.sqrtDot(cross, cross) / 2.
def _getNonOrthogonality(self): exteriorFaceArray = numerix.zeros((self.faceCellIDs.shape[1],)) numerix.put(exteriorFaceArray, numerix.nonzero(self.getExteriorFaces()), 1) unmaskedFaceCellIDs = MA.filled(self.faceCellIDs, 0) ## what we put in for the "fill" doesn't matter because only exterior faces have anything masked, and exterior faces have their displacement vectors set to zero. ## if it's an exterior face, make the "displacement vector" equal to zero so the cross product will be zero. faceDisplacementVectors = numerix.where(numerix.array(zip(exteriorFaceArray, exteriorFaceArray)), 0.0, numerix.take(self._getCellCenters().swapaxes(0,1), unmaskedFaceCellIDs[1, :]) - numerix.take(self._getCellCenters().swapaxes(0,1), unmaskedFaceCellIDs[0, :])).swapaxes(0,1) faceCrossProducts = (faceDisplacementVectors[0, :] * self.faceNormals[1, :]) - (faceDisplacementVectors[1, :] * self.faceNormals[0, :]) faceDisplacementVectorLengths = numerix.maximum(((faceDisplacementVectors[0, :] ** 2) + (faceDisplacementVectors[1, :] ** 2)) ** 0.5, 1.e-100) faceWeightedNonOrthogonalities = abs(faceCrossProducts / faceDisplacementVectorLengths) * self.faceAreas cellFaceWeightedNonOrthogonalities = numerix.take(faceWeightedNonOrthogonalities, self.cellFaceIDs) cellFaceAreas = numerix.take(self.faceAreas, self.cellFaceIDs) cellTotalWeightedValues = numerix.add.reduce(cellFaceWeightedNonOrthogonalities, axis = 0) cellTotalFaceAreas = numerix.add.reduce(cellFaceAreas, axis = 0) return (cellTotalWeightedValues / cellTotalFaceAreas)
def _getCellInterfaceFlag(self): """ Returns 1 for those cells on the interface: >>> from fipy.meshes.grid2D import Grid2D >>> from fipy.variables.cellVariable import CellVariable >>> mesh = Grid2D(dx = .5, dy = .5, nx = 2, ny = 2) >>> distanceVariable = DistanceVariable(mesh = mesh, ... value = (-0.5, 0.5, 0.5, 1.5)) >>> answer = CellVariable(mesh=mesh, value=(0, 1, 1, 0)) >>> print numerix.allclose(distanceVariable._getCellInterfaceFlag(), answer) True """ flag = MA.filled(numerix.take(self._getInterfaceFlag(), self.cellFaceIDs), 0) flag = numerix.sum(flag, axis=0) return numerix.where(numerix.logical_and(self.value > 0, flag > 0), 1, 0)
def _nonOrthogonality(self): exteriorFaceArray = numerix.zeros((self.faceCellIDs.shape[1], ), 'l') numerix.put(exteriorFaceArray, numerix.nonzero(self.exteriorFaces), 1) unmaskedFaceCellIDs = MA.filled(self.faceCellIDs, 0) # what we put in for the "fill" doesn't matter because only exterior # faces have anything masked, and exterior faces have their displacement # vectors set to zero. # # if it's an exterior face, make the "displacement vector" equal to zero # so the cross product will be zero. faceDisplacementVectors = \ numerix.where(numerix.array(zip(exteriorFaceArray, exteriorFaceArray)), 0.0, numerix.take(self._scaledCellCenters.swapaxes(0,1), unmaskedFaceCellIDs[1, :]) \ - numerix.take(self._scaledCellCenters.swapaxes(0,1), unmaskedFaceCellIDs[0, :])) faceDisplacementVectors = faceDisplacementVectors.swapaxes(0, 1) faceCrossProducts = (faceDisplacementVectors[0, :] * self.faceNormals[1,:]) \ - (faceDisplacementVectors[1, :] * self.faceNormals[0, :]) faceDisplacementVectorLengths = numerix.maximum(((faceDisplacementVectors[0, :] ** 2) \ + (faceDisplacementVectors[1, :] ** 2)) ** 0.5, 1.e-100) faceWeightedNonOrthogonalities = abs( faceCrossProducts / faceDisplacementVectorLengths) * self._faceAreas cellFaceWeightedNonOrthogonalities = numerix.take( faceWeightedNonOrthogonalities, self.cellFaceIDs) cellFaceAreas = numerix.take(self._faceAreas, self.cellFaceIDs) cellTotalWeightedValues = numerix.add.reduce( cellFaceWeightedNonOrthogonalities, axis=0) cellTotalFaceAreas = numerix.add.reduce(cellFaceAreas, axis=0) return (cellTotalWeightedValues / cellTotalFaceAreas)
def _getDiagonalSign(self, transientGeomCoeff=None, diffusionGeomCoeff=None): if transientGeomCoeff is not None and diffusionGeomCoeff is not None: diagonalSign = numerix.where( numerix.array(numerix.all(transientGeomCoeff == 0, axis=-1)), numerix.array( 2 * numerix.all(diffusionGeomCoeff[0] <= 0, axis=-1) - 1), numerix.array(2 * numerix.all(transientGeomCoeff >= 0, axis=-1) - 1)) elif transientGeomCoeff is not None: diagonalSign = 2 * numerix.all(transientGeomCoeff >= 0, axis=-1) - 1 elif diffusionGeomCoeff is not None: diagonalSign = 2 * numerix.all(diffusionGeomCoeff[0] <= 0, axis=-1) - 1 else: diagonalSign = 1 return diagonalSign
def _interfaceFlag(self): """ Returns 1 for faces on boundary and 0 otherwise. >>> from fipy.meshes import Grid2D >>> from fipy.variables.faceVariable import FaceVariable >>> mesh = Grid2D(dx = .5, dy = .5, nx = 2, ny = 2) >>> distanceVariable = DistanceVariable(mesh = mesh, ... value = (-0.5, 0.5, 0.5, 1.5)) >>> answer = FaceVariable(mesh=mesh, ... value=(0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0)) >>> print numerix.allclose(distanceVariable._interfaceFlag, answer) True """ adjacentCellIDs = self.mesh._adjacentCellIDs val0 = numerix.take(numerix.array(self._value), adjacentCellIDs[0]) val1 = numerix.take(numerix.array(self._value), adjacentCellIDs[1]) return numerix.where(val1 * val0 < 0, 1, 0)
def getElectrolyteMask(self): x, y = self.getCellCenters() Y = (y - (self.heightBelowTrench + self.trenchDepth / 2)) ## taper taper = numerix.tan(self.angle) * Y ## bow if abs(self.bowWidth) > 1e-12 and (-self.trenchDepth / 2 < Y < self.trenchDepth / 2): param1 = self.trenchDepth**2 / 8 / self.bowWidth param2 = self.bowWidth / 2 bow = -numerix.sqrt((param1 + param2)**2 - Y**2) + param1 - param2 else: bow = 0 ## over hang Y = y - (self.heightBelowTrench + self.trenchDepth - self.overBumpRadius) overBump = 0 if self.overBumpRadius > 1e-12: overBump += numerix.where(Y > -self.overBumpRadius, self.overBumpWidth / 2 * (1 + numerix.cos(Y * numerix.pi / self.overBumpRadius)), 0) tmp = self.overBumpRadius**2 - Y**2 tmp = (tmp > 0) * tmp overBump += numerix.where((Y > -self.overBumpRadius) & (Y > 0), numerix.where(Y > self.overBumpRadius, -self.overBumpRadius, -(self.overBumpRadius - numerix.sqrt(tmp))), 0) return numerix.where(y > self.trenchDepth + self.heightBelowTrench, 1, numerix.where(y < self.heightBelowTrench, 0, numerix.where(x > self.trenchWidth / 2 + taper - bow - overBump, 0, 1)))
timeStepDuration = cfl * dx / velocity distanceVariable.updateOld() distanceVariable.setValue(numerix.array(distanceVariable) - velocity * timeStepDuration) surfactantEquation.solve(surfactantVariable) totalTime += timeStepDuration distanceViewer.plot() surfactantViewer.plot() errorViewer.plot() finalRadius = initialRadius + totalTime * velocity + distanceVariable answer = initialSurfactantValue * initialRadius / finalRadius coverage = surfactantVariable.getInterfaceVar() error.setValue(numerix.where((coverage > 1e-3) & (distanceVariable > 0), abs(coverage - answer), 0)) adjDistanceVariables = numerix.take(distanceVariable, mesh._getCellToCellIDs()) adjCoverages = numerix.take(coverage, mesh._getCellToCellIDs()) flag = (adjDistanceVariables < 0) & (adjCoverages > 1e-6) error.setValue(0, where=numerix.sum(flag, index=1) > 0) del L1[0] del L2[0] del Linf[0]
def _plot(self): from scipy.interpolate import griddata var = self.vars[0] mesh = var.mesh xmin, ymin = mesh.extents['min'] xmax, ymax = mesh.extents['max'] N = 100 X = numerix.linspace(xmin, xmax, N) Y = numerix.linspace(ymin, ymax, N) grid_x, grid_y = numerix.mgrid[xmin:xmax:N * 1j, ymin:ymax:N * 1j] if isinstance(var, FaceVariable): C = mesh.faceCenters elif isinstance(var, CellVariable): C = mesh.cellCenters U = griddata(C.value.T, var.value[0], (grid_x, grid_y), method='cubic') V = griddata(C.value.T, var.value[1], (grid_x, grid_y), method='cubic') lw = self.linewidth if isinstance(lw, (FaceVariable, CellVariable)): lw = griddata(C.value.T, lw.value, (grid_x, grid_y), method='cubic') color = self.color if isinstance(color, (FaceVariable, CellVariable)): color = griddata(C.value.T, color.value, (grid_x, grid_y), method='cubic', fill_value=color.min()) U = U.T V = V.T ang = numerix.arctan2(V, U) mag = numerix.sqrt(U**2 + V**2) datamin, datamax = self._autoscale(vars=(mag, ), datamin=self._getLimit('datamin'), datamax=self._getLimit('datamax')) mag = numerix.where(mag > datamax, numerix.nan, mag) mag = numerix.where(mag < datamin, numerix.nan, mag) if self.log: mag = numerix.log10(mag) U = mag * numerix.cos(ang) V = mag * numerix.sin(ang) # if self._stream is not None: # # the following doesn't work, nor does it help to `add_collection` first # # self._stream.arrows.remove() # self._stream.lines.remove() self.axes.cla() self._stream = self.axes.streamplot(X, Y, U, V, linewidth=lw, color=color, **self.kwargs) self.axes.set_xlim(xmin=self._getLimit('xmin'), xmax=self._getLimit('xmax')) self.axes.set_ylim(ymin=self._getLimit('ymin'), ymax=self._getLimit('ymax'))
def runLeveler(kLeveler=0.018, bulkLevelerConcentration=0.02, cellSize=0.1e-7, rateConstant=0.00026, initialAcceleratorCoverage=0.0, levelerDiffusionCoefficient=5e-10, numberOfSteps=400, displayRate=10, displayViewers=True): kLevelerConsumption = 0.0005 aspectRatio = 1.5 faradaysConstant = 9.6485e4 gasConstant = 8.314 acceleratorDiffusionCoefficient = 4e-10 siteDensity = 6.35e-6 atomicVolume = 7.1e-6 charge = 2 metalDiffusionCoefficient = 4e-10 temperature = 298. overpotential = -0.25 bulkMetalConcentration = 250. bulkAcceleratorConcentration = 50.0e-3 initialLevelerCoverage = 0. cflNumber = 0.2 numberOfCellsInNarrowBand = 20 cellsBelowTrench = 10 trenchDepth = 0.4e-6 trenchSpacing = 0.6e-6 boundaryLayerDepth = 98.7e-6 i0Suppressor = 0.3 i0Accelerator = 22.5 alphaSuppressor = 0.5 alphaAccelerator = 0.4 alphaAdsorption = 0.62 m = 4 b = 2.65 A = 0.3 Ba = -40 Bb = 60 Vd = 0.098 Bd = 0.0008 etaPrime = faradaysConstant * overpotential / gasConstant / temperature from fipy import TrenchMesh from fipy.tools import numerix mesh = TrenchMesh(cellSize=cellSize, trenchSpacing=trenchSpacing, trenchDepth=trenchDepth, boundaryLayerDepth=boundaryLayerDepth, aspectRatio=aspectRatio, angle=numerix.pi * 4. / 180., bowWidth=0., overBumpRadius=0., overBumpWidth=0.) narrowBandWidth = numberOfCellsInNarrowBand * cellSize from fipy.models.levelSet.distanceFunction.distanceVariable import DistanceVariable distanceVar = DistanceVariable(name='distance variable', mesh=mesh, value=-1, narrowBandWidth=narrowBandWidth) distanceVar.setValue(1, where=mesh.getElectrolyteMask()) distanceVar.calcDistanceFunction(narrowBandWidth=1e10) from fipy.models.levelSet.surfactant.surfactantVariable import SurfactantVariable levelerVar = SurfactantVariable(name="leveler variable", value=initialLevelerCoverage, distanceVar=distanceVar) acceleratorVar = SurfactantVariable(name="accelerator variable", value=initialAcceleratorCoverage, distanceVar=distanceVar) from fipy.variables.cellVariable import CellVariable bulkAcceleratorVar = CellVariable(name='bulk accelerator variable', mesh=mesh, value=bulkAcceleratorConcentration) bulkLevelerVar = CellVariable(name='bulk leveler variable', mesh=mesh, value=bulkLevelerConcentration) metalVar = CellVariable(name='metal variable', mesh=mesh, value=bulkMetalConcentration) def depositionCoeff(alpha, i0): expo = numerix.exp(-alpha * etaPrime) return 2 * i0 * (expo - expo * numerix.exp(etaPrime)) coeffSuppressor = depositionCoeff(alphaSuppressor, i0Suppressor) coeffAccelerator = depositionCoeff(alphaAccelerator, i0Accelerator) exchangeCurrentDensity = acceleratorVar.getInterfaceVar() * ( coeffAccelerator - coeffSuppressor) + coeffSuppressor currentDensity = metalVar / bulkMetalConcentration * exchangeCurrentDensity depositionRateVariable = currentDensity * atomicVolume / charge / faradaysConstant extensionVelocityVariable = CellVariable(name='extension velocity', mesh=mesh, value=depositionRateVariable) from fipy.models.levelSet.surfactant.adsorbingSurfactantEquation \ import AdsorbingSurfactantEquation kAccelerator = rateConstant * numerix.exp(-alphaAdsorption * etaPrime) kAcceleratorConsumption = Bd + A / (numerix.exp(Ba * (overpotential + Vd)) + numerix.exp(Bb * (overpotential + Vd))) q = m * overpotential + b levelerSurfactantEquation = AdsorbingSurfactantEquation( levelerVar, distanceVar=distanceVar, bulkVar=bulkLevelerVar, rateConstant=kLeveler, consumptionCoeff=kLevelerConsumption * depositionRateVariable) accVar1 = acceleratorVar.getInterfaceVar() accVar2 = (accVar1 > 0) * accVar1 accConsumptionCoeff = kAcceleratorConsumption * (accVar2**(q - 1)) acceleratorSurfactantEquation = AdsorbingSurfactantEquation( acceleratorVar, distanceVar=distanceVar, bulkVar=bulkAcceleratorVar, rateConstant=kAccelerator, otherVar=levelerVar, otherBulkVar=bulkLevelerVar, otherRateConstant=kLeveler, consumptionCoeff=accConsumptionCoeff) from fipy.models.levelSet.advection.higherOrderAdvectionEquation \ import buildHigherOrderAdvectionEquation advectionEquation = buildHigherOrderAdvectionEquation( advectionCoeff=extensionVelocityVariable) from fipy.boundaryConditions.fixedValue import FixedValue from fipy.models.levelSet.electroChem.metalIonDiffusionEquation \ import buildMetalIonDiffusionEquation metalEquation = buildMetalIonDiffusionEquation( ionVar=metalVar, distanceVar=distanceVar, depositionRate=depositionRateVariable, diffusionCoeff=metalDiffusionCoefficient, metalIonMolarVolume=atomicVolume) metalEquationBCs = FixedValue(mesh.getTopFaces(), bulkMetalConcentration) from fipy.models.levelSet.surfactant.surfactantBulkDiffusionEquation \ import buildSurfactantBulkDiffusionEquation bulkAcceleratorEquation = buildSurfactantBulkDiffusionEquation( bulkVar=bulkAcceleratorVar, distanceVar=distanceVar, surfactantVar=acceleratorVar, otherSurfactantVar=levelerVar, diffusionCoeff=acceleratorDiffusionCoefficient, rateConstant=kAccelerator * siteDensity) bulkAcceleratorEquationBCs = (FixedValue(mesh.getTopFaces(), bulkAcceleratorConcentration), ) bulkLevelerEquation = buildSurfactantBulkDiffusionEquation( bulkVar=bulkLevelerVar, distanceVar=distanceVar, surfactantVar=levelerVar, diffusionCoeff=levelerDiffusionCoefficient, rateConstant=kLeveler * siteDensity) bulkLevelerEquationBCs = (FixedValue(mesh.getTopFaces(), bulkLevelerConcentration), ) eqnTuple = ((advectionEquation, distanceVar, ()), (levelerSurfactantEquation, levelerVar, ()), (acceleratorSurfactantEquation, acceleratorVar, ()), (metalEquation, metalVar, metalEquationBCs), (bulkAcceleratorEquation, bulkAcceleratorVar, bulkAcceleratorEquationBCs), (bulkLevelerEquation, bulkLevelerVar, bulkLevelerEquationBCs)) levelSetUpdateFrequency = int(0.7 * narrowBandWidth / cellSize / cflNumber / 2) totalTime = 0.0 if displayViewers: from fipy.viewers.mayaviViewer.mayaviSurfactantViewer import MayaviSurfactantViewer viewers = (MayaviSurfactantViewer(distanceVar, acceleratorVar.getInterfaceVar(), zoomFactor=1e6, limits={ 'datamax': 0.5, 'datamin': 0.0 }, smooth=1, title='accelerator coverage'), MayaviSurfactantViewer(distanceVar, levelerVar.getInterfaceVar(), zoomFactor=1e6, limits={ 'datamax': 0.5, 'datamin': 0.0 }, smooth=1, title='leveler coverage')) for step in range(numberOfSteps): if displayViewers: if step % displayRate == 0: for viewer in viewers: viewer.plot() if step % levelSetUpdateFrequency == 0: distanceVar.calcDistanceFunction(deleteIslands=True) extensionVelocityVariable.setValue(depositionRateVariable) extOnInt = numerix.where( distanceVar > 0, numerix.where(distanceVar < 2 * cellSize, extensionVelocityVariable, 0), 0) dt = cflNumber * cellSize / numerix.max(extOnInt) id = numerix.max(numerix.nonzero(distanceVar._getInterfaceFlag())) distanceVar.extendVariable(extensionVelocityVariable, deleteIslands=True) extensionVelocityVariable[mesh.getFineMesh().getNumberOfCells():] = 0. for eqn, var, BCs in eqnTuple: var.updateOld() for eqn, var, BCs in eqnTuple: eqn.solve(var, boundaryConditions=BCs, dt=dt) totalTime += dt try: testFile = 'testLeveler.gz' import os import examples.levelSet.electroChem from fipy.tools import dump data = dump.read( os.path.join(examples.levelSet.electroChem.__path__[0], testFile)) N = mesh.getFineMesh().getNumberOfCells() print numerix.allclose(data[:N], levelerVar[:N], rtol=1e-3) except: return 0
def _getStructure(self): ##maxX = self.distanceVar.mesh.faceCenters[0].max() ##minX = self.distanceVar.mesh.faceCenters[0].min() IDs = numerix.nonzero(self.distanceVar._cellInterfaceFlag)[0] coordinates = numerix.take(numerix.array(self.distanceVar.mesh.cellCenters).swapaxes(0, 1), IDs) coordinates -= numerix.take(numerix.array(self.distanceVar.grad * self.distanceVar).swapaxes(0, 1), IDs) coordinates *= self.zoomFactor shiftedCoords = coordinates.copy() shiftedCoords[:, 0] = -coordinates[:, 0] ##+ (maxX - minX) coordinates = numerix.concatenate((coordinates, shiftedCoords)) from .lines import _getOrderedLines lines = _getOrderedLines(list(range(2 * len(IDs))), coordinates, thresholdDistance = self.distanceVar.mesh._cellDistances.min() * 10) data = numerix.take(self.surfactantVar, IDs) data = numerix.concatenate((data, data)) tmpIDs = numerix.nonzero(data > 0.0001)[0] if len(tmpIDs) > 0: val = numerix.take(data, tmpIDs).min() else: val = 0.0001 data = numerix.where(data < 0.0001, val, data) for line in lines: if len(line) > 2: for smooth in range(self.smooth): for arr in (coordinates, data): tmp = numerix.take(arr, line) tmp[1:-1] = tmp[2:] * 0.25 + tmp[:-2] * 0.25 + tmp[1:-1] * 0.5 if len(arr.shape) > 1: for i in range(len(arr[0])): arrI = arr[:, i].copy() numerix.put(arrI, line, tmp[:, i]) arr[:, i] = arrI else: numerix.put(arrI, line, tmp) name = self.title name = name.strip() if name == '': name = None coords = numerix.zeros((coordinates.shape[0], 3), 'd') coords[:, :coordinates.shape[1]] = coordinates import pyvtk ## making lists as pyvtk doesn't know what to do with numpy arrays coords = list(coords) coords = [[float(coord[0]), float(coord[1]), float(coord[2])] for coord in coords] data = list(data) data = [float(item) for item in data] return (pyvtk.UnstructuredGrid(points = coords, poly_line = lines), pyvtk.PointData(pyvtk.Scalars(data, name = name)))
def logs_to_signed(v, plus, minus): v = numerix.where(v > 0, plus, -minus) v = numerix.where(numerix.isnan(v), 0., v) return v
def signed_to_logs(v): return (numerix.where(v > 0, numerix.log10(v), numerix.nan), numerix.where(v < 0, numerix.log10(-v), numerix.nan))
def _calcValue(self): P = self.P.numericValue alpha = numerix.where(P > 0., 1., 0.) return PhysicalField(value=alpha)
nx = 50 valueLeft = 0. fluxRight = 1. timeStepDuration = 1. L = 1. dx = L / nx mesh = Grid1D(dx = dx, nx = nx) var = CellVariable( name = "solution variable", mesh = mesh, value = valueLeft) x = mesh.getFaceCenters()[:,0] middleFaces = numerix.logical_or(x < L / 4.,x >= 3. * L / 4.) diffCoeff = numerix.where(middleFaces, 1., 0.1) boundaryConditions=(FixedValue(mesh.getFacesLeft(),valueLeft), FixedFlux(mesh.getFacesRight(),fluxRight)) if __name__ == '__main__': import fipy.viewers viewer = fipy.viewers.make(vars = var, limits = {'datamax': L + 18. * L / 4.}) viewer.plot() raw_input('finished')
def _calcValue(self): areas = numerix.array( self.surfactantVar.distanceVar.cellInterfaceAreas) areas = numerix.where(areas > 1e-20, areas, 1) return numerix.array( self.surfactantVar) * self.mesh.cellVolumes / areas