示例#1
0
    def wavePropagation(domain, h, tend, lam, mu, rho, xc, src_radius, U0):
        # lists to collect displacement at point source
        ts, u_pc0, u_pc1, u_pc2 = [], [], [], []
        x = domain.getX()
        # ... open new PDE ...
        mypde = LinearPDE(domain)
        mypde.getSolverOptions().setSolverMethod(SolverOptions.HRZ_LUMPING)
        kron = kronecker(mypde.getDim())

        dunit = numpy.array([1., 0., 0.])  # defines direction of point source

        mypde.setValue(D=kron * rho,
                       q=whereNegative(length(x - xc) - src_radius) * dunit)
        # ... set initial values ....
        n = 0
        # for first two time steps
        u = Vector(0., Solution(domain))
        u_last = Vector(0., Solution(domain))
        t = 0

        # define the location of the point source
        L = Locator(domain, xc)
        # find potential at point source
        u_pc = L.getValue(u)
        print("u at point charge = %s" % u_pc)
        ts.append(t)
        u_pc0.append(u_pc[0]), u_pc1.append(u_pc[1]), u_pc2.append(u_pc[2])

        while t < tend:
            t += h
            # ... get current stress ....
            g = grad(u)
            stress = lam * trace(g) * kron + mu * (g + transpose(g))
            # ... get new acceleration ....
            amplitude = U0 * (4 * (t - t0)**3 / alpha**3 - 6 *
                              (t - t0) / alpha) * sqrt(2.) / alpha**2 * exp(
                                  1. / 2. - (t - t0)**2 / alpha**2)
            mypde.setValue(X=-stress, r=dunit * amplitude)
            a = mypde.getSolution()
            # ... get new displacement ...
            u_new = 2 * u - u_last + h**2 * a
            # ... shift displacements ....
            u_last = u
            u = u_new
            n += 1
            print("time step %d, t = %s" % (n, t))
            u_pc = L.getValue(u)
            print("u at point charge = %s" % u_pc)
            ts.append(t)
            u_pc0.append(u_pc[0]), u_pc1.append(u_pc[1]), u_pc2.append(u_pc[2])

            # ... save current acceleration in units of gravity and displacements
            if n == 1 or n % 10 == 0:
                saveVTK("./data/usoln.%i.vtu" % (n / 10),
                        acceleration=length(a) / 9.81,
                        displacement=length(u),
                        tensor=stress,
                        Ux=u[0])
        return ts, u_pc0, u_pc1, u_pc2
    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 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=whereZero(x[DIM-1]-inf(x[DIM-1]))
        for i in xrange(DIM-1):
            xi=x[i]
            q+=whereZero(xi-inf(xi))+whereZero(xi-sup(xi))
        A = self.secondaryConductivity * kronecker(self.domain)
        APrimary = self.primaryConductivity * 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=Scalar(0,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) * 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 getPotential(self):
        """
        returns a list containing 3 lists one for each the primary, secondary
        and total potential.
        """


        primCon=self.primaryConductivity
        coords=self.domain.getX()
        pde=LinearPDE(self.domain, numEquations=1)
        tol=1e-8
        pde.getSolverOptions().setTolerance(tol)
        pde.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)
        pde.setValue(A=A,q=q)

        delPhiSecondary = []
        delPhiPrimary = []
        delPhiTotal = []
        if(len(self.electrodes[0])==3):

            for i in range(self.numElectrodes-1):
                analyticRs=es.Data(0,(3,),es.ContinuousFunction(self.domain))
                analyticRs[0]=(coords[0]-self.electrodes[i][0])
                analyticRs[1]=(coords[1]-self.electrodes[i][1])
                analyticRs[2]=(coords[2])
                rsMag=(analyticRs[0]**2+analyticRs[1]**2+analyticRs[2]**2)**0.5
                analyticPrimaryPot=(self.current*(1./primCon))/(2*pi*(rsMag+(es.whereZero(rsMag)*0.0000001))) #the magic number 0.0000001 is to avoid devide by 0
                analyticRsPolePower=(analyticRs[0]**2+analyticRs[1]**2+analyticRs[2]**2)**1.5
                analyticRsPolePower = analyticRsPolePower+(es.whereZero(analyticRsPolePower)*0.0000001)
                gradUPrimary = es.Data(0,(3,),es.ContinuousFunction(self.domain))
                gradUPrimary[0] =(self.current/(2*pi*primCon)) * (analyticRs[0]/analyticRsPolePower)
                gradUPrimary[1] =(self.current/(2*pi*primCon)) * (analyticRs[1]/analyticRsPolePower)
                gradUPrimary[2] =(self.current/(2*pi*primCon)) * (analyticRs[2]/analyticRsPolePower)
                gradUPrimary=-gradUPrimary
                X=(primCon-self.secondaryConductivity) * gradUPrimary
                pde.setValue(X=X)
                u=pde.getSolution()
                loc=Locator(self.domain,self.electrodes[i+1])
                delPhiSecondary.append(loc.getValue(u))
                delPhiPrimary.append(loc.getValue(analyticPrimaryPot))
        else:
            raise NotImplementedError("2d forward model is not yet implemented")

        self.delPhiSecondary = delPhiSecondary
        self.delPhiPrimary = delPhiPrimary
        for i in range(len(delPhiPrimary)):
            delPhiTotal.append(delPhiPrimary[i] + delPhiSecondary[i])
        self.delPhiTotal=delPhiTotal
        return [delPhiPrimary, delPhiSecondary, delPhiTotal]
    def getPotential(self):
        """
        returns a list containing 3 lists one for each the primary, secondary
        and total potential.
        """


        primCon=self.primaryConductivity
        coords=self.domain.getX()
        pde=LinearPDE(self.domain, numEquations=1)
        tol=1e-8
        pde.getSolverOptions().setTolerance(tol)
        pde.setSymmetryOn()

        DIM=self.domain.getDim()
        x=self.domain.getX()
        q=whereZero(x[DIM-1]-inf(x[DIM-1]))
        for i in xrange(DIM-1):
            xi=x[i]
            q+=whereZero(xi-inf(xi))+whereZero(xi-sup(xi))
        A = self.secondaryConductivity * kronecker(self.domain)
        pde.setValue(A=A,q=q)

        delPhiSecondary = []
        delPhiPrimary = []
        delPhiTotal = []
        if(len(self.electrodes[0])==3):

            for i in range(self.numElectrodes-1):
                analyticRs=Data(0,(3,),ContinuousFunction(self.domain))
                analyticRs[0]=(coords[0]-self.electrodes[i][0])
                analyticRs[1]=(coords[1]-self.electrodes[i][1])
                analyticRs[2]=(coords[2])
                rsMag=(analyticRs[0]**2+analyticRs[1]**2+analyticRs[2]**2)**0.5
                analyticPrimaryPot=(self.current*(1./primCon))/(2*pi*(rsMag+(whereZero(rsMag)*0.0000001))) #the magic number 0.0000001 is to avoid devide by 0
                analyticRsPolePower=(analyticRs[0]**2+analyticRs[1]**2+analyticRs[2]**2)**1.5
                analyticRsPolePower = analyticRsPolePower+(whereZero(analyticRsPolePower)*0.0000001)
                gradUPrimary = Data(0,(3,),ContinuousFunction(self.domain))
                gradUPrimary[0] =(self.current/(2*pi*primCon)) * (analyticRs[0]/analyticRsPolePower)
                gradUPrimary[1] =(self.current/(2*pi*primCon)) * (analyticRs[1]/analyticRsPolePower)
                gradUPrimary[2] =(self.current/(2*pi*primCon)) * (analyticRs[2]/analyticRsPolePower)
                gradUPrimary=-gradUPrimary
                X=(primCon-self.secondaryConductivity) * gradUPrimary
                pde.setValue(X=X)
                u=pde.getSolution()
                loc=Locator(self.domain,self.electrodes[i+1])
                delPhiSecondary.append(loc.getValue(u))
                delPhiPrimary.append(loc.getValue(analyticPrimaryPot))
        else:
            raise NotImplementedError("2d forward model is not yet implemented")

        self.delPhiSecondary = delPhiSecondary
        self.delPhiPrimary = delPhiPrimary
        for i in range(len(delPhiPrimary)):
            delPhiTotal.append(delPhiPrimary[i] + delPhiSecondary[i])
        self.delPhiTotal=delPhiTotal
        return [delPhiPrimary, delPhiSecondary, delPhiTotal]
示例#6
0
 def __init__(self, name, domain, Q=[0.], schedule=[0.], phase="Water", BHP_limit=1.*U.atm, X0=[0.,0.,0.], *args, **kwargs):
     """
     set up well 
     """
     if not len(schedule) == len(Q):
         raise ValueError("length of schedule and Q must match.")
     self.__schedule=schedule
     self.__Q = Q
     self.__phase=phase
     self.__BHP_limit=BHP_limit
     self.name=name
     self.domain=domain
     self.locator=Locator(DiracDeltaFunctions(self.domain),X0[:self.domain.getDim()])
     self.X0=self.locator.getX()
示例#7
0
def cbphones(domain, U, phones, dim, savepath=""):
    #find the number of geophones
    nphones = len(phones)
    u_pot = np.zeros([nphones, dim], float)

    for i in range(0, nphones):
        # define the location of the phone source
        L = Locator(domain, numpy.array(phones[i]))
        # find potential at point source.
        temp = L.getValue(U)
        for j in range(0, dim):
            u_pot[i, j] = temp[j]

    # open file to save displacement at point source
    return u_pot
示例#8
0
def cbphones(domain,U,phones,dim,savepath=""):
   #find the number of geophones
   nphones = len(phones)
   u_pot = np.zeros([nphones,dim],float)
   
   for i in range(0,nphones):
     # define the location of the phone source 
     L=Locator(domain,numpy.array(phones[i]))
     # find potential at point source.
     temp = L.getValue(U)
     for j in range(0,dim):
       u_pot[i,j]=temp[j]

   # open file to save displacement at point source
   return u_pot
示例#9
0
class Well(object):
   """
   generic well
   
   :var WATER: phase identifier for water well
   :var GAS: phase identifier for gas well
   """
   WATER="Water"
   GAS="Gas"
   def __init__(self, name, domain, Q=[0.], schedule=[0.], phase="Water", BHP_limit=1.*U.atm, X0=[0.,0.,0.], *args, **kwargs):
       """
       set up well 
       """
       if not len(schedule) == len(Q):
           raise ValueError("length of schedule and Q must match.")
       self.__schedule=schedule
       self.__Q = Q
       self.__phase=phase
       self.__BHP_limit=BHP_limit
       self.name=name
       self.domain=domain
       self.locator=Locator(DiracDeltaFunctions(self.domain),X0[:self.domain.getDim()])
       self.X0=self.locator.getX()
       
   def getLocation(self):
       return self.X0      

   def getProductivityIndex(self):
       """
       returns the productivity index of the well.
       typically a Gaussian profile around the location of the well.
       
       :note: needs to be overwritten
       """
       raise NotImplementedError
   
   def getFlowRate(self,t):
      """
      returns the flow rate
      """
      out=0.
      for i in range(len(self.__schedule)):
         if t <= self.__schedule[i]:
             out=self.__Q[i]
             break
      return out
         
   def getBHPLimit(self):
      """
      return bottom-hole pressure limit
      
      :note: needs to be overwritten
      """
      return self.__BHP_limit
      
   def getPhase(self):
      """
      returns the pahse the well works on
      """
      return self.__phase
示例#10
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])
示例#11
0
    def test_PDE2D(self):
        dx_tests = 0.1
        sigma0 = 1.
        electrodes = [(0.5 - 2 * dx_tests, 1.), (0.5 - dx_tests, 1.),
                      (0.5 + dx_tests, 1.), (0.5 + 2 * dx_tests, 1.)]
        domain = finRectangle(20,
                              20,
                              d1=mpisize,
                              diracPoints=electrodes,
                              diracTags=["sl0", "sl1", "sr0", "sr1"])
        loc = Locator(domain, electrodes[2:])

        # this creates some reference Data:
        x = domain.getX()
        q = whereZero(x[0] - inf(x[0])) + whereZero(
            x[0] - sup(x[0])) + whereZero(x[1] - inf(x[1]))
        ppde = LinearPDE(domain, numEquations=1)
        s = Scalar(0., DiracDeltaFunctions(domain))
        s.setTaggedValue("sl0", 1.)
        s.setTaggedValue("sl1", -1.)
        ppde.setValue(A=kronecker(2) * sigma0, q=q, y_dirac=s)
        pp = ppde.getSolution()
        uu = loc(pp)

        # arguments for DcRes
        current = 10.
        sourceInfo = ["sl0", "sl1"]
        sampleTags = [("sr0", "sr1")]

        sigmaPrimary = 7.
        phiPrimary = pp * current * sigma0 / sigmaPrimary

        uuscale = 1 - current * sigma0 / sigmaPrimary
        delphi_in = [(uu[1] - uu[0]) * uuscale]

        acw = DcRes(domain, loc, delphi_in, sampleTags, phiPrimary,
                    sigmaPrimary)

        self.assertLess(Lsup(phiPrimary - acw.getPrimaryPotential()),
                        1.e-10 * Lsup(acw.getPrimaryPotential()))

        SIGMA = 10.  # matches current
        args0 = acw.getArguments(SIGMA)
        p = args0[0]
        u = args0[1]

        # true secondary potential
        pps = pp - phiPrimary
        self.assertLess(Lsup(p - pps), 1.e-6 * Lsup(pps))

        # test return values at electrodes:
        self.assertLess(abs(u[0] - uu[0] * uuscale),
                        1.e-6 * abs(uu[0] * uuscale))
        self.assertLess(abs(u[1] - uu[1] * uuscale),
                        1.e-6 * abs(uu[1] * uuscale))

        # this sould be zero
        dd = acw.getDefect(SIGMA, *args0)
        self.assertTrue(dd >= 0.)
        self.assertTrue(dd <= 1e-7)
示例#12
0
class Well(object):
   """
   generic well
   
   :var WATER: phase identifier for water well
   :var GAS: phase identifier for gas well
   """
   WATER="Water"
   GAS="Gas"
   def __init__(self, name, domain, Q=[0.], schedule=[0.], phase="Water", BHP_limit=1.*U.atm, X0=[0.,0.,0.], *args, **kwargs):
       """
       set up well 
       """
       if not len(schedule) == len(Q):
           raise ValueError("length of schedule and Q must match.")
       self.__schedule=schedule
       self.__Q = Q
       self.__phase=phase
       self.__BHP_limit=BHP_limit
       self.name=name
       self.domain=domain
       self.locator=Locator(DiracDeltaFunctions(self.domain),X0[:self.domain.getDim()])
       self.X0=self.locator.getX()
       
   def getLocation(self):
       return self.X0      

   def getProductivityIndex(self):
       """
       returns the productivity index of the well.
       typically a Gaussian profile around the location of the well.
       
       :note: needs to be overwritten
       """
       raise NotImplementedError
   
   def getFlowRate(self,t):
      """
      returns the flow rate
      """
      out=0.
      for i in range(len(self.__schedule)):
         if t <= self.__schedule[i]:
             out=self.__Q[i]
             break
      return out
         
   def getBHPLimit(self):
      """
      return bottom-hole pressure limit
      
      :note: needs to be overwritten
      """
      return self.__BHP_limit
      
   def getPhase(self):
      """
      returns the pahse the well works on
      """
      return self.__phase
示例#13
0
 def setUp(self):
     self.domain = Rectangle(self.NEX,
                             self.NEZ,
                             l0=self.WIDTH,
                             l1=self.DEPTH)
     self.loc = Locator(
         ReducedFunction(self.domain),
         [(self.STATION_OFFSET, self.DEPTH - self.DEPTH / self.NEZ / 2)])
示例#14
0
 def setUp(self):
     Width = self.DX * self.NEx
     Center = self.NEx // 2 * self.DX
     self.domain = Rectangle(self.NEx,
                             self.NEx,
                             l0=Width,
                             l1=Width,
                             diracPoints=[(Center, Center)],
                             diracTags=["src"],
                             order=self.Order,
                             fullOrder=True)
     numStation = (self.NEx // 2 - 3 - self.NE_STATION0 - 1)
     stations = [((self.NE_STATION0 + i) * self.DX, Center)
                 for i in range(numStation)]
     self.loc = Locator(Solution(self.domain), stations)
     self.source = Scalar(0j, DiracDeltaFunctions(self.domain))
     self.source.setTaggedValue("src", self.Amplitude)
     self.sourceX = (Center, Center)
示例#15
0
    def gzpot(p, y, x, *args):
        #rho, rhox, rhoy, R = p
        rhox = args[0] / 2.
        rhoy = args[1] / 2.
        rho, R, z = p
        #Domain related.
        mx = args[0]
        my = args[1]
        #PDE related
        G = 6.67300 * 10E-11

        #DOMAIN CONSTRUCTION
        domain = ReadGmsh('data/example10m/example10m.msh', 2)
        domx = Solution(domain).getX()
        mask = wherePositive(R - length(domx - rholoc))
        rhoe = rho * mask
        kro = kronecker(domain)

        q = whereZero(domx[1] - my) + whereZero(domx[1]) + whereZero(
            domx[0]) + whereZero(domx[0] - mx)
        #ESCRIPT PDE CONSTRUCTION
        mypde = LinearPDE(domain)
        mypde.setValue(A=kro, Y=4. * np.pi * G * rhoe, q=q, r=0.0)
        mypde.setSymmetryOn()
        sol = mypde.getSolution()

        g_field = grad(sol)  #The graviational accelleration g.
        g_fieldz = g_field * [0, 1]  #The vertical component of the g field.
        gz = length(g_fieldz)  #The magnitude of the vertical component.

        #MODEL SIZE SAMPLING
        sol_escgz = []
        sol_escx = []
        for i in range(0, len(x)):
            sol_escgz.append([x[i], rhoy + z])

        sample = []  # array to hold values
        rec = Locator(gz.getFunctionSpace(), sol_escgz)  #location to record
        psol = rec.getValue(gz)

        err = np.sum((np.array(y) - np.array(psol))**2.)
        print("Lsup= ",
              Lsup(np.array(psol) - np.array(sol_angz)) / Lsup(np.array(psol)))
        return err
示例#16
0
    def __init__(self,
                 domain,
                 survey,
                 locations=[],
                 field_resolution=1.,
                 field_origin=(0., 0., 0),
                 sigma_background=0.1,
                 gamma_background=0.0001,
                 padding_tags=[],
                 stationsFMT=None):
        self.domain = domain
        self.survey = survey
        self.locations = locations
        self.stationsFMT = stationsFMT
        self.pde = setupERTPDE(domain)
        x = self.pde.getDomain().getX()[0]
        y = self.pde.getDomain().getX()[1]
        z = self.pde.getDomain().getX()[2]
        self.pde.setValue(q=whereZero(x - inf(x)) + whereZero(x - sup(x)) +
                          whereZero(y - inf(y)) + whereZero(y - sup(y)) +
                          whereZero(z - inf(z)))

        self.locations = locations
        self.observation_locator = Locator(Solution(domain), [
            self.survey.getStationLocation(s)
            for s in self.survey.getObservationElectrodes()
        ])
        self.source_locator = Locator(ContinuousFunction(domain), [
            self.survey.getStationLocation(ip)
            for ip in self.survey.getInjectionStations()
        ])

        self.field_resolution = field_resolution
        self.field_origin = field_origin
        self.sigma_background = sigma_background
        self.gamma_background = gamma_background
        self.padding_tags = padding_tags

        self.injections = [i for i in self.survey.injectionIterator()]
        self.injectionMap = [k for k in range(len(self.injections))]

        self.setUpDataMaps()
        self.setPrimaryPotential()
示例#17
0
def subsample(u, nx=50, ny=50):
    """
    subsamples ```u``` over an ```nx``` x ```ny``` grid
    and returns ``numpy`` arrays for the values and locations
    used for subsampling.
    """
    xx = u.getDomain().getX()  # points of the domain
    x0 = inf(xx[0])
    y0 = inf(xx[1])
    dx = (sup(xx[0]) - x0) / nx  # x spacing
    dy = (sup(xx[1]) - y0) / ny  # y spacing
    grid = []
    for j in range(0, ny - 1):
        for i in range(0, nx - 1):
            grid.append([x0 + dx / 2 + dx * i, y0 + dy / 2 + dy * j])
    uLoc = Locator(u.getFunctionSpace(), grid)
    subu = uLoc(u)  # get data of u at sample points closests to grid points
    usublocs = uLoc.getX()  #returns actual locations from data
    return np.array(usublocs), np.array(subu)
示例#18
0
def subsample(u, nx=50, ny=50):
    """
    subsamples ```u``` over an ```nx``` x ```ny``` grid
    and returns ``numpy`` arrays for the values and locations
    used for subsampling.
    """
    xx=u.getDomain().getX()  # points of the domain
    x0=inf(xx[0])         
    y0=inf(xx[1])
    dx = (sup(xx[0])-x0)/nx # x spacing
    dy = (sup(xx[1])-y0)/ny # y spacing
    grid = [ ] 
    for j in range(0,ny-1):
        for i in range(0,nx-1):
               grid.append([x0+dx/2+dx*i,y0+dy/2+dy*j])
    uLoc = Locator(u.getFunctionSpace(),grid)
    subu= uLoc(u) # get data of u at sample points closests to grid points
    usublocs = uLoc.getX() #returns actual locations from data
    return np.array(usublocs), np.array(subu)
示例#19
0
    def test_Differential2D(self):
        INC=0.001
        sigma0=1.
        dx_tests=0.1
        electrodes=[(0.5-2*dx_tests,1.), (0.5-dx_tests,1.), (0.5+dx_tests,1.), (0.5+2*dx_tests,1.)]
        domain=finRectangle(20,20, d1=mpisize,  diracPoints=electrodes, diracTags=["sl0", "sl1", "sr0", "sr1"] )
        loc=Locator(domain,electrodes[2:])

        # arguments for DcRes
        #current = 10.
        sampleTags = [ ("sr0", "sr1") ]

        delphi_in = [ 0.05 ]

        sigmaPrimary=1
        x=domain.getX()
        phiPrimary=(x[0]-inf(x[0]))*(x[1]-inf(x[1]))*(x[0]-sup(x[0]))

        acw=DcRes(domain, loc, delphi_in, sampleTags,  phiPrimary, sigmaPrimary)

        #=====================================================================
        x=Function(domain).getX()
        SIGMA0=x[0]*x[1]+1
        args0=acw.getArguments(SIGMA0)
        d0=acw.getDefect(SIGMA0, *args0)
        grad_d=acw.getGradient(SIGMA0, *args0)

        dS=exp(-(length(x-[0.5,0.5])/0.2)**2)
        SIGMA1=SIGMA0+INC*dS
        args1=acw.getArguments(SIGMA1)
        d1=acw.getDefect(SIGMA1, *args1)
        ref=abs((d1-d0)/INC)
        self.assertLess(abs((d1-d0)/INC-integrate(grad_d* dS)), ref * 1.e-3)

        dS=-exp(-(length(x-[0.5,0.5])/0.2)**2)
        SIGMA2=SIGMA0+INC*dS
        args2=acw.getArguments(SIGMA2)
        d2=acw.getDefect(SIGMA2, *args2)
        ref=abs((d2-d0)/INC)
        self.assertLess(abs((d2-d0)/INC-integrate(grad_d* dS)), ref * 1.e-3)

        dS=-1
        SIGMA3=SIGMA0+INC*dS
        args3=acw.getArguments(SIGMA3)
        d3=acw.getDefect(SIGMA3, *args3)
        ref=abs((d3-d0)/INC)
        self.assertLess(abs((d3-d0)/INC-integrate(grad_d* dS)), ref * 1.e-3)

        dS=1
        SIGMA4=SIGMA0+INC*dS
        args4=acw.getArguments(SIGMA4)
        d4=acw.getDefect(SIGMA4, *args4)
        ref=abs((d4-d0)/INC)
        self.assertLess(abs((d4-d0)/INC-integrate(grad_d* dS)), ref * 1.e-3)
示例#20
0
    def gzpot(p, y, x, *args):
        #rho, rhox, rhoy, R = p
        rhox=args[0]/2.; rhoy=args[1]/2.
        rho, R, z =p
        #Domain related.
        mx = args[0]; my = args[1];
        #PDE related
        G=6.67300*10E-11

        #DOMAIN CONSTRUCTION
        domain=ReadGmsh('data/example10m/example10m.msh',2)
        domx=Solution(domain).getX()
        mask=wherePositive(R-length(domx-rholoc))
        rhoe=rho*mask
        kro=kronecker(domain)

        q=whereZero(domx[1]-my)+whereZero(domx[1])+whereZero(domx[0])+whereZero(domx[0]-mx)
        #ESCRIPT PDE CONSTRUCTION
        mypde=LinearPDE(domain)
        mypde.setValue(A=kro,Y=4.*np.pi*G*rhoe,q=q,r=0.0)
        mypde.setSymmetryOn()
        sol=mypde.getSolution()

        g_field=grad(sol) #The graviational accelleration g.
        g_fieldz=g_field*[0,1] #The vertical component of the g field.
        gz=length(g_fieldz) #The magnitude of the vertical component.

        #MODEL SIZE SAMPLING
        sol_escgz=[]
        sol_escx=[]
        for i in range(0,len(x)):
            sol_escgz.append([x[i],rhoy+z])

        sample=[] # array to hold values
        rec=Locator(gz.getFunctionSpace(),sol_escgz) #location to record
        psol=rec.getValue(gz)

        err = np.sum((np.array(y) - np.array(psol))**2.)
        print("Lsup= ",Lsup(np.array(psol)-np.array(sol_angz))/Lsup(np.array(psol)))
        return err
示例#21
0
 def setUp(self):
     self.domain = Rectangle(self.NEX,
                             self.NEZ,
                             l0=self.WIDTH,
                             l1=self.DEPTH)
     self.loc = Locator(ReducedFunction(self.domain),
                        [(self.STATION_OFFSET, self.DEPTH - self.AIR_LAYER -
                          self.DEPTH / self.NEZ / 2)])
     self.airLayerMask = whereNonNegative(self.domain.getX()[1] -
                                          self.DEPTH + self.AIR_LAYER)
     self.airLayerMaskCenter = whereNonNegative(
         ReducedFunction(self.domain).getX()[1] - self.DEPTH +
         self.AIR_LAYER)
示例#22
0
 def __init__(self, name, domain, Q=[0.], schedule=[0.], phase="Water", BHP_limit=1.*U.atm, X0=[0.,0.,0.], *args, **kwargs):
     """
     set up well 
     """
     if not len(schedule) == len(Q):
         raise ValueError("length of schedule and Q must match.")
     self.__schedule=schedule
     self.__Q = Q
     self.__phase=phase
     self.__BHP_limit=BHP_limit
     self.name=name
     self.domain=domain
     self.locator=Locator(DiracDeltaFunctions(self.domain),X0[:self.domain.getDim()])
     self.X0=self.locator.getX()
def runValetAcceleration(order):
   domain=finley.Rectangle(100,10,order)
   x=domain.getX()
   
   
   # test Velet scheme 
   dt=inf(domain.getSize()/c)*(1./6.)
   q=whereZero(x[0])+whereZero(x[0]-1.)
   
   mypde_f=LinearSinglePDE(domain)
   mypde_f.setSymmetryOn()
   mypde_f.setValue(D=1,q=q)
   u_f_old=ref_u(x,-dt)
   u_f=ref_u(x,0)
   
   mypde_HRZ=LinearSinglePDE(domain)
   mypde_HRZ.getSolverOptions().setSolverMethod(SolverOptions.HRZ_LUMPING)
   mypde_HRZ.setValue(D=1,q=q)
   u_HRZ_old=ref_u(x,-dt)
   u_HRZ=ref_u(x,0)
   
   mypde_RS=LinearSinglePDE(domain)
   mypde_RS.getSolverOptions().setSolverMethod(SolverOptions.ROWSUM_LUMPING)
   mypde_RS.setValue(D=1,q=q)
   u_RS_old=ref_u(x,-dt)
   u_RS=ref_u(x,0)
   
   l=Locator(domain,[0.5,0.5])
   t=0
   
   u=ref_u(x,t)
   t_list=[t]
   u_list=[l(u)]
   f_list=[l(u_f)]
   HRZ_list=[l(u_HRZ)]
   RS_list=[l(u_RS)]
   print(t_list[-1], u_list[-1], f_list[-1], HRZ_list[-1] , RS_list[-1])
   
   while t< 4/n/c:
       t+=dt
       u=ref_u(x,t)
       mypde_f.setValue(X=-c**2*grad(u_f), r=-c**2*u)
       mypde_HRZ.setValue(X=-c**2*grad(u_HRZ), r=-c**2*u)
       mypde_RS.setValue(X=-c**2*grad(u_RS), r=-c**2*u)
    
       a_f=mypde_f.getSolution()
       a_HRZ=mypde_HRZ.getSolution()
       a_RS=mypde_RS.getSolution()
   
       u_f, u_f_old = 2*u_f-u_f_old + dt**2*a_f ,  u_f
       u_HRZ, u_HRZ_old = 2*u_HRZ-u_HRZ_old + dt**2*a_HRZ ,  u_HRZ
       u_RS, u_RS_old = 2*u_RS-u_RS_old + dt**2*a_RS ,  u_RS
      
       t_list.append(t)
       u_list.append(l(u))
       f_list.append(l(u_f))
       HRZ_list.append(l(u_HRZ))
       RS_list.append(l(u_RS))
       print(t_list[-1], u_list[-1], f_list[-1], HRZ_list[-1] , RS_list[-1])
     
   
   import matplotlib.pyplot as plt
   if getMPIRankWorld() == 0:
         plt.clf()
         plt.plot(t_list, u_list, '-', label="exact", linewidth=1)
         plt.plot(t_list, f_list, '-', label="full", linewidth=1)
         plt.plot(t_list, HRZ_list, '-', label="HRZ lumping", linewidth=1)
         plt.plot(t_list, RS_list, '-', label="row sum lumping", linewidth=1)
         plt.axis([0.,max(t_list),-1.3,1.3])
         plt.xlabel('time')
         plt.ylabel('displacement')
         plt.legend()
         plt.savefig('lumping_valet_a_%d.png'%order, format='png')
示例#24
0
    def __init__(self,
                 domain,
                 data,
                 L_stations=1.,
                 w0=0.,
                 w1=1.,
                 alpha0=1.,
                 alpha1=0.,
                 sigma0=.001,
                 region_fixed=Data(),
                 stationsFMT="e%s",
                 weightLogDefect=0.5,
                 adjustStationLocationsToElementCenter=True,
                 logclip=15):
        """
        cost function for electric field intensity inversion. 
        regularization is 
        
        int( w0* m^2 + w1*grad(m)^2) where log(sigma/sigma0)=p is given a alpha0*p+alpha1*laplace(p)=m
        
        :domain: pde domain
        :data: data, is `fingal.SurveyData`, requires 'E' and - if available - 'RELERR_E' 
        :sigma0: reference conductivity
        :w0: weighting L2 regularization  int m^2
        :w1: weighting H1 regularization  int grad(m)^2
        :alpha0: regularization factor 
        :alpha1: regularization factor 
        :weightLogDefect: weighting factor for the logarithm defect in the cost funtion.
        :region_fixed: mask for fixed conductivity. needs to be set if w1>0 and w0=0 or alpha1> and alpha0=0
        :adjustStationLocationsToElementCenter: moves the station locations to match element centers.
        :stationsFMT: format used to map station keys k to mesh tags stationsFMT%k or None
        :logclip: cliping for p to avoid overflow in conductivity calculation
        :L_stations: radius of electric field averaging. 
        """
        super(DCInversionByFieldIntensity, self).__init__()
        assert weightLogDefect >= 0 and weightLogDefect <= 1, "weightLogDefect needs to be between 0 and 1."
        self.datatol = 1e-30
        self.sigma0 = sigma0
        self.stationsFMT = stationsFMT
        self.weightLogDefect = weightLogDefect
        self.logclip = logclip

        # setup PDE for forward models (potentials are fixed on all faces except the surface)
        self.pde = setupERTPDE(domain)

        x = self.pde.getDomain().getX()[0]
        y = self.pde.getDomain().getX()[1]
        z = self.pde.getDomain().getX()[2]
        self.pde.setValue(q=whereZero(x - inf(x)) + whereZero(x - sup(x)) +
                          whereZero(y - inf(y)) + whereZero(y - sup(y)) +
                          whereZero(z - inf(z)))

        self.data = data

        # when points are adjusted get the element center locations:
        adjustmax = 0.
        if adjustStationLocationsToElementCenter:
            station_locations = []
            for s in data.getStationNumeration():
                station_locations.append(data.getStationLocation(s))
            XStations = Locator(ReducedFunction(domain),
                                station_locations).getX()

        ########################################################
        if getMPIRankWorld() == 0:
            lslogger.info(
                "building misfit weighting (this will take some time)")
        Xcenter = ReducedFunction(domain).getX()
        X = Function(domain).getX()

        self.misfit = lambda: None
        self.misfit.data = {}
        self.misfit.w = {}

        for AB in self.data.injectionIterator():
            self.misfit.w[AB] = Scalar(0., X.getFunctionSpace())
            self.misfit.data[AB] = Scalar(0., X.getFunctionSpace())

        for M in self.data.getObservationElectrodes():
            L_ABS = L_stations
            if adjustStationLocationsToElementCenter:
                xs = XStations[data.getStationNumber(M)]
                adjustmax = max(adjustmax,
                                length(xs - self.data.getStationLocation(M)))
            else:
                xs = self.data.getStationLocation(M)

            mask = whereNegative(
                interpolate(
                    length(Xcenter - xs) - L_ABS, X.getFunctionSpace()))
            for A, B in self.data.getInjections(M):
                E = self.data.getFieldIntensityData((A, B, M))
                RELERR = self.data.getFieldIntensityRelError((A, B, M))
                self.misfit.w[(A, B)].copyWithMask(
                    Scalar(1 / RELERR**2,
                           self.misfit.w[AB].getFunctionSpace()),
                    mask)  # >0 where data are measured @M
                self.misfit.data[(A, B)].copyWithMask(
                    Scalar(E, self.misfit.w[AB].getFunctionSpace()),
                    mask)  # data inserted  @ M

        if getMPIRankWorld() == 0:
            lslogger.debug("re-scaling of misfit weights:")
        for AB in self.data.injectionIterator():
            s = integrate(self.misfit.w[AB])
            self.misfit.data[AB] += whereNonPositive(
                self.misfit.w[AB])  # data inserted  @ M
            assert s > 0, "no observation for dipole %s. Maybe you need to increase the value for L_stations." % (
                str(AB))
            if s > 0:
                self.misfit.w[AB] *= 1. / (s * len(self.misfit.w))
        # primary potentials:
        if getMPIRankWorld() == 0:
            lslogger.info("maximal station adjustment is %e" % adjustmax)
            lslogger.info(
                "building primary electric fields (this will take some time)")

        self.phi_p = self.getPrimaryElectricPotentials(sigma0)
        lslogger.info("Primary potentials for %d injections calculated." %
                      (len(self.phi_p)))
        # this defines the regularization:
        self.w0 = w0
        self.w1 = w1
        self.alpha0 = alpha0
        self.alpha1 = alpha1
        # used for Hessian inverse
        self.Hpde = setupERTPDE(domain)
        self.Hpde.setValue(A=w1 * kronecker(3), D=w0, q=region_fixed)

        if self.alpha1 > 0:
            self.Spde = setupERTPDE(domain)
            self.Spde.setValue(A=self.alpha1 * kronecker(3), D=self.alpha0)
            if not self.alpha0 > 0:
                self.Spde.setValue(q=region_fixed)
        else:
            self.Spde = None
示例#25
0
    g_fieldz = g_field * [0, 1]  #The vertical component of the g field.
    gz = length(g_fieldz)  #The magnitude of the vertical component.
    # Save the output to file.
    saveVTK(os.path.join(save_path,"ex10d.vtu"),\
            grav_pot=sol,g_field=g_field,g_fieldz=g_fieldz,gz=gz,rho=rhoe)

    ################################################MODEL SIZE SAMPLING
    smoother = Projector(domain)  #Function smoother.
    z = 1000.  #Distance of profile from source.
    sol_angz = []  #Array for analytic gz
    sol_anx = []  #Array for x
    #calculate analytic gz and x location.
    for x in range(int(-mx / 2.), int(mx / 2.), 10):
        sol_angz.append(analytic_gz(x, z, R, rho))
        sol_anx.append(x + mx / 2)
    #save analytic solution
    pl.savetxt(os.path.join(save_path, "ex10d_as.asc"), sol_angz)

    sol_escgz = []  #Array for escript solution for gz
    #calculate the location of the profile in the domain
    for i in range(0, len(sol_anx)):
        sol_escgz.append([sol_anx[i], my / 2. - z])

    rec = Locator(gz.getFunctionSpace(), sol_escgz)  #location to record
    psol = rec.getValue(smoother(gz))  #extract the solution
    #save X and escript solution profile to file
    pl.savetxt(os.path.join(save_path, "ex10d_%05d.asc" % mx), psol)
    pl.savetxt(os.path.join(save_path, "ex10d_x%05d.asc" % mx), sol_anx)

    #plot the pofile and analytic solution using example10q.py
示例#26
0
    def __init__(self,
                 domain,
                 data,
                 L_stations=1.,
                 w0=0.,
                 w1=1.,
                 alpha0=1.,
                 alpha1=0.,
                 gamma0=0.001,
                 sigma=0.001,
                 region_fixed=Data(),
                 stationsFMT="e%s",
                 adjustStationLocationsToElementCenter=True,
                 logclip=15,
                 weightLogDefect=0.):
        """
        cost function for chargeability inversion based electric fields. 
        regularization is 
        
        int( w0* m^2 + w1*grad(m)^2) where log(sigma/sigma0)=p is given a alpha0*p+alpha1*laplace(p)=m
        
        :domain: pde domain
        :data: data, is `fingal.SurveyData`, requires 'GAMMA' if available  'RELERR_GAMMA' 
        :gamma0: reference modified chargeability
        :sigma: conductivity
        :w0: weighting L2 regularization  int m^2
        :w1: weighting H1 regularization  int grad(m)^2
        :alpha0: regularization factor 
        :alpha1: regularization factor 
        :weightLogDefect: weighting factor for the logarithm defect in the cost funtion.
        :region_fixed: mask for fixed conductivity. needs to be set if w1>0 and w0=0 or alpha1> and alpha0=0
        :adjustStationLocationsToElementCenter: moves the station locations to match element centers.
        :stationsFMT: format used to map station keys k to mesh tags stationsFMT%k or None
        :logclip: cliping for p to avoid overflow in conductivity calculation
        :L_stations: radius of electric field averaging. 
        """
        super(ChargeabilityInversionByField, self).__init__()
        self.datatol = 1e-30
        self.logclip = logclip
        if getMPIRankWorld() == 0:
            if weightLogDefect > 0:
                lslogger.info("weightLogDefect>0 but ignored.")
            lslogger.info(
                "building misfit weighting (this will take some time)")

        self.weightLogDefect = weightLogDefect
        self.sigma = sigma
        self.gamma0 = gamma0
        self.useDifferenceOfFields = False
        self.stationsFMT = stationsFMT
        self.misfitFunctionSpace = Function(domain)
        # setup PDE:
        self.pde = setupERTPDE(domain)

        x = self.pde.getDomain().getX()[0]
        y = self.pde.getDomain().getX()[1]
        z = self.pde.getDomain().getX()[2]
        self.pde.setValue(q=whereZero(x - inf(x)) + whereZero(x - sup(x)) +
                          whereZero(y - inf(y)) + whereZero(y - sup(y)) +
                          whereZero(z - inf(z)))

        self.data = data

        # when points are adjusted to match element centers:
        adjustmax = 0.
        if adjustStationLocationsToElementCenter:
            station_locations = []
            for s in data.getStationNumeration():
                station_locations.append(data.getStationLocation(s))
            XStations = Locator(ReducedFunction(domain),
                                station_locations).getX()

        ########################################################
        Xcenter = ReducedFunction(domain).getX()
        X = self.misfitFunctionSpace.getX()
        self.misfit = lambda: None
        self.misfit.data = {}
        self.misfit.w = {}

        for AB in self.data.injectionIterator():
            self.misfit.w[AB] = Scalar(0., self.misfitFunctionSpace)
            self.misfit.data[AB] = Scalar(0., self.misfitFunctionSpace)

        for M in self.data.getObservationElectrodes():
            L_ABS = L_stations
            if adjustStationLocationsToElementCenter:
                xs = XStations[data.getStationNumber(M)]
                adjustmax = max(adjustmax,
                                length(xs - self.data.getStationLocation(M)))
            else:
                xs = self.data.getStationLocation(M)

            mask = whereNegative(
                interpolate(
                    length(Xcenter - xs) - L_ABS, self.misfitFunctionSpace))
            for A, B in self.data.getInjections(M):
                GAMMA = self.data.getModifiedChargeabilityData((A, B, M))
                RELERR = self.data.getModifiedChargeabilityRelError((A, B, M))
                if abs(GAMMA) > 0.:
                    self.misfit.w[(A, B)].copyWithMask(
                        Scalar(1. / RELERR**2, self.misfitFunctionSpace),
                        mask)  # 1 where data are measured @M
                    self.misfit.data[(A, B)].copyWithMask(
                        Scalar(GAMMA, self.misfitFunctionSpace),
                        mask)  # data inserted  @ M

        if adjustStationLocationsToElementCenter and getMPIRankWorld() == 0:
            lslogger.info("maximal station adjustment is %e" % adjustmax)
        if getMPIRankWorld() == 0:
            lslogger.debug("rescaling of misfit weights:")
        for AB in self.data.injectionIterator():
            self.misfit.data[AB] += whereNonPositive(
                self.misfit.w[AB])  # insert 1's to avoid division by zero
            s = integrate(self.misfit.w[AB])
            assert s > 0, "no observation for dipole %s. Maybe you need to increase the value for L_stations." % (
                str(AB))
            if s > 0:
                self.misfit.w[AB] *= 1. / (s * len(self.misfit.w))
        # primary potentials:
        self.phi_p = self.getElectricPotentials(self.sigma)
        #self.secondary_potential=self.getSecondaryElectricPotentials(self.sigma, self.sigma0, self.phi_p)
        self.w0 = w0
        self.w1 = w1
        self.alpha0 = alpha0
        self.alpha1 = alpha1
        # used for Hessian inverse
        self.Hpde = setupERTPDE(domain)
        self.Hpde.setValue(A=w1 * kronecker(3), D=w0, q=region_fixed)

        self.Spde = None
        if self.alpha1 > 0:
            self.Spde = setupERTPDE(domain)
            self.Spde.setValue(A=self.alpha1 * kronecker(3), D=self.alpha0)
            if not self.alpha0 > 0:
                self.Spde.setValue(q=region_fixed)
示例#27
0
    # define small radius around point xc
    src_radius = 30
    print("src_radius = ", src_radius)
    # set initial values for first two time steps with source terms
    u = U0 * (cos(length(x - xc) * 3.1415 / src_radius) +
              1) * whereNegative(length(x - xc) - src_radius)
    u_m1 = u
    #plot source shape
    cut_loc = []  #where the cross section of the source along x will be
    src_cut = []  #where the cross section of the source will be
    # create locations for source cross section
    for i in range(ndx // 2 - ndx // 10, ndx // 2 + ndx // 10):
        cut_loc.append(xstep * i)
        src_cut.append([xstep * i, xc[1]])
    # locate the nearest nodes to the points in src_cut
    src = Locator(mydomain, src_cut)
    src_cut = src.getValue(u)  #retrieve the values from the nodes
    # plot the x locations vs value and save the figure
    pl.plot(cut_loc, src_cut)
    pl.axis([xc[0] - src_radius * 3, xc[0] + src_radius * 3, 0., 2. * U0])
    pl.savefig(os.path.join(savepath, "source_line.png"))

    ####################################################ITERATION VARIABLES
    n = 0  # iteration counter
    t = 0  # time counter
    ##############################################################ITERATION
    while t < tend:
        g = grad(u)
        pres = csq * h * h * g  # get current pressure
        mypde.setValue(X=-pres, Y=(2. * u - u_m1))  # set values in pde
        u_p1 = mypde.getSolution()  # get the new displacement
示例#28
0
    for l in range(len(layers)):
        m=whereNonPositive(z-z_top)*wherePositive(z-(z_top-layers[l]))
        V_P = V_P     * (1-m)  + v_P[l]  * m
        V_S = V_S     * (1-m)  + v_S[l]  * m
        Delta = Delta * (1-m)  + delta[l]* m
        Eps = Eps     * (1-m)  + eps[l]  * m
        Tilt = Tilt   * (1-m)  + tilt[l] * m
        Rho = Rho     * (1-m)  + rho[l]  * m
        z_top-=layers[l]

    sw=TTIWave(domain, V_P, V_S, wl, src_tags[0], source_vector = src_dir,
                    eps=Eps, delta=Delta, rho=Rho, theta=Tilt,
                    absorption_zone=absorption_zone, absorption_cut=1e-2, lumping=lumping)

    srclog=Locator(domain, [ (r , depth) for r in receiver_line ] )
    grploc=[ (x[0], 0.) for x in srclog.getX() ]

    tracer_x=SimpleSEGYWriter(receiver_group=grploc, source=srcloc, sampling_interval=sampling_interval, text='x-displacement')
    tracer_z=SimpleSEGYWriter(receiver_group=grploc, source=srcloc, sampling_interval=sampling_interval, text='z-displacement')

    if not tracer_x.obspy_available():
        print("\nWARNING: obspy not available, SEGY files will not be written\n")
    elif getMPISizeWorld() > 1:
        print("\nWARNING: SEGY files cannot be written with multiple processes\n")

    t=0.
    mkDir('output')
    n=0
    k_out=0
    print("calculation starts @ %s"%(time.asctime(),))
示例#29
0
# set the true sigma and gamma:
assert config.true_properties, f"True properties must be defined. See true_properties in {args.config}.py"
sigma_true, gamma_true = config.true_properties(domain)

txt1 = str(sigma_true).replace("\n", ';')
txt2 = str(gamma_true).replace("\n", ';')
if getMPIRankWorld() == 0:
    print(f"True conductivity sigma_true = {txt1}.")
    print(f"True modifies chargeability gamma_true = {txt2}.")

# set locators to extract predictions:
station_locations = []
for s in survey.getStationNumeration():
    station_locations.append(survey.getStationLocation(s))

nodelocators = Locator(Solution(domain), station_locations)
elementlocators = Locator(ReducedFunction(domain), station_locations)

if getMPIRankWorld() == 0:
    print(str(len(station_locations)) + " station locators calculated.")

# PDE:
pde = setupERTPDE(domain)
x = pde.getDomain().getX()[0]
y = pde.getDomain().getX()[1]
z = pde.getDomain().getX()[2]
q = whereZero(x - inf(x)) + whereZero(x - sup(x)) + whereZero(
    y - inf(y)) + whereZero(y - sup(y)) + whereZero(z - inf(z))
pde.setValue(q=q)

primary_field_field = {}
    def getPotential(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()
        pde=LinearPDE(self.domain, numEquations=1)
        tol=1e-8
        pde.getSolverOptions().setTolerance(tol)
        pde.setSymmetryOn()

        DIM=self.domain.getDim()
        x=self.domain.getX()
        q=whereZero(x[DIM-1]-inf(x[DIM-1]))
        for i in xrange(DIM-1):
            xi=x[i]
            q+=whereZero(xi-inf(xi))+whereZero(xi-sup(xi))
        A = self.secondaryConductivity * kronecker(self.domain)
        pde.setValue(A=A,q=q)

        delPhiSecondaryList = []
        delPhiPrimaryList = []
        delPhiTotalList = []
        for i in range(1,self.n+1): # 1 to n
            maxR = self.numElectrodes - 1 - i #max amount of readings that will fit in the survey
            delPhiSecondary = []
            delPhiPrimary = []
            delPhiTotal = []
            for j in range(maxR):
                analyticRs=Data(0,(3,),ContinuousFunction(self.domain))
                analyticRs[0]=(coords[0]-self.electrodes[j][0])
                analyticRs[1]=(coords[1]-self.electrodes[j][1])
                analyticRs[2]=(coords[2])
                rsMag=(analyticRs[0]**2+analyticRs[1]**2+analyticRs[2]**2)**0.5
                analyticPrimaryPot=(self.current*(1./primCon))/(2*pi*(rsMag+(whereZero(rsMag)*0.0000001))) #the magic number 0.0000001 is to avoid devide by 0

                analyticRsPolePower=(analyticRs[0]**2+analyticRs[1]**2+analyticRs[2]**2)**1.5
                analyticRsPolePower = analyticRsPolePower+(whereZero(analyticRsPolePower)*0.0000001)
                gradUPrimary = Data(0,(3,),ContinuousFunction(self.domain))
                gradUPrimary[0] =(self.current/(2*pi*primCon)) * (analyticRs[0]/analyticRsPolePower)
                gradUPrimary[1] =(self.current/(2*pi*primCon)) * (analyticRs[1]/analyticRsPolePower)
                gradUPrimary[2] =(self.current/(2*pi*primCon)) * (analyticRs[2]/analyticRsPolePower)
                gradUPrimary=-gradUPrimary
                X=(primCon-self.secondaryConductivity) * gradUPrimary
                pde.setValue(X=X)
                u=pde.getSolution()
                loc=Locator(self.domain,[self.electrodes[i+j],self.electrodes[i+j+1]])
                valPrimary=loc.getValue(analyticPrimaryPot)
                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]
示例#31
0
    ############################################FIRST TIME STEPS AND SOURCE
    # define small radius around point xc
    src_radius = 25.0
    print("src_radius = ", src_radius)
    # set initial values for first two time steps with source terms
    u = U0 * (cos(length(x - xc) * 3.1415 / src_radius) + 1) * whereNegative(length(x - xc) - src_radius)
    u_m1 = u
    # plot source shape
    cut_loc = []  # where the cross section of the source along x will be
    src_cut = []  # where the cross section of the source will be
    # create locations for source cross section
    for i in range(ndx // 2 - ndx // 10, ndx // 2 + ndx // 10):
        cut_loc.append(xstep * i)
        src_cut.append([xstep * i, xc[1]])
    # locate the nearest nodes to the points in src_cut
    src = Locator(mydomain, src_cut)
    src_cut = src.getValue(u)  # retrieve the values from the nodes
    # plot the x locations vs value and save the figure
    pl.plot(cut_loc, src_cut)
    pl.axis([xc[0] - src_radius * 3, xc[0] + src_radius * 3, 0.0, 2.0 * U0])
    pl.savefig(os.path.join(savepath, "source_line.png"))

    ###########################SAVING THE VALUE AT A LOC FOR EACH TIME STEP
    u_rec0 = []  # array to hold values
    rec = Locator(mydomain, [250.0, 250.0])  # location to record
    u_rec = rec.getValue(u)
    u_rec0.append(u_rec)  # get the first two time steps

    ####################################################ITERATION VARIABLES
    n = 0  # iteration counter
    t = 0  # time counter
    m=m2-m_top
    sigma=(1-m)*sigma+m*s
    if s > 0:
       rho=(1-m)*rho+m*1./s
    else:
       rho=(1-m)*rho+m*0. # arbitray number as air_layer is backed out in TM mode.
       
    z_top, m_top=z_top-l, m2
    
print("sigma =", sigma)
print("rho =", rho)
#
# ... create Locator to get impedance at position of observations:
#
stationX=np.linspace(OFFSET_STATION, WIDTH-OFFSET_STATION, num=NUM_STATION, endpoint=True)
loc=Locator(ReducedFunction(domain), [ (s, DEPTH-DEPTH_STATIONS) for s in stationX])

print("position of observation stations %s:"%(NUM_STATION//2,), loc.getX()[NUM_STATION//2]) # moved to the next element center!!!
#================================================================================================
FRQ=1./PERIODS
#================================================================================================
print("Start TM mode ...")
model=MT2DTMModel(domain, airLayer=DEPTH-L_AIR)
model.setResistivity(rho, rho_boundary=1/SIGMA0) # rho can be interpolated to the boundary (e.g. when conductivity is given on node) rho_boundary can be omited. 

# collects app. rho and phase for the frequencies:
arho_TM=[]
phase_TM=[]

for frq in FRQ:
    Zyx = model.getImpedance(f=frq)
示例#33
0
    ############################################FIRST TIME STEPS AND SOURCE
    # define small radius around point xc
    src_radius = 30
    print("src_radius = ",src_radius)
    # set initial values for first two time steps with source terms
    u=U0*(cos(length(x-xc)*3.1415/src_radius)+1)*whereNegative(length(x-xc)-src_radius)
    u_m1=u
    #plot source shape
    cut_loc=[] #where the cross section of the source along x will be
    src_cut=[] #where the cross section of the source will be
    # create locations for source cross section
    for i in range(ndx//2-ndx//10,ndx//2+ndx//10):
        cut_loc.append(xstep*i)
        src_cut.append([xstep*i,xc[1]])
    # locate the nearest nodes to the points in src_cut
    src=Locator(mydomain,src_cut)
    src_cut=src.getValue(u) #retrieve the values from the nodes
    # plot the x locations vs value and save the figure
    pl.plot(cut_loc,src_cut)
    pl.axis([xc[0]-src_radius*3,xc[0]+src_radius*3,0.,2.*U0])
    pl.savefig(os.path.join(savepath,"source_line.png"))

    ####################################################ITERATION VARIABLES
    n=0 # iteration counter
    t=0 # time counter
    ##############################################################ITERATION
    while t<tend:
        g=grad(u); pres=csq*h*h*g # get current pressure
        mypde.setValue(X=-pres,Y=(2.*u-u_m1)) # set values in pde
        u_p1 = mypde.getSolution() # get the new displacement
        u_m1=u; u=u_p1 # shift values back one time step for next iteration
示例#34
0
def runTaylorGalerkinIncremental(order):
    domain = finley.Rectangle(100, 10, order)
    x = domain.getX()

    # test Velet scheme
    dt = inf(domain.getSize() / length(v)) * (1. / 6.)
    q = whereZero(x[0]) + whereZero(x[0] - 1.)

    mypde_f = LinearSinglePDE(domain)
    mypde_f.setSymmetryOn()
    mypde_f.setValue(D=1, q=q)
    u_f = ref_u(x, 0)

    mypde_HRZ = LinearSinglePDE(domain)
    mypde_HRZ.getSolverOptions().setSolverMethod(SolverOptions.HRZ_LUMPING)
    mypde_HRZ.setValue(D=1, q=q)
    u_HRZ = ref_u(x, 0)

    mypde_RS = LinearSinglePDE(domain)
    mypde_RS.getSolverOptions().setSolverMethod(SolverOptions.ROWSUM_LUMPING)
    mypde_RS.setValue(D=1, q=q)
    u_RS = ref_u(x, 0)

    l = Locator(domain, [0.5, 0.5])
    t = 0

    u = ref_u(x, t)
    t_list = [t]
    u_list = [l(u)]
    f_list = [l(u_f)]
    HRZ_list = [l(u_HRZ)]
    RS_list = [l(u_RS)]
    print(t_list[-1], u_list[-1], f_list[-1], HRZ_list[-1], RS_list[-1])

    while t < 1. / Lsup(v):
        t += dt
        u = ref_u(x, t)
        mypde_f.setValue(X=-dt / 2. * u_f * v, r=ref_u(x, t - dt / 2) - u_f)
        mypde_HRZ.setValue(X=-dt / 2. * u_HRZ * v,
                           r=ref_u(x, t - dt / 2) - u_f)
        mypde_RS.setValue(X=-dt / 2. * u_RS * v, r=ref_u(x, t - dt / 2) - u_f)

        u_f_h = u_f + mypde_f.getSolution()
        u_HRZ_h = u_HRZ + mypde_HRZ.getSolution()
        u_RS_h = u_RS + mypde_RS.getSolution()

        mypde_f.setValue(X=-dt * u_f_h * v, r=u - u_f)
        mypde_HRZ.setValue(X=-dt * u_HRZ_h * v, r=u - u_HRZ)
        mypde_RS.setValue(X=-dt * u_RS_h * v, r=u - u_RS)

        u_f = u_f + mypde_f.getSolution()
        u_HRZ = u_HRZ + mypde_HRZ.getSolution()
        u_RS = u_RS + mypde_RS.getSolution()

        t_list.append(t)
        u_list.append(l(u))
        f_list.append(l(u_f))
        HRZ_list.append(l(u_HRZ))
        RS_list.append(l(u_RS))
        print(t_list[-1], u_list[-1], f_list[-1], HRZ_list[-1], RS_list[-1],
              " : ", sup(u))

    import matplotlib.pyplot as plt
    if getMPIRankWorld() == 0:
        plt.clf()
        plt.plot(t_list, u_list, '-', label="exact", linewidth=1)
        plt.plot(t_list, f_list, '-', label="full", linewidth=1)
        plt.plot(t_list, HRZ_list, '-', label="HRZ lumping", linewidth=1)
        plt.plot(t_list, RS_list, '-', label="row sum lumping", linewidth=1)
        plt.axis([0., max(t_list), -.3, 2.])
        plt.xlabel('time')
        plt.ylabel('displacement')
        plt.legend()
        plt.savefig('lumping_SUPG_du_%d.png' % order, format='png')
示例#35
0
    else:
        print("Dipole - Pole survey")
else:
    if config.dipoleMeasurements:
        print("Pole - Dipole survey")
    else:
        print("Pole - Pole survey")

sigma0 = config.sigma0
sigma_background = config.sigma_background

gamma_background = config.eta_background / (1 - config.eta_background)
gamma0 = (config.eta0 / (1 - config.eta0))

srclocators = Locator(ContinuousFunction(domain), [
    survey.getStationLocation(ip)
    for i, ip in enumerate(survey.getListOfInjectionStations())
])

model = IPModel(domain,
                survey=survey,
                locations=elocations,
                field_resolution=config.dx,
                field_origin=config.coreOrigin,
                sigma_background=config.sigma_background,
                gamma_background=config.eta_background /
                (1 - config.eta_background),
                padding_tags=config.tagsPadding,
                stationsFMT=config.stationsFMT)

origin = config.coreOrigin
if config.SurveyDim == 2:
示例#36
0
    rho=rho*mask
    kro=kronecker(domain)

    mass=rho*vol(domain)
    ipot=FunctionOnBoundary(domain)
    xb=ipot.getX()

    q=whereZero(x[2]-inf(x[2]))
    ###############################################ESCRIPT PDE CONSTRUCTION

    mypde=LinearPDE(domain)
    mypde.setValue(A=kro,Y=4.*3.1415*G*rho,q=q,r=0)
    mypde.setSymmetryOn()
    sol=mypde.getSolution()
    saveVTK(os.path.join(save_path,"ex10b.vtu"),\
            grav_pot=sol,\
            g_field=-grad(sol),\
            g_fieldz=-grad(sol)*[0,0,1],\
            gz=length(-grad(sol)*[0,0,1]))

    ################################################MODEL SIZE SAMPLING
    sampler=[]
    for i in range(-250,250,1):
        sampler.append([i,0,250])

    sample=[] # array to hold values
    rec=Locator(domain,sampler) #location to record
    psol=rec.getValue(sol)
    np.savetxt(os.path.join(save_path,"example10b_%04d.asc"%mx),psol)

    #
    #  print some info:
    #
    print("ne_x = ", ne_x)
    print("ne_z = ", ne_z)
    print("h_x = ", width_x / ne_x)
    print("h_z = ", depth / ne_z)
    print("dt = ", sw.getTimeStepSize() * 1000, "msec")
    print("width_x = ", width_x)
    print("depth = ", depth)
    print("number receivers = ", numRcvPerLine)
    print("receiver spacing = ", receiver_line[1] - receiver_line[0])
    print("sampling time = ", sampling_interval * 1000, "msec")
    print("source @ ", src_locations[0])
    #
    loc = Locator(domain, rcv_locations)
    tracerP = SimpleSEGYWriter(receiver_group=rg,
                               source=src_loc_2D,
                               sampling_interval=sampling_interval,
                               text='P')
    tracerQ = SimpleSEGYWriter(receiver_group=rg,
                               source=src_loc_2D,
                               sampling_interval=sampling_interval,
                               text='Q')

    if not tracerP.obspy_available():
        print(
            "\nWARNING: obspy not available, SEGY files will not be written\n")
    elif getMPISizeWorld() > 1:
        print(
            "\nWARNING: SEGY files cannot be written with multiple processes\n"
示例#38
0
    g_field = grad(sol)  # The gravitational acceleration g.
    g_fieldz = g_field * [0, 1]  # The vertical component of the g field.
    gz = length(g_fieldz)  # The magnitude of the vertical component.
    # Save the output to file.
    saveVTK(os.path.join(save_path, "ex10d.vtu"), grav_pot=sol, g_field=g_field, g_fieldz=g_fieldz, gz=gz, rho=rhoe)

    ################################################MODEL SIZE SAMPLING
    smoother = Projector(domain)  # Function smoother.
    z = 1000.0  # Distance of profile from source.
    sol_angz = []  # Array for analytic gz
    sol_anx = []  # Array for x
    # calculate analytic gz and x location.
    for x in range(int(-mx / 2.0), int(mx / 2.0), 10):
        sol_angz.append(analytic_gz(x, z, R, rho))
        sol_anx.append(x + mx / 2)
    # save analytic solution
    pl.savetxt(os.path.join(save_path, "ex10d_as.asc"), sol_angz)

    sol_escgz = []  # Array for escript solution for gz
    # calculate the location of the profile in the domain
    for i in range(0, len(sol_anx)):
        sol_escgz.append([sol_anx[i], my / 2.0 - z])

    rec = Locator(gz.getFunctionSpace(), sol_escgz)  # location to record
    psol = rec.getValue(smoother(gz))  # extract the solution
    # save X and escript solution profile to file
    pl.savetxt(os.path.join(save_path, "ex10d_%05d.asc" % mx), psol)
    pl.savetxt(os.path.join(save_path, "ex10d_x%05d.asc" % mx), sol_anx)

    # plot the pofile and analytic solution using example10q.py
    def getPotentialAnalytic(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.
        """
        coords=self.domain.getX()
        pde=LinearPDE(self.domain, numEquations=1)
        tol=1e-8
        pde.getSolverOptions().setTolerance(tol)
        pde.setSymmetryOn()
        primCon=self.primaryConductivity
        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)
        pde.setValue(A=A,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):
                analyticRsOne=es.Data(0,(3,),es.ContinuousFunction(self.domain))
                analyticRsOne[0]=(coords[0]-self.electrodes[j][0])
                analyticRsOne[1]=(coords[1]-self.electrodes[j][1])
                analyticRsOne[2]=(coords[2])
                rsMagOne=(analyticRsOne[0]**2+analyticRsOne[1]**2+analyticRsOne[2]**2)**0.5
                analyticRsTwo=es.Data(0,(3,),es.ContinuousFunction(self.domain))
                analyticRsTwo[0]=(coords[0]-self.electrodes[j + ((2*i) + 1)][0])
                analyticRsTwo[1]=(coords[1]-self.electrodes[j + ((2*i) + 1)][1])
                analyticRsTwo[2]=(coords[2])
                rsMagTwo=(analyticRsTwo[0]**2+analyticRsTwo[1]**2+analyticRsTwo[2]**2)**0.5
                self.sources.append([self.electrodeTags[j], self.electrodeTags[j + ((2*i) + 1)]])
                rsMagOne+=(es.whereZero(rsMagOne)*0.0000001)
                rsMagTwo+=(es.whereZero(rsMagTwo)*0.0000001)
                
                analyticPrimaryPot=(self.current/(2*pi*primCon*rsMagOne))-(self.current/(2*pi*primCon*rsMagTwo))
                analyticRsOnePower=(analyticRsOne[0]**2+analyticRsOne[1]**2+analyticRsOne[2]**2)**1.5
                analyticRsOnePower = analyticRsOnePower+(es.whereZero(analyticRsOnePower)*0.0001)
                analyticRsTwoPower=(analyticRsTwo[0]**2+analyticRsTwo[1]**2+analyticRsTwo[2]**2)**1.5
                analyticRsTwoPower = analyticRsTwoPower+(es.whereZero(analyticRsTwoPower)*0.0001)

                gradAnalyticPrimaryPot = es.Data(0,(3,),es.ContinuousFunction(self.domain))
                gradAnalyticPrimaryPot[0] =(self.current/(2*pi*primCon)) * ((-analyticRsOne[0]/analyticRsOnePower) + (analyticRsTwo[0]/analyticRsTwoPower))
                gradAnalyticPrimaryPot[1] =(self.current/(2*pi*primCon)) * ((-analyticRsOne[1]/analyticRsOnePower) + (analyticRsTwo[1]/analyticRsTwoPower))
                gradAnalyticPrimaryPot[2] =(self.current/(2*pi*primCon)) * ((-analyticRsOne[2]/analyticRsOnePower) + (analyticRsTwo[2]/analyticRsTwoPower))
                X=(primCon-self.secondaryConductivity) * (gradAnalyticPrimaryPot)
                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(analyticPrimaryPot)
                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]
                       l1=width_y,
                       l2=depth,
                       diracPoints=src_locations,
                       diracTags=src_tags)
    wl = Ricker(frq)
    m = whereNegative(Function(domain).getX()[DIM - 1] - reflector_at)
    v_p = v_p_bottom * m + v_p_top * (1 - m)

    sw = SonicWave(domain,
                   v_p,
                   source_tag=src_tags[0],
                   wavelet=wl,
                   absorption_zone=absorption_zone,
                   lumping=True)

    locEW = Locator(domain, rcvEW_locations)
    tracerEW = SimpleSEGYWriter(receiver_group=rgEW,
                                source=src_loc_2D,
                                sampling_interval=sampling_interval)
    if DIM == 3:
        locNS = Locator(domain, rcvNS_locations)
        tracerNS = SimpleSEGYWriter(receiver_group=rgNS,
                                    source=src_loc_2D,
                                    sampling_interval=sampling_interval)

    if not tracerEW.obspy_available():
        print(
            "\nWARNING: obspy not available, SEGY files will not be written\n")
    elif getMPISizeWorld() > 1:
        print(
            "\nWARNING: SEGY files cannot be written with multiple processes\n"
    def getPotential(self):
        """
        returns a list containing 3 lists one for each the primary, secondary
        and total potential.
        """

        primCon=self.primaryConductivity
        coords=self.domain.getX()
        pde=LinearPDE(self.domain, numEquations=1)
        tol=1e-8
        pde.getSolverOptions().setTolerance(tol)
        pde.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)
        pde.setValue(A=A,q=q)

        delPhiSecondary = []
        delPhiPrimary = []
        delPhiTotal = []
        if(len(self.electrodes[0])==3):

            for i in range(self.numElectrodes-3):
                analyticRsOne=es.Data(0,(3,),es.ContinuousFunction(self.domain))
                analyticRsOne[0]=(coords[0]-self.electrodes[i][0])
                analyticRsOne[1]=(coords[1]-self.electrodes[i][1])
                analyticRsOne[2]=(coords[2])
                rsMagOne=(analyticRsOne[0]**2+analyticRsOne[1]**2+analyticRsOne[2]**2)**0.5
                analyticRsTwo=es.Data(0,(3,),es.ContinuousFunction(self.domain))
                analyticRsTwo[0]=(coords[0]-self.electrodes[i+3][0])
                analyticRsTwo[1]=(coords[1]-self.electrodes[i+3][1])
                analyticRsTwo[2]=(coords[2])
                rsMagTwo=(analyticRsTwo[0]**2+analyticRsTwo[1]**2+analyticRsTwo[2]**2)**0.5
                rsMagOne+=(es.whereZero(rsMagOne)*0.0000001)
                rsMagTwo+=(es.whereZero(rsMagTwo)*0.0000001)
                analyticPrimaryPot=(self.current/(2*pi*primCon*rsMagOne))-(self.current/(2*pi*primCon*rsMagTwo))

                analyticRsOnePower=(analyticRsOne[0]**2+analyticRsOne[1]**2+analyticRsOne[2]**2)**1.5
                analyticRsOnePower = analyticRsOnePower+(es.whereZero(analyticRsOnePower)*0.0001)
                analyticRsTwoPower=(analyticRsTwo[0]**2+analyticRsTwo[1]**2+analyticRsTwo[2]**2)**1.5
                analyticRsTwoPower = analyticRsTwoPower+(es.whereZero(analyticRsTwoPower)*0.0001)

                gradAnalyticPrimaryPot = es.Data(0,(3,),es.ContinuousFunction(self.domain))
                gradAnalyticPrimaryPot[0] =(self.current/(2*pi*primCon)) \
                        * ((-analyticRsOne[0]/analyticRsOnePower) \
                            + (analyticRsTwo[0]/analyticRsTwoPower))
                gradAnalyticPrimaryPot[1] =(self.current/(2*pi*primCon)) \
                        * ((-analyticRsOne[1]/analyticRsOnePower) \
                            + (analyticRsTwo[1]/analyticRsTwoPower))
                gradAnalyticPrimaryPot[2] =(self.current/(2*pi*primCon)) \
                        * ((-analyticRsOne[2]/analyticRsOnePower)
                            + (analyticRsTwo[2]/analyticRsTwoPower))
                X=(primCon-self.secondaryConductivity) * (gradAnalyticPrimaryPot)
                pde.setValue(X=X)
                u=pde.getSolution()
                loc=Locator(self.domain,[self.electrodes[i+1],self.electrodes[i+2]])
                valPrimary=loc.getValue(analyticPrimaryPot)
                valSecondary=loc.getValue(u)
                delPhiPrimary.append(valPrimary[1]-valPrimary[0])
                delPhiSecondary.append(valSecondary[1]-valSecondary[0])
                delPhiTotal.append(delPhiPrimary[i]+delPhiSecondary[i])
        else:
            raise NotImplementedError("2d forward model is not yet implemented")

        self.delPhiSecondary = delPhiSecondary
        self.delPhiPrimary = delPhiPrimary
        self.delPhiTotal=delPhiTotal
        return [delPhiPrimary, delPhiSecondary, delPhiTotal]
    def getPotential(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.
        """
        coords=self.domain.getX()
        pde=LinearPDE(self.domain, numEquations=1)
        tol=1e-8
        pde.getSolverOptions().setTolerance(tol)
        pde.setSymmetryOn()
        primCon=self.primaryConductivity
        DIM=self.domain.getDim()
        x=self.domain.getX()
        q=whereZero(x[DIM-1]-inf(x[DIM-1]))
        for i in xrange(DIM-1):
            xi=x[i]
            q+=whereZero(xi-inf(xi))+whereZero(xi-sup(xi))
        A = self.secondaryConductivity * kronecker(self.domain)
        pde.setValue(A=A,q=q)


        delPhiSecondaryList = []
        delPhiPrimaryList = []
        delPhiTotalList = []
        for i in range(1,self.n+1): # 1 to n
            maxR = self.numElectrodes - 2 - (i) #max amount of readings that will fit in the survey
            delPhiSecondary = []
            delPhiPrimary = []
            delPhiTotal = []
            for j in range(maxR):
                analyticRsOne=Data(0,(3,),ContinuousFunction(self.domain))
                analyticRsOne[0]=(coords[0]-self.electrodes[j][0])
                analyticRsOne[1]=(coords[1]-self.electrodes[j][1])
                analyticRsOne[2]=(coords[2])
                rsMagOne=(analyticRsOne[0]**2+analyticRsOne[1]**2+analyticRsOne[2]**2)**0.5
                analyticRsTwo=Data(0,(3,),ContinuousFunction(self.domain))
                analyticRsTwo[0]=(coords[0]-self.electrodes[j + 1][0])
                analyticRsTwo[1]=(coords[1]-self.electrodes[j + 1][1])
                analyticRsTwo[2]=(coords[2])
                rsMagTwo=(analyticRsTwo[0]**2+analyticRsTwo[1]**2+analyticRsTwo[2]**2)**0.5
                rsMagOne+=(whereZero(rsMagOne)*0.0000001)
                rsMagTwo+=(whereZero(rsMagTwo)*0.0000001)
                analyticPrimaryPot=(self.current/(2*pi*primCon*rsMagTwo))-(self.current/(2*pi*primCon*rsMagOne))

                analyticRsOnePower=(analyticRsOne[0]**2+analyticRsOne[1]**2+analyticRsOne[2]**2)**1.5
                analyticRsOnePower = analyticRsOnePower+(whereZero(analyticRsOnePower)*0.0001)
                analyticRsTwoPower=(analyticRsTwo[0]**2+analyticRsTwo[1]**2+analyticRsTwo[2]**2)**1.5
                analyticRsTwoPower = analyticRsTwoPower+(whereZero(analyticRsTwoPower)*0.0001)

                gradAnalyticPrimaryPot = Data(0,(3,),ContinuousFunction(self.domain))
                gradAnalyticPrimaryPot[0] =(self.current/(2*pi*primCon)) * ((analyticRsOne[0]/analyticRsOnePower) - (analyticRsTwo[0]/analyticRsTwoPower))
                gradAnalyticPrimaryPot[1] =(self.current/(2*pi*primCon)) * ((analyticRsOne[1]/analyticRsOnePower) - (analyticRsTwo[1]/analyticRsTwoPower))
                gradAnalyticPrimaryPot[2] =(self.current/(2*pi*primCon)) * ((analyticRsOne[2]/analyticRsOnePower) - (analyticRsTwo[2]/analyticRsTwoPower))
                X=(primCon-self.secondaryConductivity) * (gradAnalyticPrimaryPot)
                pde.setValue(X=X)
                u=pde.getSolution()
                loc=Locator(self.domain,[self.electrodes[1+j+i],self.electrodes[j+i+2]])
                valPrimary=loc.getValue(analyticPrimaryPot)
                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 getPotential(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()
        pde=LinearPDE(self.domain, numEquations=1)
        tol=1e-8
        pde.getSolverOptions().setTolerance(tol)
        pde.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)
        pde.setValue(A=A,q=q)

        delPhiSecondaryList = []
        delPhiPrimaryList = []
        delPhiTotalList = []
        for i in range(1,self.n+1): # 1 to n
            maxR = self.numElectrodes - 1 - i #max amount of readings that will fit in the survey
            delPhiSecondary = []
            delPhiPrimary = []
            delPhiTotal = []
            for j in range(maxR):
                analyticRs=es.Data(0,(3,),es.ContinuousFunction(self.domain))
                analyticRs[0]=(coords[0]-self.electrodes[j][0])
                analyticRs[1]=(coords[1]-self.electrodes[j][1])
                analyticRs[2]=(coords[2])
                rsMag=(analyticRs[0]**2+analyticRs[1]**2+analyticRs[2]**2)**0.5
                analyticPrimaryPot=(self.current*(1./primCon))/(2*pi*(rsMag+(es.whereZero(rsMag)*0.0000001))) #the magic number 0.0000001 is to avoid devide by 0

                analyticRsPolePower=(analyticRs[0]**2+analyticRs[1]**2+analyticRs[2]**2)**1.5
                analyticRsPolePower = analyticRsPolePower+(es.whereZero(analyticRsPolePower)*0.0000001)
                gradUPrimary = es.Data(0,(3,),es.ContinuousFunction(self.domain))
                gradUPrimary[0] =(self.current/(2*pi*primCon)) * (analyticRs[0]/analyticRsPolePower)
                gradUPrimary[1] =(self.current/(2*pi*primCon)) * (analyticRs[1]/analyticRsPolePower)
                gradUPrimary[2] =(self.current/(2*pi*primCon)) * (analyticRs[2]/analyticRsPolePower)
                gradUPrimary=-gradUPrimary
                X=(primCon-self.secondaryConductivity) * gradUPrimary
                pde.setValue(X=X)
                u=pde.getSolution()
                loc=Locator(self.domain,[self.electrodes[i+j],self.electrodes[i+j+1]])
                valPrimary=loc.getValue(analyticPrimaryPot)
                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]
示例#44
0
    def __init__(self,
                 domain,
                 data,
                 L_stations=1.,
                 w0=0.,
                 w1=1.,
                 alpha0=1.,
                 alpha1=0.,
                 sigma0=.001,
                 region_fixed=Data(),
                 stationsFMT="e%s",
                 adjustStationLocationsToElementCenter=True,
                 useLogDefect=True):
        """
        cost funtion for ERT inversion 
        
        :domain: pde domain
        :data: data, is ERTSurveyData object supporting makePrediction
        :w0: weighting L2 regularization
        :w1: weighting H1 regularization
        :sigma0: reference conductivity
        :region_fixed: mask for fixed conductivities
        :stationsFMT: format used to map station keys k to mesh tags stationsFMT%k or None
        """
        super(FieldInversion, self).__init__()
        self.datatol = 1e-30
        self.sigma0 = sigma0
        self.stationsFMT = stationsFMT
        self.useLogDefect = useLogDefect

        if self.useLogDefect:
            lslogger.info("Misfit is using logarithm.")
        else:
            lslogger.info("Misfit is using norm relative difference.")
        # setup PDE:
        self.pde = setupERTPDE(domain)

        x = self.pde.getDomain().getX()[0]
        y = self.pde.getDomain().getX()[1]
        z = self.pde.getDomain().getX()[2]
        self.pde.setValue(q=whereZero(x - inf(x)) + whereZero(x - sup(x)) +
                          whereZero(y - inf(y)) + whereZero(y - sup(y)) +
                          whereZero(z - inf(z)))

        self.data = data

        # when points are adjusted:
        adjustmax = 0.
        if adjustStationLocationsToElementCenter:
            station_locations = []
            for s in data.getStationNumeration():
                station_locations.append(data.getStationLocation(s))
            XStations = Locator(ReducedFunction(domain),
                                station_locations).getX()

        ########################################################
        lslogger.info("building misfit weighting (this will take some time)")
        Xcenter = ReducedFunction(domain).getX()
        X = Function(domain).getX()

        self.misfit = lambda: None
        self.misfit.data = {}
        self.misfit.w = {}

        for AB in self.data.injectionIterator():
            self.misfit.w[AB] = Scalar(0., X.getFunctionSpace())
            self.misfit.data[AB] = Vector(0., X.getFunctionSpace())

        for M in self.data.getObservationElectrodes():
            L_ABS = L_stations
            if adjustStationLocationsToElementCenter:
                xs = XStations[data.getStationNumber(M)]
                adjustmax = max(adjustmax,
                                length(xs - self.data.getStationLocation(M)))
            else:
                xs = self.data.getStationLocation(M)
            mask = whereNegative(
                interpolate(
                    length(Xcenter - xs) - L_ABS, X.getFunctionSpace()))
            for A, B in self.data.getInjections(M):
                E0, E1, E2 = self.data.getFieldData((A, B, M))
                n = E0**2 + E1**2 + E2**2
                if n > 0:
                    self.misfit.w[(A, B)].copyWithMask(
                        Scalar(1. / n, self.misfit.w[AB].getFunctionSpace()),
                        mask)  # 1 where data are measured @M
                    self.misfit.data[(A, B)].copyWithMask(
                        Vector((E0, E1, E2),
                               self.misfit.w[AB].getFunctionSpace()),
                        mask * [1, 1, 1])  # data inserted  @ M
                    #self.misfit.data[(A,B)]=self.misfit.data[(A,B)]*(1-mask)+mask*Vector((E0, E1, E2), self.misfit.w[AB].getFunctionSpace())

        lslogger.debug("rescaling of misfit weights:")
        for AB in self.data.injectionIterator():
            s = integrate(self.misfit.w[AB] * length(self.misfit.data[AB])**2)
            #print(AB, s, integrate(length(self.misfit.w[(A,B)]*self.misfit.data[AB])**2))
            #self.misfit.data[AB]+=(1-wherePositive(self.misfit.w[AB])) # one inserted to avoid division by zero in misfit
            assert s > 0, "no observation for dipole %s. Maybe you need to increase the value for L_stations." % (
                str(AB))
            if s > 0:
                self.misfit.w[AB] *= 1. / (s * len(self.misfit.w))

        # primary potentials:
        lslogger.info("maximal station adjustment is %e" % adjustmax)
        lslogger.info(
            "building primary electric fields (this will take some time)")
        self.phi_p = self.getPrimaryElectricPotentials(sigma0)
        lslogger.info("Primary potentials for %d injections calculated." %
                      (len(self.phi_p)))
        self.w0 = w0
        self.w1 = w1
        self.alpha0 = alpha0
        self.alpha1 = alpha1
        # used for Hessian inverse
        self.Hpde = setupERTPDE(domain, poisson=(abs(w1) > 0))
        self.Hpde.setValue(A=w1 * kronecker(3), D=w0, q=region_fixed)
        if self.alpha1 > 0:
            self.Spde = setupERTPDE(domain)
            self.Spde.setValue(A=self.alpha1 * kronecker(3), D=self.alpha0)
            if not self.alpha0 > 0:
                self.Spde.setValue(q=region_fixed)
        else:
            self.Spde = None
    def getPotential(self):
        """
        returns a list containing 3 lists one for each the primary, secondary
        and total potential.
        """

        primCon=self.primaryConductivity
        coords=self.domain.getX()
        pde=LinearPDE(self.domain, numEquations=1)
        tol=1e-8
        pde.getSolverOptions().setTolerance(tol)
        pde.setSymmetryOn()

        DIM=self.domain.getDim()
        x=self.domain.getX()
        q=whereZero(x[DIM-1]-inf(x[DIM-1]))
        for i in xrange(DIM-1):
            xi=x[i]
            q+=whereZero(xi-inf(xi))+whereZero(xi-sup(xi))
        A = self.secondaryConductivity * kronecker(self.domain)
        pde.setValue(A=A,q=q)

        delPhiSecondary = []
        delPhiPrimary = []
        delPhiTotal = []
        if(len(self.electrodes[0])==3):

            for i in range(self.numElectrodes-3):
                analyticRsOne=Data(0,(3,),ContinuousFunction(self.domain))
                analyticRsOne[0]=(coords[0]-self.electrodes[i][0])
                analyticRsOne[1]=(coords[1]-self.electrodes[i][1])
                analyticRsOne[2]=(coords[2])
                rsMagOne=(analyticRsOne[0]**2+analyticRsOne[1]**2+analyticRsOne[2]**2)**0.5
                analyticRsTwo=Data(0,(3,),ContinuousFunction(self.domain))
                analyticRsTwo[0]=(coords[0]-self.electrodes[i+3][0])
                analyticRsTwo[1]=(coords[1]-self.electrodes[i+3][1])
                analyticRsTwo[2]=(coords[2])
                rsMagTwo=(analyticRsTwo[0]**2+analyticRsTwo[1]**2+analyticRsTwo[2]**2)**0.5
                rsMagOne+=(whereZero(rsMagOne)*0.0000001)
                rsMagTwo+=(whereZero(rsMagTwo)*0.0000001)
                analyticPrimaryPot=(self.current/(2*pi*primCon*rsMagOne))-(self.current/(2*pi*primCon*rsMagTwo))

                analyticRsOnePower=(analyticRsOne[0]**2+analyticRsOne[1]**2+analyticRsOne[2]**2)**1.5
                analyticRsOnePower = analyticRsOnePower+(whereZero(analyticRsOnePower)*0.0001)
                analyticRsTwoPower=(analyticRsTwo[0]**2+analyticRsTwo[1]**2+analyticRsTwo[2]**2)**1.5
                analyticRsTwoPower = analyticRsTwoPower+(whereZero(analyticRsTwoPower)*0.0001)

                gradAnalyticPrimaryPot = Data(0,(3,),ContinuousFunction(self.domain))
                gradAnalyticPrimaryPot[0] =(self.current/(2*pi*primCon)) \
                        * ((-analyticRsOne[0]/analyticRsOnePower) \
                            + (analyticRsTwo[0]/analyticRsTwoPower))
                gradAnalyticPrimaryPot[1] =(self.current/(2*pi*primCon)) \
                        * ((-analyticRsOne[1]/analyticRsOnePower) \
                            + (analyticRsTwo[1]/analyticRsTwoPower))
                gradAnalyticPrimaryPot[2] =(self.current/(2*pi*primCon)) \
                        * ((-analyticRsOne[2]/analyticRsOnePower)
                            + (analyticRsTwo[2]/analyticRsTwoPower))
                X=(primCon-self.secondaryConductivity) * (gradAnalyticPrimaryPot)
                pde.setValue(X=X)
                u=pde.getSolution()
                loc=Locator(self.domain,[self.electrodes[i+1],self.electrodes[i+2]])
                valPrimary=loc.getValue(analyticPrimaryPot)
                valSecondary=loc.getValue(u)
                delPhiPrimary.append(valPrimary[1]-valPrimary[0])
                delPhiSecondary.append(valSecondary[1]-valSecondary[0])
                delPhiTotal.append(delPhiPrimary[i]+delPhiSecondary[i])
        else:
            raise NotImplementedError("2d forward model is not yet implemented")

        self.delPhiSecondary = delPhiSecondary
        self.delPhiPrimary = delPhiPrimary
        self.delPhiTotal=delPhiTotal
        return [delPhiPrimary, delPhiSecondary, delPhiTotal]