Beispiel #1
0
    def __init__(self, mesh_r, refinements=1, order=1):
        mh = fd.MeshHierarchy(mesh_r, refinements)
        self.mesh_hierarchy = mh

        # Control space on coarsest mesh
        self.mesh_r_coarse = self.mesh_hierarchy[0]
        self.V_r_coarse = fd.VectorFunctionSpace(self.mesh_r_coarse, "CG",
                                                 order)

        # Create self.id and self.T on refined mesh.
        element = self.V_r_coarse.ufl_element()

        self.intermediate_Ts = []
        for i in range(refinements - 1):
            mesh = self.mesh_hierarchy[i + 1]
            V = fd.FunctionSpace(mesh, element)
            self.intermediate_Ts.append(fd.Function(V))

        self.mesh_r = self.mesh_hierarchy[-1]
        element = self.V_r_coarse.ufl_element()
        self.V_r = fd.FunctionSpace(self.mesh_r, element)

        X = fd.SpatialCoordinate(self.mesh_r)
        self.id = fd.Function(self.V_r).interpolate(X)
        self.T = fd.Function(self.V_r, name="T")
        self.T.assign(self.id)
        self.mesh_m = fda.Mesh(self.T)
        self.V_m = fd.FunctionSpace(self.mesh_m, element)
Beispiel #2
0
def setupMesh(meshFile, degree=2, meshOversample=None, savegmsh=False):
    """
    Read argus mesh file and return mesh alongw ith function spaces

    Parameters
    ----------
    meshFile : str
        argus meshfile name
    degree : int, optional
        degree of function spaces, by default 2

    Returns
    -------
    mesh
        firedrake mesh
    Q, V
        firedrake scalar and vectory functions
    """
    # Input the mesh
    maxOversample = 4  # Arbitrary could be increased
    mesh, opts = argusToFiredrakeMesh(meshFile, savegmsh=savegmsh)
    if meshOversample is not None:
        numLevels = meshOversample - 1
        if numLevels < 0 or numLevels > (maxOversample - 1):
            myerror(f'meshOverample={meshOversample} but  0 < '
                    'meshOversample < 4')
        mesh = firedrake.MeshHierarchy(mesh, numLevels)[numLevels]
    # Create scalar and vector function spaces
    Q = firedrake.FunctionSpace(mesh, family='CG', degree=degree)
    V = firedrake.VectorFunctionSpace(mesh, family='CG', degree=degree)
    return mesh, Q, V, opts
Beispiel #3
0
import firedrake as fd
import fireshape as fs
import fireshape.zoo as fsz
import ROL

n = 30
# mesh = fd.UnitSquareMesh(n, n)
mesh = fd.Mesh("UnitSquareCrossed.msh")
mesh = fd.MeshHierarchy(mesh, 1)[-1]

Q = fs.FeMultiGridControlSpace(mesh, refinements=3, order=2)
inner = fs.LaplaceInnerProduct(Q)
mesh_m = Q.mesh_m
V_m = fd.FunctionSpace(mesh_m, "CG", 1)
f_m = fd.Function(V_m)

(x, y) = fd.SpatialCoordinate(mesh_m)
f = (pow(x - 0.5, 2)) + pow(y - 0.5, 2) - 2.
out = fd.File("domain.pvd")
J = fsz.LevelsetFunctional(f, Q, cb=lambda: out.write(mesh_m.coordinates))

q = fs.ControlVector(Q, inner)

params_dict = {
    'General': {
        'Secant': {
            'Type': 'Limited-Memory BFGS',
            'Maximum Storage': 5
        }
    },
    'Step': {
Beispiel #4
0
import argparse
import firedrake
import icepack.plot

parser = argparse.ArgumentParser()
parser.add_argument('--input')
parser.add_argument('--level', type=int)
parser.add_argument('--output')

args = parser.parse_args()

Lx, Ly = 640e3, 80e3
ny = 20
nx = int(Lx / Ly) * ny
coarse_mesh = firedrake.RectangleMesh(nx, ny, Lx, Ly)
mesh_hierarchy = firedrake.MeshHierarchy(coarse_mesh, args.level)
mesh = mesh_hierarchy[args.level]

Q = firedrake.FunctionSpace(mesh, family='CG', degree=1)
V = firedrake.VectorFunctionSpace(mesh, family='CG', degree=1)

h = firedrake.Function(Q)
u = firedrake.Function(V)

input_name = os.path.splitext(args.input)[0]
with firedrake.DumbCheckpoint(input_name, mode=firedrake.FILE_READ) as chk:
    timesteps, indices = chk.get_timesteps()
    chk.set_timestep(timesteps[-1], idx=indices[-1])

    chk.load(h, name='h')
    chk.load(u, name='u')
Beispiel #5
0
base_level = args.base_level
nrefs = args.ref_level - base_level
name = args.filename
deg = args.coords_degree
distribution_parameters = {
    "partition": True,
    "overlap_type": (fd.DistributedMeshOverlapType.VERTEX, 2)
}

if args.tlblock == "mg":
    basemesh = fd.IcosahedralSphereMesh(
        radius=R0,
        refinement_level=base_level,
        degree=deg,
        distribution_parameters=distribution_parameters)
    mh = fd.MeshHierarchy(basemesh, nrefs)
    for mesh in mh:
        x = fd.SpatialCoordinate(mesh)
        mesh.init_cell_orientations(x)
    mesh = mh[-1]
else:
    mesh = fd.IcosahedralSphereMesh(
        radius=R0,
        refinement_level=args.ref_level,
        degree=deg,
        distribution_parameters=distribution_parameters)
    x = fd.SpatialCoordinate(mesh)
    mesh.init_cell_orientations(x)
R0 = fd.Constant(R0)
cx, cy, cz = fd.SpatialCoordinate(mesh)
Beispiel #6
0
def compliance():
    parser = argparse.ArgumentParser(description="Compliance problem with MMA")
    parser.add_argument(
        "--nref",
        action="store",
        dest="nref",
        type=int,
        help="Number of mesh refinements",
        default=2,
    )
    parser.add_argument(
        "--uniform",
        action="store",
        dest="uniform",
        type=int,
        help="Use uniform mesh",
        default=0,
    )
    parser.add_argument(
        "--inner_product",
        action="store",
        dest="inner_product",
        type=str,
        help="Inner product, euclidean or L2",
        default="L2",
    )
    parser.add_argument(
        "--output_dir",
        action="store",
        dest="output_dir",
        type=str,
        help="Directory for all the output",
        default="./",
    )
    args = parser.parse_args()
    nref = args.nref
    inner_product = args.inner_product
    output_dir = args.output_dir

    assert inner_product == "L2" or inner_product == "euclidean"

    mesh = fd.Mesh("./beam_uniform.msh")
    #mh = fd.MeshHierarchy(mesh, 2)
    #mesh = mh[-1]

    if nref > 0:
        mh = fd.MeshHierarchy(mesh, nref)
        mesh = mh[-1]
    elif nref < 0:
        raise RuntimeError("Non valid mesh argument")

    V = fd.VectorFunctionSpace(mesh, "CG", 1)
    u, v = fd.TrialFunction(V), fd.TestFunction(V)

    # Elasticity parameters
    E, nu = 1e0, 0.3
    mu, lmbda = fd.Constant(E / (2 * (1 + nu))), fd.Constant(
        E * nu / ((1 + nu) * (1 - 2 * nu))
    )

    # Helmholtz solver
    RHO = fd.FunctionSpace(mesh, "CG", 1)
    rho = fd.interpolate(fd.Constant(0.1), RHO)
    af, b = fd.TrialFunction(RHO), fd.TestFunction(RHO)

    #filter_radius = fd.Constant(0.2)
    #x, y = fd.SpatialCoordinate(mesh)
    #x_ = fd.interpolate(x, RHO)
    #y_ = fd.interpolate(y, RHO)
    #aH = filter_radius * inner(grad(af), grad(b)) * dx + af * b * dx
    #LH = rho * b * dx

    rhof = fd.Function(RHO)
    solver_params = {
        "ksp_type": "preonly",
        "pc_type": "lu",
        "pc_factor_mat_solver_type": "mumps",
        "mat_mumps_icntl_14": 200,
        "mat_mumps_icntl_24": 1,
    }
    #fd.solve(aH == LH, rhof, solver_parameters=solver_params)
    rhof.assign(rho)
    rhofControl = fda.Control(rhof)

    eps = fd.Constant(1e-5)
    p = fd.Constant(3.0)

    def simp(rho):
        return eps + (fd.Constant(1.0) - eps) * rho ** p

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

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

    DIRICHLET = 3
    NEUMANN = 4

    a = inner(simp(rhof) * sigma(u), epsilon(v)) * dx
    load = fd.Constant((0.0, -1.0))
    L = inner(load, v) * ds(NEUMANN)

    u_sol = fd.Function(V)

    bcs = fd.DirichletBC(V, fd.Constant((0.0, 0.0)), DIRICHLET)

    fd.solve(a == L, u_sol, bcs=bcs, solver_parameters=solver_params)
    c = fda.Control(rho)
    J = fd.assemble(fd.Constant(1e-4) * inner(u_sol, load) * ds(NEUMANN))
    Vol = fd.assemble(rhof * dx)
    VolControl = fda.Control(Vol)

    with fda.stop_annotating():
        Vlimit = fd.assemble(fd.Constant(1.0) * dx(domain=mesh)) * 0.5

    rho_viz_f = fd.Function(RHO, name="rho")
    plot_file = f"{output_dir}/design_{inner_product}.pvd"
    controls_f = fd.File(plot_file)

    def deriv_cb(j, dj, rho):
        with fda.stop_annotating():
            rho_viz_f.assign(rhofControl.tape_value())
            controls_f.write(rho_viz_f)

    Jhat = fda.ReducedFunctional(J, c, derivative_cb_post=deriv_cb)
    Volhat = fda.ReducedFunctional(Vol, c)

    class VolumeConstraint(fda.InequalityConstraint):
        def __init__(self, Vhat, Vlimit, VolControl):
            self.Vhat = Vhat
            self.Vlimit = float(Vlimit)
            self.VolControl = VolControl

        def function(self, m):
            # Compute the integral of the control over the domain
            integral = self.VolControl.tape_value()
            with fda.stop_annotating():
                value = -integral / self.Vlimit + 1.0
            return [value]

        def jacobian(self, m):
            with fda.stop_annotating():
                gradients = self.Vhat.derivative()
                with gradients.dat.vec as v:
                    v.scale(-1.0 / self.Vlimit)
            return [gradients]

        def output_workspace(self):
            return [0.0]

        def length(self):
            """Return the number of components in the constraint vector (here, one)."""
            return 1

    lb = 1e-5
    ub = 1.0
    problem = fda.MinimizationProblem(
        Jhat,
        bounds=(lb, ub),
        constraints=[VolumeConstraint(Volhat, Vlimit, VolControl)],
    )

    parameters_mma = {
        "move": 0.2,
        "maximum_iterations": 200,
        "m": 1,
        "IP": 0,
        "tol": 1e-6,
        "accepted_tol": 1e-4,
        "norm": inner_product,
        #"norm": "euclidean",
        "gcmma": False,
    }
    solver = MMASolver(problem, parameters=parameters_mma)

    rho_opt = solver.solve()

    with open(f"{output_dir}/finished_{inner_product}.txt", "w") as f:
        f.write("Done")
Beispiel #7
0
def compliance_optimization(n_iters=200):

    output_dir = "cantilever/"

    path = os.path.abspath(__file__)
    dir_path = os.path.dirname(path)
    m = fd.Mesh(f"{dir_path}/mesh_cantilever.msh")
    mesh = fd.MeshHierarchy(m, 0)[-1]

    # Perturb the mesh coordinates. Necessary to calculate shape derivatives
    S = fd.VectorFunctionSpace(mesh, "CG", 1)
    s = fd.Function(S, name="deform")
    mesh.coordinates.assign(mesh.coordinates + s)

    # Initial level set function
    x, y = fd.SpatialCoordinate(mesh)
    PHI = fd.FunctionSpace(mesh, "CG", 1)
    lx = 2.0
    ly = 1.0
    phi_expr = (
        -cos(6.0 / lx * pi * x) * cos(4.0 * pi * y)
        - 0.6
        + max_value(200.0 * (0.01 - x ** 2 - (y - ly / 2) ** 2), 0.0)
        + max_value(100.0 * (x + y - lx - ly + 0.1), 0.0)
        + max_value(100.0 * (x - y - lx + 0.1), 0.0)
    )
    # Avoid recording the operation interpolate into the tape.
    # Otherwise, the shape derivatives will not be correct
    with fda.stop_annotating():
        phi = fd.interpolate(phi_expr, PHI)
        phi.rename("LevelSet")
        fd.File(output_dir + "phi_initial.pvd").write(phi)

    # Physics. Elasticity
    rho_min = 1e-5
    beta = fd.Constant(200.0)

    def hs(phi, beta):
        return fd.Constant(1.0) / (
            fd.Constant(1.0) + exp(-beta * phi)
        ) + fd.Constant(rho_min)

    H1_elem = fd.VectorElement("CG", mesh.ufl_cell(), 1)
    W = fd.FunctionSpace(mesh, H1_elem)

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

    # Elasticity parameters
    E, nu = 1.0, 0.3
    mu, lmbda = fd.Constant(E / (2 * (1 + nu))), fd.Constant(
        E * nu / ((1 + nu) * (1 - 2 * nu))
    )

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

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

    a = inner(hs(-phi, beta) * sigma(u), nabla_grad(v)) * dx
    t = fd.Constant((0.0, -75.0))
    L = inner(t, v) * ds(2)

    bc = fd.DirichletBC(W, fd.Constant((0.0, 0.0)), 1)
    parameters = {
        "ksp_type": "preonly",
        "pc_type": "lu",
        "mat_type": "aij",
        "ksp_converged_reason": None,
        "pc_factor_mat_solver_type": "mumps",
    }
    u_sol = fd.Function(W)
    F = fd.action(a, u_sol) - L
    problem = fd.NonlinearVariationalProblem(F, u_sol, bcs=bc)
    solver = fd.NonlinearVariationalSolver(
        problem, solver_parameters=parameters
    )
    solver.solve()
    # fd.solve(
    #    a == L, u_sol, bcs=[bc], solver_parameters=parameters
    # )  # , nullspace=nullspace)
    with fda.stop_annotating():
        fd.File("u_sol.pvd").write(u_sol)

    # Cost function: Compliance
    J = fd.assemble(
        fd.Constant(1e-2)
        * inner(hs(-phi, beta) * sigma(u_sol), epsilon(u_sol))
        * dx
    )

    # Constraint: Volume
    with fda.stop_annotating():
        total_volume = fd.assemble(fd.Constant(1.0) * dx(domain=mesh))
    VolPen = fd.assemble(hs(-phi, beta) * dx)
    # Needed to track the value of the volume
    VolControl = fda.Control(VolPen)
    Vval = total_volume / 2.0

    phi_pvd = fd.File("phi_evolution.pvd", target_continuity=fd.H1)

    def deriv_cb(phi):
        with fda.stop_annotating():
            phi_pvd.write(phi[0])

    c = fda.Control(s)
    Jhat = LevelSetFunctional(J, c, phi, derivative_cb_pre=deriv_cb)
    Vhat = LevelSetFunctional(VolPen, c, phi)
    beta_param = 0.1
    # Boundary conditions for the shape derivatives.
    # They must be zero at the boundary conditions.
    bcs_vel = fd.DirichletBC(S, fd.Constant((0.0, 0.0)), (1, 2))
    # Regularize the shape derivatives
    reg_solver = RegularizationSolver(
        S,
        mesh,
        beta=beta_param,
        gamma=1.0e5,
        dx=dx,
        bcs=bcs_vel,
        output_dir=None,
    )
    # Hamilton-Jacobi equation to advect the level set
    dt = 0.05
    tol = 1e-5

    # Optimization problem
    vol_constraint = Constraint(Vhat, Vval, VolControl)
    problem = InfDimProblem(Jhat, reg_solver, ineqconstraints=vol_constraint)

    parameters = {
        "ksp_type": "preonly",
        "pc_type": "lu",
        "mat_type": "aij",
        "ksp_converged_reason": None,
        "pc_factor_mat_solver_type": "mumps",
    }

    params = {
        "alphaC": 3.0,
        "K": 0.1,
        "debug": 5,
        "alphaJ": 1.0,
        "dt": dt,
        "maxtrials": 10,
        "maxit": n_iters,
        "itnormalisation": 50,
        "tol": tol,
    }
    results = nlspace_solve(problem, params)

    return results
Beispiel #8
0
def main():
    mesh = fd.Mesh("./mesh_stokes.msh")
    mh = fd.MeshHierarchy(mesh, 1)
    mesh = mh[-1]
    # mesh = fd.Mesh("./mesh_stokes_inlets.msh")
    S = fd.VectorFunctionSpace(mesh, "CG", 1)
    s = fd.Function(S, name="deform")
    mesh.coordinates.assign(mesh.coordinates + s)

    x, y = fd.SpatialCoordinate(mesh)
    PHI = fd.FunctionSpace(mesh, "DG", 1)
    lx = 1.0
    # phi_expr = -0.5 * cos(3.0 / lx * pi * x + 1.0) * cos(3.0 * pi * y) - 0.3
    lx = 2.0
    phi_expr = -cos(6.0 / lx * pi * x + 1.0) * cos(4.0 * pi * y) - 0.6

    with stop_annotating():
        phi = fd.interpolate(phi_expr, PHI)
    phi.rename("LevelSet")

    nu = fd.Constant(1.0)
    V = fd.VectorFunctionSpace(mesh, "CG", 1)
    P = fd.FunctionSpace(mesh, "CG", 1)
    W = V * P
    w_sol = fd.Function(W)
    brinkmann_penalty = 1e6
    F = NavierStokesBrinkmannForm(W,
                                  w_sol,
                                  phi,
                                  nu,
                                  brinkmann_penalty=brinkmann_penalty)

    x, y = fd.SpatialCoordinate(mesh)
    u_inflow = 1.0
    y_inlet_1_1 = 0.2
    y_inlet_1_2 = 0.4
    inflow1 = fd.as_vector([
        u_inflow * 100 * (y - y_inlet_1_1) * (y - y_inlet_1_2),
        0.0,
    ])
    y_inlet_2_1 = 0.6
    y_inlet_2_2 = 0.8
    inflow2 = fd.as_vector([
        u_inflow * 100 * (y - y_inlet_2_1) * (y - y_inlet_2_2),
        0.0,
    ])

    noslip = fd.Constant((0.0, 0.0))
    bc1 = fd.DirichletBC(W.sub(0), noslip, 5)
    bc2 = fd.DirichletBC(W.sub(0), inflow1, (1))
    bc3 = fd.DirichletBC(W.sub(0), inflow2, (2))
    bcs = [bc1, bc2, bc3]

    problem = fd.NonlinearVariationalProblem(F, w_sol, bcs=bcs)
    solver_parameters = {
        "ksp_type": "preonly",
        "pc_type": "lu",
        "mat_type": "aij",
        "ksp_converged_reason": None,
        "pc_factor_mat_solver_type": "mumps",
    }
    # solver_parameters = {
    #    "ksp_type": "fgmres",
    #    "pc_type": "hypre",
    #    "pc_hypre_type": "euclid",
    #    "pc_hypre_euclid_level": 5,
    #    "mat_type": "aij",
    #    "ksp_converged_reason": None,
    #    "ksp_atol": 1e-3,
    #    "ksp_rtol": 1e-3,
    #    "snes_atol": 1e-3,
    #    "snes_rtol": 1e-3,
    # }
    solver = NavierStokesBrinkmannSolver(problem,
                                         solver_parameters=solver_parameters)
    solver.solve()
    pvd_file = fd.File("ns_solution.pvd")
    u, p = w_sol.split()
    pvd_file.write(u, p)

    u, p = fd.split(w_sol)

    Vol = fd.assemble(hs(-phi) * fd.Constant(1.0) * dx(0, domain=mesh))
    VControl = fda.Control(Vol)
    Vval = fd.assemble(fd.Constant(0.5) * dx(domain=mesh), annotate=False)
    with stop_annotating():
        print("Initial constraint function value {}".format(Vol))

    J = fd.assemble(
        fd.Constant(brinkmann_penalty) * hs(phi) * inner(u, u) * dx(0) +
        nu / fd.Constant(2.0) * inner(grad(u), grad(u)) * dx)

    c = fda.Control(s)

    phi_pvd = fd.File("phi_evolution_euclid.pvd", target_continuity=fd.H1)

    def deriv_cb(phi):
        with stop_annotating():
            phi_pvd.write(phi[0])

    Jhat = LevelSetFunctional(J, c, phi, derivative_cb_pre=deriv_cb)
    Vhat = LevelSetFunctional(Vol, c, phi)

    bcs_vel_1 = fd.DirichletBC(S, noslip, (1, 2, 3, 4))
    bcs_vel = [bcs_vel_1]
    reg_solver = RegularizationSolver(S,
                                      mesh,
                                      beta=0.5,
                                      gamma=1e5,
                                      dx=dx,
                                      bcs=bcs_vel,
                                      design_domain=0)

    tol = 1e-5
    dt = 0.0002
    params = {
        "alphaC": 1.0,
        "debug": 5,
        "alphaJ": 1.0,
        "dt": dt,
        "K": 0.1,
        "maxit": 2000,
        "maxtrials": 5,
        "itnormalisation": 10,
        "tol_merit": 1e-4,  # new merit can be within 5% of the previous merit
        # "normalize_tol" : -1,
        "tol": tol,
    }

    problem = InfDimProblem(
        Jhat,
        reg_solver,
        ineqconstraints=[Constraint(Vhat, Vval, VControl)],
    )
    _ = nullspace_shape(problem, params)
Beispiel #9
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)
Beispiel #10
0
def heat_exchanger_3D():
    parser = argparse.ArgumentParser(description="Level set method parameters")
    parser.add_argument(
        "--nu",
        action="store",
        dest="nu",
        type=float,
        help="Kinematic Viscosity",
        default=1.0,
    )
    parser.add_argument(
        "--brinkmann_penalty",
        action="store",
        dest="brinkmann_penalty",
        type=float,
        help="Brinkmann term",
        default=1e5,
    )
    parser.add_argument(
        "--refinement",
        action="store",
        dest="refinement",
        type=int,
        help="Level of refinement",
        default=0,
    )
    parser.add_argument(
        "--pressure_drop_constraint",
        action="store",
        dest="pressure_drop_constraint",
        type=float,
        help="Pressure drop constraint",
        default=10.0,
    )
    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 folder",
    )
    parser.add_argument(
        "--type",
        dest="type_he",
        type=str,
        action="store",
        default="parallel",
        help="Type of heat exchanger: parallel or counter",
    )
    opts = parser.parse_args()
    print(f"Parameters used: {opts}")

    beta_param = 0.4
    mesh = fd.Mesh("./box_heat_exch.msh")

    from parameters_box import (
        INLET2,
        INLET1,
        OUTLET1,
        OUTLET2,
        INMOUTH1,
        INMOUTH2,
        OUTMOUTH1,
        OUTMOUTH2,
    )

    if opts.type_he == "counter":
        INLET1, OUTLET1 = OUTLET1, INLET1
    elif opts.type_he == "u_flow":
        INLET2, OUTLET1 = OUTLET1, INLET2
        OUTMOUTH1, INMOUTH2 = INMOUTH2, OUTMOUTH1

    markers = {
        "WALLS": WALLS,
        "INLET1": INLET1,
        "INLET2": INLET2,
        "OUTLET1": OUTLET1,
        "OUTLET2": OUTLET2,
    }

    no_flow_domain_1 = [INMOUTH2, OUTMOUTH2]
    no_flow_domain_2 = [INMOUTH1, OUTMOUTH1]
    no_flow = no_flow_domain_1.copy()
    no_flow.extend(no_flow_domain_2)
    mesh = mark_no_flow_regions(mesh, no_flow, no_flow)

    mh = fd.MeshHierarchy(mesh, opts.refinement)
    mesh = mh[-1]

    pressure_drop_constraint = opts.pressure_drop_constraint
    pressure_drop_1 = pressure_drop_constraint
    pressure_drop_2 = pressure_drop_constraint

    S = fd.VectorFunctionSpace(mesh, "CG", 1)

    PHI = fd.FunctionSpace(mesh, "CG", 1)
    phi = fd.Function(PHI, name="LevelSet")
    x, y, z = fd.SpatialCoordinate(mesh)

    ω = 0.25
    phi_expr = sin(y * pi / ω) * cos(x * pi / ω) * sin(
        z * pi / ω) - fd.Constant(0.2)

    checkpoints = is_checkpoint(opts.output_dir)
    if checkpoints:
        current_iter = read_checkpoint(checkpoints, phi)
        with open(f"{opts.output_dir}/brinkmann_penalty.txt",
                  "r") as txt_brinkmann:
            brinkmann_penalty_initial = fd.Constant(txt_brinkmann.read())
        print(
            f"Current brinkmann term: {brinkmann_penalty_initial.values()[0]}")
    else:
        with stop_annotating():
            phi.interpolate(phi_expr)
        current_iter = 0
        brinkmann_penalty_initial = fd.Constant(opts.brinkmann_penalty)

    P2 = fd.VectorElement("CG", mesh.ufl_cell(), 1)
    P1 = fd.FiniteElement("CG", mesh.ufl_cell(), 1)
    TH = P2 * P1
    W = fd.FunctionSpace(mesh, TH)
    print(f"DOFS: {W.dim()}")

    T = fd.FunctionSpace(mesh, "CG", 1)

    global_counter = count(current_iter)

    def receive_signal(signum, stack):
        iter_current = next(copy(global_counter))
        print(f"Received: {signum}, iter: {iter_current}")
        with fd.HDF5File(
                f"{opts.output_dir}/checkpoint_iter_{iter_current}.h5",
                "w") as checkpoint:
            checkpoint.write(phi, "/checkpoint")
        with open(f"{opts.output_dir}/brinkmann_penalty.txt",
                  "w") as txt_brinkmann:
            txt_brinkmann.write(str(brinkmann_penalty.values()[0]))

    signal.signal(signal.SIGHUP, receive_signal)

    phi_pvd = fd.File(
        f"{opts.output_dir}/phi_evolution.pvd",
        target_degree=1,
        target_continuity=fd.H1,
        mode="a",
    )
    ns1 = fd.File(f"{opts.output_dir}/navier_stokes_1.pvd", mode="a")
    ns2 = fd.File(f"{opts.output_dir}/navier_stokes_2.pvd", mode="a")
    temperature = fd.File(f"{opts.output_dir}/temperature.pvd", mode="a")
    temperature_pvd = fd.Function(T)

    def termination_event_1():
        p1_constraint = P1control.tape_value() - 1
        p2_constraint = P2control.tape_value() - 1
        event_value = max(p1_constraint, p2_constraint)
        print(f"Value event: {event_value}")
        return event_value

    def termination_event_2():
        iter_current = next(copy(global_counter))
        print(f"Value event iter count: {iter_current}")
        return float(iter_current % 500)

    brinkmann_penalty_initial_value = brinkmann_penalty_initial.values()[0]
    if brinkmann_penalty_initial_value > opts.brinkmann_penalty:
        termination_events = [termination_event_2, termination_event_2]
        brinkmann_pen_terms = [
            brinkmann_penalty_initial,
            fd.Constant(brinkmann_penalty_initial_value * 10),
        ]
    else:
        termination_events = [termination_event_1, None]
        brinkmann_pen_terms = [
            brinkmann_penalty_initial,
            fd.Constant(brinkmann_penalty_initial_value * 5),
        ]

    for termination_event, brinkmann_penalty in zip(termination_events,
                                                    brinkmann_pen_terms):

        s = fd.Function(S, name="deform")
        mesh.coordinates.assign(mesh.coordinates + s)
        # w_sol1, w_sol2, t = forward(brinkmann_penalty)

        w_sol1, w_sol2, t = forward(
            W,
            T,
            phi,
            opts,
            brinkmann_penalty,
            no_flow_domain_1=no_flow_domain_1,
            no_flow_domain_2=no_flow_domain_2,
            markers=markers,
        )

        w_sol1_control = fda.Control(w_sol1)
        w_sol2_control = fda.Control(w_sol2)
        t_control = fda.Control(t)

        J = heat_flux(w_sol2, t, OUTLET2)
        J_hot = heat_flux(w_sol1, t, OUTLET1)
        Pdrop1 = pressure_drop(w_sol1, INLET1, OUTLET1, pressure_drop_1)
        Pdrop2 = pressure_drop(w_sol2, INLET2, OUTLET2, pressure_drop_2)
        print(f"Cold flux: {J}, hot flux: {J_hot}")

        c = fda.Control(s)
        J_hot_control = fda.Control(J_hot)

        def deriv_cb(phi):
            with stop_annotating():
                iter = next(global_counter)
                print(f"Hot flux: {J_hot_control.tape_value()}")
                if iter % 15 == 0:
                    u_sol1, p_sol1 = w_sol1_control.tape_value().split()
                    u_sol2, p_sol2 = w_sol2_control.tape_value().split()

                    u_sol1.rename("Velocity1")
                    p_sol1.rename("Pressure1")

                    u_sol2.rename("Velocity2")
                    p_sol2.rename("Pressure2")

                    ns1.write(u_sol1, p_sol1, time=iter)
                    ns2.write(u_sol2, p_sol2, time=iter)
                    phi_pvd.write(phi[0], time=iter)

                    temperature_pvd.assign(t_control.tape_value())
                    temperature_pvd.rename("temperature")
                    temperature.write(temperature_pvd, time=iter)

        # Reduced Functionals
        Jhat = LevelSetFunctional(J, c, phi, derivative_cb_pre=deriv_cb)
        P1hat = LevelSetFunctional(Pdrop1, c, phi)
        P1control = fda.Control(Pdrop1)

        P2hat = LevelSetFunctional(Pdrop2, c, phi)
        P2control = fda.Control(Pdrop2)
        print("Pressure drop 1 {:.5f}".format(Pdrop1))
        print("Pressure drop 2 {:.5f}".format(Pdrop2))

        reg_solver = RegularizationSolver(
            S,
            mesh,
            beta=beta_param,
            gamma=1e6,
            dx=dx,
            design_domain=DESIGN_DOMAIN,
            solver_parameters=regularization_solver_parameters,
        )

        tol = 1e-7
        dt = 0.02
        params = {
            "alphaC": 0.1,
            "debug": 5,
            "alphaJ": 0.1,
            "dt": dt,
            "K": 1e-3,
            "maxit": opts.n_iters,
            "maxtrials": 10,
            "itnormalisation": 10,
            "tol_merit":
            1e-2,  # new merit can be within 1% of the previous merit
            # "normalize_tol" : -1,
            "tol": tol,
        }

        hj_solver_parameters["ts_dt"] = dt / 50.0
        solver_parameters = {
            "hj_solver": hj_solver_parameters,
            "reinit_solver": reinit_solver_parameters,
        }

        problem = InfDimProblem(
            Jhat,
            reg_solver,
            ineqconstraints=[
                Constraint(P1hat, 1.0, P1control),
                Constraint(P2hat, 1.0, P2control),
            ],
            reinit_distance=0.08,
            solver_parameters=solver_parameters,
        )
        problem.set_termination_event(termination_event,
                                      termination_tolerance=1e-1)

        _ = nlspace_solve(problem, params)
        fda.get_working_tape().clear_tape()