def __dot(A, B, operatorClass): """ Workhorse method to return a `_BinaryOperatorVariable` that will dynamically perform the mesh-element--by--mesh-element (cell-by-cell, face-by-face, etc.) scalar product .. math:: \mathsf{A} \cdot \mathsf{B} Both `A` and `B` can be of arbitrary rank, but at this point, both must be appropriately broadcast `_MeshVariable` objects. """ rankA = len(A.shape) - 1 rankB = len(B.shape) - 1 index = (numerix.index_exp[...] + (numerix.newaxis,) * (rankB - 1) + numerix.index_exp[:]) opShape = numerix._broadcastShape(A[index].shape, B.shape) if rankA > 0: opShape = opShape[:rankA-1] + opShape[rankA:] return A._BinaryOperatorVariable(lambda a,b: _MeshVariable._dot(a, b, index), B, opShape=opShape, operatorClass=operatorClass, canInline=False)
def __dot(A, B, operatorClass): """ Workhorse method to return a `_BinaryOperatorVariable` that will dynamically perform the mesh-element--by--mesh-element (cell-by-cell, face-by-face, etc.) scalar product .. math:: \mathsf{A} \cdot \mathsf{B} Both `A` and `B` can be of arbitrary rank, but at this point, both must be appropriately broadcast `_MeshVariable` objects. Test for inline bug >>> from fipy import * >>> m = Grid2D(nx=2, ny=2) >>> v = FaceVariable(mesh=m, rank=1, value=m._orientedFaceNormals) >>> print len(v.dot(1.).shape) 2 >>> print v.dot(1.).globalValue.shape (2, 12) >>> tmp = m._cellDistances * v.dot(1.) >>> print tmp.globalValue.shape (2, 12) The value shouldn't change shape the second time it's evaluated. The second time is inline and the inline code does not have the correct shape. >>> print tmp.globalValue.shape (2, 12) More inconsistent shape problems. >>> m = Grid2D(nx=3, ny=3) >>> v0 = FaceVariable(mesh=m, rank=1, value=m._orientedFaceNormals) >>> print len(v0.dot(m.faceCenters[0]).shape) 2 >>> print v0.dot(m.faceCenters[0]).globalValue.shape (2, 24) """ rankA = len(A.shape) - 1 rankB = len(B.shape) - 1 index = (numerix.index_exp[...] + (numerix.newaxis, ) * (rankB - 1) + numerix.index_exp[:]) opShape = numerix._broadcastShape(A[index].shape, B.shape) if rankA > 0 and rankB > (rankA - 1): opShape = opShape[:rankA - 1] + opShape[rankA:] return A._BinaryOperatorVariable( lambda a, b: _MeshVariable._dot(a, b, index), B, opShape=opShape, operatorClass=operatorClass, canInline=False)
def __dot(A, B, operatorClass): """ Workhorse method to return a `_BinaryOperatorVariable` that will dynamically perform the mesh-element--by--mesh-element (cell-by-cell, face-by-face, etc.) scalar product .. math:: \mathsf{A} \cdot \mathsf{B} Both `A` and `B` can be of arbitrary rank, but at this point, both must be appropriately broadcast `_MeshVariable` objects. Test for inline bug >>> from fipy import * >>> m = Grid2D(nx=2, ny=2) >>> v = FaceVariable(mesh=m, rank=1, value=m._orientedFaceNormals) >>> print len(v.dot(1.).shape) 2 >>> print v.dot(1.).globalValue.shape (2, 12) >>> tmp = m._cellDistances * v.dot(1.) >>> print tmp.globalValue.shape (2, 12) The value shouldn't change shape the second time it's evaluated. The second time is inline and the inline code does not have the correct shape. >>> print tmp.globalValue.shape (2, 12) More inconsistent shape problems. >>> m = Grid2D(nx=3, ny=3) >>> v0 = FaceVariable(mesh=m, rank=1, value=m._orientedFaceNormals) >>> print len(v0.dot(m.faceCenters[0]).shape) 2 >>> print v0.dot(m.faceCenters[0]).globalValue.shape (2, 24) """ rankA = len(A.shape) - 1 rankB = len(B.shape) - 1 index = (numerix.index_exp[...] + (numerix.newaxis,) * (rankB - 1) + numerix.index_exp[:]) opShape = numerix._broadcastShape(A[index].shape, B.shape) if rankA > 0 and rankB > (rankA - 1): opShape = opShape[:rankA-1] + opShape[rankA:] return A._BinaryOperatorVariable(lambda a,b: _MeshVariable._dot(a, b, index), B, opShape=opShape, operatorClass=operatorClass, canInline=False)
def __init__(self, mesh, name='', value=0., rank=None, elementshape=None, unit=None, cached=1): """ :Parameters: - `mesh`: the mesh that defines the geometry of this `Variable` - `name`: the user-readable name of the `Variable` - `value`: the initial value - `rank`: the rank (number of dimensions) of each element of this `Variable`. Default: 0 - `elementshape`: the shape of each element of this variable Default: `rank * (mesh.getDim(),)` - `unit`: the physical units of the `Variable` """ from fipy.tools import debug if isinstance(value, (list, tuple)): value = numerix.array(value) if isinstance(value, _MeshVariable): if mesh is None: mesh = value.mesh elif mesh != value.mesh: raise ValueError, "The new 'Variable' must use the same mesh as the supplied value" self.mesh = mesh value = self._globalToLocalValue(value) if value is None: array = None elif not isinstance(value, _Constant) and isinstance(value, Variable): name = name or value.name unit = None if isinstance(value, _MeshVariable): if not isinstance(value, self._getVariableClass()): raise TypeError, "A '%s' cannot be cast to a '%s'" % (value._getVariableClass().__name__, self._getVariableClass().__name__) if elementshape is not None and elementshape != value.shape[:-1]: raise ValueError, "'elementshape' != shape of elements of 'value'" if rank is not None and rank != value.getRank(): raise ValueError, "'rank' != rank of 'value'" elementshape = value.shape[:-1] array = None # value = value._copyValue() if elementshape is None: valueShape = numerix.getShape(value) if valueShape != () and valueShape[-1] == self._getShapeFromMesh(mesh)[-1]: if elementshape is not None and elementshape != valueShape[:-1]: raise ValueError, "'elementshape' != shape of elements of 'value'" if rank is not None and rank != len(valueShape[:-1]): raise ValueError, "'rank' != rank of 'value'" elementshape = valueShape[:-1] elif rank is None and elementshape is None: elementshape = valueShape if rank is None: if elementshape is None: elementshape = () elif elementshape is None: elementshape = rank * (mesh.getDim(),) elif len(elementshape) != rank: raise ValueError, 'len(elementshape) != rank' self.elementshape = elementshape if not locals().has_key("array"): if numerix._isPhysical(value): dtype = numerix.obj2sctype(value.value) else: dtype = numerix.obj2sctype(value) array = numerix.zeros(self.elementshape + self._getShapeFromMesh(mesh), dtype) if numerix._broadcastShape(array.shape, numerix.shape(value)) is None: if not isinstance(value, Variable): value = _Constant(value) value = value[..., numerix.newaxis] Variable.__init__(self, name=name, value=value, unit=unit, array=array, cached=cached)
def __init__(self, mesh, name='', value=0., rank=None, elementshape=None, unit=None, cached=1): """ :Parameters: - `mesh`: the mesh that defines the geometry of this `Variable` - `name`: the user-readable name of the `Variable` - `value`: the initial value - `rank`: the rank (number of dimensions) of each element of this `Variable`. Default: 0 - `elementshape`: the shape of each element of this variable Default: `rank * (mesh.dim,)` - `unit`: the physical units of the `Variable` """ if isinstance(value, (list, tuple)): value = numerix.array(value) if isinstance(value, _MeshVariable): if mesh is None: mesh = value.mesh elif mesh != value.mesh: raise ValueError, "The new 'Variable' must use the same mesh as the supplied value" self.mesh = mesh value = self._globalToLocalValue(value) if value is None: array = None elif not isinstance(value, _Constant) and isinstance(value, Variable): name = name or value.name unit = None if isinstance(value, _MeshVariable): if not isinstance(value, self._variableClass): raise TypeError, "A '%s' cannot be cast to a '%s'" % ( value._variableClass.__name__, self._variableClass.__name__) if elementshape is not None and elementshape != value.shape[: -1]: raise ValueError, "'elementshape' != shape of elements of 'value'" if rank is not None and rank != value.rank: raise ValueError, "'rank' != rank of 'value'" elementshape = value.shape[:-1] array = None # value = value._copyValue() if elementshape is None: valueShape = numerix.getShape(value) if valueShape != () and valueShape[-1] == self._getShapeFromMesh( mesh)[-1]: if elementshape is not None and elementshape != valueShape[:-1]: raise ValueError, "'elementshape' != shape of elements of 'value'" if rank is not None and rank != len(valueShape[:-1]): raise ValueError, "'rank' != rank of 'value'" elementshape = valueShape[:-1] elif rank is None and elementshape is None: elementshape = valueShape if rank is None: if elementshape is None: elementshape = () elif elementshape is None: elementshape = rank * (mesh.dim, ) elif len(elementshape) != rank: raise ValueError, 'len(elementshape) != rank' self.elementshape = elementshape if not "array" in locals(): if numerix._isPhysical(value): dtype = numerix.obj2sctype(value.value) else: dtype = numerix.obj2sctype(value) #print "meshvariable elshape: ",self.elementshape #print "meshvariable _getShapeFromMesh: ",self._getShapeFromMesh(mesh) array = numerix.zeros( self.elementshape + self._getShapeFromMesh(mesh), dtype) if numerix._broadcastShape(array.shape, numerix.shape(value)) is None: if not isinstance(value, Variable): value = _Constant(value) value = value[..., numerix.newaxis] Variable.__init__(self, name=name, value=value, unit=unit, array=array, cached=cached)