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
Beispiel #3
0
    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
Beispiel #4
0
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)
Beispiel #6
0
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
Beispiel #7
0
    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()
Beispiel #8
0
    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)
Beispiel #9
0
    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
Beispiel #10
0
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
Beispiel #11
0
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