Beispiel #1
0
 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)
Beispiel #2
0
    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)
Beispiel #3
0
    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)
Beispiel #4
0
    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)
Beispiel #5
0
    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)