Пример #1
0
    def solve(self, var, b):
        x = dolfin.Function(self.test_function().function_space())

        # b is a libadjoint object (form or function)
        (a, L) = (self.data, b.data)

        # First: check if L is None (meaning zero)
        if L is None:
            x_vec = adjlinalg.Vector(x)
            return x_vec

        if isinstance(L, dolfin.Function):
            b_vec = L.vector()
            L = None
        else:
            b_vec = dolfin.assemble(L)

        # Next: if necessary, create a new solver and add to dictionary
        idx = a.arguments()
        if idx not in caching.localsolvers:
            if dolfin.parameters["adjoint"]["debug_cache"]:
                dolfin.info_red("Creating new LocalSolver")
            newsolver = dolfin.LocalSolver(a, None, solver_type=self.solver_parameters["solver_type"])
            if self.solver_parameters["factorize"] : newsolver.factorize()
            caching.localsolvers[idx] = newsolver
        else:
            if dolfin.parameters["adjoint"]["debug_cache"]:
                dolfin.info_green("Reusing LocalSolver")

        # Get the right solver from the solver dictionary
        solver = caching.localsolvers[idx]
        solver.solve_local(x.vector(), b_vec, b.fn_space.dofmap())

        x_vec = adjlinalg.Vector(x)
        return x_vec
Пример #2
0
    def _setup_solver(self, Model, Scheme, time=0.0, stim=None, params=None):
        ''' Generate a new solver object with the given start time, stimulus and parameters. '''
        # Create model instance
        if isinstance(Model, str):
            Model = eval(Model)
        model = Model(params=params)

        # Initialize time and stimulus (note t=time construction!)
        if stim is None:
            stim = Expression("1000*t", t=time, degree=1)

        # Initialize solver
        mesh = UnitIntervalMesh(5)
        params = CardiacODESolver.default_parameters()
        params["scheme"] = Scheme

        solver = CardiacODESolver(mesh, time, model, I_s=stim, params=params)

        # Create scheme
        info_green("\nTesting %s with %s scheme" % (model, Scheme))

        # Start with native initial conditions
        (vs_, vs) = solver.solution_fields()
        vs_.assign(model.initial_conditions())
        vs.assign(vs_)

        return solver
    def test_default_basic_single_cell_solver(self, cell_model, theta):
        "Test basic single cell solver."
        time = Constant(0.0)
        model = cell_model
        Model = cell_model.__class__

        if Model == supported_cell_models[3] and theta > 0:
            pytest.xfail("failing configuration (but should work)")

        model.stimulus = Expression("1000*t", t=time, degree=1)

        info_green("\nTesting %s" % model)
        vec_solve = self._run_solve(model, time, theta)

        if Model == supported_cell_models[3] and theta == 0:
            pytest.xfail("failing configuration (but should work)")

        if Model in self.references and theta in self.references[Model]:
            ind, ref_value = self.references[Model][theta]
            print("vec_solve", vec_solve.array())
            print("ind", ind, "ref", ref_value)

            assert_almost_equal(vec_solve[ind], ref_value, 1e-10)
        else:
            info_red("Missing references for %r, %r" % (Model, theta))
Пример #4
0
    def test_ReplayOfSplittingSolver_IsExact(self, Solver, solver_type, tol):
        """Test that basic and optimised splitting solvers yield
        very comparative results when configured identically."""

        self.tlm_adj_setup(Solver, solver_type)

        info_green("Replaying")
        success = replay_dolfin(tol=tol, stop=True)
        assert success
    def test_AdjointModelOfSplittingSolver_PassesTaylorTest(
            self, Solver, solver_type):
        """Test that basic and optimised splitting solvers yield
        very comparative results when configured identically."""

        J, Jhat, m, Jics = self.tlm_adj_setup(Solver, solver_type)

        # Check adjoint model correctness
        info_green("Compute gradient with adjoint linear model")
        dJdics = compute_gradient(J, m, forget=False)

        assert (dJdics is not None), "Gradient is None (#fail)."
        conv_rate = taylor_test(Jhat, m, Jics, dJdics, seed=1.)

        # Check that minimal convergence rate is greater than some given number
        assert_greater(conv_rate, 1.9)
Пример #6
0
    def test_TangentLinearModelOfSplittingSolver_PassesTaylorTest(
            self, Solver, solver_type):
        """Test that basic and optimised splitting solvers yield
        very comparative results when configured identically."""
        if isinstance(Solver, BasicSplittingSolver):
            pytest.mark.xfail("PETSc error 73: Object is in wring state")

        J, Jhat, m, Jics = self.tlm_adj_setup(Solver, solver_type)

        # Check TLM correctness
        info_green("Compute gradient with tangent linear model")
        dJdics = compute_gradient_tlm(J, m, forget=False)

        assert (dJdics is not None), "Gradient is None (#fail)."
        conv_rate_tlm = taylor_test(Jhat, m, Jics, dJdics, seed=1)

        # Check that minimal convergence rate is greater than some given number
        assert_greater(conv_rate_tlm, 1.9)
Пример #7
0
    def _setup_solver(self, Model, Scheme, mesh, time, stim=None, params=None):
        # Create model instance
        model = Model(params=params)

        # Initialize time and stimulus (note t=time construction!)
        if stim is None:
            stim = Expression("1000*t", t=time, degree=1)

        # Initialize solver
        params = CardiacODESolver.default_parameters()
        params["scheme"] = Scheme
        solver = CardiacODESolver(mesh, time, model, I_s=stim, params=params)

        # Create scheme
        info_green("\nTesting %s with %s scheme" % (model, Scheme))

        # Start with native initial conditions
        (vs_, vs) = solver.solution_fields()
        vs_.assign(model.initial_conditions())
        vs.assign(vs_)

        return solver
Пример #8
0
    def solve(self, var, b):
        x = dolfin.Function(self.test_function().function_space())

        # b is a libadjoint object (form or function)
        (a, L) = (self.data, b.data)

        # First: check if L is None (meaning zero)
        if L is None:
            x_vec = adjlinalg.Vector(x)
            return x_vec

        if isinstance(L, dolfin.Function):
            b_vec = L.vector()
            L = None
        else:
            b_vec = dolfin.assemble(L)

        # Next: if necessary, create a new solver and add to dictionary
        idx = a.arguments()
        if idx not in caching.localsolvers:
            if dolfin.parameters["adjoint"]["debug_cache"]:
                dolfin.info_red("Creating new LocalSolver")
            newsolver = dolfin.LocalSolver(
                a, None, solver_type=self.solver_parameters["solver_type"])
            if self.solver_parameters["factorize"]: newsolver.factorize()
            caching.localsolvers[idx] = newsolver
        else:
            if dolfin.parameters["adjoint"]["debug_cache"]:
                dolfin.info_green("Reusing LocalSolver")

        # Get the right solver from the solver dictionary
        solver = caching.localsolvers[idx]
        solver.solve_local(x.vector(), b_vec, b.fn_space.dofmap())

        x_vec = adjlinalg.Vector(x)
        return x_vec
Пример #9
0
 def info_green(self, message, values, log_keys, time=None):
     info_green(message % values)
     self._log_data(values, log_keys, time)
Пример #10
0
    def __init__(self, turbine, flow):
        # add radius to model params
        if model_parameters is None:
            model_parameters = {"radius": turbine_radius}
        else:
            model_parameters.update({"radius": turbine_radius})
        # check if gradient required
        if "compute_gradient" in model_parameters:
            compute_gradient = model_parameters["compute_gradient"]
        else:
            compute_gradient = True
        # check if a wake and wake gradients are provided
        if "wake" in model_parameters:
            if "wake_gradients" in model_parameters:
                gradients = model_parameters["wake_gradients"]
            else:
                gradients = None
            self.wake = ADDolfinExpression(model_parameters["wake"],
                                           compute_gradient=compute_gradient,
                                           gradients=gradients)
        # compute wake and gradients
        else:
            # mimic a SteadyConfiguration but change a few things along the way
            config = otf.DefaultConfiguration()
            config.params['steady_state'] = True
            config.params[
                'initial_condition'] = otf.ConstantFlowInitialCondition(config)
            config.params['include_advection'] = True
            config.params['include_diffusion'] = True
            config.params['diffusion_coef'] = 3.0
            config.params['quadratic_friction'] = True
            config.params['newton_solver'] = True
            config.params['friction'] = dolfin.Constant(0.0025)
            config.params['theta'] = 1.0
            config.params["dump_period"] = 0

            xmin, ymin = -100, -200
            xsize, ysize = 1000, 400
            xcells, ycells = 400, 160
            mesh = dolfin.RectangleMesh(xmin, ymin, xmin + xsize, ymin + ysize,
                                        xcells, ycells)

            V, H = config.finite_element(mesh)
            config.function_space = dolfin.MixedFunctionSpace([V, H])
            config.turbine_function_space = dolfin.FunctionSpace(mesh, 'CG', 2)

            class Domain(object):
                """
                Domain object used for setting boundary conditions etc later on
                """
                def __init__(self, mesh):
                    class InFlow(dolfin.SubDomain):
                        def inside(self, x, on_boundary):
                            return dolfin.near(x[0], -100)

                    class OutFlow(dolfin.SubDomain):
                        def inside(self, x, on_boundary):
                            return dolfin.near(x[0], 900)

                    inflow = InFlow()
                    outflow = OutFlow()

                    self.mesh = mesh
                    self.boundaries = dolfin.FacetFunction("size_t", mesh)
                    self.boundaries.set_all(0)
                    inflow.mark(self.boundaries, 1)
                    outflow.mark(self.boundaries, 2)

                    self.ds = dolfin.Measure('ds')[self.boundaries]

            config.domain = Domain(mesh)
            config.set_domain(config.domain, warning=False)

            # Boundary conditions
            bc = otf.DirichletBCSet(config)
            bc.add_constant_flow(1, 1.0 + 1e-10)
            bc.add_zero_eta(2)
            config.params['bctype'] = 'strong_dirichlet'
            config.params['strong_bc'] = bc
            config.params['free_slip_on_sides'] = True

            # Optimisation settings
            config.params['functional_final_time_only'] = True
            config.params['automatic_scaling'] = False

            # Turbine settings
            config.params['turbine_pos'] = []
            config.params['turbine_friction'] = []
            config.params['turbine_x'] = turbine_radius * 2
            config.params['turbine_y'] = turbine_radius * 2
            config.params['controls'] = ['turbine_pos']

            # Finally set some DOLFIN optimisation flags
            dolfin.parameters['form_compiler']['cpp_optimize'] = True
            dolfin.parameters['form_compiler']['cpp_optimize_flags'] = '-O3'
            dolfin.parameters['form_compiler']['optimize'] = True

            # place a turbine with default friction
            turbine = [(0., 0.)]
            config.set_turbine_pos(turbine)

            # solve the shallow water equations
            rf = otf.ReducedFunctional(config, plot=False)
            dolfin.info_blue("Generating the wake model...")
            rf.j(rf.initial_control())
            # get state
            state = rf.last_state
            V = dolfin.VectorFunctionSpace(config.function_space.mesh(),
                                           "CG",
                                           2,
                                           dim=2)
            u_out = dolfin.TrialFunction(V)
            v_out = dolfin.TestFunction(V)
            M_out = dolfin_adjoint.assemble(
                dolfin.inner(v_out, u_out) * dolfin.dx)
            out_state = dolfin.Function(V)
            rhs = dolfin_adjoint.assemble(
                dolfin.inner(v_out,
                             state.split()[0]) * dolfin.dx)
            dolfin_adjoint.solve(M_out,
                                 out_state.vector(),
                                 rhs,
                                 "cg",
                                 "sor",
                                 annotate=False)
            dolfin.info_green("Wake model generated.")
            self.wake = ADDolfinExpression(out_state.split()[0],
                                           compute_gradient)

        super(ApproximateShallowWater,
              self).__init__("ApproximateShallowWater", flow_field,
                             model_parameters)
Пример #11
0
def info_green(*args, **kwargs):
    if MPI.process_number() == 0:
        dolfin.info_green(*args, **kwargs)
Пример #12
0
def info_green(*args, **kwargs):
    if MPI.process_number() == 0:
        dolfin.info_green(*args, **kwargs)
Пример #13
0
def info_green(*args, **kwargs):
    if get_rank() == 0:
        dolfin.info_green(*args, **kwargs)
Пример #14
0
def mg_opt(rf, meshes, current_mesh_idx):
    if current_mesh_idx == len(meshes) - 1:
        info_green("Solve problem on coarsest grid")
        m_h_p1 = minimize(rf)
    else:
        m_h1 = minimize(rf, options = {"maxiter": 1})
def mg_opt(rf, meshes, current_mesh_idx):
    if current_mesh_idx == len(meshes) - 1:
        info_green("Solve problem on coarsest grid")
        m_h_p1 = minimize(rf)
    else:
        m_h1 = minimize(rf, options = {"maxiter": 1})