def setCoefficients(self, pde, system):
        """sets PDE coefficients"""        
        FAC_DIAG = self.FAC_DIAG
        FAC_OFFDIAG =self.FAC_OFFDIAG
        x = Solution(self.domain).getX()
        mask = whereZero(x[0])
        dim = self.domain.getDim()
        u_ex = self.getSolution(system)
        g_ex = self.getGrad(system)

        if system:
            A = Tensor4(0., Function(self.domain))
            for i in range(dim):
                A[i,:,i,:] = kronecker(dim)

            Y = Vector(0., Function(self.domain))
            if dim == 2:
                Y[0] = u_ex[0]*FAC_DIAG+u_ex[1]*FAC_OFFDIAG-20
                Y[1] = u_ex[1]*FAC_DIAG+u_ex[0]*FAC_OFFDIAG-10
            else:
                Y[0] = u_ex[0]*FAC_DIAG+u_ex[2]*FAC_OFFDIAG+u_ex[1]*FAC_OFFDIAG-60
                Y[1] = u_ex[1]*FAC_DIAG+u_ex[0]*FAC_OFFDIAG+u_ex[2]*FAC_OFFDIAG-20
                Y[2] = u_ex[2]*FAC_DIAG+u_ex[1]*FAC_OFFDIAG+u_ex[0]*FAC_OFFDIAG-22
            pde.setValue(r=u_ex, q=mask*numpy.ones(dim,),
                         A=A,
                         D=kronecker(dim)*(FAC_DIAG-FAC_OFFDIAG)+numpy.ones((dim,dim))*FAC_OFFDIAG,
                         Y=Y,
                         y=matrixmult(g_ex,self.domain.getNormal()))
        else:
            pde.setValue(r=u_ex, q=mask, A=kronecker(dim),
                         y=inner(g_ex, self.domain.getNormal()))
            if dim == 2:
                pde.setValue(Y=-20.)
            else:
                pde.setValue(Y=-60.)
Exemplo n.º 2
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
Exemplo n.º 3
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
Exemplo n.º 4
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
Exemplo n.º 5
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()
    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)
Exemplo n.º 7
0
    def __init__(self,
                 domain,
                 p0=0.,
                 level0=0,
                 gravity0=-9.81 * U.m * U.sec**(-2),
                 background_density=2670 * U.kg * U.m**(-3),
                 gravity_constant=U.Gravitational_Constant,
                 coordinates=None,
                 tol=1e-8):
        """
        :param domain: domain of the model
        :type domain: `Domain`
        :param p0: pressure at level0
        :type p0: scalar `Data` or ``float``
        :param background_density: defines background_density in kg/m^3
        :type background_density: ``float``
        :param coordinates: defines coordinate system to be used
        :type coordinates: ReferenceSystem` or `SpatialCoordinateTransformation`
        :param tol: tolerance of underlying PDE
        :type tol: positive ``float``
        :param level0: pressure for z>=`level0` is set to zero.
        :type level0: ``float``
        :param gravity0: vertical background gravity at `level0`
        :type gravity0: ``float``
        """
        DIM = domain.getDim()
        self.__domain = domain
        self.__trafo = makeTransformation(domain, coordinates)
        self.__pde = LinearSinglePDE(domain)
        self.__pde.getSolverOptions().setTolerance(tol)
        self.__pde.setSymmetryOn()

        z = domain.getX()[DIM - 1]
        self.__pde.setValue(q=whereNonNegative(z - level0), r=p0)

        fw = self.__trafo.getScalingFactors(
        )**2 * self.__trafo.getVolumeFactor()
        A = self.__pde.createCoefficient("A")
        for i in range(DIM):
            A[i, i] = fw[i]
        self.__pde.setValue(A=A)
        z = Function(domain).getX()[DIM - 1]
        self.__g_b = 4 * PI * gravity_constant / self.__trafo.getScalingFactors(
        )[DIM - 1] * background_density * (level0 - z) + gravity0
        self.__rho_b = background_density