예제 #1
0
파일: assembDom.py 프로젝트: zimoun/mtf
 def matvec(self, x):
     tol = 1e-6
     maxiter = self.maxiter
     A = self._matvec
     b = self._rhs(x)
     y, info = gmres(A, b, orthog='mgs', tol=tol, maxiter=maxiter)
     return y
예제 #2
0
파일: assembDom.py 프로젝트: zimoun/mtf
 def matvec(self, x):
     tol = 1e-6
     maxiter = self.maxiter
     A = self._matvec
     b = self._rhs(x)
     y, info = gmres(A, b,
                     orthog='mgs',
                     tol=tol,
                     maxiter=maxiter)
     return y
예제 #3
0
파일: algo.py 프로젝트: zimoun/mtf
def solve(Mat, b, tol=1e-6, res=[], restart=None, maxiter=300):
    del res
    res = []
    tt = time()
    x, info = gmres(Mat, b,
                    orthog='mgs',
                    tol=tol,
                    residuals=res,
                    restrt=restart,
                    maxiter=maxiter)
    tt = time() - tt
    print(info, len(res))
    res = np.array(res)
    return x
예제 #4
0
def my_gmres(mystr, M, b, tol, restart, maxiter):
    print(mystr.format(restart, maxiter), flush=True)
    res = []
    tt = time()
    xx, info = gmres(M, b,
                     orthog='mgs',
                     tol=tol,
                     residuals=res,
                     restrt=restart,
                     maxiter=maxiter)
    tt = time() - tt
    print(info, len(res))
    oRes = np.array(res)
    Res = rescaleRes(oRes, lambda x: x, b)
    print('#time: {}'.format(tt))
    return (xx, len(Res), Res, tt)
예제 #5
0
def my_gmres(mystr, M, b, tol, restart, maxiter):
    print(mystr.format(restart, maxiter), flush=True)
    res = []
    tt = time()
    xx, info = gmres(M, b,
                     orthog='mgs',
                     tol=tol,
                     residuals=res,
                     restrt=restart,
                     maxiter=maxiter)
    tt = time() - tt
    print(info, len(res))
    oRes = np.array(res)
    Res = rescaleRes(oRes, lambda x: x, b)
    print('#time: {}'.format(tt))
    return (xx, len(Res), Res, tt)
예제 #6
0
    def jacobian_solver(self, psi, mu, rhs):
        def _apply_jacobian(phi):
            out = ((0.5 * self.A * phi) / self.mesh.control_volumes +
                   (self.V - mu + 2.0 *
                    (psi.real**2 + psi.imag**2)) * phi + psi**2 * phi.conj())
            # out[self.mesh.is_boundary_node] = 1.0
            return out

        n = len(self.mesh.points)
        jac = LinearOperator((n, n),
                             dtype=complex,
                             matvec=_apply_jacobian,
                             rmatvec=_apply_jacobian)

        def prec(psi):
            def _apply(phi):
                prec = 0.5 * self.A
                diag = prec.diagonal()
                cv = self.mesh.control_volumes
                diag += (self.V + 2.0 * (psi.real**2 + psi.imag**2)) * cv
                prec.setdiag(diag)
                # TODO pyamg solve
                out = spsolve(prec, phi)
                return out

            num_unknowns = len(self.mesh.points)
            return LinearOperator(
                (num_unknowns, num_unknowns),
                dtype=complex,
                matvec=_apply,
                rmatvec=_apply,
            )

        out, _ = krylov.gmres(
            A=jac,
            b=rhs,
            # M=prec(psi),
            inner=self.inner,
            maxiter=100,
            tol=1.0e-12,
            # Minv=prec_inv(psi),
            # U=1j * psi,
        )
        return out.xk
예제 #7
0
    def jacobian_solver(self, psi, mu, rhs):
        abs_psi2 = np.zeros(psi.shape[0])
        abs_psi2[0::2] += psi[0::2]**2 + psi[1::2]**2
        cv = to_real(self.mesh.control_volumes)

        def prec_inv(psi):
            prec_orig = pyfvm.get_fvm_matrix(self.mesh,
                                             edge_kernels=[Energy(mu)])
            diag = prec_orig.diagonal()
            diag += self.g * 2.0 * (psi[0::2]**2 + psi[1::2]**2) * cv[0::2]
            prec_orig.setdiag(diag)
            return split_sparse_matrix(prec_orig).tocsr()

        def prec(psi):
            p = prec_inv(psi)

            def _apply(phi):
                out = spsolve(p, phi)
                return out

            num_unknowns = len(self.mesh.points)
            return LinearOperator(
                (2 * num_unknowns, 2 * num_unknowns),
                dtype=float,
                matvec=_apply,
                rmatvec=_apply,
            )

        jac = self.jacobian(psi, mu)

        # Cannot use direct solve since jacobian is always singular
        # return spsolve(jac, rhs)

        sol, _ = krylov.gmres(
            A=jac,
            b=rhs,
            # TODO enable preconditioner
            # M=prec(psi),
            inner=self.inner,
            maxiter=100,
            tol=1.0e-12,
        )
        return sol
예제 #8
0
def rescaleRes(res, P, b):
    scale = 1.0 / la.norm(P(b))
    new_res = scale * res
    return new_res


#################################################

print('\nWO restart={0} maxiter={1}'.format(restart, maxiter), flush=True)
del res
res = []
tt = time()
xx, info = gmres(M,
                 b,
                 orthog='mgs',
                 tol=tol,
                 residuals=res,
                 restrt=restart,
                 maxiter=maxiter)
tt = time() - tt
print(info, len(res))
oResWO = np.array(res)
ResWO = rescaleRes(oResWO, lambda x: x, b)
print('#time: {}'.format(tt))

checker('Calderon WO', A, J, xx)

#################################################

print('\nWO bicgstab maxiter={0}'.format(maxiter), flush=True)
del res
예제 #9
0
        print("nl:", nl, "dof:", dof)

        A, X = my.get_A(space, kk), my.get_X(space)
        b = my.rhs(space, funs)
        tt = time() - tt
        J = my.get_J(space)
        M = A - 0.5 * X
        MM = spla.LinearOperator(M.shape, matvec=M.matvec, dtype=complex)
        print('assembled.')

        res = []
        tol = 1e-5
        restart, maxiter = None, MM.shape[0]
        xx, info = gmres(MM, b,
                         orthog='mgs',
                         tol=tol,
                         residuals=res,
                         restrt=restart,
                         maxiter=maxiter)
        print(info, len(res), MM.shape)
        ea, et = my.check_sol(space, kk, xx, b, diri, neum,
                              A, X, J)

        DofErr[j][i, :] = dof, ea, et, tt


lw, ms = 3, 10
f, axarr = plt.subplots(2, sharex=True)
pls = zip(names, colors)
for i, pl in enumerate(pls):
    n, c = pl
    axarr[0].loglog(DofErr[i][:, 0], DofErr[i][:, 1], c, label=n,
예제 #10
0
#################################################


def rescaleRes(res, P, b):
    scale = 1.0 / la.norm(P(b))
    new_res = scale * res
    return new_res


#################################################

print("\nWO restart={0} maxiter={1}".format(restart, maxiter), flush=True)
del res
res = []
tt = time()
xx, info = gmres(M, b, orthog="mgs", tol=tol, residuals=res, restrt=restart, maxiter=maxiter)
tt = time() - tt
print(info, len(res))
oResWO = np.array(res)
ResWO = rescaleRes(oResWO, lambda x: x, b)
print("#time: {}".format(tt))

checker("Calderon WO", A, J, xx)

#################################################

print("\nWO bicgstab maxiter={0}".format(maxiter), flush=True)
del res
res = []
tt = time()
xx, info = bicgstab(M, b, tol=tol, residuals=res, maxiter=maxiter)
예제 #11
0
파일: eg-1.py 프로젝트: zimoun/mtf
a, b = fdir.projections(), fneu.projections()
rhs_mtf = 0.5 * np.concatenate((a, -b, -a, -b))
fd, fn = a, b

rescaleRes = lambda res, P, rhs: res / la.norm(P(rhs))

print('\nSTF restart={0} maxiter={1}'.format(restart, maxiter), flush=True)
Mat, b = stf, rhs_stf
print('size: ', stf.shape, 2*shape)
del res
res = []
tt = time()
x_stf, info = gmres(Mat, b,
                 orthog='mgs',
                 tol=tol,
                 residuals=res,
                 restrt=restart,
                 maxiter=maxiter)
tt = time() - tt
print(info, len(res))
oRes = np.array(res)
ResSTF = rescaleRes(oRes, lambda x: x, b)
print('#time: {}'.format(tt))

xd_stf, xn_stf = x_stf[0:shape], x_stf[shape:]

print('\nMTF restart={0} maxiter={1}'.format(restart, maxiter), flush=True)
Mat, b = mtf, rhs_mtf
print('size: ', mtf.shape, 4*shape)
del res
res = []
예제 #12
0
파일: ex-1-strong.py 프로젝트: zimoun/mtf
#################################################

def rescaleRes(res, P, b):
    scale = 1.0 / la.norm(P(b))
    new_res = scale * res
    return new_res

#################################################

print('\nWO restart={0} maxiter={1}'.format(restart, maxiter), flush=True)
del res
res = []
tt = time()
xx, info = gmres(J, b,
                 orthog='mgs',
                 tol=tol,
                 residuals=res,
                 restrt=restart,
                 maxiter=maxiter)
tt = time() - tt
print(info, len(res))
oResWO = np.array(res)
ResWO_mass = rescaleRes(oResWO, lambda x: x, b)
print('#time: {}'.format(tt))

checker('Calderon WO', A, J, xx)

#################################################

print('\nWO restart={0} maxiter={1}'.format(restart, maxiter), flush=True)
del res
res = []
예제 #13
0
    def jacobian_solver(self, psi, mu, rhs):
        keo = pyfvm.get_fvm_matrix(self.mesh, edge_kernels=[Energy(mu)])
        cv = self.mesh.control_volumes

        def prec_inv(psi):
            prec = keo.copy()
            # Add diagonal to avoid singularity for mu = 0. Also, this is a better
            # preconditioner.
            diag = prec.diagonal()
            diag += self.g * 2.0 * (psi.real**2 + psi.imag**2) * cv
            prec.setdiag(diag)
            return prec

        def prec(psi):
            p = prec_inv(psi)

            def _apply(phi):
                # ml = pyamg.smoothed_aggregation_solver(p, phi)
                # out = ml.solve(b=phi, tol=1e-12)
                out = spsolve(p, phi)
                return out

            num_unknowns = len(self.mesh.points)
            return LinearOperator(
                (num_unknowns, num_unknowns),
                dtype=complex,
                matvec=_apply,
                rmatvec=_apply,
            )

        jac = self.jacobian(psi, mu)
        sol, info = krylov.gmres(
            A=jac,
            b=rhs,
            M=prec(psi),
            inner=self.inner,
            maxiter=100,
            tol=1.0e-12,
            # Minv=prec_inv(psi),
            # U=1j * psi,
        )
        print(f"  GMRES: {info.numsteps} it, {info.resnorms[-1]:.3e} resnorm")

        if not info.success:
            raise pacopy.JacobianSolverError

        # print("Krylov residual:", out.resnorms[-1])
        # res = jac * out.xk - rhs
        # print("Krylov residual (explicit):", np.sqrt(self.norm2_r(res)))

        # self.ax1.semilogy(out.resnorms)
        # self.ax1.grid()
        # plt.show()

        # Since
        #
        #     (J_psi) psi = K psi + (-1 +2|psi|^2) psi - psi^2 conj(psi)
        #                 = K psi - psi + psi |psi|^2
        #                 = f(psi),
        #
        # we have (J_psi)(i psi) = i f(psi). The RHS is typically f(psi) or
        # df/dlmbda(psi), but obviously
        #
        #     <f(psi), (J_psi)(i psi)> = <f(psi), i f(psi)> = 0,
        #
        # so the i*psi-component in the solution plays no role if the rhs is f(psi).
        # Using 0 as a starting guess for Krylov, the solution will have no component in
        # the i*psi-direction. This means that the Newton updates won't jump around the
        # solution manifold. It wouldn't matter if they did, though.
        # TODO show this for df/dlmbda as well
        # i_psi = 1j * psi
        # out.xk -= self.inner(i_psi, out.xk) / self.inner(i_psi, i_psi) * i_psi
        # print("solution component i*psi", self.inner(i_psi, out.xk) / np.sqrt(self.inner(i_psi, i_psi)))
        return sol
예제 #14
0
파일: ex-1-strong.py 프로젝트: zimoun/mtf
def rescaleRes(res, P, b):
    scale = 1.0 / la.norm(P(b))
    new_res = scale * res
    return new_res


#################################################

print('\nWO restart={0} maxiter={1}'.format(restart, maxiter), flush=True)
del res
res = []
tt = time()
xx, info = gmres(J,
                 b,
                 orthog='mgs',
                 tol=tol,
                 residuals=res,
                 restrt=restart,
                 maxiter=maxiter)
tt = time() - tt
print(info, len(res))
oResWO = np.array(res)
ResWO_mass = rescaleRes(oResWO, lambda x: x, b)
print('#time: {}'.format(tt))

checker('Calderon WO', A, J, xx)

#################################################

print('\nWO restart={0} maxiter={1}'.format(restart, maxiter), flush=True)
del res
예제 #15
0
파일: eg-2.py 프로젝트: zimoun/mtf
stf, rhs_stf = STF.get(), STF.rhs()
mtf, rhs_mtf = MTF.get(), MTF.rhs()

rescaleRes = lambda res, P, rhs: res / la.norm(P(rhs))

print('\nSTF restart={0} maxiter={1}'.format(restart, maxiter), flush=True)
Mat, b = stf, rhs_stf
print('size: ', stf.shape, 2 * shape)
del res
res = []
tt = time()
x_stf, info = gmres(Mat,
                    b,
                    orthog='mgs',
                    tol=tol,
                    residuals=res,
                    restrt=restart,
                    maxiter=maxiter)
tt = time() - tt
print(info, len(res))
oRes = np.array(res)
ResSTF = rescaleRes(oRes, lambda x: x, b)
print('#time: {}'.format(tt))

xd_stf, xn_stf = x_stf[0:shape], x_stf[shape:]

print('\nMTF restart={0} maxiter={1}'.format(restart, maxiter), flush=True)
Mat, b = mtf, rhs_mtf
print('size: ', mtf.shape, 4 * shape)
del res