示例#1
0
def coarsen_vectorspacebasis(basis, self, coefficient_mapping=None):
    coarse_vecs = [
        self(vec, self, coefficient_mapping=coefficient_mapping)
        for vec in basis._vecs
    ]
    vsb = firedrake.VectorSpaceBasis(coarse_vecs, constant=basis._constant)
    vsb.orthonormalize()
    return vsb
示例#2
0
 def nullspace(self):
     """Inform solver that pressure solution is not unique.
     
     It is only defined up to adding an arbitrary constant.
     """
     W = self.solution_space
     
     return fe.MixedVectorSpaceBasis(
         W, [W.sub(0), fe.VectorSpaceBasis(constant=True)])            
示例#3
0
 def nullspace(self):
     """Inform solver that pressure solution is not unique.
     
     It is only defined up to adding an arbitrary constant.
     """
     return fe.MixedVectorSpaceBasis(
         self.solution_space,
         (fe.VectorSpaceBasis(constant=True),
          self.solution_subspaces["u"]))
     
示例#4
0
    def get_nullspace(self):
        """Specify nullspace of state/adjoint equation."""

        if len(self.outflow_bids) > 0:
            # If the pressure is fixed (anywhere) by a Dirichlet bc, nsp = None
            nsp = None
        else:
            nsp = fd.MixedVectorSpaceBasis(
                self.V, [self.V.sub(0),
                         fd.VectorSpaceBasis(constant=True)])
        return nsp
示例#5
0
    def __init__(self, Q, fixed_bids=[], extra_bcs=[], direct_solve=False):
        if isinstance(extra_bcs, fd.DirichletBC):
            extra_bcs = [extra_bcs]

        self.direct_solve = direct_solve
        self.fixed_bids = fixed_bids  # fixed parts of bdry
        self.params = self.get_params()  # solver parameters
        self.Q = Q
        """
        V: type fd.FunctionSpace
        I: type PETSc.Mat, interpolation matrix between V and  ControlSpace
        """
        (V, I_interp) = Q.get_space_for_inner()
        free_bids = list(V.mesh().topology.exterior_facets.unique_markers)
        self.free_bids = [int(i) for i in free_bids]  # np.int->int
        for bid in self.fixed_bids:
            self.free_bids.remove(bid)

        # Some weak forms have a nullspace. We import the nullspace if no
        # parts of the bdry are fixed (we assume that a DirichletBC is
        # sufficient to empty the nullspace).
        nsp = None
        if len(self.fixed_bids) == 0:
            nsp_functions = self.get_nullspace(V)
            if nsp_functions is not None:
                nsp = fd.VectorSpaceBasis(nsp_functions)
                nsp.orthonormalize()

        bcs = []
        # impose homogeneous Dirichlet bcs on bdry parts that are fixed.
        if len(self.fixed_bids) > 0:
            dim = V.value_size
            if dim == 2:
                zerovector = fd.Constant((0, 0))
            elif dim == 3:
                zerovector = fd.Constant((0, 0, 0))
            else:
                raise NotImplementedError
            bcs.append(fd.DirichletBC(V, zerovector, self.fixed_bids))

        if len(extra_bcs) > 0:
            bcs += extra_bcs

        if len(bcs) == 0:
            bcs = None

        a = self.get_weak_form(V)
        A = fd.assemble(a, mat_type='aij', bcs=bcs)
        ls = fd.LinearSolver(A,
                             solver_parameters=self.params,
                             nullspace=nsp,
                             transpose_nullspace=nsp)
        self.ls = ls
        self.A = A.petscmat
        self.interpolated = False

        # If the matrix I is passed, replace A with transpose(I)*A*I
        # and set up a ksp solver for self.riesz_map
        if I_interp is not None:
            self.interpolated = True
            ITAI = self.A.PtAP(I_interp)
            from firedrake.petsc import PETSc
            import numpy as np
            zero_rows = []

            # if there are zero-rows, replace them with rows that
            # have 1 on the diagonal entry
            for row in range(*ITAI.getOwnershipRange()):
                (cols, vals) = ITAI.getRow(row)
                valnorm = np.linalg.norm(vals)
                if valnorm < 1e-13:
                    zero_rows.append(row)
            for row in zero_rows:
                ITAI.setValue(row, row, 1.0)
            ITAI.assemble()

            # overwrite the self.A created by get_impl
            self.A = ITAI

            # create ksp solver for self.riesz_map
            Aksp = PETSc.KSP().create(comm=V.comm)
            Aksp.setOperators(ITAI)
            Aksp.setType("preonly")
            Aksp.pc.setType("cholesky")
            Aksp.pc.setFactorSolverType("mumps")
            Aksp.setFromOptions()
            Aksp.setUp()
            self.Aksp = Aksp
示例#6
0
def compliance_bridge():

    parser = argparse.ArgumentParser(description="Heat exchanger")
    parser.add_argument(
        "--n_iters",
        dest="n_iters",
        type=int,
        action="store",
        default=1000,
        help="Number of optimization iterations",
    )
    parser.add_argument(
        "--output_dir",
        dest="output_dir",
        type=str,
        action="store",
        default="./",
        help="Output directory",
    )
    opts = parser.parse_args()
    output_dir = opts.output_dir
    # Elasticity parameters
    E, nu = 1.0, 0.3
    rho_min = fd.Constant(1e-4)  # Min Vol fraction
    eps = fd.Constant(100.0)  # Heaviside parameter
    mu, lmbda = fd.Constant(E / (2 * (1 + nu))), fd.Constant(
        E * nu / ((1 + nu) * (1 - 2 * nu)))

    mesh = fd.RectangleMesh(20, 40, 0.5, 1, quadrilateral=True)
    mh = fd.MeshHierarchy(mesh, 1)
    m = fd.ExtrudedMeshHierarchy(mh, height=1, base_layer=40)
    mesh = m[-1]

    S = fd.VectorFunctionSpace(mesh, "CG", 1)
    s = fd.Function(S, name="deform")
    mesh.coordinates.assign(mesh.coordinates + s)

    x, y, z = fd.SpatialCoordinate(mesh)
    PHI = fd.FunctionSpace(mesh, "CG", 1)
    lx = 1.0
    ly = 2.0
    lz = ly
    phi_expr = (-cos(4.0 / lx * pi * x) * cos(4.0 * pi / ly * y) *
                cos(4.0 / lz * pi * z) - 0.6)
    with fda.stop_annotating():
        phi = fd.interpolate(-phi_expr, PHI)
        phi.rename("LevelSet")

    H1 = fd.VectorElement("CG", mesh.ufl_cell(), 1)
    W = fd.FunctionSpace(mesh, H1)
    print(f"DOFS: {W.dim()}")

    modes = [fd.Function(W) for _ in range(6)]
    modes[0].interpolate(fd.Constant([1, 0, 0]))
    modes[1].interpolate(fd.Constant([0, 1, 0]))
    modes[2].interpolate(fd.Constant([0, 0, 1]))
    modes[3].interpolate(fd.as_vector([0, z, -y]))
    modes[4].interpolate(fd.as_vector([-z, 0, x]))
    modes[5].interpolate(fd.as_vector([y, -x, 0]))
    nullmodes = fd.VectorSpaceBasis(modes)
    # Make sure they're orthonormal.
    nullmodes.orthonormalize()

    u = fd.TrialFunction(W)
    v = fd.TestFunction(W)

    def epsilon(u):
        return sym(nabla_grad(u))

    def sigma(v):
        return 2.0 * mu * epsilon(v) + lmbda * tr(epsilon(v)) * Identity(3)

    # Variational forms
    a = inner(hs(phi, eps, min_value=rho_min) * sigma(u),
              nabla_grad(v)) * dx(degree=2)
    t = fd.Constant((0.0, 0.0, -1.0e-1))
    L = inner(t, v) * ds_t

    # Dirichlet BCs
    ylimits = (0.2, 1.8)
    xlimits = (0.4, 0.6)
    I_BC = create_function_marker(PHI, W, xlimits, ylimits)
    bc1 = MyBC(W, 0, I_BC)
    bc2 = fd.DirichletBC(W.sub(0), fd.Constant(0.0), 2)
    bc3 = fd.DirichletBC(W.sub(1), fd.Constant(0.0), 4)

    u_sol = fd.Function(W)
    fd.solve(
        a == L,
        u_sol,
        bcs=[bc1, bc2, bc3],
        solver_parameters=gamg_parameters,
        near_nullspace=nullmodes,
    )

    # Cost function
    Jform = fd.assemble(
        inner(hs(phi, eps, min_value=rho_min) * sigma(u_sol), epsilon(u_sol)) *
        dx(degree=2))
    # Constraint
    VolPen = fd.assemble(hs(phi, eps, min_value=rho_min) * dx(degree=2))
    total_vol = fd.assemble(fd.Constant(1.0) * dx(domain=mesh), annotate=False)
    VolControl = fda.Control(VolPen)
    Vval = 0.15 * total_vol

    # Plotting
    global_counter1 = itertools.count()
    phi_pvd = fd.File(f"{output_dir}/level_set_evolution.pvd")

    def deriv_cb(phi):
        iter = next(global_counter1)
        if iter % 10 == 0:
            phi_pvd.write(phi[0])

    c = fda.Control(s)
    Jhat = LevelSetFunctional(Jform, c, phi, derivative_cb_pre=deriv_cb)
    Vhat = LevelSetFunctional(VolPen, c, phi)

    # Regularization solver. Zero on the BCs boundaries
    beta_param = 0.005
    bcs_vel_1 = MyBC(S, 0, I_BC)
    bcs_vel_2 = fd.DirichletBC(S, fd.Constant((0.0, 0.0, 0.0)), "top")
    bcs_vel = [bcs_vel_1, bcs_vel_2]
    reg_solver = RegularizationSolver(
        S,
        mesh,
        beta=beta_param,
        gamma=1.0e4,
        dx=dx,
        bcs=bcs_vel,
        output_dir=None,
        solver_parameters=gamg_parameters,
    )
    dt = 0.05
    tol = 1e-5

    params = {
        "alphaC": 1.0,
        "K": 0.0001,
        "debug": 5,
        "maxit": opts.n_iters,
        "alphaJ": 2.0,
        "dt": dt,
        "maxtrials": 500,
        "tol_merit":
        5e-2,  # new merit can be within 0.5% of the previous merit
        "itnormalisation": 50,
        "tol": tol,
    }
    hj_solver_parameters["ts_dt"] = dt / 50.0
    solver_parameters = {
        "hj_solver": hj_solver_parameters,
        "reinit_solver": reinit_solver_parameters,
    }

    vol_constraint = Constraint(Vhat, Vval, VolControl)
    problem = InfDimProblem(
        Jhat,
        reg_solver,
        ineqconstraints=vol_constraint,
        solver_parameters=solver_parameters,
    )
    _ = nlspace_solve(problem, params)