Example #1
0
 def aveF2CC(self):
     "Construct the averaging operator on cell faces to cell centers."
     if getattr(self, '_aveF2CC', None) is None:
         n = self.vnC
         if self.isSymmetric:
             avR = Utils.av(n[0])[:, 1:]
             avR[0, 0] = 1.
             self._aveF2CC = ((0.5)*sp.hstack((sp.kron(Utils.speye(n[2]),
                                                       avR),
                                               sp.kron(Utils.av(n[2]),
                                                       Utils.speye(n[0]))),
                                              format="csr"))
         else:
             raise NotImplementedError('wrapping in the averaging is not '
                                       'yet implemented')
             # self._aveF2CC = (1./3.)*sp.hstack((Utils.kron3(Utils.speye(n[2]),
             #                                                Utils.speye(n[1]),
             #                                                Utils.av(n[0])),
             #                                    Utils.kron3(Utils.speye(n[2]),
             #                                                Utils.av(n[1]),
             #                                                Utils.speye(n[0])),
             #                                    Utils.kron3(Utils.av(n[2]),
             #                                                Utils.speye(n[1]),
             #                                                Utils.speye(n[0]))),
             #                                   format="csr")
     return self._aveF2CC
Example #2
0
 def W(self):
     """Regularization matrix W"""
     if getattr(self, '_W', None) is None:
         ntx = self.xyz_line.shape[0]
         meshline = Mesh.TensorMesh([ntx])
         Gx = meshline.cellGradx
         Wx = np.sqrt(self.alpha_x) * sp.kron(Gx, Utils.speye(self.ntau))
         Ws = np.sqrt(self.alpha_s) * Utils.speye(self.ntau * ntx)
         wlist = (Wx, Ws)
         self._W = sp.vstack(wlist)
     return self._W
Example #3
0
 def faceDivz(self):
     """
     Construct divergence operator in the z component
     (face-stg to cell-centres).
     """
     if getattr(self, "_faceDivz", None) is None:
         D3 = Utils.kron3(Utils.ddx(self.nCz), Utils.speye(self.nCy), Utils.speye(self.nCx))
         S = self.r(self.area, "F", "Fz", "V")
         V = self.vol
         self._faceDivz = Utils.sdiag(1 / V) * D3 * Utils.sdiag(S)
     return self._faceDivz
Example #4
0
 def faceDivz(self):
     """
     Construct divergence operator in the z component
     (face-stg to cell-centres).
     """
     if getattr(self, '_faceDivz', None) is None:
         D3 = Utils.kron3(Utils.ddx(self.nCz), Utils.speye(self.nCy),
                          Utils.speye(self.nCx))
         S = self.r(self.area, 'F', 'Fz', 'V')
         V = self.vol
         self._faceDivz = Utils.sdiag(1/V)*D3*Utils.sdiag(S)
     return self._faceDivz
Example #5
0
 def aveF2CCV(self):
     "Construct the averaging operator on cell faces to cell centers."
     if getattr(self, "_aveF2CCV", None) is None:
         n = self.vnC
         if self.isSymmetric:
             avR = Utils.av(n[0])[:, 1:]
             avR[0, 0] = 1.0
             self._aveF2CCV = sp.block_diag(
                 (sp.kron(Utils.speye(n[2]), avR), sp.kron(Utils.av(n[2]), Utils.speye(n[0]))), format="csr"
             )
         else:
             raise NotImplementedError("wrapping in the averaging is not " "yet implemented")
     return self._aveF2CCV
Example #6
0
 def faceDivy(self):
     """
     Construct divergence operator in the y component
     (face-stg to cell-centres).
     """
     raise NotImplementedError("Wrapping the Utils.ddx is not yet " "implemented.")
     if getattr(self, "_faceDivy", None) is None:
         # TODO: this needs to wrap to join up faces which are
         # connected in the cylinder
         D2 = Utils.kron3(Utils.speye(self.nCz), Utils.ddx(self.nCy), Utils.speye(self.nCx))
         S = self.r(self.area, "F", "Fy", "V")
         V = self.vol
         self._faceDivy = Utils.sdiag(1 / V) * D2 * Utils.sdiag(S)
     return self._faceDivy
Example #7
0
    def get_grad_horizontal(self, xy, hz):
        """
            Compute Gradient in horizontal direction using Delaunay

        """
        tri = sp.spatial.Delaunay(xy)
        # Split the triangulation into connections
        edges = np.r_[tri.simplices[:, :2], tri.simplices[:, 1:],
                      tri.simplices[:, [0, 2]]]

        # Sort and keep uniques
        edges = np.sort(edges, axis=1)
        edges = np.unique(edges[np.argsort(edges[:, 0]), :], axis=0)

        # Create 2D operator, dimensionless for now
        nN = edges.shape[0]
        nStn = xy.shape[0]
        stn, count = np.unique(edges[:, 0], return_counts=True)

        col = []
        row = []
        dm = []
        avg = []
        for ii in range(nN):
            row += [ii] * 2
            col += [edges[ii, 0], edges[ii, 1]]

            scale = count[stn == edges[ii, 0]][0]
            dm += [-1., 1.]
            avg += [0.5, 0.5]

        D = sp.sparse.csr_matrix((dm, (row, col)), shape=(nN, nStn))
        A = sp.sparse.csr_matrix((avg, (row, col)), shape=(nN, nStn))

        # Kron vertically for nCz
        Grad = sp.sparse.kron(D, Utils.speye(hz.size))
        Avg = sp.sparse.kron(A, Utils.speye(hz.size))

        # Override the gradient operator in y-drection
        # This is because of ordering ... See def get_2d_mesh
        # y first then x
        self.regmesh._cellDiffyStencil = self.regmesh.cellDiffxStencil.copy()
        # Override the gradient operator in x-drection
        self.regmesh._cellDiffxStencil = Grad
        # Do the same for the averaging operator
        self.regmesh._aveCC2Fy = self.regmesh.aveCC2Fx.copy()
        self.regmesh._aveCC2Fx = Avg
        self.regmesh._aveFy2CC = self.regmesh.aveFx2CC.copy()
        self.regmesh._aveFx2CC = Avg.T
        return tri
Example #8
0
 def aveF2CCV(self):
     "Construct the averaging operator on cell faces to cell centers."
     if getattr(self, '_aveF2CCV', None) is None:
         n = self.vnC
         if self.isSymmetric:
             avR = Utils.av(n[0])[:, 1:]
             avR[0, 0] = 1.
             self._aveF2CCV = sp.block_diag(
                 (sp.kron(Utils.speye(n[2]),
                          avR), sp.kron(Utils.av(n[2]), Utils.speye(n[0]))),
                 format="csr")
         else:
             raise NotImplementedError('wrapping in the averaging is not '
                                       'yet implemented')
     return self._aveF2CCV
Example #9
0
 def faceDivy(self):
     """
     Construct divergence operator in the y component
     (face-stg to cell-centres).
     """
     raise NotImplementedError('Wrapping the Utils.ddx is not yet '
                               'implemented.')
     if getattr(self, '_faceDivy', None) is None:
         # TODO: this needs to wrap to join up faces which are
         # connected in the cylinder
         D2 = Utils.kron3(Utils.speye(self.nCz), Utils.ddx(self.nCy),
                         Utils.speye(self.nCx))
         S = self.r(self.area, 'F', 'Fy', 'V')
         V = self.vol
         self._faceDivy = Utils.sdiag(1/V)*D2*Utils.sdiag(S)
     return self._faceDivy
Example #10
0
    def Pac(self):
        """
        diagonal matrix that nulls out inactive cells

        :rtype: scipy.sparse.csr_matrix
        :return: active cell diagonal matrix
        """
        if getattr(self, "_Pac", None) is None:
            if self.indActive is None:
                self._Pac = Utils.speye(self.mesh.nC)
            else:
                e = np.zeros(self.mesh.nC)
                e[self.indActive] = 1.0
                # self._Pac = Utils.speye(self.mesh.nC)[:, self.indActive]
                self._Pac = Utils.sdiag(e)
        return self._Pac
Example #11
0
    def Pafy(self):
        """
        diagonal matrix that nulls out inactive y-faces
        to full modelling space (ie. nFy x nindActive_Fy )

        :rtype: scipy.sparse.csr_matrix
        :return: active face-y diagonal matrix
        """
        if getattr(self, '_Pafy', None) is None:
            if self.indActive is None:
                self._Pafy = Utils.speye(self.mesh.nFy)
            else:
                indActive_Fy = (self.mesh.aveFy2CC.T * self.indActive) >= 1
                e = np.zeros(self.mesh.nFy)
                e[indActive_Fy] = 1.
                self._Pafy = Utils.sdiag(e)
        return self._Pafy
Example #12
0
    def Pafz(self):
        """
        diagonal matrix that nulls out inactive z-faces
        to full modelling space (ie. nFz x nindActive_Fz )

        :rtype: scipy.sparse.csr_matrix
        :return: active face-z diagonal matrix
        """
        if getattr(self, "_Pafz", None) is None:
            if self.indActive is None:
                self._Pafz = Utils.speye(self.mesh.nFz)
            else:
                indActive_Fz = (self.mesh.aveFz2CC.T * self.indActive) >= 1
                e = np.zeros(self.mesh.nFz)
                e[indActive_Fz] = 1.0
                self._Pafz = Utils.sdiag(e)
        return self._Pafz
Example #13
0
    def Pafx(self):
        """
        diagonal matrix that nulls out inactive x-faces
        to full modelling space (ie. nFx x nindActive_Fx )

        :rtype: scipy.sparse.csr_matrix
        :return: active face-x diagonal matrix
        """
        if getattr(self, "_Pafx", None) is None:
            if self.indActive is None:
                self._Pafx = Utils.speye(self.mesh.nFx)
            else:
                indActive_Fx = self.mesh.aveFx2CC.T * self.indActive >= 1
                e = np.zeros(self.mesh.nFx)
                e[indActive_Fx] = 1.0
                self._Pafx = Utils.sdiag(e)
        return self._Pafx
Example #14
0
    def getJtJdiag(self, m, W=None, threshold=1e-8):
        """
        Compute diagonal component of JtJ or
        trace of sensitivity matrix (J)
        """
        J_sigma = self.getJ_sigma(m)
        J_matrix = J_sigma*(Utils.sdiag(1./self.sigma)*(self.sigmaDeriv))

        if self.hMap is not None:
            J_height = self.getJ_height(m)
            J_matrix += J_height*self.hDeriv

        if W is None:
            W = Utils.speye(J_matrix.shape[0])

        J_matrix = W*J_matrix
        JtJ_diag = (J_matrix.T*J_matrix).diagonal()
        JtJ_diag /= JtJ_diag.max()
        JtJ_diag += threshold
        return JtJ_diag
Example #15
0
    def getAdiag(self, tInd):
        """
        System matrix at a given time index

        .. math::
            (\mathbf{I} + \mathbf{dt} \mathbf{C} \mathbf{M_{\sigma}^e}^{-1}
            \mathbf{C}^{\\top} \mathbf{M_{\mu^{-1}}^f})

        """
        assert tInd >= 0 and tInd < self.nT

        dt = self.timeSteps[tInd]
        C = self.mesh.edgeCurl
        MeSigmaI = self.MeSigmaI
        MfMui = self.MfMui
        I = Utils.speye(self.mesh.nF)

        A = 1./dt * I + ( C * ( MeSigmaI * (C.T * MfMui ) ) )

        if self._makeASymmetric is True:
            return MfMui.T * A
        return A
Example #16
0
    def getAdiag(self, tInd):
        """
        System matrix at a given time index

        .. math::
            (\mathbf{I} + \mathbf{dt} \mathbf{C} \mathbf{M_{\sigma}^e}^{-1}
            \mathbf{C}^{\\top} \mathbf{M_{\mu^{-1}}^f})

        """
        assert tInd >= 0 and tInd < self.nT

        dt = self.timeSteps[tInd]
        C = self.mesh.edgeCurl
        MeSigmaI = self.MeSigmaI
        MfMui = self.MfMui
        I = Utils.speye(self.mesh.nF)

        A = 1. / dt * I + (C * (MeSigmaI * (C.T * MfMui)))

        if self._makeASymmetric is True:
            return MfMui.T * A
        return A
Example #17
0
def run(plotIt=True, n=60):
    """
        Mesh: Operators: Cahn Hilliard
        ==============================

        This example is based on the example in the FiPy_ library.
        Please see their documentation for more information about the
        Cahn-Hilliard equation.

        The "Cahn-Hilliard" equation separates a field \\\\( \\\\phi \\\\)
        into 0 and 1 with smooth transitions.

        .. math::

            \\frac{\partial \phi}{\partial t} = \\nabla \cdot D \\nabla \left( \\frac{\partial f}{\partial \phi} - \epsilon^2 \\nabla^2 \phi \\right)

        Where \\\\( f \\\\) is the energy function \\\\( f = ( a^2 / 2 )\\\\phi^2(1 - \\\\phi)^2 \\\\)
        which drives \\\\( \\\\phi \\\\) towards either 0 or 1, this competes with the term
        \\\\(\\\\epsilon^2 \\\\nabla^2 \\\\phi \\\\) which is a diffusion term that creates smooth changes in \\\\( \\\\phi \\\\).
        The equation can be factored:

        .. math::

            \\frac{\partial \phi}{\partial t} = \\nabla \cdot D \\nabla \psi \\\\
            \psi = \\frac{\partial^2 f}{\partial \phi^2} (\phi - \phi^{\\text{old}}) + \\frac{\partial f}{\partial \phi} - \epsilon^2 \\nabla^2 \phi

        Here we will need the derivatives of \\\\( f \\\\):

        .. math::

            \\frac{\partial f}{\partial \phi} = (a^2/2)2\phi(1-\phi)(1-2\phi)
            \\frac{\partial^2 f}{\partial \phi^2} = (a^2/2)2[1-6\phi(1-\phi)]

        The implementation below uses backwards Euler in time with an
        exponentially increasing time step. The initial \\\\( \\\\phi \\\\)
        is a normally distributed field with a standard deviation of 0.1 and
        mean of 0.5. The grid is 60x60 and takes a few seconds to solve ~130
        times. The results are seen below, and you can see the field separating
        as the time increases.

        .. _FiPy: http://www.ctcms.nist.gov/fipy/examples/cahnHilliard/generated/examples.cahnHilliard.mesh2DCoupled.html

    """

    np.random.seed(5)

    # Here we are going to rearrange the equations:

    # (phi_ - phi)/dt = A*(d2fdphi2*(phi_ - phi) + dfdphi - L*phi_)
    # (phi_ - phi)/dt = A*(d2fdphi2*phi_ - d2fdphi2*phi + dfdphi - L*phi_)
    # (phi_ - phi)/dt = A*d2fdphi2*phi_ + A*( - d2fdphi2*phi + dfdphi - L*phi_)
    # phi_ - phi = dt*A*d2fdphi2*phi_ + dt*A*(- d2fdphi2*phi + dfdphi - L*phi_)
    # phi_ - dt*A*d2fdphi2 * phi_ =  dt*A*(- d2fdphi2*phi + dfdphi - L*phi_) + phi
    # (I - dt*A*d2fdphi2) * phi_ =  dt*A*(- d2fdphi2*phi + dfdphi - L*phi_) + phi
    # (I - dt*A*d2fdphi2) * phi_ =  dt*A*dfdphi - dt*A*d2fdphi2*phi - dt*A*L*phi_ + phi
    # (dt*A*d2fdphi2 - I) * phi_ =  dt*A*d2fdphi2*phi + dt*A*L*phi_ - phi - dt*A*dfdphi
    # (dt*A*d2fdphi2 - I - dt*A*L) * phi_ =  (dt*A*d2fdphi2 - I)*phi - dt*A*dfdphi

    h = [(0.25, n)]
    M = Mesh.TensorMesh([h, h])

    # Constants
    D = a = epsilon = 1.
    I = Utils.speye(M.nC)

    # Operators
    A = D * M.faceDiv * M.cellGrad
    L = epsilon**2 * M.faceDiv * M.cellGrad

    duration = 75
    elapsed = 0.
    dexp = -5
    phi = np.random.normal(loc=0.5, scale=0.01, size=M.nC)
    ii, jj = 0, 0
    PHIS = []
    capture = np.logspace(-1, np.log10(duration), 8)
    while elapsed < duration:
        dt = min(100, np.exp(dexp))
        elapsed += dt
        dexp += 0.05

        dfdphi = a**2 * 2 * phi * (1 - phi) * (1 - 2 * phi)
        d2fdphi2 = Utils.sdiag(a**2 * 2 * (1 - 6 * phi * (1 - phi)))

        MAT = (dt * A * d2fdphi2 - I - dt * A * L)
        rhs = (dt * A * d2fdphi2 - I) * phi - dt * A * dfdphi
        phi = Solver(MAT) * rhs

        if elapsed > capture[jj]:
            PHIS += [(elapsed, phi.copy())]
            jj += 1
        if ii % 10 == 0:
            print(ii, elapsed)
        ii += 1

    if plotIt:
        fig, axes = plt.subplots(2, 4, figsize=(14, 6))
        axes = np.array(axes).flatten().tolist()
        for ii, ax in zip(np.linspace(0, len(PHIS) - 1, len(axes)), axes):
            ii = int(ii)
            M.plotImage(PHIS[ii][1], ax=ax)
            ax.axis('off')
            ax.set_title('Elapsed Time: {0:4.1f}'.format(PHIS[ii][0]))
Example #18
0
def run(plotIt=True, n=60):

    np.random.seed(5)

    # Here we are going to rearrange the equations:

    # (phi_ - phi)/dt = A*(d2fdphi2*(phi_ - phi) + dfdphi - L*phi_)
    # (phi_ - phi)/dt = A*(d2fdphi2*phi_ - d2fdphi2*phi + dfdphi - L*phi_)
    # (phi_ - phi)/dt = A*d2fdphi2*phi_ + A*( - d2fdphi2*phi + dfdphi - L*phi_)
    # phi_ - phi = dt*A*d2fdphi2*phi_ + dt*A*(- d2fdphi2*phi + dfdphi - L*phi_)
    # phi_ - dt*A*d2fdphi2 * phi_ =  dt*A*(- d2fdphi2*phi + dfdphi - L*phi_) + phi
    # (I - dt*A*d2fdphi2) * phi_ =  dt*A*(- d2fdphi2*phi + dfdphi - L*phi_) + phi
    # (I - dt*A*d2fdphi2) * phi_ =  dt*A*dfdphi - dt*A*d2fdphi2*phi - dt*A*L*phi_ + phi
    # (dt*A*d2fdphi2 - I) * phi_ =  dt*A*d2fdphi2*phi + dt*A*L*phi_ - phi - dt*A*dfdphi
    # (dt*A*d2fdphi2 - I - dt*A*L) * phi_ =  (dt*A*d2fdphi2 - I)*phi - dt*A*dfdphi

    h = [(0.25, n)]
    M = Mesh.TensorMesh([h, h])

    # Constants
    D = a = epsilon = 1.
    I = Utils.speye(M.nC)

    # Operators
    A = D * M.faceDiv * M.cellGrad
    L = epsilon**2 * M.faceDiv * M.cellGrad

    duration = 75
    elapsed = 0.
    dexp = -5
    phi = np.random.normal(loc=0.5, scale=0.01, size=M.nC)
    ii, jj = 0, 0
    PHIS = []
    capture = np.logspace(-1, np.log10(duration), 8)
    while elapsed < duration:
        dt = min(100, np.exp(dexp))
        elapsed += dt
        dexp += 0.05

        dfdphi = a**2 * 2 * phi * (1 - phi) * (1 - 2 * phi)
        d2fdphi2 = Utils.sdiag(a**2 * 2 * (1 - 6 * phi * (1 - phi)))

        MAT = (dt*A*d2fdphi2 - I - dt*A*L)
        rhs = (dt*A*d2fdphi2 - I)*phi - dt*A*dfdphi
        phi = Solver(MAT)*rhs

        if elapsed > capture[jj]:
            PHIS += [(elapsed, phi.copy())]
            jj += 1
        if ii % 10 == 0:
            print(ii, elapsed)
        ii += 1

    if plotIt:
        fig, axes = plt.subplots(2, 4, figsize=(14, 6))
        axes = np.array(axes).flatten().tolist()
        for ii, ax in zip(np.linspace(0, len(PHIS)-1, len(axes)), axes):
            ii = int(ii)
            M.plotImage(PHIS[ii][1], ax=ax)
            ax.axis('off')
            ax.set_title('Elapsed Time: {0:4.1f}'.format(PHIS[ii][0]))
Example #19
0
def run(plotIt=True, n=60):

    np.random.seed(5)

    # Here we are going to rearrange the equations:

    # (phi_ - phi)/dt = A*(d2fdphi2*(phi_ - phi) + dfdphi - L*phi_)
    # (phi_ - phi)/dt = A*(d2fdphi2*phi_ - d2fdphi2*phi + dfdphi - L*phi_)
    # (phi_ - phi)/dt = A*d2fdphi2*phi_ + A*( - d2fdphi2*phi + dfdphi - L*phi_)
    # phi_ - phi = dt*A*d2fdphi2*phi_ + dt*A*(- d2fdphi2*phi + dfdphi - L*phi_)
    # phi_ - dt*A*d2fdphi2 * phi_ =  dt*A*(- d2fdphi2*phi + dfdphi - L*phi_) + phi
    # (I - dt*A*d2fdphi2) * phi_ =  dt*A*(- d2fdphi2*phi + dfdphi - L*phi_) + phi
    # (I - dt*A*d2fdphi2) * phi_ =  dt*A*dfdphi - dt*A*d2fdphi2*phi - dt*A*L*phi_ + phi
    # (dt*A*d2fdphi2 - I) * phi_ =  dt*A*d2fdphi2*phi + dt*A*L*phi_ - phi - dt*A*dfdphi
    # (dt*A*d2fdphi2 - I - dt*A*L) * phi_ =  (dt*A*d2fdphi2 - I)*phi - dt*A*dfdphi

    h = [(0.25, n)]
    M = Mesh.TensorMesh([h, h])

    # Constants
    D = a = epsilon = 1.
    I = Utils.speye(M.nC)

    # Operators
    A = D * M.faceDiv * M.cellGrad
    L = epsilon**2 * M.faceDiv * M.cellGrad

    duration = 75
    elapsed = 0.
    dexp = -5
    phi = np.random.normal(loc=0.5, scale=0.01, size=M.nC)
    ii, jj = 0, 0
    PHIS = []
    capture = np.logspace(-1, np.log10(duration), 8)
    while elapsed < duration:
        dt = min(100, np.exp(dexp))
        elapsed += dt
        dexp += 0.05

        dfdphi = a**2 * 2 * phi * (1 - phi) * (1 - 2 * phi)
        d2fdphi2 = Utils.sdiag(a**2 * 2 * (1 - 6 * phi * (1 - phi)))

        MAT = (dt * A * d2fdphi2 - I - dt * A * L)
        rhs = (dt * A * d2fdphi2 - I) * phi - dt * A * dfdphi
        phi = Solver(MAT) * rhs

        if elapsed > capture[jj]:
            PHIS += [(elapsed, phi.copy())]
            jj += 1
        if ii % 10 == 0:
            print(ii, elapsed)
        ii += 1

    if plotIt:
        fig, axes = plt.subplots(2, 4, figsize=(14, 6))
        axes = np.array(axes).flatten().tolist()
        for ii, ax in zip(np.linspace(0, len(PHIS) - 1, len(axes)), axes):
            ii = int(ii)
            M.plotImage(PHIS[ii][1], ax=ax)
            ax.axis('off')
            ax.set_title('Elapsed Time: {0:4.1f}'.format(PHIS[ii][0]))
Example #20
0
    def get_grad_horizontal(
        self, xy, hz, dim=3,
        use_cell_weights=True,
        minimum_distance=None
    ):
        """
            Compute Gradient in horizontal direction using Delaunay

        """
        if use_cell_weights:
            self.cell_weights = np.tile(hz, (xy.shape[0], 1)).flatten()

        if dim == 3:
            tri = sp.spatial.Delaunay(xy)
            # Split the triangulation into connections
            edges = np.r_[
                tri.simplices[:, :2],
                tri.simplices[:, 1:],
                tri.simplices[:, [0, 2]]
            ]

            # Sort and keep uniques
            edges = np.sort(edges, axis=1)
            edges = np.unique(
                edges[np.argsort(edges[:, 0]), :], axis=0
            )
            # Compute distance
            if minimum_distance is not None:
                dx = xy[edges[:, 0], 0]-xy[edges[:, 1], 0]
                dy = xy[edges[:, 0], 1]-xy[edges[:, 1], 1]
                distance = np.sqrt(dx**2+dy**2)
                inds = distance < minimum_distance
                edges = edges[inds, :]

            # Create 2D operator, dimensionless for now
            nN = edges.shape[0]
            nStn = xy.shape[0]
            stn, count = np.unique(edges[:, 0], return_counts=True)

            col = []
            row = []
            dm = []
            avg = []
            for ii in range(nN):
                row += [ii]*2
                col += [edges[ii, 0], edges[ii, 1]]
                scale = count[stn == edges[ii, 0]][0]
                dm += [-1., 1.]
                avg += [0.5, 0.5]

            D = sp.sparse.csr_matrix((dm, (row, col)), shape=(nN, nStn))
            A = sp.sparse.csr_matrix((avg, (row, col)), shape=(nN, nStn))

            # Kron vertically for nCz
            Grad = sp.sparse.kron(D, Utils.speye(hz.size))
            Avg = sp.sparse.kron(A, Utils.speye(hz.size))

            # Override the gradient operator in y-drection
            # This is because of ordering ... See def get_2d_mesh
            # y first then x
            self.regmesh._cellDiffyStencil = self.regmesh.cellDiffxStencil.copy()
            # Override the gradient operator in x-drection
            self.regmesh._cellDiffxStencil = Grad
            # Do the same for the averaging operator
            self.regmesh._aveCC2Fy = self.regmesh.aveCC2Fx.copy()
            self.regmesh._aveCC2Fx = Avg
            self.regmesh._aveFy2CC = self.regmesh.aveFx2CC.copy()
            self.regmesh._aveFx2CC = Avg.T
            return tri

        elif dim == 2:
            # Override the gradient operator in y-drection
            # This is because of ordering ... See def get_2d_mesh
            # y first then x
            temp_x = self.regmesh.cellDiffxStencil.copy()
            temp_y = self.regmesh.cellDiffyStencil.copy()
            self.regmesh._cellDiffyStencil = temp_x
            # Override the gradient operator in x-drection
            self.regmesh._cellDiffxStencil = temp_y
            # Do the same for the averaging operator
            temp_x = self.regmesh.aveCC2Fx.copy()
            temp_y = self.regmesh.aveCC2Fy.copy()
            self.regmesh._aveCC2Fy = temp_x
            self.regmesh._aveCC2Fx = temp_y
            temp_x = self.regmesh.aveCC2Fx.copy()
            temp_y = self.regmesh.aveCC2Fy.copy()
            self.regmesh._aveFy2CC = temp_x
            self.regmesh._aveFx2CC = temp_y
            return True
Example #21
0
vec = np.c_[mx, my, mz]

nC = mesh.nC
atp = Utils.matutils.xyz2atp(vec)

theta = atp[nC:2 * nC]
phi = atp[2 * nC:]

# theta = np.ones(mesh.nC) * 45
# phi = np.ones(mesh.nC) * 0

indActive = np.zeros(mesh.nC, dtype=bool)
indActive[actv] = True

print("Building operators")
Pac = Utils.speye(mesh.nC)[:, indActive]

Dx1 = Regularization.getDiffOpRot(mesh, np.deg2rad(0.), theta, phi, 'X')
Dy1 = Regularization.getDiffOpRot(mesh, np.deg2rad(0.), theta, phi, 'Y')
Dz1 = Regularization.getDiffOpRot(mesh, np.deg2rad(0.), theta, phi, 'Z')

Dx1 = Pac.T * Dx1 * Pac
Dy1 = Pac.T * Dy1 * Pac
Dz1 = Pac.T * Dz1 * Pac

Dx2 = Regularization.getDiffOpRot(mesh,
                                  np.deg2rad(0.),
                                  theta,
                                  phi,
                                  'X',
                                  forward=False)
Example #22
0
    def get_grad_horizontal(
        self, xy, hz, dim=3,
        use_cell_weights=True,
        minimum_distance=None
    ):
        """
            Compute Gradient in horizontal direction using Delaunay

        """
        self.cell_weights = np.tile(hz, (xy.shape[0], 1)).flatten()

        if dim == 3:
            tri = sp.spatial.Delaunay(xy)
            # Split the triangulation into connections
            edges = np.r_[
                tri.simplices[:, :2],
                tri.simplices[:, 1:],
                tri.simplices[:, [0, 2]]
            ]

            # Sort and keep uniques
            edges = np.sort(edges, axis=1)
            edges = np.unique(
                edges[np.argsort(edges[:, 0]), :], axis=0
            )
            # Compute distance
            if minimum_distance is not None:
                dx = xy[edges[:, 0], 0]-xy[edges[:, 1], 0]
                dy = xy[edges[:, 0], 1]-xy[edges[:, 1], 1]
                distance = np.sqrt(dx**2+dy**2)
                inds = distance < minimum_distance
                edges = edges[inds, :]

            # Create 2D operator, dimensionless for now
            nN = edges.shape[0]
            nStn = xy.shape[0]
            stn, count = np.unique(edges[:, 0], return_counts=True)

            col = []
            row = []
            dm = []
            avg = []
            for ii in range(nN):
                row += [ii]*2
                col += [edges[ii, 0], edges[ii, 1]]
                scale = count[stn == edges[ii, 0]][0]
                dm += [-1., 1.]
                avg += [0.5, 0.5]

            D = sp.sparse.csr_matrix((dm, (row, col)), shape=(nN, nStn))
            A = sp.sparse.csr_matrix((avg, (row, col)), shape=(nN, nStn))

            # Kron vertically for nCz
            Grad = sp.sparse.kron(D, Utils.speye(hz.size))
            Avg = sp.sparse.kron(A, Utils.speye(hz.size))

            # Override the gradient operator in y-drection
            # This is because of ordering ... See def get_2d_mesh
            # y first then x
            self.regmesh._cellDiffyStencil = self.regmesh.cellDiffxStencil.copy()
            # Override the gradient operator in x-drection
            self.regmesh._cellDiffxStencil = Grad
            # Do the same for the averaging operator
            self.regmesh._aveCC2Fy = self.regmesh.aveCC2Fx.copy()
            self.regmesh._aveCC2Fx = Avg
            self.regmesh._aveFy2CC = self.regmesh.aveFx2CC.copy()
            self.regmesh._aveFx2CC = Avg.T
            return tri

        elif dim == 2:
            # Override the gradient operator in y-drection
            # This is because of ordering ... See def get_2d_mesh
            # y first then x
            temp_x = self.regmesh.cellDiffxStencil.copy()
            temp_y = self.regmesh.cellDiffyStencil.copy()
            self.regmesh._cellDiffyStencil = temp_x
            # Override the gradient operator in x-drection
            self.regmesh._cellDiffxStencil = temp_y
            # Do the same for the averaging operator
            temp_x = self.regmesh.aveCC2Fx.copy()
            temp_y = self.regmesh.aveCC2Fy.copy()
            self.regmesh._aveCC2Fy = temp_x
            self.regmesh._aveCC2Fx = temp_y
            temp_x = self.regmesh.aveCC2Fx.copy()
            temp_y = self.regmesh.aveCC2Fy.copy()
            self.regmesh._aveFy2CC = temp_x
            self.regmesh._aveFx2CC = temp_y
            return True