Example #1
0
def CylindricalGrid2D(dr=None, dz=None,
                      nr=None, nz=None,
                      Lr=None, Lz=None,
                      dx=1., dy=1.,
                      nx=None, ny=None,
                      Lx=None, Ly=None,
                      origin=((0,),(0,)),
                      overlap=2,
                      communicator=parallelComm):

    r""" Factory function to select between CylindricalUniformGrid2D and
    CylindricalNonUniformGrid2D. If `Lx` is specified the length of
    the domain is always `Lx` regardless of `dx`.

    :Parameters:

      - `dr` or `dx`: grid spacing in the radial direction
      - `dz` or `dy`: grid spacing in the vertical direction
      - `nr` or `nx`: number of cells in the radial direction
      - `nz` or `ny`: number of cells in the vertical direction
      - `Lr` or `Lx`: the domain length in the radial direction
      - `Lz` or `Ly`: the domain length in the vertical direction
      - `origin` : position of the mesh's origin in the form ((x,),(y,))
      - `overlap`: the number of overlapping cells for parallel
        simulations. Generally 2 is adequate. Higher order equations or
        discretizations require more.
      - `communicator`: either `fipy.tools.parallelComm` or
        `fipy.tools.serialComm`. Select `fipy.tools.serialComm` to create a
        serial mesh when running in parallel. Mostly used for test
        purposes.

    """




    if dr is not None:
        dx = dr

    if dz is not None:
        dy = dz


    nx = nr or nx
    ny = nz or ny

    Lx = Lr or Lx
    Ly = Lz or Ly

    if numerix.getShape(dx) == () and numerix.getShape(dy) == ():

        dx, nx = _dnl(dx, nx, Lx)
        dy, ny = _dnl(dy, ny, Ly)
        from fipy.meshes.cylindricalUniformGrid2D import CylindricalUniformGrid2D
        return CylindricalUniformGrid2D(dx=dx, dy=dy, nx=nx or 1, ny=ny or 1, origin=origin, overlap=overlap, communicator=communicator)
    else:
        from fipy.meshes.cylindricalNonUniformGrid2D import CylindricalNonUniformGrid2D
        return CylindricalNonUniformGrid2D(dx=dx, dy=dy, nx=nx, ny=ny, origin=origin, overlap=overlap, communicator=communicator)
Example #2
0
def CylindricalGrid2D(dr=None, dz=None, 
                      nr=None, nz=None, 
                      Lr=None, Lz=None,
                      dx=1., dy=1., 
                      nx=None, ny=None,
                      Lx=None, Ly=None,
                      origin=((0,),(0,)),
                      overlap=2,
                      communicator=parallelComm):

    r""" Factory function to select between CylindricalUniformGrid2D and
    CylindricalNonUniformGrid2D. If `Lx` is specified the length of
    the domain is always `Lx` regardless of `dx`.

    :Parameters:

      - `dr` or `dx`: grid spacing in the radial direction
      - `dz` or `dy`: grid spacing in the vertical direction
      - `nr` or `nx`: number of cells in the radial direction
      - `nz` or `ny`: number of cells in the vertical direction
      - `Lr` or `Lx`: the domain length in the radial direction
      - `Lz` or `Ly`: the domain length in the vertical direction
      - `origin` : position of the mesh's origin in the form ((x,),(y,))
      - `overlap`: the number of overlapping cells for parallel
        simulations. Generally 2 is adequate. Higher order equations or
        discretizations require more.
      - `communicator`: either `fipy.tools.parallelComm` or
        `fipy.tools.serialComm`. Select `fipy.tools.serialComm` to create a
        serial mesh when running in parallel. Mostly used for test
        purposes.
    
    """




    if dr is not None:
        dx = dr

    if dz is not None:
        dy = dz


    nx = nr or nx
    ny = nz or ny

    Lx = Lr or Lx
    Ly = Lz or Ly
    
    if numerix.getShape(dx) == () and numerix.getShape(dy) == ():

        dx, nx = _dnl(dx, nx, Lx)
        dy, ny = _dnl(dy, ny, Ly)
        from fipy.meshes.cylindricalUniformGrid2D import CylindricalUniformGrid2D
        return CylindricalUniformGrid2D(dx=dx, dy=dy, nx=nx or 1, ny=ny or 1, origin=origin, overlap=overlap, communicator=communicator)
    else:
        from fipy.meshes.cylindricalNonUniformGrid2D import CylindricalNonUniformGrid2D
        return CylindricalNonUniformGrid2D(dx=dx, dy=dy, nx=nx, ny=ny, origin=origin, overlap=overlap, communicator=communicator)
Example #3
0
    def _calcGeomCoeff(self, var):

        mesh = var.mesh
        if self.nthCoeff is not None:

            coeff = self.nthCoeff

            shape = numerix.getShape(coeff)

            if isinstance(coeff, FaceVariable):
                rank = coeff.rank
            else:
                rank = len(shape)

            if var.rank == 0:
                anisotropicRank = rank
            elif var.rank == 1:
                anisotropicRank = rank - 2
            else:
                raise IndexError('the solution variable has the wrong rank')

            if anisotropicRank == 0 and self._treatMeshAsOrthogonal(mesh):

                if coeff.shape != () and not isinstance(coeff, FaceVariable):
                    coeff = coeff[..., numerix.newaxis]

                tmpBop = (coeff *
                          FaceVariable(mesh=mesh, value=mesh._faceAreas) /
                          mesh._cellDistances)[numerix.newaxis, :]

            else:

                if anisotropicRank == 1 or anisotropicRank == 0:
                    coeff = coeff * numerix.identity(mesh.dim)

                if anisotropicRank > 0:
                    shape = numerix.getShape(coeff)
                    if mesh.dim != shape[0] or mesh.dim != shape[1]:
                        raise IndexError(
                            'diffusion coefficient tensor is not an appropriate shape for this mesh'
                        )

                faceNormals = FaceVariable(mesh=mesh,
                                           rank=1,
                                           value=mesh.faceNormals)
                rotationTensor = self.__getRotationTensor(mesh)
                rotationTensor[:,
                               0] = rotationTensor[:, 0] / mesh._cellDistances

                tmpBop = faceNormals.dot(coeff).dot(
                    rotationTensor) * mesh._faceAreas

            return tmpBop

        else:

            return None
Example #4
0
def Grid2D(dx=1.,
           dy=1.,
           nx=None,
           ny=None,
           Lx=None,
           Ly=None,
           overlap=2,
           communicator=parallelComm):
    r""" Factory function to select between UniformGrid2D and
    NonUniformGrid2D.  If `Lx` is specified the length of the domain
    is always `Lx` regardless of `dx`.

    :Parameters:

        - `dx`: grid spacing in the horizontal direction
        - `dy`: grid spacing in the vertical direction
        - `nx`: number of cells in the horizontal direction
        - `ny`: number of cells in the vertical direction
        - `Lx`: the domain length in the horizontal direction
        - `Ly`: the domain length in the vertical direction
        - `overlap`: the number of overlapping cells for parallel
          simulations. Generally 2 is adequate. Higher order equations or
          discretizations require more.
        - `communicator`: either `fipy.tools.parallelComm` or
          `fipy.tools.serialComm`. Select `fipy.tools.serialComm` to create a
          serial mesh when running in parallel. Mostly used for test
          purposes.

    >>> print(Grid2D(Lx=3., nx=2).dx)
    1.5

    """

    if numerix.getShape(dx) == () and numerix.getShape(dy) == ():

        dx, nx = _dnl(dx, nx, Lx)
        dy, ny = _dnl(dy, ny, Ly)

        from fipy.meshes.uniformGrid2D import UniformGrid2D
        return UniformGrid2D(dx=dx,
                             dy=dy,
                             nx=nx,
                             ny=ny,
                             overlap=overlap,
                             communicator=communicator)
    else:
        from fipy.meshes.nonUniformGrid2D import NonUniformGrid2D
        return NonUniformGrid2D(dx=dx,
                                dy=dy,
                                nx=nx,
                                ny=ny,
                                overlap=overlap,
                                communicator=communicator)
Example #5
0
    def _calcGeomCoeff(self, var):

        mesh = var.mesh
        if self.nthCoeff is not None:
          
            coeff = self.nthCoeff

            shape = numerix.getShape(coeff)

            if isinstance(coeff, FaceVariable):
                rank = coeff.rank
            else:
                rank = len(shape)

            if var.rank == 0:
                anisotropicRank = rank
            elif var.rank == 1:
                anisotropicRank = rank - 2
            else:
                raise IndexError, 'the solution variable has the wrong rank'
                
            if anisotropicRank == 0 and self._treatMeshAsOrthogonal(mesh):
                
                if coeff.shape != () and not isinstance(coeff, FaceVariable):
                    coeff = coeff[...,numerix.newaxis]

                tmpBop = (coeff * FaceVariable(mesh=mesh, value=mesh._faceAreas) / mesh._cellDistances)[numerix.newaxis, :]

            else:

                if anisotropicRank == 1 or anisotropicRank == 0:
                    coeff = coeff * numerix.identity(mesh.dim)
                
                if anisotropicRank > 0:
                    shape = numerix.getShape(coeff)
                    if mesh.dim != shape[0] or mesh.dim != shape[1]:
                        raise IndexError, 'diffusion coefficent tensor is not an appropriate shape for this mesh'          
                    
                faceNormals = FaceVariable(mesh=mesh, rank=1, value=mesh.faceNormals)
                rotationTensor = self.__getRotationTensor(mesh)
                rotationTensor[:,0] = rotationTensor[:,0] / mesh._cellDistances

                tmpBop = faceNormals.dot(coeff).dot(rotationTensor) * mesh._faceAreas

            return tmpBop

        else:

            return None
Example #6
0
    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()
Example #7
0
def Grid1D(dx=1., nx=None, Lx=None, overlap=2, communicator=parallelComm):
    r""" Factory function to select between UniformGrid1D and
    NonUniformGrid1D.  If `Lx` is specified the length of the domain
    is always `Lx` regardless of `dx`.

    :Parameters:

      - `dx`: grid spacing in the horizonal direction
      - `nx`: number of cells in the horizonal direction
      - `Lx`: the domain length in the horizonal direction
      - `overlap`: the number of overlapping cells for parallel
        simulations. Generally 2 is adequate. Higher order equations or
        discretizations require more.
      - `communicator`: either `fipy.tools.parallelComm` or
        `fipy.tools.serialComm`. Select `fipy.tools.serialComm` to create a
        serial mesh when running in parallel. Mostly used for test
        purposes.
    
    """

    if numerix.getShape(dx) == ():
        dx, nx = _dnl(dx, nx, Lx)
        from fipy.meshes.uniformGrid1D import UniformGrid1D
        return UniformGrid1D(dx=dx, nx=nx, overlap=overlap, communicator=communicator)
    else:
        from fipy.meshes.nonUniformGrid1D import NonUniformGrid1D
        return NonUniformGrid1D(dx=dx, nx=nx, overlap=overlap, communicator=communicator)
Example #8
0
    def __init__(self, dx=1., nx=None, overlap=2, communicator=parallel):
        self.args = {
            'dx': dx, 
            'nx': nx, 
            'overlap': overlap
        }

        from fipy.tools.dimensions.physicalField import PhysicalField
        self.dx = PhysicalField(value=dx)
        scale = PhysicalField(value=1, unit=self.dx.getUnit())
        self.dx /= scale
        
        nx = self._calcNumPts(d=self.dx, n=nx)

        (self.nx,
         self.overlap,
         self.offset) = self._calcParallelGridInfo(nx, overlap, communicator)

        if numerix.getShape(self.dx) is not ():
            Xoffset = numerix.sum(self.dx[0:self.offset])
            self.dx = self.dx[self.offset:self.offset + self.nx]
        else:
            Xoffset = self.dx * self.offset
            
        vertices = self._createVertices() + ((Xoffset,),)
        self.numberOfVertices = len(vertices[0])
        faces = self._createFaces()
        self.numberOfFaces = len(faces[0])
        cells = self._createCells()
        Mesh1D.__init__(self, vertices, faces, cells, communicator=communicator)
        
        self.setScale(value = scale)
Example #9
0
 def _checkDt(self, dt):
     if dt is None:
         raise TypeError, "`dt` must be specified."
     if numerix.getShape(dt) != ():
         raise TypeError, "`dt` must be a single number, not a " + type(
             dt).__name__
     return float(dt)
Example #10
0
def Grid2D(dx=1., dy=1., nx=None, ny=None, overlap=2, communicator=parallel):
    from numMesh import uniformGrid2D
    from numMesh import grid2D

    from fipy.tools import numerix
    if numerix.getShape(dx) == () and numerix.getShape(dy) == ():
        if nx is None:
            nx = 1
        if ny is None:
            ny = 1
        return uniformGrid2D.UniformGrid2D(dx=dx, dy=dy, 
                                           nx=nx, ny=ny,
                                           overlap=overlap,
                                           communicator=communicator)
    else:
        return grid2D.Grid2D(dx=dx, dy=dy, nx=nx, ny=ny, overlap=overlap, communicator=communicator)
Example #11
0
    def __buildMatrix(self, var, solver, boundaryConditions, dt):
        if numerix.sctype2char(var.getsctype()) not in numerix.typecodes['Float']:
            import warnings
            warnings.warn("""sweep() or solve() are likely to produce erroneous results when `var` does not contain floats.""",
                          UserWarning, stacklevel=4)
        
        self._verifyCoeffType(var)
        
        if numerix.getShape(dt) != ():
            raise TypeError, "`dt` must be a single number, not a " + type(dt).__name__
        dt = float(dt)
    
        if type(boundaryConditions) not in (type(()), type([])):
            boundaryConditions = (boundaryConditions,)

        for bc in boundaryConditions:
            bc._resetBoundaryConditionApplied()

        if os.environ.has_key('FIPY_DISPLAY_MATRIX'):
            if not hasattr(self, "_viewer"):
                from fipy.viewers.matplotlibViewer.matplotlibSparseMatrixViewer import MatplotlibSparseMatrixViewer
                Term._viewer = MatplotlibSparseMatrixViewer()

        matrix, RHSvector = self._buildMatrix(var, solver._getMatrixClass(), boundaryConditions, dt)
        
        solver._storeMatrix(var=var, matrix=matrix, RHSvector=RHSvector)
        
        if os.environ.has_key('FIPY_DISPLAY_MATRIX'):
            self._viewer.title = "%s %s" % (var.name, self.__class__.__name__)
            self._viewer.plot(matrix=matrix, RHSvector=RHSvector)
            from fipy import raw_input
            raw_input()
Example #12
0
    def calcDOffsets(ds, ns, offset):
        """
        :Parameters:
            - `ds`: A list, e.g. [dx, dy]
            - `ns`: A list, e.g. [nx, ny, nz]
            - `offset`

        :Returns:
            - `offsetList`: a list which contains the analogous scalars to
              `XOffset`, `YOffset`, and `ZOffset`, whichever are applicable for
              the dimensionality.
            - `newDs`: a list containing proper [dx, [dy, ...]] values
        """
        offsetList = []
        newDs = []

        if type(offset) in [int, float]:
            offset = [offset]

        for d, n, i in zip(ds, ns, list(range(len(ds)))):
            if numerix.getShape(d) is not ():
                offsetList.append(numerix.sum(d[0:offset[i]]))
                newDs.append(d[offset[i]:offset[i] + n])
            else:
                if len(offset) == 1:
                    offsetList.append(d * offset[0])
                else:
                    offsetList.append(d * offset[i])

                newDs.append(d)

        return offsetList, newDs
Example #13
0
    def _shapeClassAndOther(self, opShape, operatorClass, other):
        """
        Determine the shape of the result, the base class of the result, and (if
        necessary) a modified form of `other` that is suitable for the
        operation.
        
        By default, returns the result of the generic
        `Variable._shapeClassAndOther()`, but if that fails, and if each
        dimension of `other` is exactly the `Mesh` dimension, do what the user
        probably "meant" and project `other` onto the `Mesh`.
        
        >>> from fipy import *
        >>> mesh = Grid1D(nx=5)
        >>> A = numerix.arange(5)
        >>> B = Variable(1.)
        >>> import warnings
        >>> savedFilters = list(warnings.filters)
        >>> warnings.resetwarnings()
        >>> warnings.simplefilter("error", UserWarning, append=True)
        >>> C = CellVariable(mesh=mesh) * (A * B)
        Traceback (most recent call last):
          ...
        UserWarning: The expression `(multiply([0 1 2 3 4], Variable(value=array(1.0))))` has been cast to a constant `CellVariable`
        >>> warnings.filters = savedFilters
        """
        otherShape = numerix.getShape(other)
        if (not isinstance(other, _MeshVariable) and otherShape is not ()
                and otherShape[-1] == self._globalNumberOfElements):
            if (isinstance(other, Variable)
                    and len(other.requiredVariables) > 0):
                import warnings
                warnings.warn(
                    "The expression `%s` has been cast to a constant `%s`" %
                    (repr(other), self._variableClass.__name__),
                    UserWarning,
                    stacklevel=4)
            other = self._variableClass(value=other, mesh=self.mesh)

        newOpShape, baseClass, newOther = Variable._shapeClassAndOther(
            self, opShape, operatorClass, other)

        if ((newOpShape is None or baseClass is None) and numerix.alltrue(
                numerix.array(numerix.getShape(other)) == self.mesh.dim)):
            newOpShape, baseClass, newOther = Variable._shapeClassAndOther(
                self, opShape, operatorClass, other[..., numerix.newaxis])

        return (newOpShape, baseClass, newOther)
Example #14
0
 def setValue(self, value, unit = None, where = None):
     if where is not None:
         shape = numerix.getShape(where)
         if shape != self.shape \
           and shape == self._getShapeFromMesh(mesh=self.getMesh()):
             for dim in self.elementshape:
                 where = numerix.repeat(where[numerix.newaxis, ...], repeats=dim, axis=0)
     
     return Variable.setValue(self, value=value, unit=unit, where=where)
Example #15
0
    def _shapeClassAndOther(self, opShape, operatorClass, other):
        """
        Determine the shape of the result, the base class of the result, and (if
        necessary) a modified form of `other` that is suitable for the
        operation.
        
        By default, returns the result of the generic
        `Variable._shapeClassAndOther()`, but if that fails, and if each
        dimension of `other` is exactly the `Mesh` dimension, do what the user
        probably "meant" and project `other` onto the `Mesh`.
        
        >>> from fipy import *
        >>> mesh = Grid1D(nx=5)
        >>> A = numerix.arange(5)
        >>> B = Variable(1.)
        >>> import warnings
        >>> savedFilters = list(warnings.filters)
        >>> warnings.resetwarnings()
        >>> warnings.simplefilter("error", UserWarning, append=True)
        >>> C = CellVariable(mesh=mesh) * (A * B)
        Traceback (most recent call last):
          ...
        UserWarning: The expression `(multiply([0 1 2 3 4], Variable(value=array(1.0))))` has been cast to a constant `CellVariable`
        >>> warnings.filters = savedFilters
        """
        otherShape = numerix.getShape(other)
        if (not isinstance(other, _MeshVariable) 
            and otherShape is not () 
            and otherShape[-1] == self._globalNumberOfElements):
            if (isinstance(other, Variable) and len(other.requiredVariables) > 0):
                import warnings
                warnings.warn("The expression `%s` has been cast to a constant `%s`" 
                              % (repr(other), self._variableClass.__name__), 
                              UserWarning, stacklevel=4)
            other = self._variableClass(value=other, mesh=self.mesh)

        newOpShape, baseClass, newOther = Variable._shapeClassAndOther(self, opShape, operatorClass, other)
        
        if ((newOpShape is None or baseClass is None)
            and numerix.alltrue(numerix.array(numerix.getShape(other)) == self.mesh.dim)):
                newOpShape, baseClass, newOther = Variable._shapeClassAndOther(self, opShape, operatorClass, other[..., numerix.newaxis])

        return (newOpShape, baseClass, newOther)
Example #16
0
File: grid1D.py Project: regmi/fipy
def Grid1D(dx=1., nx=None, overlap=2, parallelModule=parallel):
    from numMesh import uniformGrid1D
    from numMesh import grid1D
    
    from fipy.tools import numerix
    if numerix.getShape(dx) == ():
        if nx is None:
            nx = 1
        return uniformGrid1D.UniformGrid1D(dx=dx, nx=nx, overlap=overlap, parallelModule=parallelModule)
    else:
        return grid1D.Grid1D(dx=dx, nx=nx, overlap=overlap, parallelModule=parallelModule)
Example #17
0
File: grid3D.py Project: regmi/fipy
def Grid3D(dx = 1., dy = 1., dz = 1., nx = None, ny = None, nz = None, overlap=2, parallelModule=parallel):
    from numMesh import uniformGrid3D
    from numMesh import grid3D

    from fipy.tools import numerix
    if numerix.getShape(dx) == () \
      and numerix.getShape(dy) == () \
      and numerix.getShape(dz) == ():
        if nx is None:
            nx = 1
        if ny is None:
            ny = 1
        if nz is None:
            nz = 1
        return uniformGrid3D.UniformGrid3D(dx = dx, dy = dy, dz = dz,
                                           nx = nx or 1, ny = ny or 1, nz = nz or 1,
                                           overlap=overlap, parallelModule=parallelModule)
    else:
        return grid3D.Grid3D(dx = dx, dy = dy, dz = dz, nx = nx, ny = ny, nz = nz,
                             overlap=overlap, parallelModule=parallelModule)
Example #18
0
    def setValue(self, value, unit=None, where=None):
        if where is not None:
            shape = numerix.getShape(where)
            if shape != self.shape \
              and shape == self._getShapeFromMesh(mesh=self.mesh):
                for dim in self.elementshape:
                    where = numerix.repeat(where[numerix.newaxis, ...],
                                           repeats=dim,
                                           axis=0)

        return Variable.setValue(self, value=value, unit=unit, where=where)
Example #19
0
def CylindricalGrid1D(dr=None,
                      nr=None,
                      Lr=None,
                      dx=1.,
                      nx=None,
                      Lx=None,
                      origin=(0, ),
                      overlap=2,
                      communicator=parallelComm):
    r""" Factory function to select between `CylindricalUniformGrid1D` and
    `CylindricalNonUniformGrid1D`. If `Lr` is specified the length of the
    domain is always `Lr` regardless of `dr`, unless `dr` is a list of
    spacings, in which case `Lr` will be the sum of `dr`.

    Parameters
    ----------
    dr : float
        Grid spacing in the radial direction. Alternative: `dx`.
    nr : int
        Number of cells in the radial direction. Alternative: `nx`.
    Lr : float
        Domain length in the radial direction. Alternative: `Lx`.
    overlap : int
        the number of overlapping cells for parallel
        simulations. Generally 2 is adequate. Higher order equations or
        discretizations require more.
    communicator : ~fipy.tools.comms.commWrapper.CommWrapper
        Generally, `fipy.tools.serialComm` or `fipy.tools.parallelComm`.
        Select `~fipy.tools.serialComm` to create a serial mesh when
        running in parallel; mostly used for test purposes.
    """

    if dr is not None:
        dx = dr

    nx = nr or nx
    Lx = Lr or Lx

    if numerix.getShape(dx) == ():
        dx, nx = _dnl(dx, nx, Lx)
        from fipy.meshes.cylindricalUniformGrid1D import CylindricalUniformGrid1D
        return CylindricalUniformGrid1D(dx=dx,
                                        nx=nx or 1,
                                        origin=origin,
                                        overlap=overlap,
                                        communicator=parallelComm)
    else:
        from fipy.meshes.cylindricalNonUniformGrid1D import CylindricalNonUniformGrid1D
        return CylindricalNonUniformGrid1D(dx=dx,
                                           nx=nx,
                                           origin=origin,
                                           overlap=overlap,
                                           communicator=parallelComm)
Example #20
0
def CylindricalGrid1D(dr=None, nr=None, dx=1., nx=None):
    from numMesh import cylindricalUniformGrid1D
    from numMesh import cylindricalGrid1D

    from fipy.tools import numerix

    if dr is not None:
        dx = dr
        
    nx = nr or nx

    if numerix.getShape(dx) == ():
        return cylindricalUniformGrid1D.CylindricalUniformGrid1D(dx=dx, nx=nx or 1)
    else:
        return cylindricalGrid1D.CylindricalGrid1D(dx=dx, nx=nx)
Example #21
0
    def _calcGeomCoeff(self, mesh):
        if self.nthCoeff is not None:
          
            coeff = self.nthCoeff
            shape = numerix.getShape(coeff)

            from fipy.variables.faceVariable import FaceVariable
            if isinstance(coeff, FaceVariable):
                rank = coeff.getRank()
            else:
                rank = len(shape)

            if rank == 0 and self._treatMeshAsOrthogonal(mesh):
                tmpBop = (coeff * mesh._getFaceAreas() / mesh._getCellDistances())[numerix.newaxis, :]

            else:

                if rank == 1 or rank == 0:
                    coeff = coeff * numerix.identity(mesh.getDim())

                if rank > 0:
                    shape = numerix.getShape(coeff)
                    if mesh.getDim() != shape[0] or mesh.getDim() != shape[1]:
                        raise IndexError, 'diffusion coefficent tensor is not an appropriate shape for this mesh'          

                faceNormals = FaceVariable(mesh=mesh, rank=1, value=mesh._getFaceNormals())
                rotationTensor = self._getRotationTensor(mesh)
                rotationTensor[:,0] = rotationTensor[:,0] / mesh._getCellDistances()
                
                tmpBop = faceNormals.dot(coeff).dot(rotationTensor) * mesh._getFaceAreas()

            return tmpBop

        else:

            return None
Example #22
0
    def _shapeClassAndOther(self, opShape, operatorClass, other):
        """
        Determine the shape of the result, the base class of the result, and (if
        necessary) a modified form of `other` that is suitable for the
        operation.
        
        By default, returns the result of the generic
        `Variable._shapeClassAndOther()`, but if that fails, and if each
        dimension of `other` is exactly the `Mesh` dimension, do what the user
        probably "meant" and project `other` onto the `Mesh`.
        """
        otherShape = numerix.getShape(other)
        if (not isinstance(other, _MeshVariable) 
            and otherShape is not () 
            and otherShape[-1] == self._getGlobalNumberOfElements()):
            other = self._getVariableClass()(value=other, mesh=self.getMesh())

        newOpShape, baseClass, newOther = Variable._shapeClassAndOther(self, opShape, operatorClass, other)
        
        if ((newOpShape is None or baseClass is None)
            and numerix.alltrue(numerix.array(numerix.getShape(other)) == self.getMesh().getDim())):
                newOpShape, baseClass, newOther = Variable._shapeClassAndOther(self, opShape, operatorClass, other[..., numerix.newaxis])

        return (newOpShape, baseClass, newOther)
Example #23
0
def CylindricalGrid2D(dr=None, dz=None, nr=None, nz=None, dx=1., dy=1., nx=None, ny=None, parallelModule=parallel):
    from numMesh import cylindricalUniformGrid2D
    from numMesh import cylindricalGrid2D

    from fipy.tools import numerix

    if dr is not None:
        dx = dr

    if dz is not None:
        dy = dz

    nx = nr or nx
    ny = nz or ny

    if dx is None:
        dx = 1.
    if dy is None:
        dy = 1.
    
    if numerix.getShape(dx) == () and numerix.getShape(dy) == ():
        return cylindricalUniformGrid2D.CylindricalUniformGrid2D(dx=dx, dy=dy, nx=nx or 1, ny=ny or 1, parallelModule=parallelModule)
    else:
        return cylindricalGrid2D.CylindricalGrid2D(dx=dx, dy=dy, nx=nx, ny=ny, parallelModule=parallelModule)
Example #24
0
 def getShape(self):
     """
         >>> Variable(value=3).shape
         ()
         >>> Variable(value=(3,)).shape
         (1,)
         >>> Variable(value=(3,4)).shape
         (2,)
         
         >>> Variable(value="3 m").shape
         ()
         >>> Variable(value=(3,), unit="m").shape
         (1,)
         >>> Variable(value=(3,4), unit="m").shape
         (2,)
     """
     if self.value is not None:
         return numerix.getShape(self.value)
     else:
         return ()
Example #25
0
    def calcDOffsets(ds, ns, offset):
        """
        Parameters
        ----------
        ds : list
            Spacing in each grid direction, e.g. `[dx, dy]`
        ns : list
            Number of grid spacings in each direction, e.g. `[nx, ny]`
        offset : list
            Displacement of grid spacings, e.g., `[Ox, Oy]`

        Returns
        -------
        offsetList : list
            Contains the analogous scalars to `XOffset`, `YOffset`, and
            `ZOffset`, whichever are applicable for the dimensionality.
        newDs : list
            proper `[dx, [dy, ...]]` values
        """
        offsetList = []
        newDs = []

        if type(offset) in [int, float]:
            offset = [offset]

        for d, n, i in zip(ds, ns, list(range(len(ds)))):
            if numerix.getShape(d) is not ():
                offsetList.append(numerix.sum(d[0:offset[i]]))
                newDs.append(d[offset[i]:offset[i] + n])
            else:
                if len(offset) == 1:
                    offsetList.append(d * offset[0])
                else:
                    offsetList.append(d * offset[i])

                newDs.append(d)

        return offsetList, newDs
Example #26
0
def Grid1D(dx=1., nx=None, Lx=None, overlap=2, communicator=parallelComm):
    r""" Factory function to select between `UniformGrid1D` and
    `NonUniformGrid1D`. If `Lx` is specified the length of the domain is
    always `Lx` regardless of `dx`, unless `dx` is a list of spacings, in
    which case `Lx` will be the sum of `dx` and `nx` will be the count of
    `dx`.

    Parameters
    ----------
    dx : float
        Grid spacing in the horizontal direction
    nx : int
        Number of cells in the horizontal direction
    Lx : float
        Domain length in the horizontal direction
    overlap : int
        Number of overlapping cells for parallel simulations.  Generally 2
        is adequate.  Higher order equations or discretizations require
        more.
    communicator : ~fipy.tools.comms.commWrapper.CommWrapper
        Generally, `fipy.tools.serialComm` or `fipy.tools.parallelComm`.
        Select `~fipy.tools.serialComm` to create a serial mesh when
        running in parallel; mostly used for test purposes.
    """

    if numerix.getShape(dx) == ():
        dx, nx = _dnl(dx, nx, Lx)
        from fipy.meshes.uniformGrid1D import UniformGrid1D
        return UniformGrid1D(dx=dx,
                             nx=nx,
                             overlap=overlap,
                             communicator=communicator)
    else:
        from fipy.meshes.nonUniformGrid1D import NonUniformGrid1D
        return NonUniformGrid1D(dx=dx,
                                nx=nx,
                                overlap=overlap,
                                communicator=communicator)
Example #27
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)
Example #28
0
File: grid2D.py Project: regmi/fipy
    def __init__(self, dx=1., dy=1., nx=None, ny=None, overlap=2, parallelModule=parallel):
        
        self.args = {
            'dx': dx, 
            'dy': dy, 
            'nx': nx, 
            'ny': ny, 
            'overlap': overlap,
            'parallelModule': parallelModule
        }

        self.dx = PhysicalField(value = dx)
        scale = PhysicalField(value=1, unit=self.dx.getUnit())
        self.dx /= scale
        
        nx = self._calcNumPts(d=self.dx, n=nx, axis="x")
        
        self.dy = PhysicalField(value = dy)
        if self.dy.getUnit().isDimensionless():
            self.dy = dy
        else:
            self.dy /= scale
            
        ny = self._calcNumPts(d=self.dy, n=ny, axis="y")
        
        (self.nx,
         self.ny,
         self.overlap,
         self.offset) = self._calcParallelGridInfo(nx, ny, overlap, parallelModule)

        if numerix.getShape(self.dx) is not ():
            Xoffset = numerix.sum(self.dx[0:self.offset[0]])
            self.dx = self.dx[self.offset[0]:self.offset[0] + self.nx]
        else:
            Xoffset = 0

        if numerix.getShape(self.dy) is not ():
            Yoffset =  numerix.sum(self.dy[0:self.offset[1]])
            self.dy = self.dy[self.offset[1]:self.offset[1] + self.ny]
        else:
            Yoffset = 0
            
        if self.nx == 0:
            self.ny = 0
        if self.ny == 0:
            self.nx = 0
        if self.nx == 0 or self.ny == 0:
            self.numberOfHorizontalRows = 0
            self.numberOfVerticalColumns = 0
        else:
            self.numberOfHorizontalRows = (self.ny + 1)
            self.numberOfVerticalColumns = (self.nx + 1)

        self.numberOfVertices = self.numberOfHorizontalRows * self.numberOfVerticalColumns

        vertices = self._createVertices() + ((Xoffset,), (Yoffset,))
        faces = self._createFaces()
        self.numberOfFaces = len(faces[0])
        cells = self._createCells()
        Mesh2D.__init__(self, vertices, faces, cells)
        
        self.setScale(value = scale)
Example #29
0
 def _checkDt(self, dt):
     if dt is None:
         raise TypeError("`dt` must be specified.")
     if numerix.getShape(dt) != ():
         raise TypeError("`dt` must be a single number, not a " + type(dt).__name__)
     return float(dt)
Example #30
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)
Example #31
0
    def __init__(self, dx = 1., dy = 1., dz = 1., nx = None, ny = None, nz = None, overlap=2, communicator=parallel):
        
        self.args = {
            'dx': dx, 
            'dy': dy,
            'dz' :dz,
            'nx': nx, 
            'ny': ny,
            'nz': nz,
            'overlap': overlap,
            'communicator': communicator
        }
        
        self.dx = PhysicalField(value = dx)
        scale = PhysicalField(value = 1, unit = self.dx.getUnit())
        self.dx /= scale
        
        nx = self._calcNumPts(d = self.dx, n = nx, axis = "x")
        
        self.dy = PhysicalField(value = dy)
        if self.dy.getUnit().isDimensionless():
            self.dy = dy
        else:
            self.dy /= scale

        ny = self._calcNumPts(d = self.dy, n = ny, axis = "y")
        
        self.dz = PhysicalField(value = dz)
        if self.dz.getUnit().isDimensionless():
            self.dz = dz
        else:
            self.dz /= scale
        
        nz = self._calcNumPts(d = self.dz, n = nz, axis = "z")

        (self.nx,
         self.ny,
         self.nz,
         self.overlap,
         self.offset) = self._calcParallelGridInfo(nx, ny, nz, overlap, communicator)

        if numerix.getShape(self.dx) is not ():
            Xoffset = numerix.sum(self.dx[0:self.offset[0]])
            self.dx = self.dx[self.offset[0]:self.offset[0] + self.nx]
        else:
            Xoffset = 0

        if numerix.getShape(self.dy) is not ():
            Yoffset =  numerix.sum(self.dy[0:self.offset[1]])
            self.dy = self.dy[self.offset[1]:self.offset[1] + self.ny]
        else:
            Yoffset = 0

        if numerix.getShape(self.dy) is not ():
            Zoffset =  numerix.sum(self.dz[0:self.offset[2]])
            self.dz = self.dz[self.offset[2]:self.offset[2] + self.nz]
        else:
            Zoffset = 0

        if self.nx == 0 or self.ny == 0 or self.nz == 0:
            self.nx = 0
            self.ny = 0
            self.nz = 0

        if self.nx == 0 or self.ny == 0 or self.nz == 0:
            self.numberOfHorizontalRows = 0
            self.numberOfVerticalColumns = 0
            self.numberOfLayersDeep = 0
        else:
            self.numberOfHorizontalRows = (self.ny + 1)
            self.numberOfVerticalColumns = (self.nx + 1)
            self.numberOfLayersDeep = (self.nz + 1)
            
        self.numberOfVertices = self.numberOfHorizontalRows * self.numberOfVerticalColumns * self.numberOfLayersDeep
        
        vertices = self._createVertices() + ((Xoffset,), (Yoffset,), (Zoffset,))
        faces = self._createFaces()
        cells = self._createCells()
        Mesh.__init__(self, vertices, faces, cells)
        
        self.setScale(value = scale)
Example #32
0
 def _checkVar(self, var):
     FaceTerm._checkVar(self, var)
     if not (isinstance(self.coeff, FaceVariable) and self.coeff.rank == 1):
         coeffShape = numerix.getShape(self.coeff)
         if (coeffShape is ()) or (coeffShape[0] != var.mesh.dim):
             raise VectorCoeffError
Example #33
0
def Grid3D(dx=1.,
           dy=1.,
           dz=1.,
           nx=None,
           ny=None,
           nz=None,
           Lx=None,
           Ly=None,
           Lz=None,
           overlap=2,
           communicator=parallelComm):
    r""" Factory function to select between `UniformGrid3D` and
    `NonUniformGrid3D`. If `L{x,y,z}` is specified, the length of the domain
    is always `L{x,y,z}` regardless of `d{x,y,z}`, unless `d{x,y,z}` is a
    list of spacings, in which case `L{x,y,z}` will be the sum of
    `d{x,y,z}` and `n{x,y,z}` will be the count of `d{x,y,z}`.

    Parameters
    ----------
    dx : float
        Grid spacing in the horizontal direction
    dy : float
        Grid spacing in the vertical direction
    dz : float
        Grid spacing in the depth direction
    nx : int
        Number of cells in the horizontal direction
    ny : int
        Number of cells in the vertical direction
    nz : int
        Number of cells in the depth direction
    Lx : float
        Domain length in the horizontal direction
    Ly : float
        Domain length in the vertical direction
    Lz : float
        Domain length in the depth direction
    overlap : int
        Number of overlapping cells for parallel simulations.  Generally 2
        is adequate.  Higher order equations or discretizations require
        more.
    communicator : ~fipy.tools.comms.commWrapper.CommWrapper
        Generally, `fipy.tools.serialComm` or `fipy.tools.parallelComm`.
        Select `~fipy.tools.serialComm` to create a serial mesh when
        running in parallel; mostly used for test purposes.
    """

    if numerix.getShape(dx) == () \
      and numerix.getShape(dy) == () \
      and numerix.getShape(dz) == ():

        dx, nx = _dnl(dx, nx, Lx)
        dy, ny = _dnl(dy, ny, Ly)
        dz, nz = _dnl(dz, nz, Lz)
        from fipy.meshes.uniformGrid3D import UniformGrid3D
        return UniformGrid3D(dx=dx,
                             dy=dy,
                             dz=dz,
                             nx=nx or 1,
                             ny=ny or 1,
                             nz=nz or 1,
                             overlap=overlap,
                             communicator=communicator)
    else:
        from fipy.meshes.nonUniformGrid3D import NonUniformGrid3D
        return NonUniformGrid3D(dx=dx,
                                dy=dy,
                                dz=dz,
                                nx=nx,
                                ny=ny,
                                nz=nz,
                                overlap=overlap,
                                communicator=communicator)
Example #34
0
 def _verifyCoeffType(self, var):
     if not (isinstance(self.coeff, FaceVariable) and self.coeff.getRank() == 1) \
     and numerix.getShape(self.coeff) != (var.getMesh().getDim(),):
         raise TypeError, "The coefficient must be a vector value."
Example #35
0
 def _broadcastShape(self, other):
     ignore, ignore, broadcastshape = numerix._broadcastShapes(self.shape, numerix.getShape(other))
     
     return broadcastshape