示例#1
0
    def __init__(self, f_dom=40, t_dom=None):
        """
                Sets up a Ricker wavelet wih dominant frequence `f_dom` and
                center at time `t_dom`. If `t_dom` is not given an estimate
                for suitable `t_dom` is calculated so f(0)~0.

                :note: maximum frequence is about 2 x the dominant frequence.
                """
        drop = 18
        self.__f = f_dom
        self.__f_max = escript.sqrt(7) * f_dom
        self.__s = math.pi * self.__f
        if t_dom == None:
            t_dom = escript.sqrt(drop) / self.__s
        self.__t0 = t_dom
示例#2
0
    def rescaleWeights(self, scale=1., sigma_scale=1.):
        """
        rescales the weights such that

        :math: integrate( ( w omega**2 * sigma_scale * data * ((1/L_j)**2)**-1) +1 )/(data*omega**2 * ((1/L_j)**2)**-1) * sigma_scale )=scale

        :param scale: scale of data weighting factors
        :type scale: positive ``float``
        :param sigma_scale: scale of 1/vp**2 velocity.
        :type sigma_scale: ``Scalar``
        """
        raise Warning("rescaleWeights is not tested yet.")
        if not scale > 0:
            raise ValueError("Value for scale must be positive.")
        if not sigma_scale * omega**2 * d > 0:
            raise ValueError(
                "Rescaling of weights failed due to zero denominator.")
        # copy back original weights before rescaling
        #self.__weight=[1.*ow for ow in self.__origweight]
        L2 = 1 / escript.length(1 / self.edge_length)**2
        d = Lsup(escript.length(data))
        A = escript.integrate(self.__weight *
                              (sigma_scale * omega**2 * d + 1) /
                              (sigma_scale * omega**2 * d))
        if A > 0:
            self.__weight *= 1. / A
            if self.scaleF:
                self.__data *= escript.sqrt(A)
        else:
            raise ValueError("Rescaling of weights failed.")
示例#3
0
    def __init__(self, domain, reference=WGS84ReferenceSystem()):
        """
        set up the orthogonal coordinate transformation.

        :param domain: domain in the domain of the coordinate transformation
        :type domain: `esys.escript.AbstractDomain`
        :param reference: the reference system
        :type reference: `ReferenceSystem`

        """
        DIM = domain.getDim()
        super(GeodeticCoordinateTransformation,
              self).__init__(domain, reference)

        a = reference.getSemiMajorAxis()
        f = reference.getFlattening()
        f_a = reference.getAngularUnit()
        f_h = reference.getHeightUnit()

        x = esc.Function(domain).getX()
        if DIM == 2:
            phi = 0.
        else:
            phi = x[1] * f_a
        h = x[DIM - 1] * f_h

        e = esc.sqrt(2 * f - f**2)
        N = a / esc.sqrt(1 - e**2 * esc.sin(phi)**2)
        M = (a * (1 - e**2)) / esc.sqrt(1 - e**2 * esc.sin(phi)**2)**3
        v_phi = f_a * (M + h)
        v_lam = f_a * (N + h) * esc.cos(phi)
        v_h = f_h
        s = esc.Vector(1., esc.Function(domain))
        if DIM == 2:
            v = v_phi * v_h
            s[0] = 1 / v_lam
            s[1] = 1 / v_h
        else:
            v = v_phi * v_lam * v_h
            s[0] = 1 / v_lam
            s[1] = 1 / v_phi
            s[2] = 1 / v_h

        self._volumefactor = v
        self._scaling_factors = s
    def getNorm(self, m):
        """
        returns the norm of ``m``.

        :param m: level set function
        :type m: `Data`
        :rtype: ``float``
        """
        return sqrt(integrate(length(m) ** 2) / self.__vol_d)
    def getNorm(self, m):
        """
        returns the norm of ``m``.

        :param m: level set function
        :type m: `Data`
        :rtype: ``float``
        """
        return sqrt(integrate(length(m)**2) / self.__vol_d)
示例#6
0
    def __init__(self, domain, reference=WGS84ReferenceSystem() ):
        """
        set up the orthogonal coordinate transformation.

        :param domain: domain in the domain of the coordinate transformation
        :type domain: `esys.escript.AbstractDomain`
        :param reference: the reference system
        :type reference: `ReferenceSystem`

        """
        DIM=domain.getDim()
        super(GeodeticCoordinateTransformation, self).__init__(domain, reference )

        a=reference.getSemiMajorAxis()
        f=reference.getFlattening()
        f_a=reference.getAngularUnit()
        f_h=reference.getHeightUnit()

        x=esc.Function(domain).getX()
        if DIM == 2:
            phi=0.
        else:
            phi=x[1] * f_a
        h=x[DIM-1] * f_h

        e = esc.sqrt(2*f-f**2)
        N = a/esc.sqrt(1 - e**2 * esc.sin(phi)**2 )
        M = ( a*(1-e**2) ) /esc.sqrt(1 - e**2 * esc.sin(phi)**2 )**3
        v_phi = f_a * (M + h) 
        v_lam = f_a * (N + h) * esc.cos(phi)
        v_h = f_h
        s= esc.Vector(1., esc.Function(domain)) 
        if DIM == 2:
            v= v_phi * v_h 
            s[0]=1/v_lam
            s[1]=1/v_h
        else:
            v= v_phi * v_lam * v_h
            s[0]=1/v_lam
            s[1]=1/v_phi
            s[2]=1/v_h

        self._volumefactor=v
        self._scaling_factors = s
示例#7
0
    def __init__(self, V_prior, Q_prior):
        """
        initializes the mapping

        :param V_prior: a-priori p-wave velocity
        :param Q_prior: a-priori Q-index (must be positive)
        """
        over2Q = 1.0 / (2 * Q_prior)
        # sigma_prior=1/(V_prior*(1-I*over2Q))**2 = 1/( V_prior * (1+over2Q**2)) **2 * ( (1-over2Q**2) + I * 2* over2Q )
        self.Mr = log(sqrt((1 - over2Q ** 2) ** 2 + (2 * over2Q) ** 2) / (V_prior * (1 + over2Q ** 2)) ** 2)
        self.Mi = atan2(2 * over2Q, 1 - over2Q ** 2)
示例#8
0
    def __init__(self, V_prior, Q_prior):
        """
        initializes the mapping

        :param V_prior: a-priori p-wave velocity
        :param Q_prior: a-priori Q-index (must be positive)
        """
        over2Q = 1. / (2 * Q_prior)
        # sigma_prior=1/(V_prior*(1-I*over2Q))**2 = 1/( V_prior * (1+over2Q**2)) **2 * ( (1-over2Q**2) + I * 2* over2Q )
        self.Mr = log(
            sqrt((1 - over2Q**2)**2 + (2 * over2Q)**2) / (V_prior *
                                                          (1 + over2Q**2))**2)
        self.Mi = atan2(2 * over2Q, 1 - over2Q**2)
示例#9
0
def calculate_concentration(solute_mass, rho_f_0, gamma):
    """
    Calculate solute concentration using total solute mass and a concentration-density function.
    :param solute_mass:
    :param rho_f_0:
    :param gamma:
    :return:
    """

    # calculate new concentration, assuming no change in density:
    #concentration = u / rho_f
    a = rho_f_0 * gamma
    b = rho_f_0
    c = -solute_mass
    d = b**2 - 4 * a * c

    concentration = (-b + es.sqrt(d)) / (2 * a)

    return concentration
示例#10
0
 def cubicinterpolate(alpha_lo, alpha_hi, old_alpha, old_phi,
                      very_old_alpha, very_old_phi):
     if very_old_alpha is None:
         return quadinterpolate(alpha_lo, alpha_hi, old_alpha, old_phi)
     a0s, a1s = very_old_alpha * very_old_alpha, old_alpha * old_alpha
     denom = a0s * a1s * (old_alpha - very_old_alpha)
     if denom == 0:
         return quadinterpolate(alpha_lo, alpha_hi, old_alpha, old_phi)
     a0c, a1c = a0s * very_old_alpha, a1s * old_alpha
     tmpA = old_phi - phi0 - gphi0 * old_alpha
     tmpB = very_old_phi - phi0 - gphi0 * very_old_alpha
     a = (a0s * tmpA - a1s * tmpB) / denom
     b = (-a0c * tmpA + a1c * tmpB) / denom
     deter = b * b - 3.0 * a * gphi0
     if deter < 0:
         return quadinterpolate(alpha_lo, alpha_hi, old_alpha, old_phi)
     alpha = (-b + sqrt(deter)) / (3.0 * a)
     if np.abs(alpha - old_alpha) < tol_df or np.abs(
             alpha) < tol_sm * np.abs(old_alpha):
         alpha = 0.5 * old_alpha
     if abs(alpha) < 1e-8:
         return quadinterpolate(alpha_lo, alpha_hi, old_alpha, old_phi)
     return alpha
示例#11
0
 def f4(x,z,r): return escript.sqrt(escript.sqrt(x*x+z*z))/r
 maps = [None, None, None, None, f4, None]
示例#12
0
 def f4(x, z, r):
     return escript.sqrt(escript.sqrt(x * x + z * z)) / r
示例#13
0
 def f4(x,z,r): return escript.sqrt(escript.sqrt(x*x+z*z))/r
 maps = [None, None, None, None, f4, None]
示例#14
0
    def __init__(self,
                 domain,
                 v_p,
                 wavelet,
                 source_tag,
                 source_vector=[1., 0.],
                 eps=0.,
                 delta=0.,
                 azimuth=0.,
                 dt=None,
                 p0=None,
                 v0=None,
                 absorption_zone=300 * U.m,
                 absorption_cut=1e-2,
                 lumping=True):
        """
           initialize the HTI wave solver

           :param domain: domain of the problem
           :type domain: `Doamin`
           :param v_p: vertical p-velocity field
           :type v_p: `escript.Scalar`
           :param v_s: vertical s-velocity field
           :type v_s: `escript.Scalar`
           :param wavelet: wavelet to describe the time evolution of source term
           :type wavelet: `Wavelet`
           :param source_tag: tag of the source location
           :type source_tag: 'str' or 'int'
           :param source_vector: source orientation vector
           :param eps: first Thompsen parameter
           :param azimuth: azimuth (rotation around verticle axis)
           :param gamma: third Thompsen parameter
           :param rho: density
           :param dt: time step size. If not present a suitable time step size is calculated.
           :param p0: initial solution (Q(t=0), P(t=0)). If not present zero is used.
           :param v0: initial solution change rate. If not present zero is used.
           :param absorption_zone: thickness of absorption zone
           :param absorption_cut: boundary value of absorption decay factor
           :param lumping: if True mass matrix lumping is being used. This is accelerates the computing but introduces some diffusion.
           """
        DIM = domain.getDim()
        f = createAbsorptionLayerFunction(v_p.getFunctionSpace().getX(),
                                          absorption_zone, absorption_cut)

        self.v2_p = v_p**2
        self.v2_t = self.v2_p * escript.sqrt(1 + 2 * delta)
        self.v2_n = self.v2_p * (1 + 2 * eps)

        if p0 == None:
            p0 = escript.Data(0., (2, ), escript.Solution(domain))
        else:
            p0 = escript.interpolate(p0, escript.Solution(domain))

        if v0 == None:
            v0 = escript.Data(0., (2, ), escript.Solution(domain))
        else:
            v0 = escript.interpolate(v0, escript.Solution(domain))

        if dt == None:
            dt = min(
                min(escript.inf(domain.getSize() / escript.sqrt(self.v2_p)),
                    escript.inf(domain.getSize() / escript.sqrt(self.v2_t)),
                    escript.inf(domain.getSize() / escript.sqrt(self.v2_n))),
                wavelet.getTimeScale()) * 0.2

        super(SonicHTIWave, self).__init__(dt, u0=p0, v0=v0, t0=0.)

        self.__wavelet = wavelet

        self.__mypde = lpde.LinearPDESystem(domain)
        if lumping:
            self.__mypde.getSolverOptions().setSolverMethod(
                lpde.SolverOptions.HRZ_LUMPING)
        self.__mypde.setSymmetryOn()
        self.__mypde.setValue(D=escript.kronecker(2),
                              X=self.__mypde.createCoefficient('X'))
        self.__source_tag = source_tag

        self.__r = escript.Vector(
            0, escript.DiracDeltaFunctions(self.__mypde.getDomain()))
        self.__r.setTaggedValue(self.__source_tag, source_vector)
示例#15
0
    def __init__(self,
                 domain,
                 v_p,
                 v_s,
                 wavelet,
                 source_tag,
                 source_vector=[0., 1.],
                 eps=0.,
                 delta=0.,
                 theta=0.,
                 rho=1.,
                 dt=None,
                 u0=None,
                 v0=None,
                 absorption_zone=300 * U.m,
                 absorption_cut=1e-2,
                 lumping=True):
        """
           initialize the TTI wave solver

           :param domain: domain of the problem
           :type domain: `Domain`
           :param v_p: vertical p-velocity field
           :type v_p: `escript.Scalar`
           :param v_s: vertical s-velocity field
           :type v_s: `escript.Scalar`
           :param wavelet: wavelet to describe the time evolution of source term
           :type wavelet: `Wavelet`
           :param source_tag: tag of the source location
           :type source_tag: 'str' or 'int'
           :param source_vector: source orientation vector
           :param eps: first Thompsen parameter
           :param delta: second Thompsen parameter
           :param theta: tilting (in Rad)
           :param rho: density
           :param dt: time step size. If not present a suitable time step size is calculated.
           :param u0: initial solution. If not present zero is used.
           :param v0: initial solution change rate. If not present zero is used.
           :param absorption_zone: thickness of absorption zone
           :param absorption_cut: boundary value of absorption decay factor
           :param lumping: if True mass matrix lumping is being used. This is accelerates the computing but introduces some diffusion.
           """
        cos = escript.cos
        sin = escript.sin
        DIM = domain.getDim()
        if not DIM == 2:
            raise ValueError("Only 2D is supported.")
        f = createAbsorptionLayerFunction(
            escript.Function(domain).getX(), absorption_zone, absorption_cut)

        v_p = v_p * f
        v_s = v_s * f

        if u0 == None:
            u0 = escript.Vector(0., escript.Solution(domain))
        else:
            u0 = escript.interpolate(p0, escript.Solution(domain))

        if v0 == None:
            v0 = escript.Vector(0., escript.Solution(domain))
        else:
            v0 = escript.interpolate(v0, escript.Solution(domain))

        if dt == None:
            dt = min((1. / 5.) * min(escript.inf(domain.getSize() / v_p),
                                     escript.inf(domain.getSize() / v_s)),
                     wavelet.getTimeScale())

        super(TTIWave, self).__init__(dt, u0=u0, v0=v0, t0=0.)

        self.__wavelet = wavelet

        self.__mypde = lpde.LinearPDESystem(domain)
        if lumping:
            self.__mypde.getSolverOptions().setSolverMethod(
                lpde.SolverOptions.HRZ_LUMPING)
        self.__mypde.setSymmetryOn()
        self.__mypde.setValue(D=rho * escript.kronecker(DIM),
                              X=self.__mypde.createCoefficient('X'))
        self.__source_tag = source_tag

        self.__r = escript.Vector(
            0, escript.DiracDeltaFunctions(self.__mypde.getDomain()))
        self.__r.setTaggedValue(self.__source_tag, source_vector)

        c0_33 = v_p**2 * rho
        c0_66 = v_s**2 * rho
        c0_11 = (1 + 2 * eps) * c0_33
        c0_13 = escript.sqrt(2 * c0_33 * (c0_33 - c0_66) * delta +
                             (c0_33 - c0_66)**2) - c0_66

        self.c11 = c0_11 * cos(theta)**4 - 2 * c0_13 * cos(
            theta)**4 + 2 * c0_13 * cos(theta)**2 + c0_33 * sin(
                theta)**4 - 4 * c0_66 * cos(theta)**4 + 4 * c0_66 * cos(
                    theta)**2
        self.c13 = -c0_11 * cos(theta)**4 + c0_11 * cos(
            theta)**2 + c0_13 * sin(theta)**4 + c0_13 * cos(
                theta)**4 - c0_33 * cos(theta)**4 + c0_33 * cos(
                    theta)**2 + 4 * c0_66 * cos(theta)**4 - 4 * c0_66 * cos(
                        theta)**2
        self.c16 = (-2 * c0_11 * cos(theta)**2 - 4 * c0_13 * sin(theta)**2 +
                    2 * c0_13 + 2 * c0_33 * sin(theta)**2 - 8 * c0_66 *
                    sin(theta)**2 + 4 * c0_66) * sin(theta) * cos(theta) / 2
        self.c33 = c0_11 * sin(theta)**4 - 2 * c0_13 * cos(
            theta)**4 + 2 * c0_13 * cos(theta)**2 + c0_33 * cos(
                theta)**4 - 4 * c0_66 * cos(theta)**4 + 4 * c0_66 * cos(
                    theta)**2
        self.c36 = (2 * c0_11 * cos(theta)**2 - 2 * c0_11 +
                    4 * c0_13 * sin(theta)**2 - 2 * c0_13 +
                    2 * c0_33 * cos(theta)**2 + 8 * c0_66 * sin(theta)**2 -
                    4 * c0_66) * sin(theta) * cos(theta) / 2
        self.c66 = -c0_11 * cos(theta)**4 + c0_11 * cos(
            theta)**2 + 2 * c0_13 * cos(theta)**4 - 2 * c0_13 * cos(
                theta)**2 - c0_33 * cos(theta)**4 + c0_33 * cos(
                    theta)**2 + c0_66 * sin(theta)**4 + 3 * c0_66 * cos(
                        theta)**4 - 2 * c0_66 * cos(theta)**2
from test_simplesolve import SimpleSolveTestCase
import esys.escriptcore.utestselect as unittest
from esys.escriptcore.testing import *

from esys.escript import getMPISizeWorld, hasFeature, sqrt
from esys.ripley import Rectangle, Brick
from esys.escript.linearPDEs import SolverOptions

HAVE_PASO = hasFeature('paso')

# number of elements in the spatial directions
NE0=12
NE1=12
NE2=8
mpiSize=getMPISizeWorld()
for x in [int(sqrt(mpiSize)),2,3,5,7,1]:
    NX=x
    NY=mpiSize//x
    if NX*NY == mpiSize:
        break

for x in [(int(mpiSize**(1/3.)),int(mpiSize**(1/3.))),(2,3),(2,2),(1,2),(1,1)]:
    NXb=x[0]
    NYb=x[1]
    NZb=mpiSize//(x[0]*x[1])
    if NXb*NYb*NZb == mpiSize:
        break

@unittest.skipIf(not HAVE_PASO, "PASO not available")
class SimpleSolveOnPaso(SimpleSolveTestCase):
    pass
示例#17
0
    def __init__(self,
                 domain,
                 omega,
                 w,
                 data,
                 F,
                 coordinates=None,
                 fixAtBottom=False,
                 tol=1e-10,
                 saveMemory=True,
                 scaleF=True):
        """
        initializes a new forward model with acoustic wave form inversion.

        :param domain: domain of the model
        :type domain: `Domain`
        :param w: weighting factors
        :type w: ``Scalar``
        :param data: real and imaginary part of data
        :type data: ``escript.Data`` of shape (2,)
        :param F: real and imaginary part of source given at Dirac points,
                  on surface or at volume.
        :type F: ``escript.Data`` of shape (2,)
        :param coordinates: defines coordinate system to be used (not supported yet)
        :type coordinates: `ReferenceSystem` or `SpatialCoordinateTransformation`
        :param tol: tolerance of underlying PDE
        :type tol: positive ``float``
        :param saveMemory: if true stiffness matrix is deleted after solution
                           of PDE to minimize memory requests. This will
                           require more compute time as the matrix needs to be
                           reallocated.
        :type saveMemory: ``bool``
        :param scaleF: if true source F is scaled to minimize defect.
        :type scaleF: ``bool``
        :param fixAtBottom: if true pressure is fixed to zero at the bottom of
                            the domain
        :type fixAtBottom: ``bool``
        """
        super(AcousticWaveForm, self).__init__()
        self.__trafo = edc.makeTransformation(domain, coordinates)
        if not self.getCoordinateTransformation().isCartesian():
            raise ValueError(
                "Non-Cartesian Coordinates are not supported yet.")
        if not isinstance(data, escript.Data):
            raise ValueError("data must be an escript.Data object.")
        if not data.getFunctionSpace() == escript.FunctionOnBoundary(domain):
            raise ValueError("data must be defined on boundary")
        if not data.getShape() == (2, ):
            raise ValueError(
                "data must have shape (2,) (real and imaginary part).")
        if w is None:
            w = 1.
        if not isinstance(w, escript.Data):
            w = escript.Data(w, escript.FunctionOnBoundary(domain))
        else:
            if not w.getFunctionSpace() == escript.FunctionOnBoundary(domain):
                raise ValueError("Weights must be defined on boundary.")
            if not w.getShape() == ():
                raise ValueError("Weights must be scalar.")

        self.__domain = domain
        self.__omega = omega
        self.__weight = w
        self.__data = data
        self.scaleF = scaleF
        if scaleF:
            A = escript.integrate(self.__weight *
                                  escript.length(self.__data)**2)
            if A > 0:
                self.__data *= 1. / escript.sqrt(A)

        self.__BX = escript.boundingBox(domain)
        self.edge_lengths = np.asarray(escript.boundingBoxEdgeLengths(domain))

        if not isinstance(F, escript.Data):
            F = escript.interpolate(F, escript.DiracDeltaFunctions(domain))
        if not F.getShape() == (2, ):
            raise ValueError(
                "Source must have shape (2,) (real and imaginary part).")

        self.__F = escript.Data()
        self.__f = escript.Data()
        self.__f_dirac = escript.Data()

        if F.getFunctionSpace() == escript.DiracDeltaFunctions(domain):
            self.__f_dirac = F
        elif F.getFunctionSpace() == escript.FunctionOnBoundary(domain):
            self.__f = F
        else:
            self.__F = F
        self.__tol = tol
        self.__fixAtBottom = fixAtBottom
        self.__pde = None
        if not saveMemory:
            self.__pde = self.setUpPDE()
    def __init__(self,
                 domain,
                 omega,
                 x,
                 Z,
                 eta=None,
                 w0=1.,
                 mu=4 * math.pi * 1e-7,
                 sigma0=0.01,
                 airLayerLevel=None,
                 fixAirLayer=False,
                 coordinates=None,
                 tol=1e-8,
                 saveMemory=False,
                 directSolver=True):
        """
        initializes a new forward model.

        :param domain: domain of the model
        :type domain: `Domain`
        :param omega: frequency
        :type omega: positive ``float``
        :param x: coordinates of measurements
        :type x: ``list`` of ``tuple`` with ``float``
        :param Z: measured impedance (possibly scaled)
        :type Z: ``list`` of ``complex``
        :param eta: spatial confidence radius
        :type eta:  positive ``float`` or ``list`` of  positive ``float``
        :param w0: confidence factors for meassurements.
        :type w0: ``None`` or a list of positive ``float``
        :param mu: permeability
        :type mu: ``float``
        :param sigma0: background conductivity
        :type sigma0: ``float``
        :param airLayerLevel: position of the air layer from to bottom of the domain. If
                              not set the air layer starts at the top of the domain
        :type airLayerLevel: ``float`` or ``None``        
        :param fixAirLayer: fix air layer (TM mode)
        :type fixAirLayer: ``bool``
        :param coordinates: defines coordinate system to be used (not supported yet)
        :type coordinates: `ReferenceSystem` or `SpatialCoordinateTransformation`
        :param tol: tolerance of underlying PDE
        :type tol: positive ``float``
        :param saveMemory: if true stiffness matrix is deleted after solution
                           of the PDE to minimize memory use. This will
                           require more compute time as the matrix needs to be
                           reallocated at each iteration.
        :type saveMemory: ``bool``
        :param directSolver: if true a direct solver (rather than an iterative
                             solver) will be used to solve the PDE
        :type directSolver: ``bool``
        """
        super(MT2DBase, self).__init__()
        self.__trafo = coords.makeTransformation(domain, coordinates)
        if not self.getCoordinateTransformation().isCartesian():
            raise ValueError(
                "Non-Cartesian coordinates are not supported yet.")
        if len(x) != len(Z):
            raise ValueError(
                "Number of data points and number of impedance values don't match."
            )

        if eta is None:
            eta = escript.sup(domain.getSize()) * 0.45

        if isinstance(eta, float) or isinstance(eta, int):
            eta = [float(eta)] * len(Z)
        elif not len(eta) == len(Z):
            raise ValueError(
                "Number of confidence radii and number of impedance values don't match."
            )

        if isinstance(w0, float) or isinstance(w0, int):
            w0 = [float(w0)] * len(Z)
        elif not len(w0) == len(Z):
            raise ValueError(
                "Number of confidence factors and number of impedance values don't match."
            )

        self.__domain = domain
        self._omega_mu = omega * mu
        self._ks = escript.sqrt(self._omega_mu * sigma0 / 2.)

        xx = escript.Function(domain).getX()
        totalS = 0
        self._Z = [
            escript.Scalar(0., escript.Function(domain)),
            escript.Scalar(0., escript.Function(domain))
        ]
        self._weight = escript.Scalar(0., escript.Function(domain))

        for s in range(len(Z)):
            chi = self.getWeightingFactor(xx, 1., x[s], eta[s])
            f = escript.integrate(chi)
            if f < eta[s]**2 * 0.01:
                raise ValueError(
                    "Zero weight (almost) for data point %s. Change eta or refine mesh."
                    % (s, ))
            w02 = w0[s] / f
            totalS += w02
            self._Z[0] += chi * Z[s].real
            self._Z[1] += chi * Z[s].imag
            self._weight += chi * w02 / (abs(Z[s])**2)

        if not totalS > 0:
            raise ValueError(
                "Scaling of weight factors failed as sum is zero.")

        DIM = domain.getDim()
        z = domain.getX()[DIM - 1]
        self._ztop = escript.sup(z)
        self._zbottom = escript.inf(z)
        if airLayerLevel is None:
            airLayerLevel = self._ztop
        self._airLayerLevel = airLayerLevel

        # botton:
        mask0 = escript.whereZero(z - self._zbottom)
        r = mask0 * [
            escript.exp(self._ks * (self._zbottom - airLayerLevel)) *
            escript.cos(self._ks * (self._zbottom - airLayerLevel)),
            escript.exp(self._ks * (self._zbottom - airLayerLevel)) *
            escript.sin(self._ks * (self._zbottom - airLayerLevel))
        ]

        #top:
        if fixAirLayer:
            mask1 = escript.whereNonNegative(z - airLayerLevel)
            r += mask1 * [1, 0]
        else:
            mask1 = escript.whereZero(z - self._ztop)
            r += mask1 * [
                self._ks * (self._ztop - airLayerLevel) + 1, self._ks *
                (self._ztop - airLayerLevel)
            ]

        self._q = (mask0 + mask1) * [1, 1]
        self._r = r
        #====================================
        self.__tol = tol
        self._directSolver = directSolver
        self._saveMemory = saveMemory
        self.__pde = None
        if not saveMemory:
            self.__pde = self.setUpPDE()
import esys.escriptcore.utestselect as unittest
from esys.escriptcore.testing import *

from esys.escript import getMPISizeWorld, hasFeature, sqrt
from esys.ripley import Rectangle, Brick
from esys.escript.linearPDEs import SolverOptions

SOLVER = "mkl"
HAVE_REQUESTED_SOLVER = hasFeature(SOLVER)

# number of elements in the spatial directions
NE0 = 12
NE1 = 12
NE2 = 8
mpiSize = getMPISizeWorld()
for x in [int(sqrt(mpiSize)), 2, 3, 5, 7, 1]:
    NX = x
    NY = mpiSize // x
    if NX * NY == mpiSize:
        break

for x in [(int(mpiSize**(1 / 3.)), int(mpiSize**(1 / 3.))), (2, 3), (2, 2),
          (1, 2), (1, 1)]:
    NXb = x[0]
    NYb = x[1]
    NZb = mpiSize // (x[0] * x[1])
    if NXb * NYb * NZb == mpiSize:
        break


@unittest.skipIf(not HAVE_REQUESTED_SOLVER, "%s not available" % SOLVER)
示例#20
0
    def __init__(self,
                 domain,
                 v_p,
                 v_s,
                 wavelet,
                 source_tag,
                 source_vector=[1., 0., 0.],
                 eps=0.,
                 gamma=0.,
                 delta=0.,
                 rho=1.,
                 dt=None,
                 u0=None,
                 v0=None,
                 absorption_zone=None,
                 absorption_cut=1e-2,
                 lumping=True,
                 disable_fast_assemblers=False):
        """
       initialize the VTI wave solver

       :param domain: domain of the problem
       :type domain: `Domain`
       :param v_p: vertical p-velocity field
       :type v_p: `escript.Scalar`
       :param v_s: vertical s-velocity field
       :type v_s: `escript.Scalar`
       :param wavelet: wavelet to describe the time evolution of source term
       :type wavelet: `Wavelet`
       :param source_tag: tag of the source location
       :type source_tag: 'str' or 'int'
       :param source_vector: source orientation vector
       :param eps: first Thompsen parameter
       :param delta: second Thompsen parameter
       :param gamma: third Thompsen parameter
       :param rho: density
       :param dt: time step size. If not present a suitable time step size is calculated.
       :param u0: initial solution. If not present zero is used.
       :param v0: initial solution change rate. If not present zero is used.
       :param absorption_zone: thickness of absorption zone
       :param absorption_cut: boundary value of absorption decay factor
       :param lumping: if True mass matrix lumping is being used. This is accelerates the computing but introduces some diffusion.
       :param disable_fast_assemblers: if True, forces use of slower and more general PDE assemblers
       """
        DIM = domain.getDim()
        self.fastAssembler = hasattr(
            domain, "createAssembler") and not disable_fast_assemblers
        f = createAbsorptionLayerFunction(v_p.getFunctionSpace().getX(),
                                          absorption_zone, absorption_cut)

        v_p = v_p * f
        v_s = v_s * f

        if u0 == None:
            u0 = escript.Vector(0., escript.Solution(domain))
        else:
            u0 = escript.interpolate(p0, escript.Solution(domain))

        if v0 == None:
            v0 = escript.Vector(0., escript.Solution(domain))
        else:
            v0 = escript.interpolate(v0, escript.Solution(domain))

        if dt == None:
            dt = min((1. / 5.) * min(escript.inf(domain.getSize() / v_p),
                                     escript.inf(domain.getSize() / v_s)),
                     wavelet.getTimeScale())

        super(HTIWave, self).__init__(dt, u0=u0, v0=v0, t0=0.)

        self.__wavelet = wavelet

        self.c33 = v_p**2 * rho
        self.c44 = v_s**2 * rho
        self.c11 = (1 + 2 * eps) * self.c33
        self.c66 = (1 + 2 * gamma) * self.c44
        self.c13 = escript.sqrt(2 * self.c33 * (self.c33 - self.c44) * delta +
                                (self.c33 - self.c44)**2) - self.c44
        self.c23 = self.c33 - 2 * self.c66

        if self.fastAssembler:
            C = [("c11", self.c11), ("c23", self.c23), ("c13", self.c13),
                 ("c33", self.c33), ("c44", self.c44), ("c66", self.c66)]
            if "speckley" in domain.getDescription().lower():
                C = [(n, escript.interpolate(d,
                                             escript.ReducedFunction(domain)))
                     for n, d in C]
            self.__mypde = lpde.WavePDE(domain, C)
        else:
            self.__mypde = lpde.LinearPDESystem(domain)
            self.__mypde.setValue(X=self.__mypde.createCoefficient('X'))

        if lumping:
            self.__mypde.getSolverOptions().setSolverMethod(
                lpde.SolverOptions.HRZ_LUMPING)
        self.__mypde.setSymmetryOn()
        self.__mypde.setValue(D=rho * escript.kronecker(DIM))
        self.__source_tag = source_tag

        if DIM == 2:
            source_vector = [source_vector[0], source_vector[2]]

        self.__r = escript.Vector(
            0, escript.DiracDeltaFunctions(self.__mypde.getDomain()))
        self.__r.setTaggedValue(self.__source_tag, source_vector)