예제 #1
0
def _solve_varproblem(*args, **kwargs):
    "Solve variational problem a == L or F == 0"

    # Extract arguments
    eq, u, bcs, J, tol, M, form_compiler_parameters, petsc_options \
        = _extract_args(*args, **kwargs)

    # Solve linear variational problem
    if isinstance(eq.lhs, ufl.Form) and isinstance(eq.rhs, ufl.Form):

        a = Form(eq.lhs, form_compiler_parameters=form_compiler_parameters)
        L = Form(eq.rhs, form_compiler_parameters=form_compiler_parameters)

        A = PETScMatrix()
        b = PETScVector()

        assembler = SystemAssembler(a, L, bcs)
        assembler.assemble(A, b)

        comm = L.mesh().mpi_comm()
        solver = PETScKrylovSolver(comm)

        solver.set_options_prefix("dolfin_solve_")
        for k, v in petsc_options.items():
            PETScOptions.set("dolfin_solve_" + k, v)
        solver.set_from_options()

        solver.set_operator(A)
        solver.solve(u.vector(), b)

    # Solve nonlinear variational problem
    else:

        raise RuntimeError("Not implemented")
예제 #2
0
def _solve_varproblem_adaptive(*args, **kwargs):
    "Solve variational problem a == L or F == 0 adaptively"

    # Extract arguments
    eq, u, bcs, J, tol, M, form_compiler_parameters, \
        solver_parameters = _extract_args(*args, **kwargs)

    print('eq.lhs = ', eq.lhs, ' eq.rhs=', eq.rhs)

    # Check that we received the goal functional
    if M is None:
        raise RuntimeError(
            "Cannot solve variational problem adaptively. Missing goal functional"
        )

    # Solve linear variational problem
    if isinstance(eq.lhs, ufl.Form) and isinstance(eq.rhs, ufl.Form):

        # Create problem
        problem = LinearVariationalProblem(
            eq.lhs,
            eq.rhs,
            u,
            bcs,
            form_compiler_parameters=form_compiler_parameters)

        # Create solver and call solve
        solver = AdaptiveLinearVariationalSolver(problem, M)
        solver.parameters.update(solver_parameters)
        solver.solve(tol)

    # Solve nonlinear variational problem
    else:

        # Create Jacobian if missing
        if J is None:
            cpp.log.info(
                "No Jacobian form specified for nonlinear variational problem."
            )
            cpp.log.info(
                "Differentiating residual form F to obtain Jacobian J = F'.")
            F = eq.lhs
            J = derivative(F, u)

        # Create problem
        problem = NonlinearVariationalProblem(
            eq.lhs,
            u,
            bcs,
            J,
            form_compiler_parameters=form_compiler_parameters)

        # Create solver and call solve
        solver = AdaptiveNonlinearVariationalSolver(problem, M)
        solver.parameters.update(solver_parameters)
        solver.solve(tol)
예제 #3
0
def solve_mixed_system(*args, **kwargs):
    "Solve assembled mixed variational problem a == L or F == 0"
    assert (len(args) == 1)  # No arguments except the assembled system
    system = args[0]

    # Extract parameters
    solver_parameters = kwargs.get("solver_parameters", {})

    # Create solver and call solve
    # FIXME : Works only for linear case
    solver = MixedLinearVariationalSolver()
    solver.parameters.update(solver_parameters)
    solver.solve(system)
예제 #4
0
def _solve_varproblem(*args, **kwargs):
    "Solve variational problem a == L or F == 0"

    # Extract arguments
    eq, u, bcs, J, tol, M, form_compiler_parameters, solver_parameters \
        = _extract_args(*args, **kwargs)

    # Solve linear variational problem
    if isinstance(eq.lhs, ufl.Form) and isinstance(eq.rhs, ufl.Form):

        # Create problem
        problem = LinearVariationalProblem(eq.lhs, eq.rhs, u, bcs,
                                           form_compiler_parameters=form_compiler_parameters)

        # Create solver and call solve
        solver = LinearVariationalSolver(problem)
        solver.parameters.update(solver_parameters)
        solver.solve()

    # Solve nonlinear variational problem
    else:

        # Create Jacobian if missing
        if J is None:
            cpp.log.info("No Jacobian form specified for nonlinear variational problem.")
            cpp.log.info("Differentiating residual form F to obtain Jacobian J = F'.")
            F = eq.lhs
            J = formmanipulations.derivative(F, u)

        # Create problem
        problem = NonlinearVariationalProblem(eq.lhs, u, bcs, J,
                                              form_compiler_parameters=form_compiler_parameters)

        # Create solver and call solve
        solver = NonlinearVariationalSolver(problem)
        solver.parameters.update(solver_parameters)
        solver.solve()
예제 #5
0
def _solve_varproblem(*args, **kwargs):
    "Solve variational problem a == L or F == 0"
    # Extract arguments
    eq, u, bcs, J, tol, M, preconditioner, form_compiler_parameters, solver_parameters\
        = _extract_args(*args, **kwargs)

    # Solve linear variational problem
    if isinstance(eq.lhs, ufl.Form) and isinstance(eq.rhs, ufl.Form):

        if u._functions is not None:
            # Extract blocks from the variational formulation
            eq_lhs_forms = extract_blocks(eq.lhs)
            eq_rhs_forms = extract_blocks(eq.rhs)

            # Create problem
            problem = MixedLinearVariationalProblem(
                eq_lhs_forms,
                eq_rhs_forms,
                u._functions,
                bcs,
                form_compiler_parameters=form_compiler_parameters)

            # Create solver and call solve
            solver = MixedLinearVariationalSolver(problem)
            solver.parameters.update(solver_parameters)
            solver.solve()

        else:
            # Create problem
            problem = LinearVariationalProblem(
                eq.lhs,
                eq.rhs,
                u,
                bcs,
                form_compiler_parameters=form_compiler_parameters)
            # Create solver and call solve
            solver = LinearVariationalSolver(problem)
            solver.parameters.update(solver_parameters)
            solver.solve()

    # Solve nonlinear variational problem
    else:

        if u._functions is not None:
            # Extract blocks from the variational formulation
            eq_lhs_forms = extract_blocks(eq.lhs)

            if J is None:
                cpp.log.info(
                    "No Jacobian form specified for nonlinear mixed variational problem."
                )
                cpp.log.info(
                    "Differentiating residual form F to obtain Jacobian J = F'."
                )
                # Give the list of jacobian for each eq_lhs
                Js = []
                for Fi in eq_lhs_forms:
                    for uj in u._functions:
                        derivative = formmanipulations.derivative(Fi, uj)
                        derivative = expand_derivatives(derivative)
                        Js.append(derivative)

            problem = MixedNonlinearVariationalProblem(
                eq_lhs_forms,
                u._functions,
                bcs,
                Js,
                form_compiler_parameters=form_compiler_parameters)
            # Create solver and call solve
            solver = MixedNonlinearVariationalSolver(problem)
            solver.parameters.update(solver_parameters)
            solver.solve()
        else:
            # Create Jacobian if missing
            if J is None:
                cpp.log.info(
                    "No Jacobian form specified for nonlinear variational problem."
                )
                cpp.log.info(
                    "Differentiating residual form F to obtain Jacobian J = F'."
                )
                F = eq.lhs
                J = formmanipulations.derivative(F, u)

            # Create problem
            problem = NonlinearVariationalProblem(
                eq.lhs,
                u,
                bcs,
                J,
                form_compiler_parameters=form_compiler_parameters)

            # Create solver and call solve
            solver = NonlinearVariationalSolver(problem)
            solver.parameters.update(solver_parameters)
            solver.solve()