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
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))
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)
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)
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
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
def info_green(self, message, values, log_keys, time=None): info_green(message % values) self._log_data(values, log_keys, time)
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)
def info_green(*args, **kwargs): if MPI.process_number() == 0: dolfin.info_green(*args, **kwargs)
def info_green(*args, **kwargs): if get_rank() == 0: dolfin.info_green(*args, **kwargs)
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})