Esempio n. 1
0
 def getDerivative(self, m):
     """
     returns the derivative of the mapping for m
     """
     # return self.__sigma0 * self.__k
     # return self.__sigma0*self.__k*exp(self.__k*m)
     return (self.__sigma0 * self.__k * self.a * exp(-self.__k * m)) / (1 + exp(-self.__k * m)) ** 2
Esempio n. 2
0
def createAbsorptionLayerFunction(x,
                                  absorption_zone=300 * U.m,
                                  absorption_cut=1.e-2,
                                  top_absorption=False):
    """
    Creates a distribution which is one in the interior of the domain of `x`
    and is falling down to the value 'absorption_cut' over a margin of thickness 'absorption_zone'
    toward each boundary except the top of the domain.

    :param x: location of points in the domain
    :type x: `escript.Data`
    :param absorption_zone: thickness of the absorption zone
    :param absorption_cut: value of decay function on domain boundary
    :return: function on 'x' which is one in the iterior and decays to almost zero over a margin
             toward the boundary.
    """

    if absorption_zone is None or absorption_zone == 0:
        return 1

    dom = x.getDomain()
    bb = escript.boundingBox(dom)
    DIM = dom.getDim()
    decay = -escript.log(absorption_cut) / absorption_zone**2
    f = 1
    for i in range(DIM):
        x_i = x[i]
        x_l = x_i - (bb[i][0] + absorption_zone)
        m_l = escript.whereNegative(x_l)
        f = f * ((escript.exp(-decay * (x_l * m_l)**2) - 1) * m_l + 1)
        if top_absorption or not DIM - 1 == i:
            x_r = (bb[i][1] - absorption_zone) - x_i
            m_r = escript.whereNegative(x_r)
            f = f * ((escript.exp(-decay * (x_r * m_r)**2) - 1) * m_r + 1)
    return f
Esempio n. 3
0
 def getDerivative(self, m):
     """
     returns the derivative of the mapping for m
     """
     # return self.__sigma0 * self.__k
     # return self.__sigma0*self.__k*exp(self.__k*m)
     return (self.__sigma0 * self.__k * self.a *
             exp(-self.__k * m)) / (1 + exp(-self.__k * m))**2
Esempio n. 4
0
 def getDerivative(self, m):
     """
     returns the value for the derivative of the mapping for m
     """
     e = exp(m[0] + self.Mr)
     return (e * cos(m[1] + self.Mi)) * [[1, 0], [0, 1]] + (
         e * sin(m[1] + self.Mi)) * [[0, -1], [1, 0]]
Esempio n. 5
0
 def getVelocity(self, t):
     """
             get the velocity f'(t) at time `t`
             """
     e2 = (self.__s * (t - self.__t0))**2
     return (-3 + 2 * e2) * escript.exp(-e2) * 2 * self.__s**2 * (t -
                                                                  self.__t0)
Esempio n. 6
0
 def getValue(self, m):
     print("in get value inf(m)=", inf(m), " sup(m)=", sup(m))
     # s=self.__sigma0 + (self.__sigma0 * self.__k*m)
     # s=self.__sigma0*exp(self.__k*m)
     #### use sigmoid mapping
     s = (self.__sigma0 * self.a / (1 + exp(-self.__k * m))) + self.minVal
     print("in get value inf(s)=", inf(s), " sup(s)=", sup(s))
     if sup(s) != 0 and inf(s) != 0:
         print("in get value 1/inf(s)=", 1.0 / inf(s), " 1/sup(s)=", 1.0 / sup(s))
     return s
Esempio n. 7
0
 def getValue(self, m):
     print("in get value inf(m)=", inf(m), " sup(m)=", sup(m))
     # s=self.__sigma0 + (self.__sigma0 * self.__k*m)
     # s=self.__sigma0*exp(self.__k*m)
     #### use sigmoid mapping
     s = (self.__sigma0 * self.a / (1 + exp(-self.__k * m))) + self.minVal
     print("in get value inf(s)=", inf(s), " sup(s)=", sup(s))
     if sup(s) != 0 and inf(s) != 0:
         print("in get value 1/inf(s)=", 1. / inf(s), " 1/sup(s)=",
               1. / sup(s))
     return s
Esempio n. 8
0
    def out(self):
        """
        Generate the Gaussian profile

        Link against this method to get the output of this model.
        """
        x = self.domain.getX()
        dim = self.domain.getDim()
        l = length(x - self.x_c[:dim])
        m = whereNegative(l - self.r)

        return (m + (1. - m) * exp(-log(2.) * (l / self.width)**2)) * self.A
Esempio n. 9
0
    def out(self):
        """
        Generate the Gaussian profile

        Link against this method to get the output of this model.
        """
        x = self.domain.getX()
        dim = self.domain.getDim()
        l = length(x-self.x_c[:dim])
        m = whereNegative(l-self.r)

        return (m+(1.-m)*exp(-log(2.)*(l/self.width)**2))*self.A
Esempio n. 10
0
def calculate_viscosity(C, T=20.0):
    """
    Calculate fluid viscosity following Batzle & Wang (1992).

    """

    viscosity = 1e-3 * (
        0.1 + 0.333 * C +
        (1.65 + 91.9 * C**3) * es.exp(-(0.42 *
                                        (C**0.8 - 0.17)**2 + 0.045) * T**0.8))

    return viscosity
Esempio n. 11
0
 def getDerivative(self, m):
     """
     returns the value for the derivative of the mapping for m
     """
     e = exp(m[0] + self.Mr)
     return (e * cos(m[1] + self.Mi)) * [[1, 0], [0, 1]] + (e * sin(m[1] + self.Mi)) * [[0, -1], [1, 0]]
    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()
Esempio n. 13
0
 def getValue(self, t):
     """
             get value of wavelet at time `t`
             """
     e2 = (self.__s * (t - self.__t0))**2
     return (1 - 2 * e2) * escript.exp(-e2)
Esempio n. 14
0
 def getAcceleration(self, t):
     """
             get the acceleration f''(t) at time `t`
             """
     e2 = (self.__s * (t - self.__t0))**2
     return 2 * self.__s**2 * (-4 * e2**2 + 12 * e2 - 3) * escript.exp(-e2)
Esempio n. 15
0
 def getDerivative(self, m):
     """
     returns the derivative of the mapping for m
     """
     return self.__sigma0 * self.__a * exp(self.__a * m)
Esempio n. 16
0
 def getValue(self, m):
     """
     returns the value of the mapping for m
     """
     return self.__sigma0 * exp(self.__a * m)
Esempio n. 17
0
 def getValue(self, m):
     """
     returns the value of the mapping for m
     """
     return exp(m[0] + self.Mr) * (cos(m[1] + self.Mi) * [1, 0] +
                                   sin(m[1] + self.Mi) * [0, 1])
Esempio n. 18
0
 def getValue(self, m):
     """
     returns the value of the mapping for m
     """
     return self.__sigma0 * exp(self.__a * m)
Esempio n. 19
0
 def getValue(self, m):
     """
     returns the value of the mapping for m
     """
     return exp(m[0] + self.Mr) * (cos(m[1] + self.Mi) * [1, 0] + sin(m[1] + self.Mi) * [0, 1])
Esempio n. 20
0
 def getDerivative(self, m):
     """
     returns the derivative of the mapping for m
     """
     return self.__sigma0 * self.__a * exp(self.__a * m)