Exemple #1
0
    def __init__(self,
                 domain,
                 v_p,
                 wavelet,
                 source_tag,
                 dt=None,
                 p0=None,
                 p0_t=None,
                 absorption_zone=300 * U.m,
                 absorption_cut=1e-2,
                 lumping=True):
        """
           initialize the sonic wave solver

           :param domain: domain of the problem
           :type domain: `Domain`
           :param v_p: p-velocity field
           :type v_p: `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 dt: time step size. If not present a suitable time step size is calculated.
           :param p0: initial solution. If not present zero is used.
           :param p0_t: 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.
           """
        f = createAbsorptionLayerFunction(
            escript.Function(domain).getX(), absorption_zone, absorption_cut)
        v_p = v_p * f

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

        if p0_t == None:
            p0_t = escript.Scalar(0., escript.Solution(domain))
        else:
            p0_t = escript.interpolate(p0_t, escript.Solution(domain))

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

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

        self.__wavelet = wavelet
        self.__mypde = lpde.LinearSinglePDE(domain)
        if lumping:
            self.__mypde.getSolverOptions().setSolverMethod(
                lpde.SolverOptions.HRZ_LUMPING)
        self.__mypde.setSymmetryOn()
        self.__mypde.setValue(D=1. / v_p**2)
        self.__source_tag = source_tag
        self.__r = escript.Scalar(
            0., escript.DiracDeltaFunctions(self.__mypde.getDomain()))
Exemple #2
0
    def __init__(self,
                 domain,
                 pore0=0.,
                 perm=1.e-5,
                 kf=2.2e9,
                 dt=0.001,
                 ng=1,
                 useMPI=False,
                 np=1,
                 rtol=1.e-2):
        """
      initialization of the problem, i.e. model constructor
      :param domain: type Domain, domain of the problem
      :param pore0: type float, initial pore pressure
      :param perm: type float, d^2/(150 mu_f) in KC equation
      :param kf: type float, bulk modulus of the fluid
      :param dt: type float, time step for calculation
      :param ng: type integer, number of Gauss points
      :param useMPI: type boolean, use MPI or not
      :param np: type integer, number of processors
      :param rtol: type float, relevative tolerance for global convergence
      """
        self.__domain = domain
        self.__upde = LinearPDE(domain,
                                numEquations=domain.getDim(),
                                numSolutions=domain.getDim())
        self.__ppde = LinearPDE(domain, numEquations=1, numSolutions=1)
        # use reduced interpolation for pore pressure
        self.__ppde.setReducedOrderOn()

        self.__upde.getSolverOptions().setSolverMethod(SolverOptions.DIRECT)
        self.__ppde.getSolverOptions().setSolverMethod(SolverOptions.DIRECT)
        self.__upde.setSymmetryOn()
        self.__ppde.setSymmetryOn()

        self.__dt = dt
        self.__bulkFluid = kf
        self.__numGaussPoints = ng
        self.__rtol = rtol
        self.__stress = escript.Tensor(0, escript.Function(domain))
        self.__S = escript.Tensor4(0, escript.Function(domain))
        self.__pool = get_pool(mpi=useMPI, threads=np)
        self.__scenes = self.__pool.map(initLoad, range(ng))
        st = self.__pool.map(getStressAndTangent2D, self.__scenes)
        for i in xrange(ng):
            self.__stress.setValueOfDataPoint(i, st[i][0])
            self.__S.setValueOfDataPoint(i, st[i][1])
        self.__strain = escript.Tensor(0, escript.Function(domain))
        self.__pore = escript.Scalar(pore0, escript.ReducedSolution(domain))
        self.__pgauss = util.interpolate(pore0, escript.Function(domain))
        self.__permeability = perm
        self.__meanStressRate = escript.Scalar(0, escript.Function(domain))
        self.__r = escript.Vector(
            0, escript.Solution(domain))  #Dirichlet BC for u
Exemple #3
0
    def __tagDomain(self, domain, X, tags, rho, maps):
        """
    DESCRIPTION:
    -----------
    Defines the conductivity model. Conductivities of tagged regions can be mapped
    via user-defined functions passed in 'maps'. If no user-defined functions are
    passed, a constant value is applied as provided in list 'rho' for each region.
    User-defined functions have 3 arguments: x-coordinate, z-coordinate, resistivity.

    ARGUMENTS:
    ----------
    domain  :: escript object of mesh
    X       :: escript object with all coordinates
    tags    :: list with domain tags
    rho     :: list with domain resistivities
    maps    :: list with user-defined resistivity mappings

    RETURNS:
    --------
    sigma   :: escript object of conductivity model

    """
        # Setup the conductivity structure (acts on elements and can be discontinuous).
        sigma = escript.Scalar(0, escript.Function(domain))

        # Setup conductivity domains.
        for i in range(len(tags)):

            # Default: assign conductivity which is the inverse of resistivity:
            m = 1.0 / rho[i]

            # Map a user-defined conductivity distribution if given:
            if maps is not None:
                # Guard against undefined elements:
                if maps[i] is not None:
                    # Map the conductivity according to the defined functions:
                    m = maps[i](X[0], X[1], rho[i])

            # Tag the mesh with the conductivity distributions at each iteration:
            sigma += m * escript.insertTaggedValues(
                escript.Scalar(0, escript.Function(domain)), **{tags[i]: 1})

        if self._debug == True:
            sigma.expand()
            mydir = os.getcwd()
            dbgfl = mydir + os.sep + "mt2d_sigma_dbg.silo"
            print("")
            print("DEBUG: writing SILO debug output of conductivity model:")
            print(dbgfl)
            print("")
            weipa.saveSilo(dbgfl, sigma=sigma)

        # All done:
        return sigma
 def test_replaceNaNTagged(self):
     dom=self.domain
     sigma = es.Scalar(0,es.FunctionOnBoundary(dom))
     dat=(sigma*0)/0
     sigma.setTaggedValue(1 , es.Lsup(dat))
     sigma.replaceNaN(10)
     self.assertEqual(es.Lsup(sigma), 10)
     sigma = es.Scalar(0,es.FunctionOnBoundary(dom))
     sigma.promote()
     dat=(sigma*0)/0
     sigma.setTaggedValue(1 , es.Lsup(dat))
     sigma.replaceNaN(3+4j)
     self.assertEqual(es.Lsup(sigma), 5)
 def test_replaceNaNExpanded(self):
     dom=self.domain
     scl=es.Scalar(0,es.ContinuousFunction(dom))
     scl.expand()
     sclNaN=scl/0
     self.assertTrue(sclNaN.hasNaN(),"sclNaN should contain NaN but its doesn't")
     sclNaN.replaceNaN(15.0)
     self.assertEqual(es.Lsup(sclNaN), 15.0)
     scl=es.Scalar(0,es.ContinuousFunction(dom))
     scl.expand()
     scl.promote()
     if not es.getEscriptParamInt('AUTOLAZY')==1:            
         sclNaN=scl/0
         self.assertTrue(sclNaN.hasNaN(),"sclNaN should contain NaN but its doesn't")
         sclNaN.replaceNaN(3+4j)
         self.assertEqual(es.Lsup(sclNaN), 5.0)
    def getPotentialNumeric(self):
        """
        Returns 3 list each made up of a number of list containing primary, secondary and total
        potentials diferences. Each of the lists contain a list for each value of n.
        """
        primCon=self.primaryConductivity
        coords=self.domain.getX()
        tol=1e-8
        pde=LinearPDE(self.domain, numEquations=1)
        pde.getSolverOptions().setTolerance(tol)
        pde.setSymmetryOn()
        primaryPde=LinearPDE(self.domain, numEquations=1)
        primaryPde.getSolverOptions().setTolerance(tol)
        primaryPde.setSymmetryOn()
        DIM=self.domain.getDim()
        x=self.domain.getX()
        q=es.whereZero(x[DIM-1]-es.inf(x[DIM-1]))
        for i in xrange(DIM-1):
            xi=x[i]
            q+=es.whereZero(xi-es.inf(xi))+es.whereZero(xi-es.sup(xi))
        A = self.secondaryConductivity * es.kronecker(self.domain)
        APrimary = self.primaryConductivity * es.kronecker(self.domain)
        pde.setValue(A=A,q=q)
        primaryPde.setValue(A=APrimary,q=q)

        delPhiSecondaryList = []
        delPhiPrimaryList = []
        delPhiTotalList = []
        for i in range(1,self.n+1): # 1 to n
            maxR = self.numElectrodes - 1 - (2*i) #max amount of readings that will fit in the survey
            delPhiSecondary = []
            delPhiPrimary = []
            delPhiTotal = []
            for j in range(maxR):
                y_dirac=es.Scalar(0,es.DiracDeltaFunctions(self.domain))
                y_dirac.setTaggedValue(self.electrodeTags[j],self.current)
                y_dirac.setTaggedValue(self.electrodeTags[j + ((2*i) + 1)],-self.current)
                self.sources.append([self.electrodeTags[j], self.electrodeTags[j + ((2*i) + 1)]])
                primaryPde.setValue(y_dirac=y_dirac)
                numericPrimaryPot = primaryPde.getSolution()
                X=(primCon-self.secondaryConductivity) * es.grad(numericPrimaryPot)
                pde.setValue(X=X)
                u=pde.getSolution()
                loc=Locator(self.domain,[self.electrodes[j+i],self.electrodes[j+i+1]])
                self.samples.append([self.electrodeTags[j+i],self.electrodeTags[j+i+1]])
                valPrimary=loc.getValue(numericPrimaryPot)
                valSecondary=loc.getValue(u)
                delPhiPrimary.append(valPrimary[1]-valPrimary[0])
                delPhiSecondary.append(valSecondary[1]-valSecondary[0])
                delPhiTotal.append(delPhiPrimary[j]+delPhiSecondary[j])
            delPhiPrimaryList.append(delPhiPrimary)
            delPhiSecondaryList.append(delPhiSecondary)
            delPhiTotalList.append(delPhiTotal)

        self.delPhiPrimaryList=delPhiPrimaryList
        self.delPhiSecondaryList=delPhiSecondaryList
        self.delPhiTotalList = delPhiTotalList
        return [delPhiPrimaryList, delPhiSecondaryList, delPhiTotalList]
 def test_replaceInfExpanded(self):
     dom=self.domain
     scl=es.Scalar(1,es.ContinuousFunction(dom))
     scl.expand()
     sclNaN=scl/0
     self.assertTrue(sclNaN.hasInf(),"sclNaN should contain Inf but its doesn't")
     sclNaN.replaceNaN(17.0) # Make sure it is distinguishing between NaN and Inf
     sclNaN.replaceInf(15.0)
     self.assertEqual(es.Lsup(sclNaN), 15.0)
     scl=es.Scalar(10,es.ContinuousFunction(dom))
     scl.expand()
     scl.promote()
     if not es.getEscriptParamInt('AUTOLAZY')==1:            
         sclNaN=scl/0
         self.assertTrue(sclNaN.hasInf(),"sclNaN should contain Inf but its doesn't")
         sclNaN.replaceInf(3+4j)
         sclNaN.replaceNaN(3+19j)    # Make sure it is distinguishing between NaN and Inf
         self.assertEqual(es.Lsup(sclNaN), 5.0)
Exemple #8
0
 def __setOutput(self):
     x = self.domain.getX()
     self.__location_of_constraint = es.Scalar(0, x.getFunctionSpace())
     if self.domain.getDim() == 3:
         vertex = [es.inf(x[0]), es.inf(x[1]), es.inf(x[2])]
     else:
         vertex = [es.inf(x[0]), es.inf(x[1])]
     self.__location_of_constraint = es.whereZero(es.length(x - vertex),
                                                  self.tol)
     if not self.value is None:
         self.__value_of_constraint = self.__location_of_constraint * self.value
Exemple #9
0
    def getGradientAtPoint(self):
        """
        returns the gradient of the cost function J with respect to m.

        :note: This implementation returns Y_k=dPsi/dm_k and X_kj=dPsi/dm_kj
        """

        # Using cached values
        m = self.__pre_input
        grad_m = self.__pre_args

        mu = self.__mu
        mu_c = self.__mu_c
        DIM = self.getDomain().getDim()
        numLS = self.getNumLevelSets()

        grad_m = escript.grad(m, escript.Function(m.getDomain()))
        if self.__w0 is not None:
            Y = m * self.__w0 * mu
        else:
            if numLS == 1:
                Y = escript.Scalar(0, grad_m.getFunctionSpace())
            else:
                Y = escript.Data(0, (numLS, ), grad_m.getFunctionSpace())

        if self.__w1 is not None:

            if numLS == 1:
                X = grad_m * self.__w1 * mu
            else:
                X = grad_m * self.__w1
                for k in range(numLS):
                    X[k, :] *= mu[k]
        else:
            X = escript.Data(0, grad_m.getShape(), grad_m.getFunctionSpace())

        # cross gradient terms:
        if numLS > 1:
            for k in range(numLS):
                grad_m_k = grad_m[k, :]
                l2_grad_m_k = escript.length(grad_m_k)**2
                for l in range(k):
                    grad_m_l = grad_m[l, :]
                    l2_grad_m_l = escript.length(grad_m_l)**2
                    grad_m_lk = inner(grad_m_l, grad_m_k)
                    f = mu_c[l, k] * self.__wc[l, k]
                    X[l, :] += f * (l2_grad_m_k * grad_m_l -
                                    grad_m_lk * grad_m_k)
                    X[k, :] += f * (l2_grad_m_l * grad_m_k -
                                    grad_m_lk * grad_m_l)

        return pdetools.ArithmeticTuple(Y, X)
Exemple #10
0
    def __init__(self, domain, reference=CartesianReferenceSystem()):
        """
        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`
        """
        self.__domain = domain
        self.__reference_system = reference
        self._volumefactor = esc.Scalar(1., esc.Function(domain))
        self._scaling_factors = esc.Vector(1., esc.Function(domain))
Exemple #11
0
 def __setOutput(self):
     x = self.domain.getX()
     self.__location_of_constraint = es.Scalar(0, x.getFunctionSpace())
     if self.domain.getDim() == 3:
         x0, x1, x2 = x[0], x[1], x[2]
         d = max(
             es.sup(x0) - es.inf(x0),
             sup(x1) - es.inf(x1),
             sup(x2) - es.inf(x2))
         if self.left:
             self.__location_of_constraint += es.whereZero(
                 x0 - es.inf(x0), self.tol * d)
         if self.right:
             self.__location_of_constraint += es.whereZero(
                 x0 - es.sup(x0), self.tol * d)
         if self.front:
             self.__location_of_constraint += es.whereZero(
                 x1 - es.inf(x1), self.tol * d)
         if self.back:
             self.__location_of_constraint += es.whereZero(
                 x1 - es.sup(x1), self.tol * d)
         if self.bottom:
             self.__location_of_constraint += es.whereZero(
                 x2 - es.inf(x2), self.tol * d)
         if self.top:
             self.__location_of_constraint += es.whereZero(
                 x2 - es.sup(x2), self.tol * d)
     else:
         x0, x1 = x[0], x[1]
         d = max(es.sup(x0) - es.inf(x0), es.sup(x1) - es.inf(x1))
         if self.left:
             self.__location_of_constraint += es.whereZero(
                 x0 - es.inf(x0), self.tol * d)
         if self.right:
             self.__location_of_constraint += es.whereZero(
                 x0 - es.sup(x0), self.tol * d)
         if self.bottom:
             self.__location_of_constraint += es.whereZero(
                 x1 - es.inf(x1), self.tol * d)
         if self.top:
             self.__location_of_constraint += es.whereZero(
                 x1 - es.sup(x1), self.tol * d)
     if not self.value is None:
         self.__value_of_constraint = self.__location_of_constraint * self.value
Exemple #12
0
 def getLocalAvgRotation(self):
    rot=escript.Scalar(0,escript.Function(self.__domain))
    r = self.__pool.map(avgRotation2D,self.__scenes)
    for i in range(self.__numGaussPoints):
       rot.setValueOfDataPoint(i,r[i])
    return rot
Exemple #13
0
 def getEquivalentPorosity(self):
    porosity=escript.Scalar(0,escript.Function(self.__domain))
    p = self.__pool.map(getEquivalentPorosity,self.__scenes)
    for i in range(self.__numGaussPoints):
       porosity.setValueOfDataPoint(i,p[i])
    return porosity
    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()
Exemple #15
0
 def getLocalDebondNum(self):
    num=escript.Scalar(0,escript.Function(self.__domain))
    n = self.__pool.map(DebondNum,self.__scenes)
    for i in xrange(self.__numGaussPoints):
       num.setValueOfDataPoint(i,n[i])
    return num
Exemple #16
0
 def getLocalVoidRatio(self):
     void = escript.Scalar(0, escript.Function(self.__domain))
     e = self.__pool.map(getVoidRatio, self.__scenes)
     for i in xrange(self.__numGaussPoints):
         void.setValueOfDataPoint(i, e[i])
     return void
Exemple #17
0
domain = finley.ReadGmsh(mesh_file, 3)
mesh_tags = escript.getTagNames(domain)
directionVector = [1, 0]

# -------------------------------------------------------------------------------------------------
# Define the primary and secondary resistivity model.
# -------------------------------------------------------------------------------------------------

#<Note>: the mesh was created with domains, which were all 'tagged' with unique id-s;
# based on the tagged domain id-s, the conductivity values are assigned to the domains.
#<Note>: the primary conductivity is the conductivity in the vicinity of the electrodes;
# the secondary conductivity is defined as the difference between primary and the
# actual input conductivity.

# Setup primary and secondary conductivity objects:
sig_p = escript.Scalar(0, escript.ContinuousFunction(domain))
sig_s = escript.Scalar(0, escript.ContinuousFunction(domain))

# Cycle tag_values dictionary and assign conductivity values;
# this is done for both, primary and secondary, potentials as
# both dictionaries are setup with identical dictionary-keys:
for tag in tag_p:
    # All initially defined tags must be in the tag list.
    # Print an error if it doesn't and exit the program.
    if tag in mesh_tags:
        # Assign value:
        sig_p.setTaggedValue(tag, tag_p[tag])
        sig_s.setTaggedValue(tag, tag_s[tag])
    else:
        print("Error: the defined tag is not defined in the mesh: " & tag)
        sys.exit()