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 getGradient(self, sigma, phi, loc_phi): """ Returns the gradient of the defect with respect to density. :param sigma: a suggestison for conductivity :type sigma: ``Data`` of shape (1,) :param phi: potential field :type phi: ``Data`` of shape (1,) """ val = loc_phi if not isinstance(val, list): tmp = val val = [tmp] sampleTags = self.__sampleTags jointSamples = {} for i in range(0, 2 * len(sampleTags), 2): #2*len because sample tags is a list of tuples half = i // 2 if sampleTags[half][1] != "-": tmp = (val[i + 1] - val[i] - self.delphiIn[half]) * self.__w[i] else: tmp = (val[i] - self.delphiIn[i // 2]) * self.__w[i] sample = sampleTags[half] if sample[1] != "-": if sample[0] in jointSamples.keys(): jointSamples[sample[0]].append((sample[1], -tmp)) else: jointSamples[sampleTags[half][0]] = [(sample[1], -tmp)] if sample[1] in jointSamples.keys(): jointSamples[sample[1]].append((sample[0], tmp)) else: jointSamples[sample[1]] = [(sample[0], tmp)] else: if sample[0] in jointSamples.keys(): jointSamples[sample[0]].append((sample[1], tmp)) else: jointSamples[sampleTags[half][0]] = [(sample[1], tmp)] pde = self.setUpPDE() dom = self.__domain # conPrimary=self.__sigmaPrimary # APrimary = conPrimary * kronecker(dom) y_dirac = Scalar(0, DiracDeltaFunctions(dom)) for i in jointSamples: total = 0 for j in jointSamples[i]: total += j[1] y_dirac.setTaggedValue(i, total) pde.setValue(A=sigma * kronecker(dom), y_dirac=y_dirac) u = pde.getSolution() retVal = -inner(grad(u), grad(phi + self.__phiPrimary)) return retVal
def getGradient(self, sigma, phi, loc_phi): """ Returns the gradient of the defect with respect to density. :param sigma: a suggestison for conductivity :type sigma: ``Data`` of shape (1,) :param phi: potential field :type phi: ``Data`` of shape (1,) """ val=loc_phi if not isinstance(val,list): tmp=val val=[tmp] sampleTags=self.__sampleTags jointSamples={} for i in range(0,2*len(sampleTags),2): #2*len because sample tags is a list of tuples half = i//2 if sampleTags[half][1]!="-": tmp=(val[i+1]-val[i]-self.delphiIn[half])*self.__w[i] else: tmp=(val[i]-self.delphiIn[i//2]) *self.__w[i] sample = sampleTags[half] if sample[1]!="-": if sample[0] in jointSamples.keys(): jointSamples[sample[0]].append((sample[1], -tmp)) else: jointSamples[sampleTags[half][0]]=[(sample[1],-tmp)] if sample[1] in jointSamples.keys(): jointSamples[sample[1]].append((sample[0], tmp)) else: jointSamples[sample[1]]=[(sample[0], tmp)] else: if sample[0] in jointSamples.keys(): jointSamples[sample[0]].append((sample[1], tmp)) else: jointSamples[sampleTags[half][0]]=[(sample[1],tmp)] pde =self.setUpPDE() dom=self.__domain # conPrimary=self.__sigmaPrimary # APrimary = conPrimary * kronecker(dom) y_dirac = Scalar(0,DiracDeltaFunctions(dom)) for i in jointSamples: total=0 for j in jointSamples[i]: total+=j[1] y_dirac.setTaggedValue(i,total) pde.setValue(A=sigma*kronecker(dom), y_dirac=y_dirac) u=pde.getSolution() retVal=-inner(grad(u),grad(phi+self.__phiPrimary)) return retVal
def getR2(y, y_fitted, chi=None): """ calculates the coefficient of determination R^2 for `y_fitted` as prediction for `y` over a region marked by chi>0 defined by R^2=1 - S_res/S_tot with S_res=int(chi*(y-y_fitted*1)**2, S_tot=int(chi*(y-m(y)*1)**2), m(y)=int(chi*y)/int(chi) If R^2=1 then `y_fitted` is predicts `y` exactly. If R^2 then `y_fitted` does not make a better prediction than the mean. :param y: target distribution :type y: `esys.escript.Scalar` :param y_fitted: fitted distribution :type y_fitted: `esys.escript.Scalar` :param chi: marker/weighting for region of interest :type chi: `esys.escript.Scalar` or None :rtype: `float` """ if chi is None: chi = Scalar(1., Function(y_fitted.getFunctionSpace().getDomain())) ybar = integrate(chi * y) / integrate(chi) S_res = integrate(chi * (y - y_fitted)**2) S_tot = integrate(chi * (y - ybar)**2) if S_tot > 0: R2 = 1 - S_res / S_tot else: if S_res > 0: R2 = 0. else: R2 = 1. return R2
def getGradient(self, m, grad_m): """ returns the gradient of the cost function J with respect to m. :note: This implementation returns Y_k=dPsi/dm_k and X_kj=dPsi/dm_kj """ mu = self.__mu mu_c = self.__mu_c DIM = self.getDomain().getDim() numLS = self.getNumLevelSets() grad_m = grad(m, Function(m.getDomain())) if self.__w0 is not None: Y = m * self.__w0 * mu else: if numLS == 1: Y = Scalar(0, grad_m.getFunctionSpace()) else: Y = Data(0, (numLS, ), grad_m.getFunctionSpace()) if self.__w1 is not None: if numLS == 1: X = grad_m * self.__w1 * mu else: X = grad_m * self.__w1 for k in range(numLS): X[k, :] *= mu[k] else: X = Data(0, grad_m.getShape(), grad_m.getFunctionSpace()) # cross gradient terms: if numLS > 1: for k in range(numLS): grad_m_k = grad_m[k, :] l2_grad_m_k = length(grad_m_k)**2 for l in range(k): grad_m_l = grad_m[l, :] l2_grad_m_l = length(grad_m_l)**2 grad_m_lk = inner(grad_m_l, grad_m_k) f = mu_c[l, k] * self.__wc[l, k] X[l, :] += f * (l2_grad_m_k * grad_m_l - grad_m_lk * grad_m_k) X[k, :] += f * (l2_grad_m_l * grad_m_k - grad_m_lk * grad_m_l) return ArithmeticTuple(Y, X)
def makeTagField(functionspace): """ this creates a data object making the tagged regions with the corresponding tag id :param functionspace: function space to create tags for :type functionspace: `esys.escript.FunctionSpace` :return: `esys.escript.Scalar` with tags """ out = Scalar(-1, functionspace) for t in functionspace.getListOfTags(): out.setTaggedValue(t, t) out.expand() return out
def getPressure(self, g=None, rho=None): """ return the pressure for gravity force anomaly `g` and density anomaly `rho` :param g: gravity anomaly data :type g: ``Vector`` :param rho: gravity anomaly data :type rho: ``Scalar`` :return: pressure distribution :rtype: ``Scalar`` """ if not g: g = Vector(0., Function(self.__domain)) if not rho: rho = Scalar(0., Function(self.__domain)) g2 = (rho * self.__g_b) * [0, 0, 1] + self.__rho_b * g + rho * g # Tests need to be updated before the following is uncommented: #g2=((rho+self.__rho_b) * self.__g_b)*[0,0,1] + self.__rho_b*g + rho*g d = self.__trafo.getScalingFactors() V = self.__trafo.getVolumeFactor() self.__pde.setValue(X=-g2 * d * V) #self.__pde.setValue(X = g2*d*V) return self.__pde.getSolution()
def getGradient(self, k, phi, magnetic_flux_density): """ Returns the gradient of the defect with respect to susceptibility. :param k: susceptibility :type k: ``Scalar`` :param phi: corresponding potential :type phi: ``Scalar`` :param magnetic_flux_density: magnetic field :type magnetic_flux_density: ``Vector`` :rtype: ``Scalar`` """ weights = self.getMisfitWeights() data = self.getData() Y = Scalar(0., magnetic_flux_density.getFunctionSpace()) for s in xrange(len(weights)): Y += weights[s]**2 * ( data[s] - inner(self.__normalized_B_b, magnetic_flux_density)) pde = self.getPDE() pde.resetRightHandSideCoefficients() pde.setValue(X=Y * self.__normalized_B_b) YT = pde.getSolution() return inner(grad(YT), self.__B_r) - Y * inner(self.__normalized_B_b, self.__B_b)
def getData(self, dname): """ return the data with given name dname from the VTK file. The function returns a ``Scalar``, ``Vector`` or ``Tensor`` escript Data object with the appropriate ``FunctionSpace``. """ from esys.escript import Scalar, Vector, ReducedFunction, ContinuousFunction print "searching for data set `%s`" % (dname, ) edata = None # check cell data: if edata is None: data = self.__vtkdb.GetCellData() for ia in xrange(data.GetNumberOfArrays()): if data.GetArrayName(ia) == dname: a = data.GetArray(ia) if a.GetNumberOfComponents() == 1: edata = Scalar(0., ReducedFunction(self.getDomain())) elif a.GetNumberOfComponents() == 3: edata = Vector(0., ReducedFunction(self.getDomain())) else: raise ValueError("unable to load %s components." % (a.GetNumberOfComponents(), )) print "'%s' imported as cell data with shape %s." % ( dname, str(edata.getShape())) indxmap = self.__elementidmap ndata = self.__vtkdb.GetNumberOfPoints() # check point data: if edata is None: data = self.__vtkdb.GetPointData() for ia in xrange(data.GetNumberOfArrays()): if data.GetArrayName(ia) == dname: a = data.GetArray(ia) if a.GetNumberOfComponents() == 1: edata = Scalar(0., ContinuousFunction(self.getDomain())) elif a.GetNumberOfComponents() == 3: edata = Vector(0., ContinuousFunction(self.getDomain())) else: raise ValueError("unable to load %s components." % (a.GetNumberOfComponents(), )) print "'%s' imported as point data with shape %s." % ( dname, str(edata.getShape())) indxmap = self.__nodeidmap ndata = self.__vtkdb.GetNumberOfCells() # all went wrong if edata is None: raise ValueError("unable to find data for '%s' in file %s." % (dname, self.getVTKFileName())) #edata.expand() if indxmap: if a.GetNumberOfComponents() == 1: for j in xrange(edata.getNumberOfDataPoints()): idx = edata.getFunctionSpace( ).getReferenceIDFromDataPointNo(j) if idx in indxmap: edata.setValueOfDataPoint(j, a.GetTuple1(indxmap[idx])) else: for j in xrange(edata.getNumberOfDataPoints()): idx = edata.getFunctionSpace( ).getReferenceIDFromDataPointNo(i) if idx in indxmap: edata.setValueOfDataPoint(j, a.GetTuple(indxmap[idx])) else: if a.GetNumberOfComponents() == 1: for j in xrange(min(edata.getNumberOfDataPoints(), ndata)): edata.setValueOfDataPoint(j, a.GetTuple1(j)) else: for j in xrange(min(edata.getNumberOfDataPoints(), ndata)): edata.setValueOfDataPoint(j, a.GetTuple(j)) return edata
def true_properties(domain): from esys.escript import Scalar, Function sigma_true = Scalar(sigma_background, Function(domain)) sigma_true.setTaggedValue("InnerBox", sigma_background) sigma_true.setTaggedValue("Anomaly1", sigma_background * 10) sigma_true.setTaggedValue("Anomaly2", sigma_background * 10) sigma_true.setTaggedValue("Anomaly3", sigma_background) gamma_background = eta_background / (1 - eta_background) gamma_true = Scalar(gamma_background, Function(domain)) gamma_true.setTaggedValue("InnerBox", gamma_background) gamma_true.setTaggedValue("Anomaly1", gamma_background) gamma_true.setTaggedValue("Anomaly2", gamma_background * 20) gamma_true.setTaggedValue("Anomaly3", gamma_background * 20) return sigma_true, gamma_true
def true_properties(domain): from esys.escript import Scalar, Function sigma_true = Scalar(sigma_background, Function(domain)) sigma_true.setTaggedValue("R1", 0.01) sigma_true.setTaggedValue("R2", 0.1) gamma_background = eta_background / (1 - eta_background) gamma_true = Scalar(gamma_background, Function(domain)) gamma_true.setTaggedValue("R1", 0.02) gamma_true.setTaggedValue("R2", 0.2) return sigma_true, gamma_true