Пример #1
0
        def fget(self):
            if(self._area is None or self._normals is None):
                # Compute areas of cell faces
                if(self.dim == 2):
                    xy = self.gridN
                    A, B = Utils.indexCube('AB', self.vnC+1, np.array([self.nNx, self.nCy]))
                    edge1 = xy[B, :] - xy[A, :]
                    normal1 = np.c_[edge1[:, 1], -edge1[:, 0]]
                    area1 = length2D(edge1)
                    A, D = Utils.indexCube('AD', self.vnC+1, np.array([self.nCx, self.nNy]))
                    # Note that we are doing A-D to make sure the normal points the right way.
                    # Think about it. Look at the picture. Normal points towards C iff you do this.
                    edge2 = xy[A, :] - xy[D, :]
                    normal2 = np.c_[edge2[:, 1], -edge2[:, 0]]
                    area2 = length2D(edge2)
                    self._area = np.r_[Utils.mkvc(area1), Utils.mkvc(area2)]
                    self._normals = [normalize2D(normal1), normalize2D(normal2)]
                elif(self.dim == 3):

                    A, E, F, B = Utils.indexCube('AEFB', self.vnC+1, np.array([self.nNx, self.nCy, self.nCz]))
                    normal1, area1 = Utils.faceInfo(self.gridN, A, E, F, B, average=False, normalizeNormals=False)

                    A, D, H, E = Utils.indexCube('ADHE', self.vnC+1, np.array([self.nCx, self.nNy, self.nCz]))
                    normal2, area2 = Utils.faceInfo(self.gridN, A, D, H, E, average=False, normalizeNormals=False)

                    A, B, C, D = Utils.indexCube('ABCD', self.vnC+1, np.array([self.nCx, self.nCy, self.nNz]))
                    normal3, area3 = Utils.faceInfo(self.gridN, A, B, C, D, average=False, normalizeNormals=False)

                    self._area = np.r_[Utils.mkvc(area1), Utils.mkvc(area2), Utils.mkvc(area3)]
                    self._normals = [normal1, normal2, normal3]
            return self._area
Пример #2
0
        def test_regularizationMesh(self):

            for i, mesh in enumerate(self.meshlist):

                print('Testing {0:d}D'.format(mesh.dim))

                # mapping = r.mapPair(mesh)
                # reg = r(mesh, mapping=mapping)
                # m = np.random.rand(mapping.nP)

                if mesh.dim == 1:
                    indAct = Utils.mkvc(mesh.gridCC <= 0.8)
                elif mesh.dim == 2:
                    indAct = (
                        Utils.mkvc(
                            mesh.gridCC[:,-1] <=
                            2*np.sin(2*np.pi*mesh.gridCC[:, 0]) + 0.5
                        )
                    )
                elif mesh.dim == 3:
                    indAct = (
                        Utils.mkvc(
                            mesh.gridCC[:, -1] <=
                            2*np.sin(2*np.pi*mesh.gridCC[:, 0]) +
                            0.5 * 2*np.sin(2*np.pi*mesh.gridCC[:, 1]) + 0.5
                        )
                    )

                regmesh = Regularization.RegularizationMesh(
                    mesh, indActive=indAct
                )

                assert (regmesh.vol == mesh.vol[indAct]).all()
Пример #3
0
        def test_regularization_ActiveCells(self):
            for R in dir(Regularization):
                r = getattr(Regularization, R)
                if not inspect.isclass(r):
                    continue
                if not issubclass(r, Regularization.BaseRegularization):
                    continue

                for i, mesh in enumerate(self.meshlist):

                    print('Testing Active Cells {0:d}D'.format((mesh.dim)))

                    if mesh.dim == 1:
                        indActive = Utils.mkvc(mesh.gridCC <= 0.8)
                    elif mesh.dim == 2:
                        indActive = Utils.mkvc(mesh.gridCC[:,-1] <= 2*np.sin(2*np.pi*mesh.gridCC[:,0])+0.5)
                    elif mesh.dim == 3:
                        indActive = Utils.mkvc(mesh.gridCC[:,-1] <= 2*np.sin(2*np.pi*mesh.gridCC[:,0])+0.5 * 2*np.sin(2*np.pi*mesh.gridCC[:,1])+0.5)

                    for indAct in [indActive, indActive.nonzero()[0]]: # test both bool and integers
                        reg = r(mesh, indActive=indAct)
                        m = np.random.rand(mesh.nC)[indAct]
                        reg.mref = np.ones_like(m)*np.mean(m)

                    print('Check: phi_m (mref) = {0:f}'.format(reg.eval(reg.mref)))
                    passed = reg.eval(reg.mref) < TOL
                    self.assertTrue(passed)

                    print('Check:', R)
                    passed = Tests.checkDerivative(lambda m : [reg.eval(m), reg.evalDeriv(m)], m, plotIt=False)
                    self.assertTrue(passed)

                    print('Check 2 Deriv:', R)
                    passed = Tests.checkDerivative(lambda m : [reg.evalDeriv(m), reg.eval2Deriv(m)], m, plotIt=False)
                    self.assertTrue(passed)
Пример #4
0
 def set_ij_height(self):
     """
     Compute (I, J) indicies to form sparse sensitivity matrix
     This will be used in GlobalEM1DProblem when after sensitivity matrix
     for each sounding is computed
     """
     I = []
     J = []
     shift_for_J = 0
     shift_for_I = 0
     m = self.n_layer
     for i in range(n_sounding):
         n = self.nD_vec[i]
         J_temp = np.tile(np.arange(m), (n, 1)) + shift_for_J
         I_temp = (
             np.tile(np.arange(n), (1, m)).reshape((n, m), order='F') +
             shift_for_I
         )
         J.append(Utils.mkvc(J_temp))
         I.append(Utils.mkvc(I_temp))
         shift_for_J += m
         shift_for_I = I_temp[-1, -1] + 1
     J = np.hstack(J).astype(int)
     I = np.hstack(I).astype(int)
     return (I, J)
Пример #5
0
    def Jvec(self, m, v, f=None):

        if f is None:
            f = self.fields(m)

        self.curModel = m

        Jv = self.dataPair(self.survey) #same size as the data

        A = self.getA()

        for src in self.survey.srcList:
            u_src = f[src, self._solutionType] # solution vector
            dA_dm_v = self.getADeriv(u_src, v)
            dRHS_dm_v = self.getRHSDeriv(src, v)
            du_dm_v = self.Ainv * ( - dA_dm_v + dRHS_dm_v )

            for rx in src.rxList:
                df_dmFun = getattr(f, '_{0!s}Deriv'.format(rx.projField), None)
                df_dm_v = df_dmFun(src, du_dm_v, v, adjoint=False)
                Jv[src, rx] = rx.evalDeriv(src, self.mesh, f, df_dm_v)
        # Conductivity (d u / d log sigma)
        if self._formulation is 'EB':
            return -Utils.mkvc(Jv)
        # Conductivity (d u / d log rho)
        if self._formulation is 'HJ':
            return Utils.mkvc(Jv)
Пример #6
0
    def test_ana_forward(self):

        survey = PF.BaseMag.BaseMagSurvey()

        Inc = 45.0
        Dec = 45.0
        Btot = 51000

        b0 = PF.MagAnalytics.IDTtoxyz(Inc, Dec, Btot)
        survey.setBackgroundField(Inc, Dec, Btot)
        xr = np.linspace(-300, 300, 41)
        yr = np.linspace(-300, 300, 41)
        X, Y = np.meshgrid(xr, yr)
        Z = np.ones((xr.size, yr.size)) * 150
        rxLoc = np.c_[Utils.mkvc(X), Utils.mkvc(Y), Utils.mkvc(Z)]
        survey.rxLoc = rxLoc

        self.prob.pair(survey)
        u = self.prob.fields(self.chi)
        B = u["B"]

        bxa, bya, bza = PF.MagAnalytics.MagSphereAnaFunA(
            rxLoc[:, 0], rxLoc[:, 1], rxLoc[:, 2], 100.0, 0.0, 0.0, 0.0, 0.01, b0, "secondary"
        )

        dpred = survey.projectFieldsAsVector(B)
        err = np.linalg.norm(dpred - np.r_[bxa, bya, bza]) / np.linalg.norm(np.r_[bxa, bya, bza])
        self.assertTrue(err < 0.08)
Пример #7
0
    def Jtvec(self, m, v, f=None):
        if f is None:
            f = self.fields(m)

        self.model = m

        # Ensure v is a data object.
        if not isinstance(v, self.dataPair):
            v = self.dataPair(self.survey, v)

        Jtv = np.zeros(m.size)
        AT = self.getA()

        for src in self.survey.srcList:
            u_src = f[src, self._solutionType]
            for rx in src.rxList:
                PTv = rx.evalDeriv(src, self.mesh, f, v[src, rx], adjoint=True)  # wrt f, need possibility wrt m
                df_duTFun = getattr(f, '_{0!s}Deriv'.format(rx.projField), None)
                df_duT, df_dmT = df_duTFun(src, None, PTv, adjoint=True)
                ATinvdf_duT = self.Ainv * df_duT
                dA_dmT = self.getADeriv(u_src, ATinvdf_duT, adjoint=True)
                dRHS_dmT = self.getRHSDeriv(src, ATinvdf_duT, adjoint=True)
                du_dmT = -dA_dmT + dRHS_dmT
                Jtv += (df_dmT + du_dmT).astype(float)
        # Conductivity ((d u / d log sigma).T)
        if self._formulation == 'EB':
            return -Utils.mkvc(Jtv)
        # Conductivity ((d u / d log rho).T)
        if self._formulation == 'HJ':
            return Utils.mkvc(Jtv)
Пример #8
0
    def forward(self, m, f=None):

        if f is None:
            f = self.fields(m)

        self.curModel = m
        Jv = self.dataPair(self.survey) #same size as the data
        # A = self.getA()
        JvAll = []
        for tind in range(len(self.survey.times)):
            #Pseudo-chareability
            t = self.survey.times[tind]
            v = self.DebyeTime(t)
            for src in self.survey.srcList:
                u_src = f[src, self._solutionType] # solution vector
                dA_dm_v = self.getADeriv(u_src, v)
                dRHS_dm_v = self.getRHSDeriv(src, v)
                du_dm_v = self.Ainv * ( - dA_dm_v + dRHS_dm_v )
                for rx in src.rxList:
                    timeindex = rx.getTimeP(self.survey.times)
                    if timeindex[tind]:
                        df_dmFun = getattr(f, '_{0!s}Deriv'.format(rx.projField), None)
                        df_dm_v = df_dmFun(src, du_dm_v, v, adjoint=False)
                        Jv[src, rx, t] = rx.evalDeriv(src, self.mesh, f, df_dm_v)

        # Conductivity (d u / d log sigma)
        if self._formulation is 'EB':
            return -Utils.mkvc(Jv)
        # Resistivity (d u / d log rho)
        if self._formulation is 'HJ':
            return Utils.mkvc(Jv)
Пример #9
0
    def _fastInnerProduct(self, projType, prop=None, invProp=False, invMat=False):
        """
            Fast version of getFaceInnerProduct.
            This does not handle the case of a full tensor prop.

            :param numpy.array prop: material property (tensor properties are possible) at each cell center (nC, (1, 3, or 6))
            :param str projType: 'E' or 'F'
            :param bool returnP: returns the projection matrices
            :param bool invProp: inverts the material property
            :param bool invMat: inverts the matrix
            :rtype: scipy.sparse.csr_matrix
            :return: M, the inner product matrix (nF, nF)
        """
        assert projType in ["F", "E"], "projType must be 'F' for faces or 'E'" " for edges"

        if prop is None:
            prop = np.ones(self.nC)

        if invProp:
            prop = 1.0 / prop

        if Utils.isScalar(prop):
            prop = prop * np.ones(self.nC)

        # number of elements we are averaging (equals dim for regular
        # meshes, but for cyl, where we use symmetry, it is 1 for edge
        # variables and 2 for face variables)
        if self._meshType == "CYL":
            n_elements = np.sum(getattr(self, "vn" + projType).nonzero())
        else:
            n_elements = self.dim

        # Isotropic? or anisotropic?
        if prop.size == self.nC:
            Av = getattr(self, "ave" + projType + "2CC")
            Vprop = self.vol * Utils.mkvc(prop)
            M = n_elements * Utils.sdiag(Av.T * Vprop)

        elif prop.size == self.nC * self.dim:
            Av = getattr(self, "ave" + projType + "2CCV")

            # if cyl, then only certain components are relevant due to symmetry
            # for faces, x, z matters, for edges, y (which is theta) matters
            if self._meshType == "CYL":
                if projType == "E":
                    prop = prop[:, 1]  # this is the action of a projection mat
                elif projType == "F":
                    prop = prop[:, [0, 2]]

            V = sp.kron(sp.identity(n_elements), Utils.sdiag(self.vol))
            M = Utils.sdiag(Av.T * V * Utils.mkvc(prop))
        else:
            return None

        if invMat:
            return Utils.sdInv(M)
        else:
            return M
Пример #10
0
    def getJ(self, sigma, emax, senseoption=True):
        """
            Computing sensitivity for airbonre time domain EM IP inversion.
        """
        Meinv = self.mesh.getEdgeInnerProduct(invMat=True)
        MeSig = self.mesh.getEdgeInnerProduct(sigma)
        Asiginf = self.mesh.nodalGrad.T*MeSig*self.mesh.nodalGrad
        MeDeriv = self.mesh.getEdgeInnerProductDeriv(np.ones(self.mesh.nC))

        print ">>Factorizing ADC matrix"
        if senseoption == True:
            # ctx = DMumpsContext()
            # if ctx.myid == 0:
            #     ctx.set_icntl(14, 60)
            #     ctx.set_centralized_sparse(Asiginf)
            # ctx.run(job=4) # Factorization
            Ainv = MumpsSolver(Asiginf)
        ntx = self.survey.xyz_tx.shape[0]
        J = np.zeros((ntx, self.mesh.nC))

        J1_temp = np.zeros(self.mesh.nC)
        J2_temp = np.zeros(self.mesh.nC)

        print ">>Computing sensitivity"
        for i in range (ntx):
            stdout.write( (" \r%d/%d transmitter") % (i, ntx) )
            stdout.flush()
            S_temp = MeDeriv((emax[i,:]))*Utils.sdiag(sigma)
            G_temp = BiotSavart.BiotSavartFun(self.mesh, self.survey.xyz_tx[i,:], component = 'z')


            # Considering eIP term in jIP
            if senseoption == True:

                rhs = self.mesh.nodalGrad.T*MeSig*Meinv*self.mesh.aveE2CCV.T*G_temp.T
                # if ctx.myid == 0:
                #     x = rhs.copy()
                #     ctx.set_rhs(x)
                # ctx.run(job=3) # Solve
                x = Ainv*rhs
                J1_temp = Utils.mkvc((S_temp.T*self.mesh.nodalGrad*x).T)
                J2_temp = Utils.mkvc(G_temp*self.mesh.aveE2CCV*Meinv*S_temp)

                J[i,:] = J1_temp - J2_temp

            # Only consider polarization current
            else:

                J2_temp = Utils.mkvc(G_temp*self.mesh.aveE2CCV*Meinv*S_temp)
                J[i,:] = - J2_temp
        stdout.write("\n")
        if senseoption == True:
            ctx.destroy()

        self.J = J
        self.sigma = sigma
        self.emax = emax
Пример #11
0
 def fget(self):
     if self._gridFy is None:
         N = self.r(self.gridN, 'N', 'N', 'M')
         if self.dim == 2:
             XY = [Utils.mkvc(0.5 * (n[:-1, :] + n[1:, :])) for n in N]
             self._gridFy = np.c_[XY[0], XY[1]]
         elif self.dim == 3:
             XYZ = [Utils.mkvc(0.25 * (n[:-1, :, :-1] + n[:-1, :, 1:] + n[1:, :, :-1] + n[1:, :, 1:])) for n in N]
             self._gridFy = np.c_[XYZ[0], XYZ[1], XYZ[2]]
     return self._gridFy
Пример #12
0
def CondSphereAnalFunB(x, y, z, R, x0, y0, z0, sig1, sig2, E0, flag):
	"""
		test
		Analytic function for Electro-Static problem. The set up here is
		conductive sphere in whole-space.

		* (x0,y0,z0)
		* (x0, y0, z0 ): is the center location of sphere
		* r: is the radius of the sphere

		.. math::

			\mathbf{E}_0 = E_0\hat{x}


	"""

	if (~np.size(x)==np.size(y)==np.size(z)):
		print "Specify same size of x, y, z"
		return
	dim = x.shape
	x = Utils.mkvc(x-x0)
	y = Utils.mkvc(y-y0)
	z = Utils.mkvc(z-z0)

	ind = np.sqrt((x)**2+(y)**2+(z)**2 ) < R
	r = Utils.mkvc(np.sqrt((x)**2+(y)**2+(z)**2 ))

	Hx = np.zeros(x.size)
	Hy = np.zeros(x.size)
	Hz = np.zeros(x.size)

	# Inside of the sphere
	rf2 = 3*sig1/(sig2+2*sig1)
	Hpy = -sig1*E0/2*z
	Hpz =  sig1*E0/2*y
	if (flag == 'total'):	
		Hy[ind] = -3/2*sig2*E0*(rf2)*z[ind]
		Hz[ind] =  3/2*sig2*E0*(rf2)*y[ind]
	elif (flag == 'secondary'):
		Hy[ind] = -3/2*sig2*E0*(rf2)*z[ind] - Hpy[ind]
		Hz[ind] =  3/2*sig2*E0*(rf2)*y[ind] - Hpz[ind]

	# Outside of the sphere
	rf1 = (sig2-sig1)/(sig2+2*sig1)

	if (flag == 'total'):
		Hy[~ind] = sig1*(E0/r[~ind]**3*(R**3)*rf1*(-z[~ind]))+Hpy
		Hz[~ind] = sig1*(E0/r[~ind]**3*(R**3)*rf1*( y[~ind]))+Hpz        
	elif (flag == 'secondary'):
		Hy[~ind] = sig1*(E0/r[~ind]**3*(R**3)*rf1*(-z[~ind]))
		Hz[~ind] = sig1*(E0/r[~ind]**3*(R**3)*rf1*( y[~ind]))        

	return np.reshape(mu_0*Hx, x.shape, order='F'), np.reshape(mu_0*Hy, x.shape, order='F'), np.reshape(mu_0*Hz, x.shape, order='F')
Пример #13
0
    def getError(self):
        #Test function
        phi = lambda x: np.cos(0.5*np.pi*x)
        j_fun = lambda x: -0.5*np.pi*np.sin(0.5*np.pi*x)
        q_fun = lambda x: -0.25*(np.pi**2)*np.cos(0.5*np.pi*x)

        xc_ana = phi(self.M.gridCC)
        q_ana = q_fun(self.M.gridCC)
        j_ana = j_fun(self.M.gridFx)

        #TODO: Check where our boundary conditions are CCx or Nx
        vecN = self.M.vectorNx
        vecC = self.M.vectorCCx

        phi_bc = phi(vecC[[0,-1]])
        j_bc = j_fun(vecN[[0,-1]])

        P, Pin, Pout = self.M.getBCProjWF([['dirichlet', 'neumann']])

        Mc = self.M.getFaceInnerProduct()
        McI = Utils.sdInv(self.M.getFaceInnerProduct())
        V = Utils.sdiag(self.M.vol)
        G = -Pin.T*Pin*self.M.faceDiv.T * V
        D = self.M.faceDiv
        j = McI*(G*xc_ana + P*phi_bc)
        q = V*D*Pin.T*Pin*j + V*D*Pout.T*j_bc

        # Rearrange if we know q to solve for x
        A = V*D*Pin.T*Pin*McI*G
        rhs = V*q_ana - V*D*Pin.T*Pin*McI*P*phi_bc - V*D*Pout.T*j_bc
        # A = D*McI*G
        # rhs = q_ana - D*McI*P*phi_bc


        if self.myTest == 'j':
            err = np.linalg.norm((Pin*j-Pin*j_ana), np.inf)
        elif self.myTest == 'q':
            err = np.linalg.norm((q-V*q_ana), np.inf)
        elif self.myTest == 'xc':
            #TODO: fix the null space
            xc, info = sp.linalg.minres(A, rhs, tol = 1e-6)
            err = np.linalg.norm((xc-xc_ana), np.inf)
            if info > 0:
                print('Solve does not work well')
                print('ACCURACY', np.linalg.norm(Utils.mkvc(A*xc) - rhs))
        elif self.myTest == 'xcJ':
            #TODO: fix the null space
            xc, info = sp.linalg.minres(A, rhs, tol = 1e-6)
            j = McI*(G*xc + P*phi_bc)
            err = np.linalg.norm((Pin*j-Pin*j_ana), np.inf)
            if info > 0:
                print('Solve does not work well')
                print('ACCURACY', np.linalg.norm(Utils.mkvc(A*xc) - rhs))
        return err
Пример #14
0
    def test_SetGet(self):
        F = self.F
        nSrc = F.survey.nSrc
        nT = F.survey.prob.nT + 1
        e = np.random.rand(F.mesh.nE, nSrc, nT)
        F[:, 'e'] = e
        b = np.random.rand(F.mesh.nF, nSrc, nT)
        F[:, 'b'] = b

        self.assertTrue(np.all(F[:, 'e'] == e))
        self.assertTrue(np.all(F[:, 'b'] == b))
        F[:] = {'b': b, 'e': e}
        self.assertTrue(np.all(F[:, 'e'] == e))
        self.assertTrue(np.all(F[:, 'b'] == b))

        for s in zero_types:
            F[:, 'b'] = s
            self.assertTrue(np.all(F[:, 'b'] == b*0))

        b = np.random.rand(F.mesh.nF, 1, nT)
        F[self.Src0, 'b'] = b
        self.assertTrue(np.all(F[self.Src0, 'b'] == b[:, 0, :]))

        b = np.random.rand(F.mesh.nF, 1, nT)
        F[self.Src0, 'b', 0] = b[:, :, 0]
        self.assertTrue(np.all(F[self.Src0, 'b', 0] == Utils.mkvc(b[:, 0, 0],
                                                                  2)))

        phi = np.random.rand(F.mesh.nC, 2, nT)
        F[[self.Src0, self.Src1], 'phi'] = phi
        self.assertTrue(np.all(F[[self.Src0, self.Src1], 'phi'] == phi))

        fdict = F[:]
        self.assertTrue(type(fdict) is dict)
        self.assertTrue(sorted([k for k in fdict]) == ['b', 'e', 'phi'])

        b = np.random.rand(F.mesh.nF, 2, nT)
        F[[self.Src0, self.Src1], 'b'] = b
        self.assertTrue(F[self.Src0]['b'].shape == (F.mesh.nF, nT))
        self.assertTrue(F[self.Src0, 'b'].shape == (F.mesh.nF, nT))
        self.assertTrue(np.all(F[self.Src0, 'b'] == b[:, 0, :]))
        self.assertTrue(np.all(F[self.Src1, 'b'] == b[:, 1, :]))
        self.assertTrue(np.all(F[self.Src0, 'b', 1] ==
                        Utils.mkvc(b[:, 0, 1], 2)))
        self.assertTrue(np.all(F[self.Src1, 'b', 1] ==
                        Utils.mkvc(b[:, 1, 1], 2)))
        self.assertTrue(np.all(F[self.Src0, 'b', 4] ==
                        Utils.mkvc(b[:, 0, 4], 2)))
        self.assertTrue(np.all(F[self.Src1, 'b', 4] ==
                        Utils.mkvc(b[:, 1, 4], 2)))

        b = np.random.rand(F.mesh.nF, 2, nT)
        F[[self.Src0, self.Src1], 'b', 0] = b[:, :, 0]
Пример #15
0
    def test_rotatePointsFromNormals(self):
        np.random.seed(10)
        v0 = np.random.rand(3)
        v0*= 1./np.linalg.norm(v0)

        np.random.seed(15)
        v1 = np.random.rand(3)
        v1*= 1./np.linalg.norm(v1)

        v2 = Utils.mkvc(Utils.coordutils.rotatePointsFromNormals(Utils.mkvc(v0,2).T,v0,v1))

        self.assertTrue(np.linalg.norm(v2-v1) < tol)
Пример #16
0
def MagSphereAnaFunA(x, y, z, R, xc, yc, zc, chi, Bo, flag):
    """Computing boundary condition using Congrous sphere method.
    This is designed for secondary field formulation.
    >> Input
    mesh:   Mesh class
    Bo:     np.array([Box, Boy, Boz]): Primary magnetic flux
    Chi:    susceptibility at cell volume

    .. math::

        \\vec{B}(r) = \\frac{\mu_0}{4\pi}\\frac{m}{\| \\vec{r}-\\vec{r}_0\|^3}[3\hat{m}\cdot\hat{r}-\hat{m}]

    """
    if (~np.size(x)==np.size(y)==np.size(z)):
        print("Specify same size of x, y, z")
        return
    dim = x.shape
    x = Utils.mkvc(x)
    y = Utils.mkvc(y)
    z = Utils.mkvc(z)

    Bot = np.sqrt(sum(Bo**2))
    mx = Bo[0]/Bot
    my = Bo[1]/Bot
    mz = Bo[2]/Bot

    ind = np.sqrt((x-xc)**2+(y-yc)**2+(z-zc)**2 ) < R

    Bx = np.zeros(x.size)
    By = np.zeros(x.size)
    Bz = np.zeros(x.size)

    # Inside of the sphere
    rf2 = 3/(chi+3)*(1+chi)
    if (flag == 'total'):
        Bx[ind] = Bo[0]*(rf2)
        By[ind] = Bo[1]*(rf2)
        Bz[ind] = Bo[2]*(rf2)
    elif (flag == 'secondary'):
        Bx[ind] = Bo[0]*(rf2)-Bo[0]
        By[ind] = Bo[1]*(rf2)-Bo[1]
        Bz[ind] = Bo[2]*(rf2)-Bo[2]

    r = Utils.mkvc(np.sqrt((x-xc)**2+(y-yc)**2+(z-zc)**2 ))
    V = 4*np.pi*R**3/3
    mom = Bot/mu_0*chi/(1+chi/3)*V
    const = mu_0/(4*np.pi)*mom
    mdotr = (mx*(x[~ind]-xc)/r[~ind] + my*(y[~ind]-yc)/r[~ind] + mz*(z[~ind]-zc)/r[~ind])
    Bx[~ind] = const/(r[~ind]**3)*(3*mdotr*(x[~ind]-xc)/r[~ind]-mx)
    By[~ind] = const/(r[~ind]**3)*(3*mdotr*(y[~ind]-yc)/r[~ind]-my)
    Bz[~ind] = const/(r[~ind]**3)*(3*mdotr*(z[~ind]-zc)/r[~ind]-mz)

    return Bx, By, Bz
Пример #17
0
    def getError(self):
        #Test function
        phi = lambda x: np.cos(np.pi*x)
        j_fun = lambda x: -np.pi*np.sin(np.pi*x)
        q_fun = lambda x: -(np.pi**2)*np.cos(np.pi*x)

        xc_ana = phi(self.M.gridCC)
        q_ana = q_fun(self.M.gridCC)
        j_ana = j_fun(self.M.gridFx)

        #TODO: Check where our boundary conditions are CCx or Nx
        # vec = self.M.vectorNx
        vec = self.M.vectorCCx

        phi_bc = phi(vec[[0,-1]])
        j_bc = j_fun(vec[[0,-1]])

        P, Pin, Pout = self.M.getBCProjWF([['dirichlet', 'dirichlet']])

        Mc = self.M.getFaceInnerProduct()
        McI = Utils.sdInv(self.M.getFaceInnerProduct())
        V = Utils.sdiag(self.M.vol)
        G = -Pin.T*Pin*self.M.faceDiv.T * V
        D = self.M.faceDiv
        j = McI*(G*xc_ana + P*phi_bc)
        q = V*D*Pin.T*Pin*j + V*D*Pout.T*j_bc

        # Rearrange if we know q to solve for x
        A = V*D*Pin.T*Pin*McI*G
        rhs = V*q_ana - V*D*Pin.T*Pin*McI*P*phi_bc - V*D*Pout.T*j_bc
        # A = D*McI*G
        # rhs = q_ana - D*McI*P*phi_bc


        if self.myTest == 'j':
            err = np.linalg.norm((j-j_ana), np.inf)
        elif self.myTest == 'q':
            err = np.linalg.norm((q-V*q_ana), np.inf)
        elif self.myTest == 'xc':
            #TODO: fix the null space
            solver = SolverCG(A, maxiter=1000)
            xc = solver * (rhs)
            print('ACCURACY', np.linalg.norm(Utils.mkvc(A*xc) - rhs))
            err = np.linalg.norm((xc-xc_ana), np.inf)
        elif self.myTest == 'xcJ':
            #TODO: fix the null space
            xc = Solver(A) * (rhs)
            print(np.linalg.norm(Utils.mkvc(A*xc) - rhs))
            j = McI*(G*xc + P*phi_bc)
            err = np.linalg.norm((j-j_ana), np.inf)

        return err
Пример #18
0
def run(plotIt=True, nx=5, ny=5):

    # 2D mesh
    mesh = Mesh.TensorMesh([nx, ny], x0='CC')
    xtopo = mesh.vectorNx

    # define a topographic surface
    topo = 0.4*np.sin(xtopo*5)

    # make it an array
    Topo = np.hstack([Utils.mkvc(xtopo, 2), Utils.mkvc(topo, 2)])

    # Compare the different options
    indtopoCC_near = surface2ind_topo(mesh, Topo, gridLoc='CC', method='nearest')
    indtopoN_near = surface2ind_topo(mesh, Topo, gridLoc='N', method='nearest')

    indtopoCC_linear = surface2ind_topo(mesh, Topo, gridLoc='CC', method='linear')
    indtopoN_linear = surface2ind_topo(mesh, Topo, gridLoc='N', method='linear')

    indtopoCC_cubic = surface2ind_topo(mesh, Topo, gridLoc='CC', method='cubic')
    indtopoN_cubic = surface2ind_topo(mesh, Topo, gridLoc='N', method='cubic')

    if plotIt:
        fig, ax = plt.subplots(2, 3, figsize=(9, 6))
        ax = mkvc(ax)
        xinterpolate = np.linspace(mesh.gridN[:, 0].min(), mesh.gridN[:, 0].max(),100)
        listindex = [indtopoCC_near,indtopoN_near,indtopoCC_linear,indtopoN_linear,indtopoCC_cubic,indtopoN_cubic]
        listmethod = ['nearest','nearest', 'linear', 'linear', 'cubic', 'cubic']
        for i in range(6):
            mesh.plotGrid(ax=ax[i], nodes=True, centers=True)
            mesh.plotImage(listindex[i], ax=ax[i], pcolorOpts = {"alpha":0.5, "cmap":plt.cm.gray})
            ax[i].scatter(Topo[:,0], Topo[:,1], color = 'black', marker = 'o',s = 50)
            ax[i].plot(
                xinterpolate,
                interp1d(Topo[:, 0], Topo[:, 1], kind=listmethod[i])(xinterpolate),
                '--k',
                linewidth=3
                )
            ax[i].xaxis.set_ticklabels([])
            ax[i].yaxis.set_ticklabels([])
            ax[i].set_aspect('equal')
            ax[i].set_xlabel('')
            ax[i].set_ylabel('')

        ax[0].set_xlabel('Nearest Interpolation', fontsize=16)
        ax[2].set_xlabel('Linear Interpolation', fontsize=16)
        ax[4].set_xlabel('Cubic Interpolation', fontsize=16)

        ax[0].set_ylabel('Cells Center \n based selection', fontsize=16)
        ax[1].set_ylabel('Nodes \n based selection', fontsize=16)

        plt.tight_layout()
Пример #19
0
        def test_regularization_ActiveCells(self):
            for R in dir(Regularization):
                r = getattr(Regularization, R)
                if not inspect.isclass(r):
                    continue
                if not issubclass(r, ObjectiveFunction.BaseObjectiveFunction):
                    continue
                if r.__name__ in IGNORE_ME:
                    continue

                for i, mesh in enumerate(self.meshlist):

                    print('Testing Active Cells {0:d}D'.format((mesh.dim)))

                    if mesh.dim == 1:
                        indActive = Utils.mkvc(mesh.gridCC <= 0.8)
                    elif mesh.dim == 2:
                        indActive = Utils.mkvc(mesh.gridCC[:, -1] <= (
                            2*np.sin(2*np.pi*mesh.gridCC[:, 0])+0.5)
                        )
                    elif mesh.dim == 3:
                        indActive = Utils.mkvc(mesh.gridCC[:, -1] <= (
                                2 * np.sin(2*np.pi*mesh.gridCC[:, 0])+0.5 *
                                2 * np.sin(2*np.pi*mesh.gridCC[:, 1])+0.5)
                            )

                    if mesh.dim < 3 and r.__name__[-1] == 'z':
                        continue
                    if mesh.dim < 2 and r.__name__[-1] == 'y':
                        continue

                    for indAct in [indActive, indActive.nonzero()[0]]: # test both bool and integers
                        if indAct.dtype != bool:
                            nP = indAct.size
                        else:
                            nP = int(indAct.sum())

                        reg = r(
                            mesh, indActive=indAct, mapping=Maps.IdentityMap(nP=nP)
                        )
                        m = np.random.rand(mesh.nC)[indAct]
                        mref = np.ones_like(m)*np.mean(m)
                        reg.mref = mref

                        print(
                                '--- Checking {} ---\n'.format(
                                    reg.__class__.__name__
                                )
                            )

                        passed = reg.test(m, eps=TOL)
                        self.assertTrue(passed)
Пример #20
0
 def gridEy(self):
     """
     Edge staggered grid in the y direction.
     """
     if getattr(self, '_gridEy', None) is None:
         N = self.r(self.gridN, 'N', 'N', 'M')
         if self.dim == 2:
             XY = [Utils.mkvc(0.5 * (n[:, :-1] + n[:, 1:])) for n in N]
             self._gridEy = np.c_[XY[0], XY[1]]
         elif self.dim == 3:
             XYZ = [Utils.mkvc(0.5 * (n[:, :-1, :] + n[:, 1:, :])) for n in N]
             self._gridEy = np.c_[XYZ[0], XYZ[1], XYZ[2]]
     return self._gridEy
Пример #21
0
    def test_data(self):
        V = []
        for src in self.D.survey.srcList:
            for rx in src.rxList:
                v = np.random.rand(rx.nD)
                V += [v]
                self.D[src, rx] = v
                self.assertTrue(np.all(v == self.D[src, rx]))
        V = np.concatenate(V)
        self.assertTrue(np.all(V == Utils.mkvc(self.D)))

        D2 = Survey.Data(self.D.survey, V)
        self.assertTrue(np.all(Utils.mkvc(D2) == Utils.mkvc(self.D)))
Пример #22
0
def MagSphereAnaFun(x, y, z, R, x0, y0, z0, mu1, mu2, H0, flag='total'):
    """
        test
        Analytic function for Magnetics problem. The set up here is
        magnetic sphere in whole-space assuming that the inducing field is oriented in the x-direction.

        * (x0, y0, z0)
        * (x0, y0, z0 ): is the center location of sphere
        * r: is the radius of the sphere

    .. math::

        \mathbf{H}_0 = H_0\hat{x}


    """

    if (~np.size(x)==np.size(y)==np.size(z)):
        print("Specify same size of x, y, z")
        return
    dim = x.shape
    x = Utils.mkvc(x)
    y = Utils.mkvc(y)
    z = Utils.mkvc(z)

    ind = np.sqrt((x-x0)**2+(y-y0)**2+(z-z0)**2) < R
    r = Utils.mkvc(np.sqrt((x-x0)**2+(y-y0)**2+(z-z0)**2))
    Bx = np.zeros(x.size)
    By = np.zeros(x.size)
    Bz = np.zeros(x.size)

    # Inside of the sphere
    rf2 = 3*mu1/(mu2+2*mu1)
    if flag is 'total' and any(ind):
        Bx[ind] = mu2*H0*(rf2)
    elif (flag == 'secondary'):
        Bx[ind] = mu2*H0*(rf2)-mu1*H0

    By[ind] = 0.
    Bz[ind] = 0.
    # Outside of the sphere
    rf1 = (mu2-mu1)/(mu2+2*mu1)
    if (flag == 'total'):
        Bx[~ind] = mu1*(H0+H0/r[~ind]**5*(R**3)*rf1*(2*(x[~ind]-x0)**2-(y[~ind]-y0)**2-(z[~ind]-z0)**2))
    elif (flag == 'secondary'):
        Bx[~ind] = mu1*(H0/r[~ind]**5*(R**3)*rf1*(2*(x[~ind]-x0)**2-(y[~ind]-y0)**2-(z[~ind]-z0)**2))

    By[~ind] = mu1*(H0/r[~ind]**5*(R**3)*rf1*(3*(x[~ind]-x0)*(y[~ind]-y0)))
    Bz[~ind] = mu1*(H0/r[~ind]**5*(R**3)*rf1*(3*(x[~ind]-x0)*(z[~ind]-z0)))
    return np.reshape(Bx, x.shape, order='F'), np.reshape(By, x.shape, order='F'), np.reshape(Bz, x.shape, order='F')
Пример #23
0
    def setUp(self):

        # Define sphere parameters
        self.rad = 2.
        self.rho = 0.1

        # Define a mesh
        cs = 0.2
        hxind = [(cs, 21)]
        hyind = [(cs, 21)]
        hzind = [(cs, 21)]
        mesh = Mesh.TensorMesh([hxind, hyind, hzind], 'CCC')

        # Get cells inside the sphere
        sph_ind = PF.MagAnalytics.spheremodel(mesh, 0., 0., 0., self.rad)

        # Adjust density for volume difference
        Vratio = (4./3.*np.pi*self.rad**3.) / (np.sum(sph_ind)*cs**3.)
        model = np.ones(mesh.nC)*self.rho*Vratio
        self.model = model[sph_ind]

        # Create reduced identity map for Linear Pproblem
        idenMap = Maps.IdentityMap(nP=int(sum(sph_ind)))

        # Create plane of observations
        xr = np.linspace(-20, 20, 21)
        yr = np.linspace(-20, 20, 21)
        X, Y = np.meshgrid(xr, yr)

        # Move obs plane 2 radius away from sphere
        Z = np.ones((xr.size, yr.size))*2.*self.rad
        self.locXyz = np.c_[Utils.mkvc(X), Utils.mkvc(Y), Utils.mkvc(Z)]
        rxLoc = PF.BaseGrav.RxObs(self.locXyz)
        srcField = PF.BaseGrav.SrcField([rxLoc])
        self.survey = PF.BaseGrav.LinearSurvey(srcField)

        self.prob_x = PF.Gravity.GravityIntegral(mesh, rhoMap=idenMap,
                                                 actInd=sph_ind,
                                                 forwardOnly=True,
                                                 rx_type='x')

        self.prob_y = PF.Gravity.GravityIntegral(mesh, rhoMap=idenMap,
                                                 actInd=sph_ind,
                                                 forwardOnly=True,
                                                 rx_type='y')

        self.prob_z = PF.Gravity.GravityIntegral(mesh, rhoMap=idenMap,
                                                 actInd=sph_ind,
                                                 forwardOnly=True,
                                                 rx_type='z')
Пример #24
0
 def vol(self):
     """Construct cell volumes of the 3D model as 1d array."""
     if getattr(self, '_vol', None) is None:
         vh = self.h
         # Compute cell volumes
         if self.dim == 1:
             self._vol = Utils.mkvc(vh[0])
         elif self.dim == 2:
             # Cell sizes in each direction
             self._vol = Utils.mkvc(np.outer(vh[0], vh[1]))
         elif self.dim == 3:
             # Cell sizes in each direction
             self._vol = Utils.mkvc(np.outer(Utils.mkvc(np.outer(vh[0], vh[1])), vh[2]))
     return self._vol
Пример #25
0
    def test_rotationMatrixFromNormals(self):
        np.random.seed(0)
        v0 = np.random.rand(3)
        v0 *= 1./np.linalg.norm(v0)

        np.random.seed(5)
        v1 = np.random.rand(3)
        v1 *= 1./np.linalg.norm(v1)

        Rf = Utils.coordutils.rotationMatrixFromNormals(v0,v1)
        Ri = Utils.coordutils.rotationMatrixFromNormals(v1,v0)

        self.assertTrue(np.linalg.norm(Utils.mkvc(Rf.dot(v0) - v1)) < tol)
        self.assertTrue(np.linalg.norm(Utils.mkvc(Ri.dot(v1) - v0)) < tol)
Пример #26
0
def CondSphereAnalFunJ(x, y, z, R, x0, y0, z0, sig1, sig2, E0, flag):
    """
        test
        Analytic function for Electro-Static problem. The set up here is
        conductive sphere in whole-space.

        * (x0,y0,z0)
        * (x0, y0, z0 ): is the center location of sphere
        * r: is the radius of the sphere

    .. math::

        \mathbf{E}_0 = E_0\hat{x}


    """
    if (~np.size(x)==np.size(y)==np.size(z)):
        print "Specify same size of x, y, z"
        return
    dim = x.shape
    x = Utils.mkvc(x-x0)
    y = Utils.mkvc(y-y0)
    z = Utils.mkvc(z-z0)

    ind = np.sqrt((x)**2+(y)**2+(z)**2 ) < R
    r = Utils.mkvc(np.sqrt((x)**2+(y)**2+(z)**2 ))

    Jx = np.zeros(x.size)
    Jy = np.zeros(x.size)
    Jz = np.zeros(x.size)

    # Inside of the sphere
    rf2 = 3*sig1/(sig2+2*sig1)
    if (flag == 'total'):
        Jx[ind] = sig2*E0*(rf2)
    elif (flag == 'secondary'):
        Jx[ind] = sig2*E0*(rf2)-sig1*E0
    Jy[ind] = 0.
    Jz[ind] = 0.
    # Outside of the sphere
    rf1 = (sig2-sig1)/(sig2+2*sig1)
    if (flag == 'total'):
        Jx[~ind] = sig1*(E0+E0/r[~ind]**5*(R**3)*rf1*(2*x[~ind]**2-y[~ind]**2-z[~ind]**2))
    elif (flag == 'secondary'):
        Jx[~ind] = sig1*(E0/r[~ind]**5*(R**3)*rf1*(2*x[~ind]**2-y[~ind]**2-z[~ind]**2))
    Jy[~ind] = sig1*(E0/r[~ind]**5*(R**3)*rf1*(3*x[~ind]*y[~ind]))
    Jz[~ind] = sig1*(E0/r[~ind]**5*(R**3)*rf1*(3*x[~ind]*z[~ind]))

    return np.reshape(Jx, x.shape, order='F'), np.reshape(Jy, x.shape, order='F'), np.reshape(Jz, x.shape, order='F')
Пример #27
0
def hzAnalyticDipoleF(r, freq, sigma, secondary=True, mu=mu_0):
    """
    4.56 in Ward and Hohmann

    .. plot::

        import matplotlib.pyplot as plt
        from SimPEG import EM
        freq = np.logspace(-1, 6, 61)
        test = EM.Analytics.FDEM.hzAnalyticDipoleF(100, freq, 0.001, secondary=False)
        plt.loglog(freq, abs(test.real))
        plt.loglog(freq, abs(test.imag))
        plt.title('Response at $r$=100m')
        plt.xlabel('Frequency')
        plt.ylabel('Response')
        plt.legend(('real','imag'))
        plt.show()

    """
    r = np.abs(r)
    k = np.sqrt(-1j*2.*np.pi*freq*mu*sigma)

    m = 1
    front = m / (2. * np.pi * (k**2) * (r**5) )
    back = 9 - ( 9 + 9j * k * r - 4 * (k**2) * (r**2) - 1j * (k**3) * (r**3)) * np.exp(-1j*k*r)
    hz = front*back

    if secondary:
        hp =-1/(4*np.pi*r**3)
        hz = hz-hp

    if hz.ndim == 1:
        hz = Utils.mkvc(hz,2)

    return hz
Пример #28
0
    def Jvec(self, m, v, u=None):
        """
        Sensitivity times a vector.

        :param numpy.array m: inversion model (nP,)
        :param numpy.array v: vector which we take sensitivity product with (nP,)
        :param SimPEG.EM.FDEM.Fields u: fields object 
        :rtype numpy.array:
        :return: Jv (ndata,) 
        """

        if u is None:
           u = self.fields(m)

        self.curModel = m

        Jv = self.dataPair(self.survey)

        for freq in self.survey.freqs:
            A = self.getA(freq) 
            Ainv = self.Solver(A, **self.solverOpts)

            for src in self.survey.getSrcByFreq(freq):
                u_src = u[src, self._solutionType]
                dA_dm_v = self.getADeriv(freq, u_src, v)
                dRHS_dm_v = self.getRHSDeriv(freq, src, v) 
                du_dm_v = Ainv * ( - dA_dm_v + dRHS_dm_v )
                
                for rx in src.rxList:
                    df_dmFun = getattr(u, '_%sDeriv'%rx.projField, None)
                    df_dm_v = df_dmFun(src, du_dm_v, v, adjoint=False)
                    Jv[src, rx] = rx.evalDeriv(src, self.mesh, u, df_dm_v)
            Ainv.clean()
        return Utils.mkvc(Jv)
Пример #29
0
    def Wd(self):
        """getWd(survey)

            The data weighting matrix.

            The default is based on the norm of the data plus a noise floor.

            :rtype: scipy.sparse.csr_matrix
            :return: Wd

        """

        if getattr(self, '_Wd', None) is None:

            survey = self.survey

            if getattr(survey,'std', None) is None:
                print('SimPEG.DataMisfit.l2_DataMisfit assigning default std of 5%')
                survey.std = 0.05

            if getattr(survey, 'eps', None) is None:
                print('SimPEG.DataMisfit.l2_DataMisfit assigning default eps of 1e-5 * ||dobs||')
                survey.eps = np.linalg.norm(Utils.mkvc(survey.dobs),2)*1e-5

            self._Wd = Utils.sdiag(1/(abs(survey.dobs)*survey.std+survey.eps))
        return self._Wd
Пример #30
0
    def Jvec(self, m, v, f=None):

        self.model = m

        # When sensitivity matrix J is stored
        if self.storeJ:
            J = self.getJ(m, f=f)
            Jv = Utils.mkvc(np.dot(J, v))
            return self.sign * Jv

        else:

            if f is None:
                f = self.fields(m)

            Jv = []

            for src in self.survey.srcList:
                u_src = f[src, self._solutionType] # solution vector
                dA_dm_v = self.getADeriv(u_src.flatten(), v, adjoint=False)
                dRHS_dm_v = self.getRHSDeriv(src, v)
                du_dm_v = self.Ainv * ( - dA_dm_v + dRHS_dm_v )

                for rx in src.rxList:
                    df_dmFun = getattr(f, '_{0!s}Deriv'.format(rx.projField), None)
                    df_dm_v = df_dmFun(src, du_dm_v, v, adjoint=False)
                    Jv.append(rx.evalDeriv(src, self.mesh, f, df_dm_v))

            # Conductivity (d u / d log sigma) - EB form
            # Resistivity (d u / d log rho) - HJ form
            return self.sign*np.hstack(Jv)
Пример #31
0
    def test_rotateMatrixFromNormals(self):
        np.random.seed(20)
        n0 = np.random.rand(3)
        n0 *= 1. / np.linalg.norm(n0)

        np.random.seed(25)
        n1 = np.random.rand(3)
        n1 *= 1. / np.linalg.norm(n1)

        np.random.seed(30)
        scale = np.random.rand(100, 1)
        XYZ0 = scale * n0
        XYZ1 = scale * n1

        XYZ2 = Utils.coordutils.rotatePointsFromNormals(XYZ0, n0, n1)
        self.assertTrue(
            np.linalg.norm(Utils.mkvc(XYZ1) - Utils.mkvc(XYZ2)) /
            np.linalg.norm(Utils.mkvc(XYZ1)) < tol)
Пример #32
0
 def gridEz(self):
     """
     Edge staggered grid in the z direction.
     """
     if getattr(self, '_gridEz', None) is None and self.dim == 3:
         N = self.r(self.gridN, 'N', 'N', 'M')
         XYZ = [Utils.mkvc(0.5 * (n[:, :, :-1] + n[:, :, 1:])) for n in N]
         self._gridEz = np.c_[XYZ[0], XYZ[1], XYZ[2]]
     return self._gridEz