Esempio n. 1
0
def permeabiltyEngelhardtPitter(poro, q=3.5, s=5e-3,
                                mesh=None, meshI=None):
    r"""
    For sand and sandstones
    
    .. math:: 
        k & = 2\cdot 10^7 \frac{\phi^2}{(1-\phi)^2}* \frac{1}{S^2} \\
        S & = q\cdot s \\
        s & = \sum_{i=1}(\frac{P_i}{r_i})
        
    * :math:`\phi` - poro 0.0 --1.0
    * :math:`S` - in cm^-1  specific surface in cm^2/cm^3
    * :math:`q` - (3 for spheres, > 3 shape differ from sphere)
        3.5 sand
    * :math:`s` - in cm^-1 (s = 1/r for particles with homogeneous radii r)
    * :math:`P_i` - Particle ration with radii :math:`r_i` on 1cm^3 Sample
    
    Returns
    -------
    k :
        in Darcy
    """
    poro = parseArgToArray(poro, mesh.cellCount(), mesh)
    q = parseArgToArray(q, mesh.cellCount(), mesh)
    s = parseArgToArray(s, mesh.cellCount(), mesh)
    
    S = q * s
    k = 2e7 * (poro**2 / (1.0-poro)**2) * 1.0/S**2 * physics.constants.Darcy
        
    if meshI:
        k = pg.interpolate(mesh, k, meshI.cellCenters()) 
        k = pg.solver.fillEmptyToCellArray(meshI, k)
    return k
Esempio n. 2
0
def density(poro, densMatrix=2510, densFluid=1000, satur=1, mesh=None):
    r"""
        densMatrix, densFluid in kg/m^3
    """
    poro = parseArgToArray(poro, mesh.cellCount(), mesh)
    densMatrix = parseArgToArray(densMatrix, mesh.cellCount(), mesh)
    densFluid = parseArgToArray(densFluid, mesh.cellCount(), mesh)
    satur = parseArgToArray(satur, mesh.cellCount(), mesh)

    dens = np.array(densMatrix * (1. - poro)) + densFluid * poro * satur
    return dens
Esempio n. 3
0
def hydraulicConductivity(perm, visc=1.0, dens=1.0, mesh=None, meshI=None):
    perm = parseArgToArray(perm, mesh.cellCount(), mesh)
    visc = parseArgToArray(visc, mesh.cellCount(), mesh)
    dens = parseArgToArray(dens, mesh.cellCount(), mesh)

    k = perm * dens / visc * pg.physics.constants.g

    if meshI:
        k = pg.interpolate(mesh, k, meshI.cellCenters())
        k = pg.solver.fillEmptyToCellArray(meshI, k)
    return k
Esempio n. 4
0
def density(poro, densMatrix=2510, densFluid=1000, satur=1,
            mesh=None):
    r"""
        densMatrix, densFluid in kg/m^3
    """
    poro = parseArgToArray(poro, mesh.cellCount(), mesh)
    densMatrix = parseArgToArray(densMatrix, mesh.cellCount(), mesh)
    densFluid = parseArgToArray(densFluid, mesh.cellCount(), mesh)
    satur = parseArgToArray(satur, mesh.cellCount(), mesh)

    dens = np.array(densMatrix * (1.-poro)) + densFluid * poro * satur
    return dens
Esempio n. 5
0
def hydraulicConductivity(perm, visc=1.0, dens=1.0,
                          mesh=None, meshI=None):
    perm = parseArgToArray(perm, mesh.cellCount(), mesh)
    visc = parseArgToArray(visc, mesh.cellCount(), mesh)
    dens = parseArgToArray(dens, mesh.cellCount(), mesh)
    
    k = perm * dens/visc * pg.physics.constants.g
    
    if meshI:
        k = pg.interpolate(mesh, k, meshI.cellCenters()) 
        k = pg.solver.fillEmptyToCellArray(meshI, k)
    return k
Esempio n. 6
0
def velocityVp(porosity, vMatrix=5000, vFluid=1442, S=1, mesh=None):
    r"""Compute velocity from porosity."""
    porosity = parseArgToArray(porosity, mesh.cellCount(), mesh)
    vMatrix = parseArgToArray(vMatrix, mesh.cellCount(), mesh)
    vFluid = parseArgToArray(vFluid, mesh.cellCount(), mesh)
    S = parseArgToArray(S, mesh.cellCount(), mesh)

    vAir = 343.0
    # better use petrophysics module
    vel = 1. / (np.array(
        (1. - porosity) / vMatrix) + porosity * S / vFluid + porosity *
                (1. - S) / vAir)
    return vel
Esempio n. 7
0
def velocityVp(porosity, vMatrix=5000, vFluid=1442, S=1, mesh=None):
    r"""
    """
    porosity = parseArgToArray(porosity, mesh.cellCount(), mesh)
    vMatrix = parseArgToArray(vMatrix, mesh.cellCount(), mesh)
    vFluid = parseArgToArray(vFluid, mesh.cellCount(), mesh)
    S = parseArgToArray(S, mesh.cellCount(), mesh)

    vAir = 343.0

    vel = 1./(np.array((1.-porosity)/vMatrix) + \
              porosity * S / vFluid + \
              porosity * (1.-S)/vAir)
    return vel
Esempio n. 8
0
def velocityVp(porosity, vMatrix=5000, vFluid=1442, S=1,
               mesh=None):
    r"""Compute velocity from porosity."""
    porosity = parseArgToArray(porosity, mesh.cellCount(), mesh)
    vMatrix = parseArgToArray(vMatrix, mesh.cellCount(), mesh)
    vFluid = parseArgToArray(vFluid, mesh.cellCount(), mesh)
    S = parseArgToArray(S, mesh.cellCount(), mesh)

    vAir = 343.0
    # better use petrophysics module
    vel = 1./(np.array((1.-porosity)/vMatrix) +
              porosity * S / vFluid +
              porosity * (1.-S)/vAir)
    return vel
Esempio n. 9
0
def velocityVp(porosity, vMatrix=5000, vFluid=1442, S=1,
               mesh=None):
    r"""
    """
    porosity = parseArgToArray(porosity, mesh.cellCount(), mesh)
    vMatrix = parseArgToArray(vMatrix, mesh.cellCount(), mesh)
    vFluid = parseArgToArray(vFluid, mesh.cellCount(), mesh)
    S = parseArgToArray(S, mesh.cellCount(), mesh)
    
    vAir = 343.0
    
    vel = 1./(np.array((1.-porosity)/vMatrix) + \
              porosity * S / vFluid + \
              porosity * (1.-S)/vAir)
    return vel
Esempio n. 10
0
def resistivityArchie(rBrine,
                      porosity,
                      a=1.0,
                      m=2.0,
                      S=1.0,
                      n=2.0,
                      mesh=None,
                      meshI=None):
    """
    .. math::
        \rho = a\rho_{\text{Brine}}\phi^{-m}\S_w^{-n}

    * :math:`\rho` - the electrical conductivity of the fluid saturated rock
    * :math:`\rho_{\text{Brine}}` - electrical conductivity of the brine
    * :math:`\phi` - porosity 0.0 --1.0
    * :math:`a` - tortuosity factor. (common 1)
    * :math:`m` - cementation exponent of the rock
            (usually in the range 1.3 -- 2.5 for sandstones)
    * :math:`n` - is the saturation exponent (usually close to 2)

    """
    rB = None

    if rBrine.ndim == 1:
        rB = pg.RMatrix(1, len(rBrine))
        rB[0] = parseArgToArray(rBrine, mesh.cellCount(), mesh)
    elif rBrine.ndim == 2:
        rB = pg.RMatrix(len(rBrine), len(rBrine[0]))
        for i in range(len(rBrine)):
            rB[i] = rBrine[i]

    porosity = parseArgToArray(porosity, mesh.cellCount(), mesh)
    a = parseArgToArray(a, mesh.cellCount(), mesh)
    m = parseArgToArray(m, mesh.cellCount(), mesh)
    S = parseArgToArray(S, mesh.cellCount(), mesh)
    n = parseArgToArray(n, mesh.cellCount(), mesh)

    r = pg.RMatrix(len(rBrine), len(rBrine[0]))
    for i in range(len(r)):
        r[i] = rB[i] * a * porosity**(-m) * S**(-n)

    rI = pg.RMatrix(len(r), meshI.cellCount())
    if meshI:
        pg.interpolate(mesh, r, meshI.cellCenters(), rI)

    for i in range(len(rI)):
        rI[i] = pg.solver.fillEmptyToCellArray(meshI, rI[i])

    return rI
Esempio n. 11
0
def resistivityArchie(rBrine, porosity, a=1.0, m=2.0, S=1.0, n=2.0,
                      mesh=None, meshI=None):
    """
    .. math::
        \rho = a\rho_{\text{Brine}}\phi^{-m}\S_w^{-n}

    * :math:`\rho` - the electrical conductivity of the fluid saturated rock
    * :math:`\rho_{\text{Brine}}` - electrical conductivity of the brine
    * :math:`\phi` - porosity 0.0 --1.0
    * :math:`a` - tortuosity factor. (common 1)
    * :math:`m` - cementation exponent of the rock
            (usually in the range 1.3 -- 2.5 for sandstones)
    * :math:`n` - is the saturation exponent (usually close to 2)

    """
    rB = None

    if rBrine.ndim == 1:
        rB = pg.RMatrix(1, len(rBrine))
        rB[0] = parseArgToArray(rBrine, mesh.cellCount(), mesh)
    elif rBrine.ndim == 2:
        rB = pg.RMatrix(len(rBrine), len(rBrine[0]))
        for i in range(len(rBrine)):
            rB[i] = rBrine[i]

    porosity = parseArgToArray(porosity, mesh.cellCount(), mesh)
    a = parseArgToArray(a, mesh.cellCount(), mesh)
    m = parseArgToArray(m, mesh.cellCount(), mesh)
    S = parseArgToArray(S, mesh.cellCount(), mesh)
    n = parseArgToArray(n, mesh.cellCount(), mesh)

    r = pg.RMatrix(len(rBrine), len(rBrine[0]))
    for i in range(len(r)):
        r[i] = rB[i] * a * porosity**(-m) * S**(-n)

    rI = pg.RMatrix(len(r), meshI.cellCount())
    if meshI:
        pg.interpolate(mesh, r, meshI.cellCenters(), rI)

    for i in range(len(rI)):
        rI[i] = pg.solver.fillEmptyToCellArray(meshI, rI[i])

    return rI
Esempio n. 12
0
def solveFiniteVolume(mesh,
                      a=1.0,
                      f=0.0,
                      fn=0.0,
                      vel=0.0,
                      u0=None,
                      times=None,
                      uL=None,
                      relax=1.0,
                      ws=None,
                      scheme='CDS',
                      **kwargs):
    """
    """
    # The Workspace is to hold temporary data or preserve matrix rebuild
    swatch = pg.core.Stopwatch(True)
    sparse = True

    workspace = WorkSpace()
    if ws:
        workspace = ws

    a = solver.parseArgToArray(a, [mesh.cellCount(), mesh.boundaryCount()])
    f = solver.parseArgToArray(f, mesh.cellCount())
    fn = solver.parseArgToArray(fn, mesh.cellCount())

    boundsDirichlet = None
    boundsNeumann = None

    if not hasattr(workspace, 'S'):

        if 'uBoundary' in kwargs:
            boundsDirichlet = pg.solver.parseArgToBoundaries(
                kwargs['uBoundary'], mesh)

        if 'duBoundary' in kwargs:
            boundsNeumann = pg.solver.parseArgToBoundaries(
                kwargs['duBoundary'], mesh)

        workspace.S, workspace.rhsBCScales = diffusionConvectionKernel(
            mesh=mesh,
            a=a,
            f=f,
            uBoundaries=boundsDirichlet,
            duBoundaries=boundsNeumann,
            u0=u0,
            fn=fn,
            vel=vel,
            scheme=scheme,
            sparse=sparse,
            userData=kwargs.pop('userData', None))
        print('FVM kernel 1:', swatch.duration(True))
        dof = len(workspace.rhsBCScales)

        #        workspace.uDir = np.zeros(dof)

        #        if u0 is not None:
        #            workspace.uDir = np.array(u0)
        #
        #        if len(boundsDirichlet):
        #            for boundary, val in boundsDirichlet.items():
        #                workspace.uDir[boundary.leftCell().id()] = val

        workspace.ap = np.zeros(dof)

        # for nonlinears

        if uL is not None:
            for i in range(dof):
                val = 0.0
                if sparse:
                    val = workspace.S.getVal(i, i) / relax
                    workspace.S.setVal(i, i, val)
#                    workspace.S[i, i] /= relax
#                    workspace.ap[i] = workspace.S[i, i]
                else:
                    val = workspace.S[i, i] / relax
                    workspace.S[i, i] = val

                workspace.ap[i] = val

        print('FVM kernel 2:', swatch.duration(True))
    # endif: not hasattr(workspace, 'S'):

    workspace.rhs = np.zeros(len(workspace.rhsBCScales))
    workspace.rhs[0:mesh.cellCount()] = f  # * mesh.cellSizes()

    #    if len(workspace.uDir):
    workspace.rhs += workspace.rhsBCScales

    # for nonlinear: relax progress with scaled last result
    if uL is not None:
        workspace.rhs += (1. - relax) * workspace.ap * uL
    # print('FVM: Prep:', swatch.duration(True))

    if not hasattr(times, '__len__'):

        if sparse and not hasattr(workspace, 'solver'):
            Sm = pg.matrix.SparseMatrix(workspace.S)
            # hold Sm until we have reference counting,
            # loosing Sm here will kill LinSolver later
            workspace.Sm = Sm
            workspace.solver = pg.core.LinSolver(Sm, True)

        u = None
        if sparse:
            u = workspace.solver.solve(workspace.rhs)
        else:
            u = np.linalg.solve(workspace.S, workspace.rhs)
        print('FVM solve:', swatch.duration(True))
        return u[0:mesh.cellCount():1]
    else:
        theta = kwargs.pop('theta', 0.5)
        verbose = kwargs.pop('verbose', False)

        if sparse:
            I = solver.identity(len(workspace.rhs))
        else:
            I = np.diag(np.ones(len(workspace.rhs)))

        print("solve cN")
        return solver.crankNicolson(times,
                                    theta,
                                    workspace.S,
                                    I,
                                    f=workspace.rhs,
                                    u0=u0,
                                    verbose=verbose)
Esempio n. 13
0
def solveFiniteVolume(mesh, a=1.0, f=0.0, fn=0.0, vel=0.0, u0=None,
                      times=None,
                      uL=None, relax=1.0,
                      ws=None, scheme='CDS', **kwargs):
    """
    """
    # The Workspace is to hold temporary data or preserve matrix rebuild
    swatch = pg.Stopwatch(True)
    sparse = True

    workspace = WorkSpace()
    if ws:
        workspace = ws

    a = solver.parseArgToArray(a, [mesh.cellCount(), mesh.boundaryCount()])
    f = solver.parseArgToArray(f, mesh.cellCount())
    fn = solver.parseArgToArray(fn, mesh.cellCount())

    boundsDirichlet = None
    boundsNeumann = None

    if not hasattr(workspace, 'S'):

        if 'uBoundary' in kwargs:
            boundsDirichlet = pg.solver.parseArgToBoundaries(
                    kwargs['uBoundary'], mesh)

        if 'duBoundary' in kwargs:
            boundsNeumann = pg.solver.parseArgToBoundaries(
                    kwargs['duBoundary'], mesh)

        workspace.S, workspace.rhsBCScales = diffusionConvectionKernel(
                mesh=mesh, a=a, f=f, uBoundaries=boundsDirichlet,
                duBoundaries=boundsNeumann, u0=u0, fn=fn, vel=vel,
                scheme=scheme, sparse=sparse,
                userData=kwargs.pop('userData', None))
        print('FVM kernel 1:', swatch.duration(True))
        dof = len(workspace.rhsBCScales)

#        workspace.uDir = np.zeros(dof)

#        if u0 is not None:
#            workspace.uDir = np.array(u0)
#
#        if len(boundsDirichlet):
#            for boundary, val in boundsDirichlet.items():
#                workspace.uDir[boundary.leftCell().id()] = val

        workspace.ap = np.zeros(dof)

        # for nonlinears

        if uL is not None:
            for i in range(dof):
                val = 0.0
                if sparse:
                    val = workspace.S.getVal(i, i) / relax
                    workspace.S.setVal(i, i, val)
#                    workspace.S[i, i] /= relax
#                    workspace.ap[i] = workspace.S[i, i]
                else:
                    val = workspace.S[i, i] / relax
                    workspace.S[i, i] = val

                workspace.ap[i] = val


        print('FVM kernel 2:', swatch.duration(True))
    # endif: not hasattr(workspace, 'S'):

    workspace.rhs = np.zeros(len(workspace.rhsBCScales))
    workspace.rhs[0:mesh.cellCount()] = f  # * mesh.cellSizes()

#    if len(workspace.uDir):
    workspace.rhs += workspace.rhsBCScales

    # for nonlinear: relax progress with scaled last result
    if uL is not None:
        workspace.rhs += (1. - relax) * workspace.ap * uL
    # print('FVM: Prep:', swatch.duration(True))

    if not hasattr(times, '__len__'):

        if sparse and not hasattr(workspace, 'solver'):
            Sm = pg.RSparseMatrix(workspace.S)
            # hold Sm until we have reference counting,
            # loosing Sm here will kill LinSolver later
            workspace.Sm = Sm
            workspace.solver = pg.LinSolver(Sm, True)

        u = None
        if sparse:
            u = workspace.solver.solve(workspace.rhs)
        else:
            u = np.linalg.solve(workspace.S, workspace.rhs)
        print('FVM solve:', swatch.duration(True))
        return u[0:mesh.cellCount():1]
    else:
        theta = kwargs.pop('theta', 0.5)
        verbose = kwargs.pop('verbose', False)

        if sparse:
            I = solver.identity(len(workspace.rhs))
        else:
            I = np.diag(np.ones(len(workspace.rhs)))

        print("solve cN")
        return solver.crankNicolson(times, theta, workspace.S, I,
                                    f=workspace.rhs, u0=u0, verbose=verbose)