예제 #1
0
 def test_yDirection(self):
     dim=self.domain.getDim()
     if dim==3:
         return
     u = Symbol('u',(2,), dim=dim)
     q = Symbol('q', (2,2))
     theta = Symbol('theta')
     theta=3.141/6
     q[0,0]=cos(theta)
     q[0,1]=-sin(theta)
     q[1,0]=sin(theta)
     q[1,1]=cos(theta)
     sigma = Symbol('sigma',(2,2))
     p = NonlinearPDE(self.domain, u, debug=0)
     epsilon = symmetric(grad(u))
  #   epsilon = matrixmult(matrixmult(q,epsilon0),q.transpose(1))
     c00=10;c01=8;c05=0
     c01=8;c11=10;c15=0
     c05=0;c15=0;c55=1
     sigma[0,0]=c00*epsilon[0,0]+c01*epsilon[1,1]+c05*2*epsilon[1,0]
     sigma[1,1]=c01*epsilon[0,0]+c11*epsilon[1,1]+c15*2*epsilon[1,0]
     sigma[0,1]=c05*epsilon[0,0]+c15*epsilon[1,1]+c55*2*epsilon[1,0]
     sigma[1,0]=sigma[0,1]
  #   sigma0=matrixmult(matrixmult(q.transpose(1),epsilon),q)
     x = self.domain.getX()
     gammaD=whereZero(x[1])*[1,1]#+whereZero(x[0])*[1,0]+whereZero(x[0]-1)*[1,0]  
     yconstraint = FunctionOnBoundary(self.domain).getX()[1]
     p.setValue(X=sigma,q=gammaD,y=[-50,0]*whereZero(yconstraint-1),r=[1,1])
     v = p.getSolution(u=[0,0])
     x=np.ndarray((2,))
     x[0]=0.5
     x[1]=0.5
     loc=Locator(v.getFunctionSpace(),x)
     valAtX=loc(v)
     self.assertTrue(valAtX[0]>10*valAtX[1])
예제 #2
0
 def test_yDirection(self):
     dim=self.domain.getDim()
     if dim==3:
         return
     u = Symbol('u',(2,), dim=dim)
     q = Symbol('q', (2,2))
     theta = Symbol('theta')
     theta=3.141/6
     q[0,0]=cos(theta)
     q[0,1]=-sin(theta)
     q[1,0]=sin(theta)
     q[1,1]=cos(theta)
     sigma = Symbol('sigma',(2,2))
     p = NonlinearPDE(self.domain, u, debug=0)
     epsilon = symmetric(grad(u))
  #   epsilon = matrixmult(matrixmult(q,epsilon0),q.transpose(1))
     c00=10;c01=8;c05=0
     c01=8;c11=10;c15=0
     c05=0;c15=0;c55=1
     sigma[0,0]=c00*epsilon[0,0]+c01*epsilon[1,1]+c05*2*epsilon[1,0]
     sigma[1,1]=c01*epsilon[0,0]+c11*epsilon[1,1]+c15*2*epsilon[1,0]
     sigma[0,1]=c05*epsilon[0,0]+c15*epsilon[1,1]+c55*2*epsilon[1,0]
     sigma[1,0]=sigma[0,1]
  #   sigma0=matrixmult(matrixmult(q.transpose(1),epsilon),q)
     x = self.domain.getX()
     gammaD=whereZero(x[1])*[1,1]#+whereZero(x[0])*[1,0]+whereZero(x[0]-1)*[1,0]  
     yconstraint = FunctionOnBoundary(self.domain).getX()[1]
     p.setValue(X=sigma,q=gammaD,y=[-50,0]*whereZero(yconstraint-1),r=[1,1])
     v = p.getSolution(u=[0,0])
     x=np.ndarray((2,))
     x[0]=0.5
     x[1]=0.5
     loc=Locator(v.getFunctionSpace(),x)
     valAtX=loc(v)
     self.assertTrue(valAtX[0]>10*valAtX[1])
예제 #3
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]]
예제 #4
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
예제 #5
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
예제 #6
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]]
예제 #7
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])
예제 #8
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])
    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()