Esempio n. 1
0
def get_poisson_steps(pts, cells, tol):
    # Still can't initialize a mesh from points, cells
    filename = "mesh.xdmf"
    if cells.shape[1] == 3:
        meshio.write_points_cells(filename, pts, {"triangle": cells})
    else:
        assert cells.shape[1] == 4
        meshio.write_points_cells(filename, pts, {"tetra": cells})

    mesh = Mesh()
    with XDMFFile(filename) as f:
        f.read(mesh)
    os.remove(filename)
    os.remove("mesh.h5")

    # build Laplace matrix with Dirichlet boundary using dolfin
    V = FunctionSpace(mesh, "Lagrange", 1)

    u = TrialFunction(V)
    v = TestFunction(V)
    a = inner(grad(u), grad(v)) * dx
    u0 = Constant(0.0)
    bc = DirichletBC(V, u0, "on_boundary")
    f = Constant(1.0)
    L = f * v * dx

    A = assemble(a)
    b = assemble(L)
    bc.apply(A, b)

    # solve(A, x, b, "cg")
    solver = KrylovSolver("cg", "none")
    solver.parameters["absolute_tolerance"] = 0.0
    solver.parameters["relative_tolerance"] = tol

    x = Function(V)
    x_vec = x.vector()
    num_steps = solver.solve(A, x_vec, b)

    # # convert to scipy matrix
    # A = as_backend_type(A).mat()
    # ai, aj, av = A.getValuesCSR()
    # A = scipy.sparse.csr_matrix(
    #     (av, aj, ai), shape=(A.getLocalSize()[0], A.getSize()[1])
    # )

    # # ev = eigvals(A.todense())
    # ev_max = scipy.sparse.linalg.eigs(A, k=1, which="LM")[0][0]
    # assert numpy.abs(ev_max.imag) < 1.0e-15
    # ev_max = ev_max.real
    # ev_min = scipy.sparse.linalg.eigs(A, k=1, which="SM")[0][0]
    # assert numpy.abs(ev_min.imag) < 1.0e-15
    # ev_min = ev_min.real
    # cond = ev_max / ev_min

    # solve poisson system, count num steps
    # b = numpy.ones(A.shape[0])
    # out = pykry.gmres(A, b)
    # num_steps = len(out.resnorms)
    return num_steps
Esempio n. 2
0
def cyclic3D(u):
    """ Symmetrize with respect to (xyz) cycle. """
    try:
        nrm = np.linalg.norm(u.vector())
        V = u.function_space()
        assert V.mesh().topology().dim() == 3
        mesh1 = Mesh(V.mesh())
        mesh1.coordinates()[:, :] = mesh1.coordinates()[:, [1, 2, 0]]
        W1 = FunctionSpace(mesh1, 'CG', 1)

        # testing if symmetric
        bc = DirichletBC(V, 1, DomainBoundary())
        test = Function(V)
        bc.apply(test.vector())
        test = interpolate(Function(W1, test.vector()), V)
        assert max(test.vector()) - min(test.vector()) < 1.1

        v1 = interpolate(Function(W1, u.vector()), V)

        mesh2 = Mesh(mesh1)
        mesh2.coordinates()[:, :] = mesh2.coordinates()[:, [1, 2, 0]]
        W2 = FunctionSpace(mesh2, 'CG', 1)
        v2 = interpolate(Function(W2, u.vector()), V)
        pr = project(u+v1+v2)
        assert np.linalg.norm(pr.vector())/nrm > 0.01
        return pr
    except:
        print "Cyclic symmetrization failed!"
        return u
Esempio n. 3
0
class StreamFunction(Field):
    def before_first_compute(self, get):
        u = get("Velocity")
        assert len(u) == 2, "Can only compute stream function for 2D problems"
        V = u.function_space()
        spaces = SpacePool(V.mesh())
        degree = V.ufl_element().degree()
        V = spaces.get_space(degree, 0)

        psi = TrialFunction(V)
        self.q = TestFunction(V)
        a = dot(grad(psi), grad(self.q)) * dx()

        self.bc = DirichletBC(V, Constant(0), DomainBoundary())
        self.A = assemble(a)
        self.L = Vector()
        self.bc.apply(self.A)
        self.solver = KrylovSolver(self.A, "cg")
        self.psi = Function(V)

    def compute(self, get):
        u = get("Velocity")
        assemble(dot(u[1].dx(0) - u[0].dx(1), self.q) * dx(), tensor=self.L)
        self.bc.apply(self.L)

        self.solver.solve(self.psi.vector(), self.L)
        #solve(self.A, self.psi.vector(), self.L)

        return self.psi
Esempio n. 4
0
class StreamFunction(Field):
    def before_first_compute(self, get):
        u = get("Velocity")
        assert len(u) == 2, "Can only compute stream function for 2D problems"
        V = u.function_space()
        spaces = SpacePool(V.mesh())
        degree = V.ufl_element().degree()
        V = spaces.get_space(degree, 0)

        psi = TrialFunction(V)
        self.q = TestFunction(V)
        a = dot(grad(psi), grad(self.q))*dx()

        self.bc = DirichletBC(V, Constant(0), DomainBoundary())
        self.A = assemble(a)
        self.L = Vector()
        self.bc.apply(self.A)
        self.solver = KrylovSolver(self.A, "cg")
        self.psi = Function(V)


    def compute(self, get):
        u = get("Velocity")
        assemble(dot(u[1].dx(0)-u[0].dx(1), self.q)*dx(), tensor=self.L)
        self.bc.apply(self.L)

        self.solver.solve(self.psi.vector(), self.L)
        #solve(self.A, self.psi.vector(), self.L)

        return self.psi
Esempio n. 5
0
def cyclic3D(u):
    """ Symmetrize with respect to (xyz) cycle. """
    try:
        nrm = np.linalg.norm(u.vector())
        V = u.function_space()
        assert V.mesh().topology().dim() == 3
        mesh1 = Mesh(V.mesh())
        mesh1.coordinates()[:, :] = mesh1.coordinates()[:, [1, 2, 0]]
        W1 = FunctionSpace(mesh1, 'CG', 1)

        # testing if symmetric
        bc = DirichletBC(V, 1, DomainBoundary())
        test = Function(V)
        bc.apply(test.vector())
        test = interpolate(Function(W1, test.vector()), V)
        assert max(test.vector()) - min(test.vector()) < 1.1

        v1 = interpolate(Function(W1, u.vector()), V)

        mesh2 = Mesh(mesh1)
        mesh2.coordinates()[:, :] = mesh2.coordinates()[:, [1, 2, 0]]
        W2 = FunctionSpace(mesh2, 'CG', 1)
        v2 = interpolate(Function(W2, u.vector()), V)
        pr = project(u + v1 + v2)
        assert np.linalg.norm(pr.vector()) / nrm > 0.01
        return pr
    except:
        print "Cyclic symmetrization failed!"
        return u
Esempio n. 6
0
def assert_solves(
    mesh: Mesh,
    diffusion: Coefficient,
    convection: Optional[Coefficient],
    reaction: Optional[Coefficient],
    source: Coefficient,
    exact: Coefficient,
    l2_tol: Optional[float] = 1.0e-8,
    h1_tol: Optional[float] = 1.0e-6,
):
    eafe_matrix = eafe_assemble(mesh, diffusion, convection, reaction)

    pw_linears = FunctionSpace(mesh, "Lagrange", 1)
    test_function = TestFunction(pw_linears)
    rhs_vector = assemble(source * test_function * dx)

    bc = DirichletBC(pw_linears, exact, lambda _, on_bndry: on_bndry)
    bc.apply(eafe_matrix, rhs_vector)

    solution = Function(pw_linears)
    solver = LUSolver(eafe_matrix, "default")
    solver.parameters["symmetric"] = False
    solver.solve(solution.vector(), rhs_vector)

    l2_err: float = errornorm(exact, solution, "l2", 3)
    assert l2_err <= l2_tol, f"L2 error too large: {l2_err} > {l2_tol}"

    h1_err: float = errornorm(exact, solution, "H1", 3)
    assert h1_err <= h1_tol, f"H1 error too large: {h1_err} > {h1_tol}"
Esempio n. 7
0
    class Heat(object):
        '''
        u' = \\Delta u + f
        '''
        def __init__(self, V):
            self.sol = Expression(sympy.printing.ccode(solution),
                                  degree=MAX_DEGREE,
                                  t=0.0,
                                  cell=triangle)

            self.V = V
            u = TrialFunction(V)
            v = TestFunction(V)
            self.M = assemble(u * v * dx)

            n = FacetNormal(self.V.mesh())
            self.A = assemble(-inner(kappa * grad(u), grad(v /
                                                           (rho * cp))) * dx +
                              inner(kappa * grad(u), n) * v / (rho * cp) * ds)

            self.bcs = DirichletBC(self.V, self.sol, 'on_boundary')
            return

        def eval_alpha_M_beta_F(self, alpha, beta, u, t):
            # Evaluate  alpha * M * u + beta * F(u, t).
            uvec = u.vector()

            v = TestFunction(self.V)
            f.t = t
            b = assemble(f * v / (rho * cp) * dx)

            out = Function(self.V)
            out.vector()[:] = \
                alpha * (self.M * uvec) + beta * (self.A * uvec + b)
            return out

        def solve_alpha_M_beta_F(self, alpha, beta, b, t):
            # Solve  alpha * M * u + beta * F(u, t) = b  for u.
            A = alpha * self.M + beta * self.A

            f.t = t
            v = TestFunction(self.V)
            b2 = f / (rho * cp)

            rhs = assemble((b - beta * b2) * v * dx)
            self.bcs.apply(A, rhs)

            solver = \
                KrylovSolver('gmres', 'ilu') if alpha < 0.0 or beta > 0.0 \
                else KrylovSolver('cg', 'amg')
            solver.parameters['relative_tolerance'] = 1.0e-13
            solver.parameters['absolute_tolerance'] = 0.0
            solver.parameters['maximum_iterations'] = 100
            solver.parameters['monitor_convergence'] = False
            solver.set_operator(A)

            u = Function(self.V)
            solver.solve(u.vector(), rhs)
            return u
Esempio n. 8
0
    class Bratu(object):
        def __init__(self):
            self.mesh = UnitSquareMesh(40, 40, "left/right")

            self.V = FunctionSpace(self.mesh, "Lagrange", 1)

            self.bc = DirichletBC(self.V, 0.0, "on_boundary")

            u = TrialFunction(self.V)
            v = TestFunction(self.V)
            self.a = assemble(dot(grad(u), grad(v)) * dx)
            self.m = assemble(u * v * dx)

        def inner(self, a, b):
            return a.inner(self.m * b)

        def norm2_r(self, a):
            return a.inner(a)

        def f(self, u, lmbda):
            v = TestFunction(self.V)
            ufun = Function(self.V)
            ufun.vector()[:] = u
            out = self.a * u - lmbda * assemble(exp(ufun) * v * dx)
            DirichletBC(self.V, ufun, "on_boundary").apply(out)
            return out

        def df_dlmbda(self, u, lmbda):
            v = TestFunction(self.V)
            ufun = Function(self.V)
            ufun.vector()[:] = u
            out = -assemble(exp(ufun) * v * dx)
            self.bc.apply(out)
            return out

        def jacobian_solver(self, u, lmbda, rhs):
            t = TrialFunction(self.V)
            v = TestFunction(self.V)
            # from dolfin import Constant
            # a = assemble(
            #     dot(grad(t), grad(v)) * dx - Constant(lmbda) * exp(u) * t * v * dx
            # )
            ufun = Function(self.V)
            ufun.vector()[:] = u
            a = self.a - lmbda * assemble(exp(ufun) * t * v * dx)
            self.bc.apply(a)
            x = Function(self.V)
            # solve(a, x.vector(), rhs, "gmres", "ilu")
            solve(a, x.vector(), rhs)
            return x.vector()
Esempio n. 9
0
def symmetrize(u, d, sym):
    """ Symmetrize function u. """
    if len(d) == 3:
        # three dimensions -> cycle XYZ
        return cyclic3D(u)
    elif len(d) >= 4:
        # four dimensions -> rotations in 2D
        return rotational(u, d[-1])
    nrm = np.linalg.norm(u.vector())
    V = u.function_space()
    mesh = Mesh(V.mesh())

    # test if domain is symmetric using function equal 0 inside, 1 on boundary
    # extrapolation will force large values if not symmetric since the flipped
    # domain is different
    bc = DirichletBC(V, 1, DomainBoundary())
    test = Function(V)
    bc.apply(test.vector())

    if len(d) == 2:
        # two dimensions given: swap dimensions
        mesh.coordinates()[:, d] = mesh.coordinates()[:, d[::-1]]
    else:
        # one dimension given: reflect
        mesh.coordinates()[:, d[0]] *= -1
    # FIXME functionspace takes a long time to construct, maybe copy?
    W = FunctionSpace(mesh, 'CG', 1)
    try:
        # testing
        test = interpolate(Function(W, test.vector()), V)
        # max-min should be around 1 if domain was symmetric
        # may be slightly above due to boundary approximation
        assert max(test.vector()) - min(test.vector()) < 1.1

        v = interpolate(Function(W, u.vector()), V)
        if sym:
            # symmetric
            pr = project(u+v)
        else:
            # antisymmetric
            pr = project(u-v)
        # small solution norm most likely means that symmetrization gives
        # trivial function
        assert np.linalg.norm(pr.vector())/nrm > 0.01
        return pr
    except:
        # symmetrization failed for some reason
        print "Symmetrization " + str(d) + " failed!"
        return u
Esempio n. 10
0
def symmetrize(u, d, sym):
    """ Symmetrize function u. """
    if len(d) == 3:
        # three dimensions -> cycle XYZ
        return cyclic3D(u)
    elif len(d) >= 4:
        # four dimensions -> rotations in 2D
        return rotational(u, d[-1])
    nrm = np.linalg.norm(u.vector())
    V = u.function_space()
    mesh = Mesh(V.mesh())

    # test if domain is symmetric using function equal 0 inside, 1 on boundary
    # extrapolation will force large values if not symmetric since the flipped
    # domain is different
    bc = DirichletBC(V, 1, DomainBoundary())
    test = Function(V)
    bc.apply(test.vector())

    if len(d) == 2:
        # two dimensions given: swap dimensions
        mesh.coordinates()[:, d] = mesh.coordinates()[:, d[::-1]]
    else:
        # one dimension given: reflect
        mesh.coordinates()[:, d[0]] *= -1
    # FIXME functionspace takes a long time to construct, maybe copy?
    W = FunctionSpace(mesh, 'CG', 1)
    try:
        # testing
        test = interpolate(Function(W, test.vector()), V)
        # max-min should be around 1 if domain was symmetric
        # may be slightly above due to boundary approximation
        assert max(test.vector()) - min(test.vector()) < 1.1

        v = interpolate(Function(W, u.vector()), V)
        if sym:
            # symmetric
            pr = project(u + v)
        else:
            # antisymmetric
            pr = project(u - v)
        # small solution norm most likely means that symmetrization gives
        # trivial function
        assert np.linalg.norm(pr.vector()) / nrm > 0.01
        return pr
    except:
        # symmetrization failed for some reason
        print "Symmetrization " + str(d) + " failed!"
        return u
Esempio n. 11
0
    def solve(self, L, a, plate_potential):
        A = assemble(a)
        b = assemble(L)
        # print(' assembled')

        dirichlet_bc = DirichletBC(self.V, plate_potential,
                                   (lambda x, on_boundary: on_boundary and x[2]
                                    < self.GROUNDED_PLATE_AT))

        dirichlet_bc.apply(A, b)
        # print(' modified')
        f = self.function()
        self.solver.solve(A, f.vector(), b)
        # print(' solved')
        return f
Esempio n. 12
0
def dolfin_comparasion(Nx, Ny, f):
    from dolfin import (UnitSquareMesh, FunctionSpace, TrialFunction,
                        TestFunction, assemble, inner, grad, dx,
                        SpatialCoordinate, DirichletBC, Function, solve, pi,
                        CellType, sin, cos)
    mesh = UnitSquareMesh.create(Nx, Ny, CellType.Type.quadrilateral)
    V = FunctionSpace(mesh, "CG", 1)
    u, v = TrialFunction(V), TestFunction(V)
    a = inner(grad(u), grad(v)) * dx

    A_dol = assemble(a)
    x, y = SpatialCoordinate(mesh)
    f = eval(f)
    l_ = inner(f, v) * dx
    B_dol = assemble(l_)
    bc = DirichletBC(V, 0, "on_boundary")
    bc.apply(A_dol, B_dol)
    u_h = Function(V)
    solve(A_dol, u_h.vector(), B_dol)
    return u_h, assemble(u_h * dx)
Esempio n. 13
0
    def initial_solution(self, mode_number):

        main_boundary = self.outsides
        left_boundary = self.left_outsides
        right_boundary = self.right_outsides

        KK = self.K
        bc = DirichletBC(self.V, Constant(0.), main_boundary)
        bc.apply(KK)
        solver = standard_solver(KK, self.M)
        solver.solve(10)

        KK1 = self.K1
        bc1 = DirichletBC(self.V1, Constant(0.), left_boundary)
        bc1.apply(KK1)
        solver1 = standard_solver(KK1, self.M1)
        solver1.solve(10)

        KK2 = self.K2
        bc2 = DirichletBC(self.V2, Constant(0.), right_boundary)
        bc2.apply(KK2)
        solver2 = standard_solver(KK2, self.M2)
        solver2.solve(10)

        r, _, rx, _ = solver.get_eigenpair(mode_number)
        r1, _, rx1, _ = solver1.get_eigenpair(mode_number)
        r2, _, rx2, _ = solver2.get_eigenpair(mode_number)

        freqs = [r, r1, r2]
        vecs = [rx, rx1, rx2]
        return freqs, vecs
Esempio n. 14
0
        def _modify_linear_equation(self, x, y, z):
            dx_src = f'(x[0] - {x})'
            dy_src = f'(x[1] - {y})'
            dz_src = f'(x[2] - {z})'

            r_src2 = f'({dx_src} * {dx_src} + {dy_src} * {dy_src} + {dz_src} * {dz_src})'
            r_src = f'sqrt({r_src2})'
            conductivity = self.base_conductivity(x, y, z)
            minus_potential_exp = Expression(f'''
                                            {-0.25 / np.pi / conductivity}
                                            / {r_src}
                                            ''',
                                             degree=self.degree,
                                             domain=self._fm._mesh)

            dirichlet_bc = DirichletBC(self._fm.function_space,
                                       minus_potential_exp,
                                       (lambda x, on_boundary: on_boundary and
                                        x[2] < self.grounded_plate_edge_z))

            logger.debug('Applying the "plate" Dirichlet BC')
            dirichlet_bc.apply(self._terms_with_unknown, self._known_terms)
            logger.debug('Done.')
Esempio n. 15
0
    class Heat(object):
        '''
        u' = \\Delta u + f
        '''
        def __init__(self, V):
            self.V = V
            u = TrialFunction(V)
            v = TestFunction(V)
            self.M = assemble(u * v * dx)
            self.A = assemble(-dot(grad(u), grad(v)) * dx)
            self.b = assemble(1.0 * v * dx)
            self.bcs = DirichletBC(self.V, 0.0, 'on_boundary')
            return

        # pylint: disable=unused-argument
        def eval_alpha_M_beta_F(self, alpha, beta, u, t):
            # Evaluate  alpha * M * u + beta * F(u, t).
            uvec = u.vector()
            return alpha * (self.M * uvec) + beta * (self.A * uvec + self.b)

        def solve_alpha_M_beta_F(self, alpha, beta, b, t):
            # Solve  alpha * M * u + beta * F(u, t) = b  for u.
            A = alpha * self.M + beta * self.A

            rhs = b - beta * self.b
            self.bcs.apply(A, rhs)

            solver = KrylovSolver('gmres', 'ilu')
            solver.parameters['relative_tolerance'] = 1.0e-13
            solver.parameters['absolute_tolerance'] = 0.0
            solver.parameters['maximum_iterations'] = 100
            solver.parameters['monitor_convergence'] = True
            solver.set_operator(A)

            u = Function(self.V)
            solver.solve(u.vector(), rhs)
            return u
Esempio n. 16
0
    def solve(self):
        """ Find eigenvalues for transformed mesh. """
        self.progress("Building mesh.")
        # build transformed mesh
        mesh = self.refineMesh()
        # dim = mesh.topology().dim()
        if self.bcLast:
            mesh = transform_mesh(mesh, self.transformList)
            Robin, Steklov, shift, bcs = get_bc_parts(mesh, self.bcList)
        else:
            Robin, Steklov, shift, bcs = get_bc_parts(mesh, self.bcList)
            mesh = transform_mesh(mesh, self.transformList)
            # boundary conditions computed on non-transformed mesh
            # copy the values to transformed mesh
            fun = FacetFunction("size_t", mesh, shift)
            fun.array()[:] = bcs.array()[:]
            bcs = fun
        ds = Measure('ds', domain=mesh, subdomain_data=bcs)
        V = FunctionSpace(mesh, self.method, self.deg)
        u = TrialFunction(V)
        v = TestFunction(V)
        self.progress("Assembling matrices.")
        wTop = Expression(self.wTop, degree=self.deg)
        wBottom = Expression(self.wBottom, degree=self.deg)

        #
        # build stiffness matrix form
        #
        s = dot(grad(u), grad(v))*wTop*dx
        # add Robin parts
        for bc in Robin:
            s += Constant(bc.parValue)*u*v*wTop*ds(bc.value+shift)

        #
        # build mass matrix form
        #
        if len(Steklov) > 0:
            m = 0
            for bc in Steklov:
                m += Constant(bc.parValue)*u*v*wBottom*ds(bc.value+shift)
        else:
            m = u*v*wBottom*dx

        # assemble
        # if USE_EIGEN:
        #     S, M = EigenMatrix(), EigenMatrix()
            # tempv = EigenVector()
        # else:
        S, M = PETScMatrix(), PETScMatrix()
        # tempv = PETScVector()

        if not np.any(bcs.array() == shift+1):
            # no Dirichlet parts
            assemble(s, tensor=S)
            assemble(m, tensor=M)
        else:
            #
            # with EIGEN we could
            #   apply Dirichlet condition symmetrically
            #   completely remove rows and columns
            #
            # Dirichlet parts are marked with shift+1
            #
            # temp = Constant(0)*v*dx
            bc = DirichletBC(V, Constant(0.0), bcs, shift+1)
            # assemble_system(s, temp, bc, A_tensor=S, b_tensor=tempv)
            # assemble_system(m, temp, bc, A_tensor=M, b_tensor=tempv)
            assemble(s, tensor=S)
            bc.apply(S)
            assemble(m, tensor=M)
            # bc.zero(M)

        # if USE_EIGEN:
        #    M = M.sparray()
        #    M.eliminate_zeros()
        #    print M.shape
        #    indices = M.indptr[:-1] - M.indptr[1:] < 0
        #    M = M[indices, :].tocsc()[:, indices]
        #    S = S.sparray()[indices, :].tocsc()[:, indices]
        #    print M.shape
        #
        # solve the eigenvalue problem
        #
        self.progress("Solving eigenvalue problem.")
        eigensolver = SLEPcEigenSolver(S, M)
        eigensolver.parameters["problem_type"] = "gen_hermitian"
        eigensolver.parameters["solver"] = "krylov-schur"
        if self.target is not None:
            eigensolver.parameters["spectrum"] = "target real"
            eigensolver.parameters["spectral_shift"] = self.target
        else:
            eigensolver.parameters["spectrum"] = "smallest magnitude"
            eigensolver.parameters["spectral_shift"] = -0.01
        eigensolver.parameters["spectral_transform"] = "shift-and-invert"
        eigensolver.solve(self.number)
        self.progress("Generating eigenfunctions.")
        if eigensolver.get_number_converged() == 0:
            return None
        eigf = []
        eigv = []
        if self.deg > 1:
            mesh = refine(mesh)
        W = FunctionSpace(mesh, 'CG', 1)
        for i in range(eigensolver.get_number_converged()):
            pair = eigensolver.get_eigenpair(i)[::2]
            eigv.append(pair[0])
            u = Function(V)
            u.vector()[:] = pair[1]
            eigf.append(interpolate(u, W))
        return eigv, eigf
Esempio n. 17
0
    def schwarz_algorithm(self, max_iterations, mode_number):

        left_robin = self.left_robin
        left_dirichlet = self.left_outsides
        right_robin = self.right_robin
        right_dirichlet = self.right_outsides

        self.build_transfer_matrices()
        B1 = self.B1
        BO1 = self.BO1
        B2 = self.B2
        BO2 = self.BO2

        V1 = self.V1
        V2 = self.V2
        VO = self.VO
        freqs, vecs = self.initial_solution(mode_number)

        r1 = freqs[1]
        r2 = freqs[2]

        M1 = self.M1
        M2 = self.M2

        rx1 = vecs[1]
        rx2 = vecs[2]

        if abs(rx1.max()) < abs(rx1.min()):
            rx1 = self.adjustment * rx1 / (rx1.min())
        else:
            rx1 = self.adjustment * rx1 / (rx1.max())

        if abs(rx2.max()) < abs(rx2.min()):
            rx2 = self.adjustment * rx2 / (rx2.min())
        else:
            rx2 = self.adjustment * rx2 / (rx2.max())

        iter = 0
        L2_error = np.zeros((max_iterations + 1, 1))
        H1_error = np.zeros((max_iterations + 1, 1))
        SH_error = np.zeros((max_iterations + 1, 1))
        r_left = np.zeros((max_iterations + 1, 1))
        r_right = np.zeros((max_iterations + 1, 1))

        u1 = Function(self.V1)
        u1.vector()[:] = rx1

        u2 = Function(self.V2)
        u2.vector()[:] = rx2

        L2, H1 = self.overlap_error_norms(u1, u2)

        L2_error[iter] = L2
        H1_error[iter] = H1
        SH_error[iter] = H1 - L2
        r_left[iter] = r1
        r_right[iter] = r2
        while (iter < max_iterations):
            #Step 1: do f1 = du/dn2, g1 = u2
            uu2 = Function(V2)
            if (np.absolute(rx2.max()) < np.absolute(rx2.min())):
                rx2 = self.adjustment * rx2 / (rx2.min())
                uu2.vector()[:] = rx2
            else:
                rx2 = self.adjustment * rx2 / (rx2.max())
                uu2.vector()[:] = rx2

            uu21 = Function(VO)
            uu21.vector()[:] = B2 * uu2.vector()

            g1 = Function(V1)
            g1.vector()[:] = BO1 * uu21.vector()

            du2 = Function(V2)
            n2 = FacetNormal(self.mesh2)
            du2 = assemble(inner(grad(uu2), n2) * ds)
            du2 = project(du2, V2)
            du2O = Function(VO)
            du2O.vector()[:] = B2 * du2.vector()

            f1 = Function(V1)
            f1.vector()[:] = BO1 * du2O.vector()

            #Step 2: Solve for u1
            boundary = left_robin
            K1, _ = self.assemble_lui_stiffness(g=g1,
                                                f=f1,
                                                mesh=self.mesh1,
                                                robin_boundary=boundary)
            bc1 = DirichletBC(V1, Constant(0.), left_dirichlet)
            bc1.apply(K1)
            solver1 = standard_solver(K1, M1)
            solver1.solve(10)
            r1, _, rx1, _ = solver1.get_eigenpair(mode_number)

            #Step 3: do f1 = du1/dn1, g2 = u1
            uu1 = Function(V1)
            if (np.absolute(rx1.max()) < np.absolute(rx1.min())):
                uu1.vector()[:] = self.adjustment * rx1 / (rx1.min())
            else:
                uu1.vector()[:] = self.adjustment * rx1 / (rx1.max())

            uu12 = Function(VO)
            uu12.vector()[:] = B1 * uu1.vector()

            g2 = Function(V2)
            g2.vector()[:] = BO2 * uu12.vector()

            du1 = Function(V1)
            n1 = FacetNormal(self.mesh1)
            du1 = assemble(inner(grad(uu1), n1) * ds)
            du1 = project(du1, V1)

            du12 = Function(VO)
            du12.vector()[:] = B1 * du1.vector()

            f2 = Function(V2)
            f2.vector()[:] = BO2 * du12.vector()

            #Step 4: solve for u2
            boundary = right_robin
            K2, _ = self.assemble_lui_stiffness(g=g2,
                                                f=f2,
                                                mesh=self.mesh2,
                                                robin_boundary=boundary)
            bc2 = DirichletBC(V2, Constant(0.), right_dirichlet)
            bc2.apply(K2)

            solver2 = standard_solver(K2, M2)
            solver2.solve(10)
            r2, _, rx2, _ = solver2.get_eigenpair(mode_number)

            uu2 = Function(V2)
            if (np.absolute(rx2.max()) < np.absolute(rx2.min())):
                rx2 = self.adjustment * rx2 / (rx2.min())
                uu2.vector()[:] = rx2
            else:
                rx2 = self.adjustment * rx2 / (rx2.max())
                uu2.vector()[:] = rx2
            #Step 5: Calculate the L2 norm for convergence
            uu21.vector()[:] = B2 * uu2.vector()
            uu12.vector()[:] = B1 * uu1.vector()
            error = ((uu12 - uu21)**2) * dx
            L2 = assemble(error)

            semi_error = inner(
                grad(uu12) - grad(uu21),
                grad(uu12) - grad(uu21)) * dx
            H1 = L2 + assemble(semi_error)
            iter += 1
            r_left[iter] = r1
            r_right[iter] = r2
            L2_error[iter] = L2
            H1_error[iter] = H1
            SH_error[iter] = H1 - L2
        return L2_error, H1_error, SH_error, uu1, uu2, r_left, r_right
u0 = Constant("0.0")
bc = DirichletBC(V, u0, u0_boundary)

# Define target medium and rhs:
mtrue_exp = Expression('1 + 7*(pow(pow(x[0] - 0.5,2) +' + \
' pow(x[1] - 0.5,2),0.5) > 0.2)')
#mtrue = interpolate(mtrue_exp, Vme)
mtrue = interpolate(mtrue_exp, Vm)
f = Expression("1.0")

# Assemble weak form
trial = TrialFunction(V)
test = TestFunction(V)
a_true = inner(mtrue*nabla_grad(trial), nabla_grad(test))*dx
A_true = assemble(a_true)
bc.apply(A_true)
solver = PETScKrylovSolver('cg')    # doesn't work with ilu preconditioner
#solver = LUSolver()    # doesn't work in parallel !?
#solver.parameters['reuse_factorization'] = True
solver.set_operator(A_true)
# Assemble rhs
L = f*test*dx
b = assemble(L)
bc.apply(b)
# Solve:
u_true = Function(V)

"""
solver.solve(u_true.vector(), b)
if myrank == 0: print 'By hand:\n'
print 'P{0}: max(u)={1}\n'.format(myrank, max(u_true.vector().array()))
Esempio n. 19
0
def test_krylov_reuse_pc():
    "Test preconditioner re-use with PETScKrylovSolver"

    # Define problem
    mesh = UnitSquareMesh(MPI.comm_world, 8, 8)
    V = FunctionSpace(mesh, ('Lagrange', 1))
    bc = DirichletBC(V, Constant(0.0), lambda x, on_boundary: on_boundary)
    u = TrialFunction(V)
    v = TestFunction(V)

    # Forms
    a, L = inner(grad(u), grad(v)) * dx, dot(Constant(1.0), v) * dx

    A, P = PETScMatrix(), PETScMatrix()
    b = PETScVector()

    # Assemble linear algebra objects
    assemble(a, tensor=A)  # noqa
    assemble(a, tensor=P)  # noqa
    assemble(L, tensor=b)  # noqa

    # Apply boundary conditions
    bc.apply(A)
    bc.apply(P)
    bc.apply(b)

    # Create Krysolv solver and set operators
    solver = PETScKrylovSolver("gmres", "bjacobi")
    solver.set_operators(A, P)

    # Solve
    x = PETScVector()
    num_iter_ref = solver.solve(x, b)

    # Change preconditioner matrix (bad matrix) and solve (PC will be
    # updated)
    a_p = u * v * dx
    assemble(a_p, tensor=P)  # noqa
    bc.apply(P)
    x = PETScVector()
    num_iter_mod = solver.solve(x, b)
    assert num_iter_mod > num_iter_ref

    # Change preconditioner matrix (good matrix) and solve (PC will be
    # updated)
    a_p = a
    assemble(a_p, tensor=P)  # noqa
    bc.apply(P)
    x = PETScVector()
    num_iter = solver.solve(x, b)
    assert num_iter == num_iter_ref

    # Change preconditioner matrix (bad matrix) and solve (PC will not
    # be updated)
    solver.set_reuse_preconditioner(True)
    a_p = u * v * dx
    assemble(a_p, tensor=P)  # noqa
    bc.apply(P)
    x = PETScVector()
    num_iter = solver.solve(x, b)
    assert num_iter == num_iter_ref

    # Update preconditioner (bad PC, will increase iteration count)
    solver.set_reuse_preconditioner(False)
    x = PETScVector()
    num_iter = solver.solve(x, b)
    assert num_iter == num_iter_mod
Esempio n. 20
0
def solverNeilanSalgadoZhang(P, opt):
    '''
    This function implements the method presented in
    Neilan, Salgado, Zhang (2017), Chapter 4
    Main characteristics:
    - test with piecewise second derivative of test_u
    - no discrete Hessian
    - first-order stabilization necessary
    '''

    assert opt["HessianSpace"] == "CG", 'opt["HessianSpace"] has to be "CG"'
    assert opt[
        "stabilityConstant1"], 'opt["stabilityConstant1"] has to be positive'

    gamma = P.normalizeSystem(opt)

    if isinstance(P.g, list):
        bc_V = []
        for fun, dom in P.g:
            bc_V.append(DirichletBC(P.V, fun, dom))
    else:
        if isinstance(P.g, Function):
            bc_V = DirichletBC(P.V, P.g, 'on_boundary')
        else:
            g = project(P.g, P.V)
            bc_V = DirichletBC(P.V, g, 'on_boundary')

    trial_u = TrialFunction(P.V)
    test_u = TestFunction(P.V)

    # Assemble right-hand side in each case
    f_h = gamma * P.f * div(grad(test_u)) * dx

    # Adjust load vector in case of time-dependent problem
    if P.isTimeDependant:
        f_h = gamma * P.u_np1 * div(grad(test_u)) * dx - P.dt * f_h

    rhs = assemble(f_h)
    if isinstance(bc_V, list):
        for bc_v in bc_V:
            bc_v.apply(rhs)
    else:
        bc_V.apply(rhs)

    repeat_setup = False

    if hasattr(P, 'timeDependentCoefs'):
        if P.timeDependentCoefs:
            repeat_setup = True

    if 'HJB' in str(type(P)):
        repeat_setup = True

    if (not P.isTimeDependant) or (P.iter == 0) or repeat_setup:

        print('Setup bilinear form')

        # Define bilinear form
        a_h = gamma * inner(P.a, grad(grad(trial_u))) * div(grad(test_u)) * dx \
            + opt["stabilityConstant1"] * avg(P.hE)**(-1) * inner(
                jump(grad(trial_u), P.nE), jump(grad(test_u), P.nE)) * dS

        if P.hasDrift:
            a_h += gamma * inner(P.b, grad(trial_u)) * div(grad(test_u)) * dx

        if P.hasPotential:
            a_h += gamma * P.c * trial_u * div(grad(test_u)) * dx

        # Adjust system matrix in case of time-dependent problem
        if P.isTimeDependant:
            a_h = gamma * trial_u * div(grad(test_u)) * dx - P.dt * a_h

        S = assemble(a_h)
        if isinstance(bc_V, list):
            for bc_v in bc_V:
                bc_v.apply(S)
        else:
            bc_V.apply(S)

        P.S = S

    if opt['time_check']:
        t1 = time()

    solve(P.S, P.u.vector(), rhs)

    # tmp = assemble(inner(P.a,grad(grad(trial_u))) * div(grad(test_u)) * dx)
    # A = assemble(a_h)
    # print('Row sum: ', sum(A.array(),1).round(4))
    # print('Col sum: ', sum(A.array(),0).round(4))
    # print('Total sum: ', sum(sum(A.array())).round(4))
    # ipdb.set_trace()
    # solve(a_h == f_h, P.u, bc_V, solver_parameters={'linear_solver': 'mumps'})

    if opt['time_check']:
        print("Solve linear equation system ... %.2fs" % (time() - t1))
        sys.stdout.flush()

    N_iter = 1

    return N_iter
Esempio n. 21
0
    def test_DoGIP_vs_FEniCS(self):
        print(
            '\n== testing DoGIP vs. FEniCS for problem of weighted projection ===='
        )
        for dim, pol_order in itertools.product([2, 3], [1, 2]):
            print('dim={}; pol_order={}'.format(dim, pol_order))
            N = 2  # no. of elements

            # creating MESH, defining MATERIAL and SOURCE
            if dim == 2:
                mesh = UnitSquareMesh(N, N)
                m = Expression("1+10*16*x[0]*(1-x[0])*x[1]*(1-x[1])", degree=4)
                f = Expression("80*x[0]*(0.5-x[0])*(1.-x[0])*x[1]*(1.-x[1])",
                               degree=5)
            elif dim == 3:
                mesh = UnitCubeMesh(N, N, N)
                m = Expression("1+10*16*x[0]*(1-x[0])*(1-x[1])*x[2]", degree=4)
                f = Expression("80*x[0]*(0.5-x[0])*(1.-x[0])*x[1]*(1.-x[1])",
                               degree=5)

            mesh.coordinates()[:] += 0.1 * np.random.random(
                mesh.coordinates().shape)  # mesh perturbation

            ## standard approach with FEniCS #############################################
            V = FunctionSpace(mesh, "CG", pol_order)  # original FEM space
            bc = DirichletBC(V, Constant(0.0),
                             lambda x, on_boundary: on_boundary)
            u, v = TrialFunction(V), TestFunction(V)
            u_fenics = Function(V)  # the vector for storing the solution
            solve(m * inner(grad(u), grad(v)) * dx == f * v * dx, u_fenics,
                  bc)  # solution by FEniCS

            ## DoGIP - double-grid integration with interpolation-projection #############
            W = FunctionSpace(mesh, "DG",
                              2 * (pol_order - 1))  # double-grid space
            Wvector = VectorFunctionSpace(
                mesh, "DG",
                2 * (pol_order - 1))  # vector variant of double-grid space
            w = TestFunction(W)
            A_dogip = assemble(
                m * w *
                dx).get_local()  # diagonal matrix of material coefficients
            A_dogip_full = np.einsum(
                'i,jk->ijk', A_dogip,
                np.eye(dim))  # block-diagonal mat. for non-isotropic mat.
            bv = assemble(f * v * dx)
            bc.apply(bv)
            b = bv.get_local()  # vector of right-hand side

            # assembling global interpolation-projection matrix B
            B = get_B(V, Wvector, problem=1)

            # solution to DoGIP problem
            def Afun(x):
                Axd = np.einsum('...jk,...j', A_dogip_full,
                                B.dot(x).reshape((-1, dim)))
                Afunx = B.T.dot(Axd.ravel())
                Afunx[list(bc.get_boundary_values()
                           )] = 0  # application of Dirichlet BC
                return Afunx

            Alinoper = linalg.LinearOperator((b.size, b.size),
                                             matvec=Afun,
                                             dtype=np.float)  # system matrix
            x, info = linalg.cg(Alinoper,
                                b,
                                x0=np.zeros_like(b),
                                tol=1e-8,
                                maxiter=1e2)  # conjugate gradients

            # testing the difference between DoGIP and FEniCS
            self.assertAlmostEqual(
                0, np.linalg.norm(u_fenics.vector().get_local() - x))
            print('...ok')
Esempio n. 22
0
def forward(mu_expression,
            lmbda_expression,
            rho,
            Lx=10,
            Ly=10,
            t_end=1,
            omega_p=5,
            amplitude=5000,
            center=0,
            target=False):
    Lpml = Lx / 10
    #c_p = cp(mu.vector(), lmbda.vector(), rho)
    max_velocity = 200  #c_p.max()

    stable_hx = stable_dx(max_velocity, omega_p)
    nx = int(Lx / stable_hx) + 1
    #nx = max(nx, 60)
    ny = int(Ly * nx / Lx) + 1
    mesh = mesh_generator(Lx, Ly, Lpml, nx, ny)
    used_hx = Lx / nx
    dt = stable_dt(used_hx, max_velocity)
    cfl_ct = cfl_constant(max_velocity, dt, used_hx)
    print(used_hx, stable_hx)
    print(cfl_ct)
    #time.sleep(10)
    PE = FunctionSpace(mesh, "DG", 0)
    mu = interpolate(mu_expression, PE)
    lmbda = interpolate(lmbda_expression, PE)

    m = 2
    R = 10e-8
    t = 0.0
    gamma = 0.50
    beta = 0.25

    ff = MeshFunction("size_t", mesh, mesh.geometry().dim() - 1)
    Dirichlet(Lx, Ly, Lpml).mark(ff, 1)

    # Create function spaces
    VE = VectorElement("CG", mesh.ufl_cell(), 1, dim=2)
    TE = TensorElement("DG", mesh.ufl_cell(), 0, shape=(2, 2), symmetry=True)

    W = FunctionSpace(mesh, MixedElement([VE, TE]))
    F = FunctionSpace(mesh, "CG", 2)
    V = W.sub(0).collapse()
    M = W.sub(1).collapse()

    alpha_0 = Alpha_0(m, stable_hx, R, Lpml)
    alpha_1 = Alpha_1(alpha_0, Lx, Lpml, degree=2)
    alpha_2 = Alpha_2(alpha_0, Ly, Lpml, degree=2)

    beta_0 = Beta_0(m, max_velocity, R, Lpml)
    beta_1 = Beta_1(beta_0, Lx, Lpml, degree=2)
    beta_2 = Beta_2(beta_0, Ly, Lpml, degree=2)

    alpha_1 = interpolate(alpha_1, F)
    alpha_2 = interpolate(alpha_2, F)
    beta_1 = interpolate(beta_1, F)
    beta_2 = interpolate(beta_2, F)

    a_ = alpha_1 * alpha_2
    b_ = alpha_1 * beta_2 + alpha_2 * beta_1
    c_ = beta_1 * beta_2

    Lambda_e = as_tensor([[alpha_2, 0], [0, alpha_1]])
    Lambda_p = as_tensor([[beta_2, 0], [0, beta_1]])

    a_ = alpha_1 * alpha_2
    b_ = alpha_1 * beta_2 + alpha_2 * beta_1
    c_ = beta_1 * beta_2

    Lambda_e = as_tensor([[alpha_2, 0], [0, alpha_1]])
    Lambda_p = as_tensor([[beta_2, 0], [0, beta_1]])

    # Set up boundary condition
    bc = DirichletBC(W.sub(0), Constant(("0.0", "0.0")), ff, 1)

    # Create measure for the source term
    dx = Measure("dx", domain=mesh)
    ds = Measure("ds", domain=mesh, subdomain_data=ff)

    # Set up initial values
    u0 = Function(V)
    u0.set_allow_extrapolation(True)
    v0 = Function(V)
    a0 = Function(V)
    U0 = Function(M)
    V0 = Function(M)
    A0 = Function(M)

    # Test and trial functions
    (u, S) = TrialFunctions(W)
    (w, T) = TestFunctions(W)

    g = ModifiedRickerPulse(0, omega_p, amplitude, center)

    F = rho * inner(a_ * N_ddot(u, u0, a0, v0, dt, beta) \
        + b_ * N_dot(u, u0, v0, a0, dt, beta, gamma) + c_ * u, w) * dx \
        + inner(N_dot(S, U0, V0, A0, dt, beta, gamma).T * Lambda_e + S.T * Lambda_p, grad(w)) * dx \
        - inner(g, w) * ds \
        + inner(compliance(a_ * N_ddot(S, U0, A0, V0, dt, beta) + b_ * N_dot(S, U0, V0, A0, dt, beta, gamma) + c_ * S, u, mu, lmbda), T) * dx \
        - 0.5 * inner(grad(u) * Lambda_p + Lambda_p * grad(u).T + grad(N_dot(u, u0, v0, a0, dt, beta, gamma)) * Lambda_e \
        + Lambda_e * grad(N_dot(u, u0, v0, a0, dt, beta, gamma)).T, T) * dx \

    a, L = lhs(F), rhs(F)

    # Assemble rhs (once)
    A = assemble(a)

    # Create GMRES Krylov solver
    solver = KrylovSolver(A, "gmres")

    # Create solution function
    S = Function(W)

    if target:
        xdmffile_u = XDMFFile("inversion_temporal_file/target/u.xdmf")
        pvd = File("inversion_temporal_file/target/u.pvd")
        xdmffile_u.write(u0, t)
        timeseries_u = TimeSeries(
            "inversion_temporal_file/target/u_timeseries")
    else:
        xdmffile_u = XDMFFile("inversion_temporal_file/obs/u.xdmf")
        xdmffile_u.write(u0, t)
        timeseries_u = TimeSeries("inversion_temporal_file/obs/u_timeseries")

    rec_counter = 0

    while t < t_end - 0.5 * dt:
        t += float(dt)

        if rec_counter % 10 == 0:
            print(
                '\n\rtime: {:.3f} (Progress: {:.2f}%)'.format(
                    t, 100 * t / t_end), )

        g.t = t

        # Assemble rhs and apply boundary condition
        b = assemble(L)
        bc.apply(A, b)

        # Compute solution
        solver.solve(S.vector(), b)
        (u, U) = S.split(True)

        # Update previous time step
        update(u, u0, v0, a0, beta, gamma, dt)
        update(U, U0, V0, A0, beta, gamma, dt)

        xdmffile_u.write(u, t)
        pvd << (u, t)
        timeseries_u.store(u.vector(), t)

        energy = inner(u, u) * dx
        E = assemble(energy)
        print("E = ", E)
        print(u.vector().max())
Esempio n. 23
0
        for i, t in enumerate(trange[1:]):
            print('Solve problem, time step t = {}'.format(np.round(t, 4)))

            # Assign current time to variable t_
            t_.assign(t)

            # Compute Ytilde, i.e. y-position of process starting in x_i,y_j
            # after application of convection in y-direction
            Ytilde = Y + by(t, X, Y) * dt[i]
            Vtilde = Yinterp1(vold, Ytilde, ydofs, ydiff)

            # Set up problem
            Sfull = M - dt[i] * S

            # Apply boundary conditions
            bc_Vx.apply(Sfull)

            # Loop over all layers in y-direction
            for j in range(ny + 1):

                y_.assign(ydofs[j])
                L = assemble(L_)

                # This is ordinary matrix multiplication
                # np.max(np.abs(M*Vtilde[3,:] - M.array() @ Vtilde[3,:]))

                Mvtmp.vector().set_local(M * Vtilde[j, :])

                Lfull = Mvtmp.vector() - dt[i] * L
                bc_Vx.apply(Lfull)
Esempio n. 24
0
    def solve(self):
        """ Find eigenvalues for transformed mesh. """
        self.progress("Building mesh.")
        # build transformed mesh
        mesh = self.refineMesh()
        # dim = mesh.topology().dim()
        if self.bcLast:
            mesh = transform_mesh(mesh, self.transformList)
            Robin, Steklov, shift, bcs = get_bc_parts(mesh, self.bcList)
        else:
            Robin, Steklov, shift, bcs = get_bc_parts(mesh, self.bcList)
            mesh = transform_mesh(mesh, self.transformList)
            # boundary conditions computed on non-transformed mesh
            # copy the values to transformed mesh
            fun = FacetFunction("size_t", mesh, shift)
            fun.array()[:] = bcs.array()[:]
            bcs = fun
        ds = Measure('ds', domain=mesh, subdomain_data=bcs)
        V = FunctionSpace(mesh, self.method, self.deg)
        u = TrialFunction(V)
        v = TestFunction(V)
        self.progress("Assembling matrices.")
        wTop = Expression(self.wTop)
        wBottom = Expression(self.wBottom)

        #
        # build stiffness matrix form
        #
        s = dot(grad(u), grad(v)) * wTop * dx
        # add Robin parts
        for bc in Robin:
            s += Constant(bc.parValue) * u * v * wTop * ds(bc.value + shift)

        #
        # build mass matrix form
        #
        if len(Steklov) > 0:
            m = 0
            for bc in Steklov:
                m += Constant(
                    bc.parValue) * u * v * wBottom * ds(bc.value + shift)
        else:
            m = u * v * wBottom * dx

        # assemble
        # if USE_EIGEN:
        #     S, M = EigenMatrix(), EigenMatrix()
        # tempv = EigenVector()
        # else:
        S, M = PETScMatrix(), PETScMatrix()
        # tempv = PETScVector()

        if not np.any(bcs.array() == shift + 1):
            # no Dirichlet parts
            assemble(s, tensor=S)
            assemble(m, tensor=M)
        else:
            #
            # with EIGEN we could
            #   apply Dirichlet condition symmetrically
            #   completely remove rows and columns
            #
            # Dirichlet parts are marked with shift+1
            #
            # temp = Constant(0)*v*dx
            bc = DirichletBC(V, Constant(0.0), bcs, shift + 1)
            # assemble_system(s, temp, bc, A_tensor=S, b_tensor=tempv)
            # assemble_system(m, temp, bc, A_tensor=M, b_tensor=tempv)
            assemble(s, tensor=S)
            bc.apply(S)
            assemble(m, tensor=M)
            # bc.zero(M)

        # if USE_EIGEN:
        #    M = M.sparray()
        #    M.eliminate_zeros()
        #    print M.shape
        #    indices = M.indptr[:-1] - M.indptr[1:] < 0
        #    M = M[indices, :].tocsc()[:, indices]
        #    S = S.sparray()[indices, :].tocsc()[:, indices]
        #    print M.shape
        #
        # solve the eigenvalue problem
        #
        self.progress("Solving eigenvalue problem.")
        eigensolver = SLEPcEigenSolver(S, M)
        eigensolver.parameters["problem_type"] = "gen_hermitian"
        eigensolver.parameters["solver"] = "krylov-schur"
        if self.target is not None:
            eigensolver.parameters["spectrum"] = "target real"
            eigensolver.parameters["spectral_shift"] = self.target
        else:
            eigensolver.parameters["spectrum"] = "smallest magnitude"
            eigensolver.parameters["spectral_shift"] = -0.01
        eigensolver.parameters["spectral_transform"] = "shift-and-invert"
        eigensolver.solve(self.number)
        self.progress("Generating eigenfunctions.")
        if eigensolver.get_number_converged() == 0:
            return None
        eigf = []
        eigv = []
        if self.deg > 1:
            mesh = refine(mesh)
        W = FunctionSpace(mesh, 'CG', 1)
        for i in range(eigensolver.get_number_converged()):
            pair = eigensolver.get_eigenpair(i)[::2]
            eigv.append(pair[0])
            u = Function(V)
            u.vector()[:] = pair[1]
            eigf.append(interpolate(u, W))
        return eigv, eigf
Esempio n. 25
0
    while t < t_end - 0.5 * dt:
        t += float(dt)

        if rank == 0 and rec_counter % 10 == 0:
            print(
                '\n\rtime: {:.3f} (Progress: {:.2f}%)'.format(
                    t, 100 * t / t_end), )
            print("time taken til this point: {}".format(time.time() - t0))

        for pulse in pulses:
            pulse.t = t
        g = sum(pulses)

        # Assemble rhs and apply boundary condition
        b = assemble(L)
        bc.apply(A, b)

        # Compute solution
        solver.solve(S.vector(), b)
        (u, U) = S.split(True)

        # Update previous time step
        update(u, u0, v0, a0, beta, gamma, dt)
        update(U, U0, V0, A0, beta, gamma, dt)

        pvd << (u0, t)

        rec_counter += 1
        energy = inner(u, u) * dx
        E = assemble(energy)
        print("E = ", E)
Esempio n. 26
0
            def __call__(self, degree=3, y=0., standard_deviation=1.):
                V = FunctionSpace(self._mesh, "CG", degree)
                v = TestFunction(V)
                potential_trial = TrialFunction(V)
                potential = Function(V)
                dx = Measure("dx")(subdomain_data=self._subdomains)
                # ds = Measure("ds")(subdomain_data=self._boundaries)
                csd = Expression(f'''
                                  x[1] >= {self.H} ?
                                  0 :
                                  a * exp({-0.5 / standard_deviation ** 2}
                                          * ((x[0])*(x[0])
                                             + (x[1] - {y})*(x[1] - {y})
                                             + (x[2])*(x[2])
                                             ))
                                  ''',
                                 degree=degree,
                                 a=1.0)

                self.a = csd.a = 1.0 / assemble(
                    csd * Measure("dx", self._mesh))
                # print(assemble(csd * Measure("dx", self._mesh)))
                L = csd * v * dx

                known_terms = assemble(L)
                # a = (inner(grad(potential_trial), grad(v))
                #      * (Constant(self.SALINE_CONDUCTIVITY) * dx(self.SALINE_VOL)
                #         + Constant(self.SLICE_CONDUCTIVITY) * (dx(self.SLICE_VOL)
                #                                                + dx(self.ROI_VOL))))
                a = sum(
                    Constant(conductivity) *
                    inner(grad(potential_trial), grad(v)) * dx(domain)
                    for domain, conductivity in [
                        (self.SALINE_VOL, self.SALINE_CONDUCTIVITY),
                        (self.SLICE_VOL, self.SLICE_CONDUCTIVITY),
                        (self.ROI_VOL, self.SLICE_CONDUCTIVITY),
                    ])
                terms_with_unknown = assemble(a)
                dirchlet_bc = DirichletBC(
                    V,
                    Constant(2.0 * 0.25 /
                             (self.RADIUS * np.pi * self.SALINE_CONDUCTIVITY)),
                    # 2.0 becaue of dielectric base duplicating
                    # the current source
                    # slice conductivity and thickness considered
                    # negligible
                    self._boundaries,
                    self.MODEL_DOME)
                dirchlet_bc.apply(terms_with_unknown, known_terms)
                solver = KrylovSolver("cg", "ilu")
                solver.parameters["maximum_iterations"] = MAX_ITER
                solver.parameters["absolute_tolerance"] = 1E-8
                # solver.parameters["monitor_convergence"] = True
                start = datetime.datetime.now()
                try:
                    self.iterations = solver.solve(terms_with_unknown,
                                                   potential.vector(),
                                                   known_terms)
                    return potential

                except RuntimeError as e:
                    self.iterations = MAX_ITER
                    logger.warning("Solver failed: {}".format(repr(e)))
                    return None

                finally:
                    self.time = datetime.datetime.now() - start