Ejemplo n.º 1
0
    def getError(self):
        #Test function
        phi = lambda x: np.cos(np.pi * x[:, 0]) * np.cos(np.pi * x[:, 1])
        j_funX = lambda x: -np.pi * np.sin(np.pi * x[:, 0]) * np.cos(np.pi *
                                                                     x[:, 1])
        j_funY = lambda x: -np.pi * np.cos(np.pi * x[:, 0]) * np.sin(np.pi *
                                                                     x[:, 1])
        q_fun = lambda x: -2 * (np.pi**2) * phi(x)

        xc_ana = phi(self.M.gridCC)
        q_ana = q_fun(self.M.gridCC)
        jX_ana = j_funX(self.M.gridFx)
        jY_ana = j_funY(self.M.gridFy)
        j_ana = np.r_[jX_ana, jY_ana]

        #TODO: Check where our boundary conditions are CCx or Nx
        # fxm,fxp,fym,fyp = self.M.faceBoundaryInd
        # gBFx = self.M.gridFx[(fxm|fxp),:]
        # gBFy = self.M.gridFy[(fym|fyp),:]
        fxm, fxp, fym, fyp = self.M.cellBoundaryInd
        gBFx = self.M.gridCC[(fxm | fxp), :]
        gBFy = self.M.gridCC[(fym | fyp), :]

        bc = phi(np.r_[gBFx, gBFy])

        # P = sp.csr_matrix(([-1,1],([0,self.M.nF-1],[0,1])), shape=(self.M.nF, 2))

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

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

        # self.M.plotImage(j, 'FxFy', showIt=True)

        # Rearrange if we know q to solve for x
        A = D * McI * G
        rhs = q_ana - D * McI * P * bc

        if self.myTest == 'j':
            err = np.linalg.norm((j - j_ana), np.inf)
        elif self.myTest == 'q':
            err = np.linalg.norm((q - q_ana), np.inf)
        elif self.myTest == 'xc':
            xc = Solver(A) * (rhs)
            err = np.linalg.norm((xc - xc_ana), np.inf)
        elif self.myTest == 'xcJ':
            xc = Solver(A) * (rhs)
            j = McI * (G * xc + P * bc)
            err = np.linalg.norm((j - j_ana), np.inf)

        return err
Ejemplo n.º 2
0
def MagneticsDiffSecondaryInv(mesh, model, data, **kwargs):
    """
        Inversion module for MagneticsDiffSecondary

    """
    from SimPEG import Optimization, Regularization, Parameters, ObjFunction, Inversion
    prob = MagneticsDiffSecondary(mesh, model)

    miter = kwargs.get('maxIter', 10)

    if prob.ispaired:
        prob.unpair()
    if data.ispaired:
        data.unpair()
    prob.pair(data)

    # Create an optimization program
    opt = Optimization.InexactGaussNewton(maxIter=miter)
    opt.bfgsH0 = Solver(sp.identity(model.nP), flag='D')
    # Create a regularization program
    reg = Regularization.Tikhonov(model)
    # Create an objective function
    beta = Parameters.BetaSchedule(beta0=1e0)
    obj = ObjFunction.BaseObjFunction(data, reg, beta=beta)
    # Create an inversion object
    inv = Inversion.BaseInversion(obj, opt)

    return inv, reg
Ejemplo n.º 3
0
    def getError(self):
        # Test function
        def phi_fun(x):
            return np.cos(np.pi * x)

        def j_fun(x):
            return np.pi * np.sin(np.pi * x)

        def phi_deriv(x):
            return -j_fun(x)

        def q_fun(x):
            return (np.pi**2) * np.cos(np.pi * x)

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

        # Get boundary locations
        vecN = self.M.vectorNx
        vecC = self.M.vectorCCx

        # Setup Mixed B.C (alpha, beta, gamma)
        alpha_xm, alpha_xp = 1., 1.
        beta_xm, beta_xp = 1., 1.
        alpha = np.r_[alpha_xm, alpha_xp]
        beta = np.r_[beta_xm, beta_xp]
        vecN = self.M.vectorNx
        vecC = self.M.vectorCCx
        phi_bc = phi_fun(vecN[[0, -1]])
        phi_deriv_bc = phi_deriv(vecN[[0, -1]])
        gamma = alpha * phi_bc + beta * phi_deriv_bc
        x_BC, y_BC = getxBCyBC_CC(self.M, alpha, beta, gamma)

        sigma = np.ones(self.M.nC)
        Mfrho = self.M.getFaceInnerProduct(1. / sigma)
        MfrhoI = self.M.getFaceInnerProduct(1. / sigma, invMat=True)
        V = Utils.sdiag(self.M.vol)
        Div = V * self.M.faceDiv
        P_BC, B = self.M.getBCProjWF_simple()
        q = q_fun(self.M.gridCC)
        M = B * self.M.aveCC2F
        G = Div.T - P_BC * Utils.sdiag(y_BC) * M
        # Mrhoj = D.T V phi + P_BC*Utils.sdiag(y_BC)*M phi - P_BC*x_BC
        rhs = V * q + Div * MfrhoI * P_BC * x_BC
        A = Div * MfrhoI * G

        if self.myTest == 'xc':
            # TODO: fix the null space
            Ainv = Solver(A)
            xc = Ainv * rhs
            err = np.linalg.norm((xc - xc_ana), np.inf)
        else:
            NotImplementedError
        return err
Ejemplo n.º 4
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
Ejemplo n.º 5
0
    def getError(self):
        # Create some functions to integrate
        fun = lambda x: np.sin(2 * np.pi * x[:, 0]) * np.sin(
            2 * np.pi * x[:, 1]) * np.sin(2 * np.pi * x[:, 2])
        sol = lambda x: -3. * ((2 * np.pi)**2) * fun(x)

        self.M.setCellGradBC('dirichlet')

        D = self.M.faceDiv
        G = self.M.cellGrad
        if self.forward:
            sA = sol(self.M.gridCC)
            sN = D * G * fun(self.M.gridCC)
            err = np.linalg.norm((sA - sN), np.inf)
        else:
            fA = fun(self.M.gridCC)
            fN = Solver(D * G) * (sol(self.M.gridCC))
            err = np.linalg.norm((fA - fN), np.inf)
        return err
Ejemplo n.º 6
0
def MagneticsDiffSecondaryInv(mesh, model, data, **kwargs):
    """
    Inversion module for MagneticsDiffSecondary

    """
    from SimPEG import Optimization, Regularization, Parameters, ObjFunction, Inversion

    prob = Simulation3DDifferential(mesh, survey=data, mu=model)

    miter = kwargs.get("maxIter", 10)

    # Create an optimization program
    opt = Optimization.InexactGaussNewton(maxIter=miter)
    opt.bfgsH0 = Solver(sp.identity(model.nP), flag="D")
    # Create a regularization program
    reg = Regularization.Tikhonov(model)
    # Create an objective function
    beta = Parameters.BetaSchedule(beta0=1e0)
    obj = ObjFunction.BaseObjFunction(prob, reg, beta=beta)
    # Create an inversion object
    inv = Inversion.BaseInversion(obj, opt)

    return inv, reg
Ejemplo n.º 7
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]))
Ejemplo n.º 8
0
def simulateMT(mesh, sigma, frequency, rtype="app_res"):
    """
       Compute apparent resistivity and phase at each frequency.
       Return apparent resistivity and phase for rtype="app_res",
       or impedance for rtype="impedance"
    """

    # Angular frequency (rad/s)
    def omega(freq):
        return 2*np.pi*freq

    # make sure we are working with numpy arrays
    if type(frequency) is float:
        frequency = np.r_[frequency]  # make it a list to loop over later if it is just a scalar
    elif type(frequency) is list:
        frequency = np.array(frequency)

    # Grad
    mesh.setCellGradBC([['dirichlet', 'dirichlet']]) # Setup boundary conditions
    Grad = mesh.cellGrad # Gradient matrix

    # MfMu
    mu = np.ones(mesh.nC)*mu_0 # magnetic permeability values for all cells
    Mmu = Utils.sdiag(mesh.aveCC2F * mu)

    # Mccsigma
    sigmahat = sigma  # quasi-static assumption
    Msighat = Utils.sdiag(sigmahat)

    # Div
    Div = mesh.faceDiv # Divergence matrix

    # Right Hand Side
    B = mesh.cellGradBC  # a matrix for boundary conditions
    Exbc = np.r_[0., 1.] # boundary values for Ex

    # Right-hand side
    rhs = np.r_[
        -B*Exbc,
        np.zeros(mesh.nC)
    ]

    # loop over frequencies
    Zxy = []
    for freq in frequency:

        # A-matrix
        A = sp.vstack([
            sp.hstack([Grad, 1j*omega(freq)*Mmu]), # Top row of A matrix
            sp.hstack((Msighat, Div)) # Bottom row of A matrix
        ])

        Ainv = Solver(A) # Factorize A matrix
        sol = Ainv*rhs   # Solve A^-1 rhs = sol
        Ex = sol[:mesh.nC] # Extract Ex from solution vector u
        Hy = sol[mesh.nC:mesh.nC+mesh.nN] # Extract Hy from solution vector u

        Zxy.append(- 1./Hy[-1]) # Impedance at the surface

    # turn it into an array
    Zxy = np.array(Zxy)

    if rtype.lower() == "impedance":
        return Zxy

    elif rtype.lower() == "app_res":
        app_res = abs(Zxy)**2 / (mu_0*omega(frequency))
        app_phase = np.rad2deg(np.arctan(Zxy.imag / Zxy.real))
        return app_res, app_phase

    else:
        raise Exception("rtype must be 'impedance' or 'app_res', not {}".format(rtype.lower()))
Ejemplo n.º 9
0
def dc_resistivity(
    log_sigma_background=1.,  # Conductivity of the background, S/m
    log_sigma_block=2,  # Conductivity of the block, S/m
    plot_type='potential'  # "conductivity", "potential", or "current"
):
    from pylab import rcParams
    rcParams['figure.figsize'] = 10, 10

    # Define a unit-cell mesh
    mesh = Mesh.TensorMesh([100, 100])  # setup a mesh on which to solve

    # model parameters
    sigma_background = 10**log_sigma_background
    sigma_block = 10**log_sigma_block

    # add a block to our model
    x_block = np.r_[0.4, 0.6]
    y_block = np.r_[0.4, 0.6]

    # assign them on the mesh
    # create a physical property model
    sigma = sigma_background * np.ones(mesh.nC)

    block_indices = ((mesh.gridCC[:, 0] >= x_block[0]) &  # left boundary
                     (mesh.gridCC[:, 0] <= x_block[1]) &  # right boundary
                     (mesh.gridCC[:, 1] >= y_block[0]) &  # bottom boundary
                     (mesh.gridCC[:, 1] <= y_block[1]))  # top boundary

    # add the block to the physical property model
    sigma[block_indices] = sigma_block

    # Define a source
    a_loc, b_loc = np.r_[0.2, 0.5], np.r_[0.8, 0.5]
    source_locs = [a_loc, b_loc]

    # locate it on the mesh
    source_loc_inds = Utils.closestPoints(mesh, source_locs)
    a_loc_mesh = mesh.gridCC[source_loc_inds[0], :]
    b_loc_mesh = mesh.gridCC[source_loc_inds[1], :]

    if plot_type == 'conductivity':
        plt.colorbar(mesh.plotImage(sigma)[0])
        plt.plot(a_loc_mesh[0], a_loc_mesh[1], 'wv', markersize=8)
        plt.plot(b_loc_mesh[0], b_loc_mesh[1], 'w^', markersize=8)
        plt.title('electrical conductivity, $\sigma$')
        return

    # Assemble and solve the DC resistivity problem
    Div = mesh.faceDiv
    Sigma = mesh.getFaceInnerProduct(sigma, invProp=True, invMat=True)
    Vol = Utils.sdiag(mesh.vol)

    # assemble the system matrix
    A = Vol * Div * Sigma * Div.T * Vol

    # right hand side
    q = np.zeros(mesh.nC)
    q[source_loc_inds] = np.r_[+1, -1]

    # solve the DC resistivity problem
    Ainv = Solver(A)  # create a matrix that behaves like A inverse
    phi = Ainv * q

    if plot_type == 'potential':
        plt.colorbar(mesh.plotImage(phi)[0])
        plt.title('Electric Potential, $\phi$')
        return

    if plot_type == 'current':
        j = Sigma * mesh.faceDiv.T * Utils.sdiag(mesh.vol) * phi
        plt.colorbar(
            mesh.plotImage(j, vType='F', view='vec', streamOpts={'color':
                                                                 'w'})[0])
        plt.title('Current, $j$')
        return
Ejemplo n.º 10
0
        if showIt: plt.show()
        return [scalarMap]


if __name__ == '__main__':
    import numpy as np
    from SimPEG import Mesh, Utils, Solver
    hx = [(5, 2, -1.3), (2, 4), (5, 2, 1.3)]
    hy = [(2, 2, -1.3), (2, 6), (2, 2, 1.3)]
    hz = [(2, 2, -1.3), (2, 6), (2, 2, 1.3)]
    M = Mesh.TensorMesh([hx, hy, hz], x0=[10, 20, 14])
    q = np.zeros(M.vnC)
    q[[4, 4], [4, 4], [2, 6]] = [-1, 1]
    q = Utils.mkvc(q)
    A = M.faceDiv * M.cellGrad
    b = Solver(A) * (q)

    M.plotSlice(M.cellGrad * b,
                'F',
                view='vec',
                grid=True,
                pcolorOpts={'alpha': 0.8})
    M2 = Mesh.TensorMesh([10, 20], x0=[10, 5])
    f = np.r_[np.sin(M2.gridFx[:, 0] * 2 * np.pi),
              np.sin(M2.gridFy[:, 1] * 2 * np.pi)]
    M2.plotImage(f, 'F', view='vec', grid=True, pcolorOpts={'alpha': 0.8})
    M2.plotImage(f, 'Fx')

    f = np.r_[np.sin(M2.gridEx[:, 0] * 2 * np.pi),
              np.sin(M2.gridEy[:, 1] * 2 * np.pi)]
    M2.plotImage(f, 'E', view='vec', grid=True, pcolorOpts={'alpha': 0.8})
Ejemplo n.º 11
0
    def getError(self):
        # Test function
        def phi_fun(x):
            return (np.cos(np.pi * x[:, 0]) * np.cos(np.pi * x[:, 1]) *
                    np.cos(np.pi * x[:, 2]))

        def j_funX(x):
            return (np.pi * np.sin(np.pi * x[:, 0]) * np.cos(np.pi * x[:, 1]) *
                    np.cos(np.pi * x[:, 2]))

        def j_funY(x):
            return (np.pi * np.cos(np.pi * x[:, 0]) * np.sin(np.pi * x[:, 1]) *
                    np.cos(np.pi * x[:, 2]))

        def j_funZ(x):
            return (np.pi * np.cos(np.pi * x[:, 0]) * np.cos(np.pi * x[:, 1]) *
                    np.sin(np.pi * x[:, 2]))

        def phideriv_funX(x):
            return -j_funX(x)

        def phideriv_funY(x):
            return -j_funY(x)

        def phideriv_funZ(x):
            return -j_funZ(x)

        def q_fun(x):
            return 3 * (np.pi**2) * phi_fun(x)

        xc_ana = phi_fun(self.M.gridCC)
        q_ana = q_fun(self.M.gridCC)
        jX_ana = j_funX(self.M.gridFx)
        jY_ana = j_funY(self.M.gridFy)
        j_ana = np.r_[jX_ana, jY_ana, jY_ana]

        # Get boundary locations
        fxm, fxp, fym, fyp, fzm, fzp = self.M.faceBoundaryInd
        gBFxm = self.M.gridFx[fxm, :]
        gBFxp = self.M.gridFx[fxp, :]
        gBFym = self.M.gridFy[fym, :]
        gBFyp = self.M.gridFy[fyp, :]
        gBFzm = self.M.gridFz[fzm, :]
        gBFzp = self.M.gridFz[fzp, :]

        # Setup Mixed B.C (alpha, beta, gamma)
        alpha_xm = np.ones_like(gBFxm[:, 0])
        alpha_xp = np.ones_like(gBFxp[:, 0])
        beta_xm = np.ones_like(gBFxm[:, 0])
        beta_xp = np.ones_like(gBFxp[:, 0])
        alpha_ym = np.ones_like(gBFym[:, 1])
        alpha_yp = np.ones_like(gBFyp[:, 1])
        beta_ym = np.ones_like(gBFym[:, 1])
        beta_yp = np.ones_like(gBFyp[:, 1])
        alpha_zm = np.ones_like(gBFzm[:, 2])
        alpha_zp = np.ones_like(gBFzp[:, 2])
        beta_zm = np.ones_like(gBFzm[:, 2])
        beta_zp = np.ones_like(gBFzp[:, 2])

        phi_bc_xm, phi_bc_xp = phi_fun(gBFxm), phi_fun(gBFxp)
        phi_bc_ym, phi_bc_yp = phi_fun(gBFym), phi_fun(gBFyp)
        phi_bc_zm, phi_bc_zp = phi_fun(gBFzm), phi_fun(gBFzp)

        phiderivX_bc_xm = phideriv_funX(gBFxm)
        phiderivX_bc_xp = phideriv_funX(gBFxp)
        phiderivY_bc_ym = phideriv_funY(gBFym)
        phiderivY_bc_yp = phideriv_funY(gBFyp)
        phiderivY_bc_zm = phideriv_funZ(gBFzm)
        phiderivY_bc_zp = phideriv_funZ(gBFzp)

        def gamma_fun(alpha, beta, phi, phi_deriv):
            return alpha * phi + beta * phi_deriv

        gamma_xm = gamma_fun(alpha_xm, beta_xm, phi_bc_xm, phiderivX_bc_xm)
        gamma_xp = gamma_fun(alpha_xp, beta_xp, phi_bc_xp, phiderivX_bc_xp)
        gamma_ym = gamma_fun(alpha_ym, beta_ym, phi_bc_ym, phiderivY_bc_ym)
        gamma_yp = gamma_fun(alpha_yp, beta_yp, phi_bc_yp, phiderivY_bc_yp)
        gamma_zm = gamma_fun(alpha_zm, beta_zm, phi_bc_zm, phiderivY_bc_zm)
        gamma_zp = gamma_fun(alpha_zp, beta_zp, phi_bc_zp, phiderivY_bc_zp)

        alpha = [alpha_xm, alpha_xp, alpha_ym, alpha_yp, alpha_zm, alpha_zp]
        beta = [beta_xm, beta_xp, beta_ym, beta_yp, beta_zm, beta_zp]
        gamma = [gamma_xm, gamma_xp, gamma_ym, gamma_yp, gamma_zm, gamma_zp]

        x_BC, y_BC = getxBCyBC_CC(self.M, alpha, beta, gamma)

        sigma = np.ones(self.M.nC)
        Mfrho = self.M.getFaceInnerProduct(1. / sigma)
        MfrhoI = self.M.getFaceInnerProduct(1. / sigma, invMat=True)
        V = Utils.sdiag(self.M.vol)
        Div = V * self.M.faceDiv
        P_BC, B = self.M.getBCProjWF_simple()
        q = q_fun(self.M.gridCC)
        M = B * self.M.aveCC2F
        G = Div.T - P_BC * Utils.sdiag(y_BC) * M
        rhs = V * q + Div * MfrhoI * P_BC * x_BC
        A = Div * MfrhoI * G

        if self.myTest == 'xc':
            # TODO: fix the null space
            Ainv = Solver(A)
            xc = Ainv * rhs
            err = np.linalg.norm((xc - xc_ana), np.inf)
        else:
            NotImplementedError
        return err
Ejemplo n.º 12
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]))
Ejemplo n.º 13
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]))