Example #1
0
 def compute_operators(self):
     u = fa.TrialFunction(self.V)
     v = fa.TestFunction(self.V)
     form_a = fa.inner(fa.grad(u), fa.grad(v)) * fa.dx
     form_b = u * v * fa.dx
     A = da.assemble(form_a)
     B = da.assemble(form_b)
     A_np = np.array(A.array())
     B_np = np.array(B.array())
     return A_np, B_np
Example #2
0
    def J(self, A: dolfin.PETScMatrix, x: dolfin.PETScVector):
        assemble(self._J, tensor=A)
        for bc in self.bcs:
            bc.apply(A)

        if self.output_matrix:
            filename = Path("{self.output_matrix_path}/J_{self.n:04d}.mtx")
            filename.parent.mkdir(exist_ok=True, parents=True)
            dump_matrix_to_mtx(A, filename)
            if self.verbose:
                print(f"Assembled matrix written to {filename}")
            self.n = self.n + 1
    def __call__(self, f, u):
        """
        Carry out projection of ufl Expression f and store result in
        the function u. The user must make sure that u lives in the
        right space.

        *Arguments*
          f (:py:class:`ufl.Expr`)
            The thing to be projected into this function space
          u (:py:class:`dolfin.Function`)
            The result of the projection
        """
        L = dolfin.inner(f, self.v)*dolfin.dx()
        assemble(L, tensor=self.b)
        self.solver.solve(u.vector(), self.b)
    def __init__(self, V, params=None):
        # Set parameters
        self.parameters = self.default_parameters()
        if params is not None:
            self.parameters.update(params)

        # Set-up mass matrix for L^2 projection
        self.V = V
        self.u = dolfin.TrialFunction(self.V)
        self.v = dolfin.TestFunction(self.V)
        self.m = dolfin.inner(self.u, self.v)*dolfin.dx()
        self.M = assemble(self.m)
        self.b = dolfin.Vector(V.mesh().mpi_comm(), V.dim())

        solver_type = self.parameters["linear_solver_type"]
        assert(solver_type == "lu" or solver_type == "cg"),  \
            "Expecting 'linear_solver_type' to be 'lu' or 'cg'"
        if solver_type == "lu":
            dolfin.debug("Setting up direct solver for projecter")
            # Customize LU solver (reuse everything)
            solver = LUSolver(self.M)
            solver.parameters["same_nonzero_pattern"] = True
            solver.parameters["reuse_factorization"] = True
        else:
            dolfin.debug("Setting up iterative solver for projecter")
            # Customize Krylov solver (reuse everything)
            solver = KrylovSolver("cg", "ilu")
            solver.set_operator(self.M)
            solver.parameters["preconditioner"]["structure"] = "same"
            # solver.parameters["nonzero_initial_guess"] = True
        self.solver = solver
def get_cavity_volume(geometry,
                      unload=False,
                      chamber="lv",
                      u=None,
                      xshift=0.0):

    if unload:
        mesh = geometry.original_geometry
        ffun = dolfin.MeshFunction("size_t", mesh, 2, mesh.domains())
    else:
        mesh = geometry.mesh
        ffun = geometry.ffun

    if chamber == "lv":
        if "ENDO_LV" in geometry.markers:
            endo_marker = geometry.markers["ENDO_LV"]
        else:
            endo_marker = geometry.markers["ENDO"]

    else:
        endo_marker = geometry.markers["ENDO_RV"]

    if hasattr(endo_marker, "__len__"):
        endo_marker = endo_marker[0]

    ds = dolfin.Measure("exterior_facet", subdomain_data=ffun,
                        domain=mesh)(endo_marker)

    vol_form = get_cavity_volume_form(geometry.mesh, u, xshift)
    return assemble(vol_form * ds)
Example #6
0
        def forward(control, annotate=True):

            self.reset_problem()
            annotation.annotate = annotate

            states = []
            functional_values = []

            functional = self.create_functional()
            functionals_time = []

            gen = self.iteration(control)
            for count in gen:

                # Collect stuff
                states.append(dolfin.Vector(self.problem.state.vector()))
                functional_values.append(functional)
                functionals_time.append(functional)

            return forward_result(
                functional=dolfin_adjoint.assemble(
                    list_sum(functionals_time) / self._meshvol *
                    dolfin.dx(domain=self.problem.geometry.mesh)),
                converged=True,
            )
Example #7
0
 def debug(self):
     _, B_np = self.compute_operators()
     dof_data = np.random.rand(self.num_dofs)
     u = da.Function(self.V)
     u.vector()[:] = dof_data
     L1 = da.assemble(u * u * fa.dx)
     L2 = (np.matmul(B_np, dof_data) * dof_data).sum()
     print(L1)
     print(L2)
Example #8
0
 def _obj(self, x):
     f = da.Function(self.poisson.V)
     f.vector()[:] = x
     self.poisson.source = f
     u = self.poisson.solve_problem_variational_form()
     L_tape = da.assemble(
         (0.5 * fa.inner(u - self.target_u, u - self.target_u) +
          0.5 * self.alpha * fa.inner(f, f)) * fa.dx)
     L = float(L_tape)
     return L, L_tape, f
Example #9
0
                      degree=3), W)
else:
    g = da.interpolate(da.Expression(("sin(2*pi*x[0])"), degree=3), W)
    f = da.interpolate(da.Expression(("sin(2*pi*x[0])"), degree=3), W)

u = da.Function(V, name='State')
v = fa.TestFunction(V)

F = (fa.inner(fa.grad(u), fa.grad(v)) - f * v) * fa.dx
bc = da.DirichletBC(V, 0.0, "on_boundary")
da.solve(F == 0, u, bc)

d = da.Function(V)
d.vector()[:] = u.vector()[:]

J = da.assemble((0.5 * fa.inner(u - d, u - d)) * fa.dx +
                alpha / 2 * f**2 * fa.dx)
control = da.Control(f)
rf = da.ReducedFunctional(J, control)

# set the initial value to be zero for optimization
f.vector()[:] = 0
# N = len(f.vector()[:])
# f.vector()[:] = np.random.rand(N)*2 -1

problem = da.MoolaOptimizationProblem(rf)
f_moola = moola.DolfinPrimalVector(f)
solver = moola.BFGS(problem,
                    f_moola,
                    options={
                        'jtol': 0,
                        'gtol': 1e-9,
def compute_meshvolume(domain=None, dx=dolfin.dx, subdomain_id=None):
    return Constant(
        assemble(
            Constant(1.0) * dx(domain=domain, subdomain_id=subdomain_id), ), )
Example #11
0
def cost_function(u_model, u_data):
    norm = lambda f: da.assemble(df.inner(f, f) * df.dx)
    return norm(u_model - u_data)
Example #12
0
 def F(self, b: dolfin.PETScVector, x: dolfin.PETScVector):
     assemble(self._F, tensor=b)
     for bc in self.bcs:
         bc.apply(b, x)
Example #13
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)
Example #14
0
 def energy(self, u):
     return da.assemble(self._energy_density(u) * fa.dx)