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]
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 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
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
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
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])
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)
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)])
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)
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
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()
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)
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)
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)
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
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)
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')
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
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
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)
# 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
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(),))
# 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]
############################################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)
############################################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
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')
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:
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"
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]
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]