示例#1
0
        def _change_degree(self, degree, *args, **kwargs):
            gc.collect()

            with self.global_preprocessing_time:
                logger.debug('Creating function space...')
                self._V = FunctionSpace(self._mesh, "CG", degree)
                logger.debug('Done.  Creating integration subdomains...')
                self.create_integration_subdomains()
                logger.debug('Done.  Creating test function...')
                self._v = TestFunction(self._V)
                logger.debug('Done.  Creating potential function...')
                self._potential_function = Function(self._V)
                logger.debug('Done.  Creating trial function...')
                self._potential_trial = TrialFunction(self._V)
                logger.debug('Done.  Creating LHS part of equation...')
                self._a = self._lhs()
                logger.debug('Done.  Assembling linear equation matrix...')
                self._terms_with_unknown = assemble(self._a)
                logger.debug('Done.  Defining boundary condition...')
                self._dirichlet_bc = self._boundary_condition(*args, **kwargs)
                logger.debug('Done.  Applying boundary condition to the matrix...')
                self._dirichlet_bc.apply(self._terms_with_unknown)

                logger.debug('Done.  Creating solver...')
                self._solver = KrylovSolver("cg", "ilu")
                self._solver.parameters["maximum_iterations"] = self.MAX_ITER
                self._solver.parameters["absolute_tolerance"] = 1E-8
                logger.debug('Done.  Solver created.')

            self._degree = degree
示例#2
0
def les_setup(u_, mesh, KineticEnergySGS, assemble_matrix, CG1Function,
              nut_krylov_solver, bcs, **NS_namespace):
    """
    Set up for solving the Kinetic Energy SGS-model.
    """
    DG = FunctionSpace(mesh, "DG", 0)
    CG1 = FunctionSpace(mesh, "CG", 1)
    dim = mesh.geometry().dim()
    delta = Function(DG)
    delta.vector().zero()
    delta.vector().axpy(1.0, assemble(TestFunction(DG) * dx))
    delta.vector().set_local(delta.vector().array()**(1. / dim))
    delta.vector().apply('insert')

    Ck = KineticEnergySGS["Ck"]
    ksgs = interpolate(Constant(1E-7), CG1)
    bc_ksgs = DirichletBC(CG1, 0, "on_boundary")
    A_mass = assemble_matrix(TrialFunction(CG1) * TestFunction(CG1) * dx)
    nut_form = Ck * delta * sqrt(ksgs)
    bcs_nut = derived_bcs(CG1, bcs['u0'], u_)
    nut_ = CG1Function(nut_form,
                       mesh,
                       method=nut_krylov_solver,
                       bcs=bcs_nut,
                       bounded=True,
                       name="nut")
    At = Matrix()
    bt = Vector(nut_.vector())
    ksgs_sol = KrylovSolver("bicgstab", "additive_schwarz")
    #ksgs_sol.parameters["preconditioner"]["structure"] = "same_nonzero_pattern"
    ksgs_sol.parameters["error_on_nonconvergence"] = False
    ksgs_sol.parameters["monitor_convergence"] = False
    ksgs_sol.parameters["report"] = False
    del NS_namespace
    return locals()
示例#3
0
    def solve_alpha_M_beta_F(self, alpha, beta, b, t):
        """Solve  :code:`alpha * M * u + beta * F(u, t) = b`  with Dirichlet
        conditions.
        """
        matrix = alpha * self.M + beta * self.A

        # See above for float conversion
        right_hand_side = -float(beta) * self.b.copy()
        if b:
            right_hand_side += b

        for bc in self.dirichlet_bcs:
            bc.apply(matrix, right_hand_side)

        # TODO proper preconditioner for convection
        if self.convection:
            # Use HYPRE-Euclid instead of ILU for parallel computation.
            # However, this PC sometimes fails.
            # solver = KrylovSolver('gmres', 'hypre_euclid')
            # Fallback:
            solver = LUSolver()
        else:
            solver = KrylovSolver("gmres", "hypre_amg")
            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(matrix)

        u = Function(self.Q)
        solver.solve(u.vector(), right_hand_side)
        return u
示例#4
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
示例#5
0
 def __init__(self):
     mesh = UnitSquareMesh(200, 200)
     self.V = FunctionSpace(mesh, 'Lagrange', 2)
     test, trial = TestFunction(self.V), TrialFunction(self.V)
     M = assemble(inner(test, trial) * dx)
     #self.M = assemble(inner(test, trial)*dx)
     self.solverM = KrylovSolver("cg", "amg")
     self.solverM.set_operator(M)
示例#6
0
        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 = assemble(f * v * dx)

            rhs = b.vector() - beta * b2
            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
示例#7
0
    def __init__(self, fem, grounded_plate_at):
        self.GROUNDED_PLATE_AT = grounded_plate_at
        self.fem = fem
        self.CONDUCTIVITY = list(fem.CONDUCTIVITY)
        self.BOUNDARY_CONDUCTIVITY = list(fem.BOUNDARY_CONDUCTIVITY)

        self.solver = KrylovSolver("cg", "ilu")
        self.solver.parameters["maximum_iterations"] = 1000
        self.solver.parameters["absolute_tolerance"] = 1E-8

        self.V = fem._fm.function_space
        self.v = fem._fm.test_function()
        self.u = fem._fm.trial_function()
        self.dx = fem._dx
        self.ds = fem._ds
        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
示例#9
0
    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)
示例#10
0
def main_slice_fem(mesh, subdomains, boundaries, src_pos, snk_pos):
    sigma_ROI = Constant(params.sigma_roi)
    sigma_SLICE = Constant(params.sigma_slice)
    sigma_SALINE = Constant(params.sigma_saline)
    sigma_AIR = Constant(0.)

    V = FunctionSpace(mesh, "CG", 2)
    v = TestFunction(V)
    u = TrialFunction(V)

    phi = Function(V)
    dx = Measure("dx")(subdomain_data=subdomains)
    ds = Measure("ds")(subdomain_data=boundaries)
    a = inner(sigma_ROI * grad(u), grad(v))*dx(params.roivol) + \
        inner(sigma_SLICE * grad(u), grad(v))*dx(params.slicevol) + \
        inner(sigma_SALINE * grad(u), grad(v))*dx(params.salinevol)
    L = Constant(0) * v * dx
    A = assemble(a)
    b = assemble(L)

    x_pos, y_pos, z_pos = src_pos
    point = Point(x_pos, y_pos, z_pos)
    delta = PointSource(V, point, 1.)
    delta.apply(b)

    x_pos, y_pos, z_pos = snk_pos
    point1 = Point(x_pos, y_pos, z_pos)
    delta1 = PointSource(V, point1, -1.)
    delta1.apply(b)

    solver = KrylovSolver("cg", "ilu")
    solver.parameters["maximum_iterations"] = 1000
    solver.parameters["absolute_tolerance"] = 1E-8
    solver.parameters["monitor_convergence"] = True

    info(solver.parameters, True)
    #    set_log_level(PROGRESS) does not work in fenics 2018.1.0
    solver.solve(A, phi.vector(), b)

    ele_pos_list = params.ele_coords
    vals = extract_pots(phi, ele_pos_list)
    # np.save(os.path.join('results', save_as), vals)
    return vals
示例#11
0
 def _set_degree(self, degree):
     self._fm.degree = degree
     with self.global_preprocessing_time:
         logger.debug('Creating integration subdomains...')
         self.create_integration_subdomains()
         logger.debug('Done.  Creating test function...')
         self._v = self._fm.test_function()
         logger.debug('Done.  Creating potential function...')
         self._potential_function = self._fm.function()
         logger.debug('Done.  Creating trial function...')
         self._potential_trial = self._fm.trial_function()
         logger.debug('Done.  Creating LHS part of equation...')
         self._a = self._lhs()
         logger.debug('Done.  Creating base potential formula...')
         self._base_potential_expression = self._potential_expression()
         self._base_potential_gradient_normal_expression = self._potential_gradient_normal(
         )
         logger.debug('Done.  Creating solver...')
         self._solver = KrylovSolver("cg", "ilu")
         self._solver.parameters["maximum_iterations"] = self.MAX_ITER
         self._solver.parameters["absolute_tolerance"] = 1E-8
         logger.debug('Done.  Solver created.')
示例#12
0
    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)

    experiment_count_file = open("experiment_counter", 'rb')
    experiment_count = pickle.load(experiment_count_file)
    experiment_count_file.close()

    paraview_file_name = "experiment_{}".format(experiment_count)
    info_file_name = "{}_experiments_info/info_n{}.txt".format(
        type_of_medium, experiment_count)

    experiment_count += 1
    experiment_count_file = open("experiment_counter", 'wb')
示例#13
0
def solve(WP, bcs, mu, f, verbose=True, tol=1.0e-13, max_iter=500):
    # Some initial sanity checks.
    assert mu > 0.0

    # Define variational problem
    (u, p) = TrialFunctions(WP)
    (v, q) = TestFunctions(WP)

    # Build system.
    # The sign of the div(u)-term is somewhat arbitrary since the right-hand
    # side is 0 here. We can either make the system symmetric or positive-
    # definite.
    # On a second note, we have
    #
    #    \int grad(p).v = - \int p * div(v) + \int_\Gamma p n.v.
    #
    # Since, we have either p=0 or n.v=0 on the boundary, we could as well
    # replace the term dot(grad(p), v) by -p*div(v).
    #
    a = mu * inner(grad(u), grad(v))*dx \
        - p * div(v) * dx \
        - q * div(u) * dx
    # a = mu * inner(grad(u), grad(v))*dx + dot(grad(p), v) * dx \
    #  - div(u) * q * dx
    L = inner(f, v) * dx
    A, b = assemble_system(a, L, bcs)

    # Use the preconditioner as recommended in
    # <http://fenicsproject.org/documentation/dolfin/dev/python/demo/pde/stokes-iterative/python/documentation.html>,
    #
    #     prec = inner(grad(u), grad(v))*dx - p*q*dx
    #
    # although it doesn't seem to be too efficient.
    # The sign on the last term doesn't matter.
    prec = mu * inner(grad(u), grad(v))*dx \
        - p*q*dx
    M, _ = assemble_system(prec, L, bcs)
    # solver = KrylovSolver('tfqmr', 'hypre_amg')
    solver = KrylovSolver('gmres', 'hypre_amg')
    solver.set_operators(A, M)

    # For an assortment of preconditioners, see
    #
    #     Performance and analysis of saddle point preconditioners
    #     for the discrete steady-state Navier-Stokes equations;
    #     H.C. Elman, D.J. Silvester, A.J. Wathen;
    #     Numer. Math. (2002) 90: 665-688;
    #     <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.145.3554>.
    #
    # Set up field split.
    # <https://fenicsproject.org/qa/12856/fieldsplit-petscpreconditioner_set_fieldsplit-arguments>
    # PETScOptions.set('ksp_view')
    # PETScOptions.set('ksp_monitor_true_residual')
    # PETScOptions.set('pc_type', 'fieldsplit')
    # PETScOptions.set('pc_fieldsplit_type', 'additive')
    # PETScOptions.set('pc_fieldsplit_detect_saddle_point')
    # PETScOptions.set('fieldsplit_0_ksp_type', 'preonly')
    # PETScOptions.set('fieldsplit_0_pc_type', 'lu')
    # PETScOptions.set('fieldsplit_1_ksp_type', 'preonly')
    # PETScOptions.set('fieldsplit_1_pc_type', 'jacobi')

    # solver = PETScKrylovSolver('gmres')
    # solver.set_operator(A)
    # solver.set_from_options()

    # http://scicomp.stackexchange.com/questions/7288/which-preconditioners-and-solver-in-petsc-for-indefinite-symmetric-systems-sho
    # PETScOptions.set('pc_type', 'fieldsplit')
    # #PETScOptions.set('pc_fieldsplit_type', 'schur')
    # #PETScOptions.set('pc_fieldsplit_schur_fact_type', 'upper')
    # PETScOptions.set('pc_fieldsplit_detect_saddle_point')
    # #PETScOptions.set('fieldsplit_u_pc_type', 'lsc')
    # #PETScOptions.set('fieldsplit_u_ksp_type', 'preonly')

    # PETScOptions.set('pc_type', 'fieldsplit')
    # PETScOptions.set('fieldsplit_u_pc_type', 'hypre')
    # PETScOptions.set('fieldsplit_u_ksp_type', 'preonly')
    # PETScOptions.set('fieldsplit_p_pc_type', 'jacobi')
    # PETScOptions.set('fieldsplit_p_ksp_type', 'preonly')

    # # From PETSc/src/ksp/ksp/examples/tutorials/ex42-fsschur.opts:
    # PETScOptions.set('pc_type', 'fieldsplit')
    # PETScOptions.set('pc_fieldsplit_type', 'SCHUR')
    # PETScOptions.set('pc_fieldsplit_schur_fact_type', 'UPPER')
    # PETScOptions.set('fieldsplit_p_ksp_type', 'preonly')
    # PETScOptions.set('fieldsplit_u_pc_type', 'bjacobi')

    # From
    #
    # Composable Linear Solvers for Multiphysics;
    # J. Brown, M. Knepley, D.A. May, L.C. McInnes, B. Smith;
    # <http://www.computer.org/csdl/proceedings/ispdc/2012/4805/00/4805a055-abs.html>;
    # <http://www.mcs.anl.gov/uploads/cels/papers/P2017-0112.pdf>.
    #
    # PETScOptions.set('pc_type', 'fieldsplit')
    # PETScOptions.set('pc_fieldsplit_type', 'schur')
    # PETScOptions.set('pc_fieldsplit_schur_factorization_type', 'upper')
    # #
    # PETScOptions.set('fieldsplit_u_ksp_type', 'cg')
    # PETScOptions.set('fieldsplit_u_ksp_rtol', 1.0e-6)
    # PETScOptions.set('fieldsplit_u_pc_type', 'bjacobi')
    # PETScOptions.set('fieldsplit_u_sub_pc_type', 'cholesky')
    # #
    # PETScOptions.set('fieldsplit_p_ksp_type', 'fgmres')
    # PETScOptions.set('fieldsplit_p_ksp_constant_null_space')
    # PETScOptions.set('fieldsplit_p_pc_type', 'lsc')
    # #
    # PETScOptions.set('fieldsplit_p_lsc_ksp_type', 'cg')
    # PETScOptions.set('fieldsplit_p_lsc_ksp_rtol', 1.0e-2)
    # PETScOptions.set('fieldsplit_p_lsc_ksp_constant_null_space')
    # #PETScOptions.set('fieldsplit_p_lsc_ksp_converged_reason')
    # PETScOptions.set('fieldsplit_p_lsc_pc_type', 'bjacobi')
    # PETScOptions.set('fieldsplit_p_lsc_sub_pc_type', 'icc')

    solver.parameters['monitor_convergence'] = verbose
    solver.parameters['report'] = verbose
    solver.parameters['absolute_tolerance'] = 0.0
    solver.parameters['relative_tolerance'] = tol
    solver.parameters['maximum_iterations'] = max_iter
    solver.parameters['error_on_nonconvergence'] = True

    # Solve
    up = Function(WP)
    solver.solve(up.vector(), b)

    # Get sub-functions
    u, p = up.split(True)

    return u, p
示例#14
0
def solve(
    V,
    dx,
    Mu,
    Sigma,  # dictionaries
    omega,
    f_list,  # list of dictionaries
    convections,  # dictionary
    f_degree=None,
    bcs=None,
    tol=1.0e-12,
    verbose=False,
):
    """Solve the complex-valued time-harmonic Maxwell system in 2D cylindrical
    coordinates

    .. math::
         \\div\\left(\\frac{1}{\\mu r} \\nabla(r\\phi)\\right)
         + \\left\\langle u, \\frac{1}{r} \\nabla(r\\phi)\\right\\rangle
         + i \\sigma \\omega \\phi
            = f

    with finite elements.

    :param V: function space for potentials

    :param dx: measure

    :param Mu: mu per subdomain
    :type Mu: dictionary

    :param Sigma: sigma per subdomain
    :type Sigma: dictionary

    :param omega: current frequency
    :type omega: float

    :param f_list: list of right-hand sides for each of which a solution will
                   be computed

    :param convections: convection, defined per subdomain
    :type convections: dictionary

    :param bcs: Dirichlet boundary conditions

    :param tol: relative solver tolerance
    :type tol: float

    :param verbose: solver verbosity
    :type verbose: boolean

    :rtype: list of functions
    """
    # For the exact solution of the magnetic scalar potential, see
    # <http://www.physics.udel.edu/~jim/PHYS809_10F/Class_Notes/Class_26.pdf>.
    # Here, the value of \\phi along the rotational axis is specified as
    #
    #    phi(z) = 2 pi I / c * (z/|z| - z/sqrt(z^2 + a^2))
    #
    # where 'a' is the radius of the coil. This expression contradicts what is
    # specified by [Chaboudez97]_ who claim that phi=0 is the natural value
    # at the symmetry axis.
    #
    # For more analytic expressions, see
    #
    #     Simple Analytic Expressions for the Magnetic Field of a Circular
    #     Current Loop;
    #     James Simpson, John Lane, Christopher Immer, and Robert Youngquist;
    #     <http://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/20010038494_2001057024.pdf>.
    #

    # Check if boundary conditions on phi are explicitly provided.
    if not bcs:
        # Create Dirichlet boundary conditions.
        # In the cylindrically symmetric formulation, the magnetic vector
        # potential is given by
        #
        #    A = e^{i omega t} phi(r,z) e_{theta}.
        #
        # It is natural to demand phi=0 along the symmetry axis r=0 to avoid
        # discontinuities there.
        # Also, this makes sure that the system is well-defined (see comment
        # below).
        #
        def xzero(x, on_boundary):
            return on_boundary and abs(x[0]) < DOLFIN_EPS

        ee = V.ufl_element() * V.ufl_element()
        VV = FunctionSpace(V.mesh(), ee)
        bcs = DirichletBC(VV, (0.0, 0.0), xzero)
        #
        # Concerning the boundary conditions for the rest of the system:
        # At the other boundaries, it is not uncommon (?) to set so-called
        # impedance boundary conditions; see, e.g.,
        #
        # Chaboudez et al.,
        # Numerical Modeling in Induction Heating for Axisymmetric
        # Geometries,
        # IEEE Transactions on Magnetics, vol. 33, no. 1, Jan 1997,
        # <http://www.esi-group.com/products/casting/publications/Articles_PDF/InductionaxiIEEE97.pdf>.
        #
        # or
        #
        # <ftp://ftp.math.ethz.ch/pub/sam-reports/reports/reports2010/2010-39.pdf>.
        #
        # TODO review those, references don't seem to be too accurate
        # Those translate into Robin-type boundary conditions (and are in fact
        # sometimes called that, cf.
        # https://en.wikipedia.org/wiki/Robin_boundary_condition).
        # The classical reference is
        #
        #   Impedance boundary conditions for imperfectly conducting surfaces,
        #   T.B.A. Senior,
        #   <http://link.springer.com/content/pdf/10.1007/BF02920074>.
        #
        # class OuterBoundary(SubDomain):
        #     def inside(self, x, on_boundary):
        #         return on_boundary and abs(x[0]) > DOLFIN_EPS
        # boundaries = MeshFunction(
        #     'size_t', mesh,
        #     mesh.topology().dim() - 1
        #     )
        # boundaries.set_all(0)
        # outer_boundary = OuterBoundary()
        # outer_boundary.mark(boundaries, 1)
        # ds = Measure('ds')[boundaries]
        # #n = FacetNormal(mesh)
        # #a += - 1.0/Mu[i] * dot(grad(r*ur), n) * vr * ds(1) \
        # #     - 1.0/Mu[i] * dot(grad(r*ui), n) * vi * ds(1)
        # #L += - 1.0/Mu[i] * 1.0 * vr * ds(1) \
        # #     - 1.0/Mu[i] * 1.0 * vi * ds(1)
        # # This is -n.grad(r u) = u:
        # a += 1.0/Mu[i] * ur * vr * ds(1) \
        #    + 1.0/Mu[i] * ui * vi * ds(1)

    # Create the system matrix, preconditioner, and the right-hand sides.
    # For preconditioners, there are two approaches. The first one, described
    # in
    #
    #     Algebraic Multigrid for Complex Symmetric Systems;
    #     D. Lahaye, H. De Gersem, S. Vandewalle, and K. Hameyer;
    #     <https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=877730>
    #
    # doesn't work too well here.
    # The matrix P, created in build_system(), provides a better alternative.
    # For more details, see documentation in build_system().
    #
    A, P, b_list, _, W = build_system(V, dx, Mu, Sigma, omega, f_list,
                                      f_degree, convections, bcs)

    # prepare solver
    # Don't use 'amg', since that defaults to `ml_amg` if available which
    # crashes
    # <https://bitbucket.org/fenics-project/docker/issues/61/petsc-vectorfunctionspace-amg-malloc>.
    solver = KrylovSolver("gmres", "hypre_amg")
    solver.set_operators(A, P)

    # The PDE for A has huge coefficients (order 10^8) all over. Hence, if
    # relative residual is set to 10^-6, the actual residual will still be of
    # the order 10^2. While this isn't too bad (after all the equations are
    # upscaled by a large factor), one can choose a very small relative
    # tolerance here to get a visually pleasing residual norm.
    solver.parameters["relative_tolerance"] = tol
    solver.parameters["absolute_tolerance"] = 0.0
    solver.parameters["maximum_iterations"] = 100
    solver.parameters["report"] = verbose
    solver.parameters["monitor_convergence"] = verbose

    phi_list = []
    for k, b in enumerate(b_list):
        phi_list.append(Function(W))
        phi_list[-1].rename("phi{}".format(k), "phi{}".format(k))
        solver.solve(phi_list[-1].vector(), b)

    return phi_list
示例#15
0
    def before_first_compute(self, get):
        u = get(self.valuename)

        if isinstance(u, Function):

            if LooseVersion(dolfin_version()) > LooseVersion("1.6.0"):
                rank = len(u.ufl_shape)
            else:
                rank = u.rank()

            if rank == 0:
                self.f = Function(u.function_space())
            elif rank >= 1:
                # Assume all subpaces are equal
                V = u.function_space().extract_sub_space([0]).collapse()
                mesh = V.mesh()
                el = V.ufl_element()
                self.f = Function(V)

                # Find out if we can operate directly on vectors, or if we have to use a projection
                # We can operate on vectors if all sub-dofmaps are ordered the same way
                # For simplicity, this is only tested for CG- or DG0-spaces
                # (this might always be true for these spaces, but better to be safe than sorry )
                self.use_project = True
                if el.family() == "Lagrange" or (el.family()
                                                 == "Discontinuous Lagrange"
                                                 and el.degree() == 0):
                    #dm = u.function_space().dofmap()
                    dm0 = V.dofmap()
                    self.use_project = False
                    for i in xrange(u.function_space().num_sub_spaces()):
                        Vi = u.function_space().extract_sub_space(
                            [i]).collapse()
                        dmi = Vi.dofmap()
                        try:
                            # For 1.6.0+ and newer
                            diff = Vi.tabulate_dof_coordinates(
                            ) - V.tabulate_dof_coordinates()
                        except:
                            # For 1.6.0 and older
                            diff = dmi.tabulate_all_coordinates(
                                mesh) - dm0.tabulate_all_coordinates(mesh)
                        if len(diff) > 0:
                            max_diff = max(abs(diff))
                        else:
                            max_diff = 0.0
                        max_diff = MPI.max(mpi_comm_world(), max_diff)
                        if max_diff > 1e-12:
                            self.use_project = True
                            break
                        self.assigner = FunctionAssigner(
                            [V] * u.function_space().num_sub_spaces(),
                            u.function_space())
                        self.subfuncs = [
                            Function(V)
                            for _ in range(u.function_space().num_sub_spaces())
                        ]

                # IF we have to use a projection, build projection matrix only once
                if self.use_project:
                    self.v = TestFunction(V)
                    M = assemble(inner(self.v, TrialFunction(V)) * dx)
                    self.projection = KrylovSolver("cg", "default")
                    self.projection.set_operator(M)
        elif isinstance(u, Iterable) and all(
                isinstance(_u, Number) for _u in u):
            pass
        elif isinstance(u, Number):
            pass
        else:
            # Don't know how to handle object
            cbc_warning(
                "Don't know how to calculate magnitude of object of type %s." %
                type(u))
示例#16
0
                  source_z=7.85,
                  source_y=0,
                  sigma_2=0.1,
                  A=(2 * np.pi * 0.1) ** -1.5,
                  degree=DEGREE)
#B_inv = assemble(csd * Measure('dx', mesh))

# csd_at = interpolate(csd, V)
# csd_at(0, 0, 7.2) < 0

def boundary(x, on_boundary):
    return x[1] <= NECK_AT

bc = DirichletBC(V, Constant(0.), boundary)

solver = KrylovSolver("cg", "ilu")
solver.parameters["maximum_iterations"] = 1100
solver.parameters["absolute_tolerance"] = 1E-8
#solver.parameters["monitor_convergence"] = True

SOURCES = []
DBG = {}

TMP_FILENAME = f'proof_of_concept_fem_dirchlet_newman_CTX_deg_{DEGREE}_.npz'
try:
    fh = np.load(TMP_FILENAME)

except FileNotFoundError:
    print('no previous results found')
    previously_solved = set()
示例#17
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
示例#18
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())