示例#1
0
def make_mesh(R, δx):
    geometry = pygmsh.built_in.Geometry()
    x1 = geometry.add_point([-R, 0, 0], lcar=δx)
    x2 = geometry.add_point([+R, 0, 0], lcar=δx)
    center1 = geometry.add_point([0, 0, 0,], lcar=δx)
    arcs = [geometry.add_circle_arc(x1, center1, x2),
            geometry.add_circle_arc(x2, center1, x1)]
    line_loop = geometry.add_line_loop(arcs)
    plane_surface = geometry.add_plane_surface(line_loop)
    physical_lines = [geometry.add_physical(arc) for arc in arcs]
    physical_surface = geometry.add_physical(plane_surface)
    with open('shallow-ice.geo', 'w') as geo_file:
        geo_file.write(geometry.get_code())
    transform_file = "gmsh -v 0 -2 -format msh2 -o shallow-ice.msh shallow-ice.geo"
    os.system(transform_file)
    mesh = firedrake.Mesh('shallow-ice.msh')
    remove_geo = "rm shallow-ice.geo"
    remove_mesh = "rm shallow-ice.msh"
    os.system(remove_geo)
    os.system(remove_mesh)
    return mesh
示例#2
0
import firedrake
import thetis
from hrds import HRDS

mesh2d = firedrake.Mesh('test_mesh.msh')  # mesh file

P1_2d = firedrake.FunctionSpace(mesh2d, 'CG', 1)
bathymetry2d = firedrake.Function(P1_2d, name="bathymetry")
bvector = bathymetry2d.dat.data
bathy = HRDS("gebco_uk.tif",
             rasters=("emod_utm.tif", "inspire_data.tif"),
             distances=(700, 200))
bathy.set_bands()
for i, (xy) in enumerate(mesh2d.coordinates.dat.data):
    bvector[i] = bathy.get_val(xy)
thetis.File('bathy.pvd').write(bathymetry2d)
示例#3
0
            # "snes_monitor": None, "ksp_monitor": None,
        }

    def solve(self):
        super().solve()
        self.failed_to_solve = False
        u_old = self.solution.copy(deepcopy=True)
        try:
            fd.solve(self.F == 0,
                     self.solution,
                     bcs=self.bcs,
                     solver_parameters=self.params)
        except fd.ConvergenceError:
            self.failed_to_solve = True
            self.solution.assign(u_old)


if __name__ == "__main__":
    mesh = fd.Mesh("pipe.msh")
    if mesh.topological_dimension() == 2:  # in 2D
        viscosity = fd.Constant(1. / 400.)
    elif mesh.topological_dimension() == 3:  # in 3D
        viscosity = fd.Constant(1 / 10.)  # simpler problem in 3D
    else:
        raise NotImplementedError
    e = NavierStokesSolver(mesh, viscosity)
    e.solve()
    print(e.failed_to_solve)
    out = fd.File("temp_PDEConstrained_u.pvd")
    out.write(e.solution.split()[0])
示例#4
0
def generate_mesh2D(model, G, comm):

    print('Entering mesh generation', flush=True)
    M = grid_point_to_mesh_point_converter_for_seismicmesh(model, G)
    method = model["opts"]["method"]

    Lz = model["mesh"]['Lz']
    lz = model['BCs']['lz']
    Lx = model["mesh"]['Lx']
    lx = model['BCs']['lx']

    Real_Lz = Lz + lz
    Real_Lx = Lx + 2 * lx

    if model['testing_parameters']['experiment_type'] == 'homogeneous':
        minimum_mesh_velocity = model['testing_parameters'][
            'minimum_mesh_velocity']
        frequency = model["acquisition"]['frequency']
        lbda = minimum_mesh_velocity / frequency

        Real_Lz = Lz + lz
        Real_Lx = Lx + 2 * lx
        edge_length = lbda / M

        bbox = (-Real_Lz, 0.0, -lx, Real_Lx - lx)
        rec = SeismicMesh.Rectangle(bbox)

        if comm.comm.rank == 0:
            # Creating rectangular mesh
            points, cells = SeismicMesh.generate_mesh(domain=rec,
                                                      edge_length=edge_length,
                                                      mesh_improvement=False,
                                                      comm=comm.ensemble_comm,
                                                      verbose=0)
            print('entering spatial rank 0 after mesh generation')

            points, cells = SeismicMesh.geometry.delete_boundary_entities(
                points, cells, min_qual=0.6)
            a = np.amin(SeismicMesh.geometry.simp_qual(points, cells))

            meshio.write_points_cells("meshes/2Dhomogeneous" + str(G) + ".msh",
                                      points, [("triangle", cells)],
                                      file_format="gmsh22",
                                      binary=False)
            meshio.write_points_cells("meshes/2Dhomogeneous" + str(G) + ".vtk",
                                      points, [("triangle", cells)],
                                      file_format="vtk")

        comm.comm.barrier()
        if method == "CG" or method == "KMV":
            mesh = fire.Mesh(
                "meshes/2Dhomogeneous" + str(G) + ".msh",
                distribution_parameters={
                    "overlap_type": (fire.DistributedMeshOverlapType.NONE, 0)
                },
            )

    elif model['testing_parameters']['experiment_type'] == 'heterogeneous':
        # Name of SEG-Y file containg velocity model.
        fname = "vel_z6.25m_x12.5m_exact.segy"

        # Bounding box describing domain extents (corner coordinates)
        bbox = (-12000.0, 0.0, 0.0, 67000.0)

        rectangle = SeismicMesh.Rectangle(bbox)

        # Desired minimum mesh size in domain
        frequency = model["acquisition"]['frequency']
        hmin = 1429.0 / (M * frequency)

        # Construct mesh sizing object from velocity model
        ef = SeismicMesh.get_sizing_function_from_segy(
            fname,
            bbox,
            hmin=hmin,
            wl=M,
            freq=5.0,
            grade=0.15,
            domain_pad=model["BCs"]["lz"],
            pad_style="edge",
        )

        points, cells = SeismicMesh.generate_mesh(domain=rectangle,
                                                  edge_length=ef,
                                                  verbose=0,
                                                  mesh_improvement=False)

        meshio.write_points_cells("meshes/2Dheterogeneous" + str(G) + ".msh",
                                  points / 1000, [("triangle", cells)],
                                  file_format="gmsh22",
                                  binary=False)
        meshio.write_points_cells("meshes/2Dheterogeneous" + str(G) + ".vtk",
                                  points / 1000, [("triangle", cells)],
                                  file_format="vtk")

        comm.comm.barrier()
        if method == "CG" or method == "KMV":
            mesh = fire.Mesh(
                "meshes/2Dheterogeneous" + str(G) + ".msh",
                distribution_parameters={
                    "overlap_type": (fire.DistributedMeshOverlapType.NONE, 0)
                },
            )
    print('Finishing mesh generation', flush=True)
    return mesh
def test_dt():
    solver_parameters = copy.deepcopy(default_solver_parameters)

    class pde_solver(PDESystem):
        def __init__(self, comp, mesh, parameters):
            PDESystem.__init__(self, comp, mesh, parameters)

        def setup_bcs(self):
            x, y = fd.SpatialCoordinate(self.mesh)
            c0 = fd.exp(x * y * self.t)

            bcu = [
                fd.DirichletBC(self.V['u'], fd.Constant((0, 0)),
                               (10, 12)),  # top-bottom and cylinder
                fd.DirichletBC(self.V['u'],
                               ((1.0 * (y - 1) * (2 - y)) / (0.5**2), 0), 9)
            ]  # inflow
            bcp = [fd.DirichletBC(self.V['p'], fd.Constant(0), 11)]  # outflow
            bcc1 = [fd.DirichletBC(self.V['c'].sub(0), c0, 'on_boundary')]

            self.bc['u'][0] = [bcu, None, None, None, 'fixed']
            self.bc['p'] = [[bcp, None, None, None, 'fixed']]
            self.bc['c'][0] = [bcc1, c0, 'on_boundary', 0, 'update']

        def setup_constants(self):
            x, y = fd.SpatialCoordinate(self.mesh)

            self.constants = {
                'deltat': fd.Constant(self.prm['dt']),
                'Kd': fd.Constant(0.01),
                'k1': fd.Constant(0.005),
                'k2': fd.Constant(0.00005),
                'lamd1': fd.Constant(0.000005),
                'lamd2': fd.Constant(0.0),
                'rho_s': fd.Constant(1.),
                'L': fd.Constant(1.),
                'phi': fd.Constant(0.3),
                'n': fd.FacetNormal(self.mesh),
                'f': fd.Constant((0.0, 0.0)),
                'nu': fd.Constant(0.001),
                'frac': fd.Constant(1.),
            }

    solver_parameters = recursive_update(
        solver_parameters, {
            'space': {
                'u': fd.VectorFunctionSpace,
                'c': fd.MixedFunctionSpace,
                'd': fd.MixedFunctionSpace
            },
            'degree': {
                'u': 2
            },
            'order': {
                'c': 3,
                'd': 3
            },
            'ksp_type': {
                'u': 'gmres',
                'p': 'gmres',
                'c': 'gmres',
                'd': 'gmres'
            },
            'precond': {
                'u': 'sor',
                'p': 'sor',
                'c': 'sor',
                'd': 'gmres'
            },
            'dt': 0.01,
            'T': 0.1
        })

    #load mesh
    mesh = fd.Mesh("meshes/step1.msh")
    deltat = [0.01 / (2**i) for i in range(1)]

    # add subsystems for navier stokes and radio_transport
    solver = pde_solver([['u', 'p']], mesh, solver_parameters)
    # solver.add_subsystem(['cd', 'cs', 'as'], solver_parameters)
    solver.add_subsystem(['c', 'd'], solver_parameters)
    #setup constants
    solver.setup_constants()
    # define subsystems and variable sequence
    solver.define(['u', 'p', 'u'], 'up', navier_stokes)
    solver.define(['c', 'd'], 'cd', radio_transport_coupled_mms)
    # setup boundary conditions
    solver.setup_bcs()

    x, y, t = sy.symbols(('x', 'y', 't'))
    expr = sy.exp(x * y * t)
    solver.test_mms('c',
                    expr,
                    temporal=True,
                    f_dict={"exp": fd.exp},
                    dt_list=deltat,
                    plot=False,
                    index=0)
def test_rxn_demo():
    solver_parameters = copy.deepcopy(default_solver_parameters)

    class pde_solver(PDESystem):
        def __init__(self, comp, mesh, parameters):
            PDESystem.__init__(self, comp, mesh, parameters)

        def setup_bcs(self):
            x, y = fd.SpatialCoordinate(self.mesh)

            bcu = [
                fd.DirichletBC(self.V['u'], fd.Constant((0, 0)),
                               (1, 4)),  # top-bottom and cylinder
                fd.DirichletBC(self.V['u'],
                               ((4.0 * 1.5 * y * (0.41 - y) / 0.41**2), 0), 2)
            ]  # inflow
            bcp = [fd.DirichletBC(self.V['p'], fd.Constant(0), 3)]  # outflow

            self.bc['u'][0] = [bcu, None, None, None, 'fixed']
            self.bc['p'] = [[bcp, None, None, None, 'fixed']]

        def setup_constants(self):
            x, y = fd.SpatialCoordinate(self.mesh)
            self.constants = {
                'deltat':
                fd.Constant(self.prm['dt']),
                'n':
                fd.FacetNormal(self.mesh),
                'f':
                fd.Constant((0.0, 0.0)),
                'nu':
                fd.Constant(0.001),
                'eps':
                fd.Constant(0.01),
                'K':
                fd.Constant(10.0),
                'f_1':
                fd.conditional(
                    pow(x - 0.1, 2) + pow(y - 0.1, 2) < 0.05 * 0.05, 0.1, 0),
                'f_2':
                fd.conditional(
                    pow(x - 0.1, 2) + pow(y - 0.3, 2) < 0.05 * 0.05, 0.1, 0),
                'f_3':
                fd.Constant(0.0)
            }

    solver_parameters = recursive_update(
        solver_parameters, {
            'space': {
                'u': fd.VectorFunctionSpace,
                'c': fd.MixedFunctionSpace
            },
            'degree': {
                'u': 2
            },
            'order': {
                'c': 3
            },
            'ksp_type': {
                'u': 'gmres',
                'p': 'gmres',
                'c': 'gmres'
            },
            'precond': {
                'u': 'sor',
                'p': 'sor',
                'c': 'sor'
            },
            'dt': 0.0005,
            'T': 1.0
        })

    mesh = fd.Mesh("meshes/cylinder.msh")
    solver = pde_solver([['u', 'p']], mesh, solver_parameters)
    solver.add_subsystem('c', solver_parameters)
    solver.setup_constants()
    solver.define(['u', 'p', 'u'], 'up', navier_stokes)
    solver.define(['c'], 'c', reactions)
    solver.setup_bcs()

    solver_parameters = recursive_update(
        solver_parameters,
        {
            'space': {
                'u': fd.VectorFunctionSpace,
                'c1': fd.FunctionSpace,
                'c2': fd.FunctionSpace,
                'c3': fd.FunctionSpace
            },
            'degree': {
                'u': 2
            },
            'ksp_type': {
                'u': 'gmres',
                'p': 'gmres',
                'c1': 'gmres',
                'c2': 'gmres',
                'c3': 'gmres'
            },
            'subsystem_class': {
                'up': navier_stokes,
                'c1c2c3': reactions_uncoupled
            },  #also a new system is declared
            'precond': {
                'u': 'sor',
                'p': 'sor',
                'c1': 'sor',
                'c2': 'sor',
                'c3': 'sor'
            },
            'dt': 0.0005,
            'T': 1.0
        })
    # test uncoupled
    solver2 = pde_solver([['u', 'p']], mesh, solver_parameters)
    solver2.add_subsystem(['c1', 'c2', 'c3'], solver_parameters)
    solver2.setup_constants()
    solver2.define(['u', 'p', 'u'], 'up', navier_stokes)
    solver2.define(['c1', 'c2', 'c3'], 'c1c2c3', reactions_uncoupled)
    solver2.setup_bcs()
import os
import argparse

parser = argparse.ArgumentParser()
parser.add_argument("--base-inner",
                    type=str,
                    default="elasticity",
                    choices=["elasticity", "laplace"])
parser.add_argument("--alpha", type=float, default=None)
parser.add_argument("--clscale", type=float, default=0.1)
parser.add_argument("--maxiter", type=int, default=50)
parser.add_argument("--weighted", default=False, action="store_true")
parser.add_argument("--rstar", type=float, default=0.79)
args = parser.parse_args()

mesh = fd.Mesh("annulus.msh")
R = 1.0
r = 0.5
print("Harmonic map exists for r^*/R^* = %.2f" % ((0.5 * (R / r + r / R))**-1))
Rs = 1.0
rs = args.rstar

Q = fs.FeControlSpace(mesh)
d = distance_function(Q.get_space_for_inner()[0].mesh(), boundary_ids=[1, 2])
if args.weighted:
    mu_base = 0.01 / (0.01 + d)
else:
    mu_base = fd.Constant(1.)

# mu_base = fd.Constant(1.0)
if args.base_inner == "elasticity":
示例#8
0
文件: 3dex.py 项目: benSepanski/fd2mm
ambient_dim = 3
degree = 1

fine_order = 4 * degree
# Parameter to tune accuracy of pytential
fmm_order = 5
# This should be (order of convergence = qbx_order + 1)
qbx_order = degree

qbx_kwargs = {'fine_order': fine_order,
              'fmm_order': fmm_order,
              'qbx_order': qbx_order}
with_refinement = True

# Let's compute some layer potentials!
m = fd.Mesh("meshes/ball.msh")
V = fd.FunctionSpace(m, 'DG', degree)
Vdim = fd.VectorFunctionSpace(m, 'DG', degree)

mesh_analog = fd2mm.MeshAnalog(m)
fspace_analog = fd2mm.FunctionSpaceAnalog(cl_ctx, mesh_analog, V)

x, y, z = fd.SpatialCoordinate(m)
r"""
..math:

    \f{1}{4\pi \sqrt{(x-2)^2 + (y-2)^2 + (z-2)^2)}}

i.e. a shift of the fundamental solution
"""
expr = fd.Constant(1 / 4 / fd.pi) * 1 / fd.sqrt(
示例#9
0
def test_spectral_constraint(pytestconfig):
    n = 5
    mesh = fd.UnitSquareMesh(n, n)
    T = fd.Function(fd.VectorFunctionSpace(
        mesh, "CG",
        1)).interpolate(fd.SpatialCoordinate(mesh) - fd.Constant((0.5, 0.5)))
    mesh = fd.Mesh(T)
    Q = fs.FeControlSpace(mesh)
    inner = fs.LaplaceInnerProduct(Q)
    mesh_m = Q.mesh_m
    q = fs.ControlVector(Q, inner)
    if pytestconfig.getoption("verbose"):
        out = fd.File("domain.pvd")

        def cb():
            out.write(mesh_m.coordinates)
    else:

        def cb():
            pass

    J = fsz.MoYoSpectralConstraint(0.5, fd.Constant(0.1), Q, cb=cb)
    q.fun += Q.T
    g = q.clone()
    J.update(q, None, -1)
    J.gradient(g, q, None)
    cb()
    taylor_result = J.checkGradient(q, g, 7, 1)

    for i in range(len(taylor_result) - 1):
        assert taylor_result[i + 1][3] <= taylor_result[i][3] * 0.11

    params_dict = {
        'General': {
            'Secant': {
                'Type': 'Limited-Memory BFGS',
                'Maximum Storage': 2
            }
        },
        'Step': {
            'Type': 'Line Search',
            'Line Search': {
                'Descent Method': {
                    'Type': 'Quasi-Newton Step'
                }
            }
        },
        'Status Test': {
            'Gradient Tolerance': 1e-10,
            'Step Tolerance': 1e-10,
            'Iteration Limit': 150
        }
    }

    params = ROL.ParameterList(params_dict, "Parameters")
    problem = ROL.OptimizationProblem(J, q)
    solver = ROL.OptimizationSolver(problem, params)
    solver.solve()
    Tvec = Q.T.vector()[:, :]
    for i in range(Tvec.shape[0]):
        assert abs(Tvec[i, 0]) < 0.55 + 1e-4
        assert abs(Tvec[i, 1]) < 0.55 + 1e-4
    assert np.any(np.abs(Tvec) > 0.55 - 1e-4)
示例#10
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)
示例#11
0
import numpy as np
from mpl_toolkits.axes_grid1 import make_axes_locatable
import firedrake
from firedrake import sqrt, inner
import icepack.plot


def colorbar(figure, axes, mappable, *args, **kwargs):
    divider = make_axes_locatable(axes)
    cax = divider.append_axes('right', size='5%', pad=0.05)
    return figure.colorbar(mappable, *args, cax=cax, **kwargs)


mesh = firedrake.Mesh('ice-shelf.msh')
Q = firedrake.FunctionSpace(mesh, family='CG', degree=2)
V = firedrake.VectorFunctionSpace(mesh, family='CG', degree=2)
Δ = firedrake.FunctionSpace(mesh, family='DG', degree=1)

filename = 'steady-state-undamaged'
with firedrake.DumbCheckpoint(filename, mode=firedrake.FILE_READ) as chk:
    h_undamaged = firedrake.Function(Q)
    u_undamaged = firedrake.Function(V)
    chk.load(h_undamaged, name='h')
    chk.load(u_undamaged, name='u')

filename = 'steady-state-damaged'
with firedrake.DumbCheckpoint(filename, mode=firedrake.FILE_READ) as chk:
    h_damaged = firedrake.Function(Q)
    u_damaged = firedrake.Function(V)
    D = firedrake.Function(Δ)
    chk.load(h_damaged, name='h')
示例#12
0
queue = cl.CommandQueue(cl_ctx)

import pytest

# This has been my convention since both firedrake and pytential
# have some similar names. This makes defining bilinear forms really
# unpleasant.
import firedrake as fd
from sumpy.kernel import LaplaceKernel
from pytential import sym

# The user should only need to interact with firedrake_to_pytential.op
import fd2mm

cwd = abspath(dirname(__file__))
mesh2d = fd.Mesh(join(cwd, 'meshes', 'circle.msh'))
mesh3d = fd.Mesh(join(cwd, 'meshes', 'ball.msh'))


@pytest.mark.parametrize('family', ['DG', 'CG'])
@pytest.mark.parametrize('degree', [1, 3])
@pytest.mark.parametrize('ambient_dim', [2, 3])
def test_greens_formula(degree, family, ambient_dim):

    fine_order = 4 * degree
    # Parameter to tune accuracy of pytential
    fmm_order = 5
    # This should be (order of convergence = qbx_order + 1)
    qbx_order = degree
    with_refinement = True
示例#13
0
import fireshape.zoo as fsz
from cr_inner_product import CauchyRiemannAugmentation, distance_function
import ROL
import numpy as np
import os
import argparse

parser = argparse.ArgumentParser()
parser.add_argument("--use_cr", type=int, default=0)
parser.add_argument("--base_inner", type=str, default="elasticity")
args = parser.parse_args()

use_cr = bool(args.use_cr)
base_inner = args.base_inner

mesh = fd.Mesh("Sphere2D.msh")
Q = fs.FeControlSpace(mesh)
d = distance_function(Q.get_space_for_inner()[0].mesh(), eps=fd.Constant(0.1))
mu_base = 0.01 / (0.01 + d)

if base_inner == "elasticity":
    inner = fs.ElasticityInnerProduct(Q,
                                      fixed_bids=[1, 2, 3],
                                      mu=mu_base,
                                      direct_solve=True)
elif base_inner == "laplace":
    inner = fs.LaplaceInnerProduct(Q,
                                   fixed_bids=[1, 2, 3],
                                   mu=mu_base,
                                   direct_solve=True)
else:
示例#14
0
    def __init__(self,
                 mesh,
                 bbox,
                 orders,
                 levels,
                 fixed_dims=[],
                 boundary_regularities=None):
        """
        bbox: a list of tuples describing [(xmin, xmax), (ymin, ymax), ...]
              of a Cartesian grid that extends around the shape to be
              optimised
        orders: describe the orders (one integer per geometric dimension)
                of the tensor-product B-spline basis. A univariate B-spline
                has order "o" if it is a piecewise polynomial of degree
                "o-1". For instance, a hat function is a B-spline of
                order 2 and thus degree 1.
        levels: describe the subdivision levels (one integers per
                geometric dimension) used to construct the knots of
                univariate B-splines
        fixed_dims: dimensions in which the deformation should be zero

        boundary_regularities: how fast the splines go to zero on the boundary
                               for each dimension
                               [0,..,0] : they don't go to zero
                               [1,..,1] : they go to zero with C^0 regularity
                               [2,..,2] : they go to zero with C^1 regularity
        """
        self.boundary_regularities = [o - 1 for o in orders] \
            if boundary_regularities is None else boundary_regularities
        # information on B-splines
        self.dim = len(bbox)  # geometric dimension
        self.bbox = bbox
        self.orders = orders
        self.levels = levels
        if isinstance(fixed_dims, int):
            fixed_dims = [fixed_dims]
        self.fixed_dims = fixed_dims
        self.construct_knots()
        self.comm = mesh.mpi_comm()
        # create temporary self.mesh_r and self.V_r to assemble innerproduct
        if self.dim == 2:
            nx = len(self.knots[0]) - 1
            ny = len(self.knots[1]) - 1
            Lx = self.bbox[0][1] - self.bbox[0][0]
            Ly = self.bbox[1][1] - self.bbox[1][0]
            meshloc = fd.RectangleMesh(nx,
                                       ny,
                                       Lx,
                                       Ly,
                                       quadrilateral=True,
                                       comm=self.comm)  # quads or triangle?
            # shift in x- and y-direction
            meshloc.coordinates.dat.data[:, 0] += self.bbox[0][0]
            meshloc.coordinates.dat.data[:, 1] += self.bbox[1][0]
            # inner_product.fixed_bids = [1,2,3,4]

        elif self.dim == 3:
            # maybe use extruded meshes, quadrilateral not available
            nx = len(self.knots[0]) - 1
            ny = len(self.knots[1]) - 1
            nz = len(self.knots[2]) - 1
            Lx = self.bbox[0][1] - self.bbox[0][0]
            Ly = self.bbox[1][1] - self.bbox[1][0]
            Lz = self.bbox[2][1] - self.bbox[2][0]
            meshloc = fd.BoxMesh(nx, ny, nz, Lx, Ly, Lz, comm=self.comm)
            # shift in x-, y-, and z-direction
            meshloc.coordinates.dat.data[:, 0] += self.bbox[0][0]
            meshloc.coordinates.dat.data[:, 1] += self.bbox[1][0]
            meshloc.coordinates.dat.data[:, 2] += self.bbox[2][0]
            # inner_product.fixed_bids = [1,2,3,4,5,6]

        self.mesh_r = meshloc
        maxdegree = max(self.orders) - 1
        # self.V_r =
        # self.inner_product = inner_product
        # self.inner_product.get_impl(self.V_r, self.FullIFW)

        # is this the proper space?
        self.V_control = fd.VectorFunctionSpace(self.mesh_r, "CG", maxdegree)
        self.I_control = self.build_interpolation_matrix(self.V_control)

        # standard construction of ControlSpace
        self.mesh_r = mesh
        element = fd.VectorElement("CG", mesh.ufl_cell(), maxdegree)
        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 = fd.Mesh(self.T)
        self.V_m = fd.FunctionSpace(self.mesh_m, element)

        assert self.dim == self.mesh_r.geometric_dimension()

        # assemble correct interpolation matrix
        self.FullIFW = self.build_interpolation_matrix(self.V_r)
示例#15
0
def MeshHierarchy(mesh,
                  refinement_levels,
                  refinements_per_level=1,
                  reorder=None,
                  distribution_parameters=None,
                  callbacks=None):
    """Build a hierarchy of meshes by uniformly refining a coarse mesh.

    :arg mesh: the coarse :func:`~.Mesh` to refine
    :arg refinement_levels: the number of levels of refinement
    :arg refinements_per_level: the number of refinements for each
        level in the hierarchy.
    :arg distribution_parameters: options controlling mesh
        distribution, see :func:`~.Mesh` for details.  If ``None``,
        use the same distribution parameters as were used to
        distribute the coarse mesh, otherwise, these options override
        the default.
    :arg reorder: optional flag indicating whether to reorder the
         refined meshes.
    :arg callbacks: A 2-tuple of callbacks to call before and
        after refinement of the DM.  The before callback receives
        the DM to be refined (and the current level), the after
        callback receives the refined DM (and the current level).
    """
    cdm = mesh._plex
    cdm.setRefinementUniform(True)
    dms = []
    if mesh.comm.size > 1 and mesh._grown_halos:
        raise RuntimeError(
            "Cannot refine parallel overlapped meshes "
            "(make sure the MeshHierarchy is built immediately after the Mesh)"
        )
    parameters = {}
    if distribution_parameters is not None:
        parameters.update(distribution_parameters)
    else:
        parameters.update(mesh._distribution_parameters)

    parameters["partition"] = False
    distribution_parameters = parameters

    if callbacks is not None:
        before, after = callbacks
    else:
        before = after = lambda dm, i: None

    for i in range(refinement_levels * refinements_per_level):
        if i % refinements_per_level == 0:
            before(cdm, i)
        rdm = cdm.refine()
        if i % refinements_per_level == 0:
            after(rdm, i)
        # Remove interior facet label (re-construct from
        # complement of exterior facets).  Necessary because the
        # refinement just marks points "underneath" the refined
        # facet with the appropriate label.  This works for
        # exterior, but not marked interior facets
        rdm.removeLabel("interior_facets")
        # Remove vertex (and edge) points from labels on exterior
        # facets.  Interior facets will be relabeled in Mesh
        # construction below.
        impl.filter_exterior_facet_labels(rdm)
        rdm.removeLabel("pyop2_core")
        rdm.removeLabel("pyop2_owned")
        rdm.removeLabel("pyop2_ghost")

        dms.append(rdm)
        cdm = rdm
        # Fix up coords if refining embedded circle or sphere
        if hasattr(mesh, '_radius'):
            # FIXME, really we need some CAD-like representation
            # of the boundary we're trying to conform to.  This
            # doesn't DTRT really for cubed sphere meshes (the
            # refined meshes are no longer gnonomic).
            coords = cdm.getCoordinatesLocal().array.reshape(
                -1, mesh.geometric_dimension())
            scale = mesh._radius / np.linalg.norm(coords, axis=1).reshape(
                -1, 1)
            coords *= scale

    meshes = [mesh] + [
        firedrake.Mesh(dm,
                       dim=mesh.ufl_cell().geometric_dimension(),
                       distribution_parameters=distribution_parameters,
                       reorder=reorder) for dm in dms
    ]

    lgmaps = []
    for i, m in enumerate(meshes):
        no = impl.create_lgmap(m._plex)
        m.init()
        o = impl.create_lgmap(m._plex)
        m._plex.setRefineLevel(i)
        lgmaps.append((no, o))

    coarse_to_fine_cells = []
    fine_to_coarse_cells = [None]
    for (coarse, fine), (clgmaps, flgmaps) in zip(zip(meshes[:-1], meshes[1:]),
                                                  zip(lgmaps[:-1],
                                                      lgmaps[1:])):
        c2f, f2c = impl.coarse_to_fine_cells(coarse, fine, clgmaps, flgmaps)
        coarse_to_fine_cells.append(c2f)
        fine_to_coarse_cells.append(f2c)

    coarse_to_fine_cells = dict((Fraction(i, refinements_per_level), c2f)
                                for i, c2f in enumerate(coarse_to_fine_cells))
    fine_to_coarse_cells = dict((Fraction(i, refinements_per_level), f2c)
                                for i, f2c in enumerate(fine_to_coarse_cells))
    return HierarchyBase(meshes,
                         coarse_to_fine_cells,
                         fine_to_coarse_cells,
                         refinements_per_level,
                         nested=True)
示例#16
0
                                              verbose=0)

    points, cells = SeismicMesh.geometry.delete_boundary_entities(points,
                                                                  cells,
                                                                  min_qual=0.6)

    meshio.write_points_cells("meshes/benchmark_2d.msh",
                              points, [("triangle", cells)],
                              file_format="gmsh22",
                              binary=False)

## Mesh generation finishes here.

mesh = fire.Mesh(
    "meshes/benchmark_2d.msh",
    distribution_parameters={
        "overlap_type": (fire.DistributedMeshOverlapType.NONE, 0)
    },
)

method = model["opts"]["method"]
degree = model["opts"]["degree"]

if comm.ensemble_comm.rank == 0 and comm.comm.rank == 0:
    print(f"Setting up {method} a {degree}tetra element", flush=True)

element = fire.FiniteElement(method,
                             mesh.ufl_cell(),
                             degree=degree,
                             variant="KMV")

V = fire.FunctionSpace(mesh, element)
示例#17
0
def mesh_for_sensors(dim, n):
    mesh = uniform_mesh(dim, n, l=2)
    coords = firedrake.Function(mesh.coordinates)
    coords -= 1.0
    return firedrake.Mesh(coords)
# boundary conditions
c0 = 0.0  # boundary concentration

# problem parameters
verbose = False
Dm = 1.0  # diffusion (m²/s)
c = (25, 25)

# %%
# Process section (simulation)
# -----------------------------

# 2) Define mesh
print('* define mesh')
if from_file:
    mesh = fd.Mesh("nguyen.msh")
    mesh.init()
else:
    mesh = fd.SquareMesh(n, n, L, quadrilateral=quad_mesh, diagonal="right")

x, y = fd.SpatialCoordinate(mesh)
if verbose:
    fd.triplot(mesh)
    plt.legend()
    plt.savefig("plots/cd_hdg_mesh.png")

# 3) Setting problem (FunctionSpace, Init.Bound.Condition, VariationalForms)

# 3.1) Set Function spaces
if quad_mesh:
    DG1 = fd.FunctionSpace(mesh, "DQ", order)
示例#19
0
degree = 1

fine_order = 4 * degree
# Parameter to tune accuracy of pytential
fmm_order = 10
# This should be (order of convergence = qbx_order + 1)
qbx_order = degree

qbx_kwargs = {'fine_order': fine_order,
              'fmm_order': fmm_order,
              'qbx_order': qbx_order}
with_refinement = True

# Let's compute some layer potentials!
m = fd.Mesh('meshes/circle.msh')
V = fd.FunctionSpace(m, 'DG', degree)
Vdim = fd.VectorFunctionSpace(m, 'DG', degree)

mesh_analog = fd2mm.MeshAnalog(m)
fspace_analog = fd2mm.FunctionSpaceAnalog(cl_ctx, mesh_analog, V)

xx = fd.SpatialCoordinate(m)
r"""
..math:

    \ln(\sqrt{(x+1)^2 + (y+1)^2})

i.e. a shift of the fundamental solution
"""
expr = fd.ln(fd.sqrt((xx[0] + 2)**2 + (xx[1] + 2)**2))
示例#20
0
def test_objective_plus_box_constraint(pytestconfig):

    n = 10
    mesh = fd.UnitSquareMesh(n, n)
    T = mesh.coordinates.copy(deepcopy=True)
    (x, y) = fd.SpatialCoordinate(mesh)
    T.interpolate(T + fd.Constant((0, 0)))
    mesh = fd.Mesh(T)

    Q = fs.FeControlSpace(mesh)
    inner = fs.LaplaceInnerProduct(Q)
    mesh_m = Q.mesh_m
    q = fs.ControlVector(Q, inner)
    if pytestconfig.getoption("verbose"):
        out = fd.File("domain.pvd")

        def cb():
            out.write(mesh_m.coordinates)
    else:

        def cb():
            pass

    lower_bound = Q.T.copy(deepcopy=True)
    lower_bound.interpolate(fd.Constant((-0.2, -0.2)))
    upper_bound = Q.T.copy(deepcopy=True)
    upper_bound.interpolate(fd.Constant((+1.2, +1.2)))

    # levelset test case
    (x, y) = fd.SpatialCoordinate(Q.mesh_m)
    f = (pow(x - 0.5, 2)) + pow(y - 0.5, 2) - 4.
    J1 = fsz.LevelsetFunctional(f, Q, cb=cb, quadrature_degree=10)
    J2 = fsz.MoYoBoxConstraint(10., [1, 2, 3, 4],
                               Q,
                               lower_bound=lower_bound,
                               upper_bound=upper_bound,
                               cb=cb,
                               quadrature_degree=10)
    J3 = fsz.MoYoSpectralConstraint(100,
                                    fd.Constant(0.6),
                                    Q,
                                    cb=cb,
                                    quadrature_degree=100)

    J = 0.1 * J1 + J2 + J3
    g = q.clone()
    J.gradient(g, q, None)
    taylor_result = J.checkGradient(q, g, 9, 1)

    for i in range(len(taylor_result) - 1):
        if taylor_result[i][3] > 1e-6 and taylor_result[i][3] < 1e-3:
            assert taylor_result[i + 1][3] <= taylor_result[i][3] * 0.15

    params_dict = {
        'Step': {
            'Type': 'Line Search',
            'Line Search': {
                'Descent Method': {
                    'Type': 'Quasi-Newton Step'
                }
            }
        },
        'General': {
            'Secant': {
                'Type': 'Limited-Memory BFGS',
                'Maximum Storage': 2
            }
        },
        'Status Test': {
            'Gradient Tolerance': 1e-10,
            'Step Tolerance': 1e-10,
            'Iteration Limit': 10
        }
    }

    params = ROL.ParameterList(params_dict, "Parameters")
    problem = ROL.OptimizationProblem(J, q)
    solver = ROL.OptimizationSolver(problem, params)
    solver.solve()
    Tvec = Q.T.vector()
    nodes = fd.DirichletBC(Q.V_r, fd.Constant((0.0, 0.0)), [2]).nodes
    assert np.all(Tvec[nodes, 0] <= 1.2 + 1e-1)
    assert np.all(Tvec[nodes, 1] <= 1.2 + 1e-1)
示例#21
0
def BaryMeshHierarchy(mesh, refinement_levels, distribution_parameters=None, callbacks=None, reorder=None,
                      refinements_per_level=1):
    cdm = mesh._topology_dm
    cdm.setRefinementUniform(True)
    dms = []
    if mesh.comm.size > 1 and mesh._grown_halos:
        raise RuntimeError("Cannot refine parallel overlapped meshes "
                           "(make sure the MeshHierarchy is built immediately after the Mesh)")
    parameters = {}
    if distribution_parameters is not None:
        parameters.update(distribution_parameters)
    else:
        parameters.update(mesh._distribution_parameters)

    parameters["partition"] = False
    distribution_parameters = parameters

    if callbacks is not None:
        before, after = callbacks
    else:
        before = after = lambda dm, i: None

    for i in range(refinement_levels*refinements_per_level):
        if i % refinements_per_level == 0:
            before(cdm, i)
        rdm = cdm.refine()
        if i % refinements_per_level == 0:
            after(rdm, i)
        # Remove interior facet label (re-construct from
        # complement of exterior facets).  Necessary because the
        # refinement just marks points "underneath" the refined
        # facet with the appropriate label.  This works for
        # exterior, but not marked interior facets
        rdm.removeLabel("interior_facets")
        # Remove vertex (and edge) points from labels on exterior
        # facets.  Interior facets will be relabeled in Mesh
        # construction below.
        impl.filter_labels(rdm, rdm.getHeightStratum(1),
                           "exterior_facets", "boundary_faces",
                           FACE_SETS_LABEL)

        rdm.removeLabel("pyop2_core")
        rdm.removeLabel("pyop2_owned")
        rdm.removeLabel("pyop2_ghost")

        dms.append(rdm)
        cdm = rdm
        # Fix up coords if refining embedded circle or sphere
        if hasattr(mesh, '_radius'):
            # FIXME, really we need some CAD-like representation
            # of the boundary we're trying to conform to.  This
            # doesn't DTRT really for cubed sphere meshes (the
            # refined meshes are no longer gnonomic).
            coords = cdm.getCoordinatesLocal().array.reshape(-1, mesh.geometric_dimension())
            scale = mesh._radius / np.linalg.norm(coords, axis=1).reshape(-1, 1)
            coords *= scale

    barydms = (bary(mesh._topology_dm), ) + tuple(bary(dm) for dm in dms)

    for bdm in barydms:
        impl.filter_labels(bdm, bdm.getHeightStratum(1),
                           "exterior_facets", "boundary_faces",
                           FACE_SETS_LABEL)

    barymeshes = [firedrake.Mesh(dm, dim=mesh.ufl_cell().geometric_dimension(),
                                 distribution_parameters=distribution_parameters,
                                 reorder=reorder)
                           for dm in barydms]

    meshes = [mesh] + [firedrake.Mesh(dm, dim=mesh.ufl_cell().geometric_dimension(),
                                      distribution_parameters=distribution_parameters,
                                      reorder=reorder)
                       for dm in dms]

    lgmaps = []
    for i, m in enumerate(meshes):
        no = impl.create_lgmap(m._topology_dm)
        m.init()
        o = impl.create_lgmap(m._topology_dm)
        m._topology_dm.setRefineLevel(i)
        lgmaps.append((no, o))

    coarse_to_fine_cells = []
    fine_to_coarse_cells = [None]
    for (coarse, fine), (clgmaps, flgmaps) in zip(zip(meshes[:-1], meshes[1:]),
                                                  zip(lgmaps[:-1], lgmaps[1:])):
        c2f, f2c = impl.coarse_to_fine_cells(coarse, fine, clgmaps, flgmaps)
        coarse_to_fine_cells.append(c2f)
        fine_to_coarse_cells.append(f2c)

    lgmaps = []
    for i, m in enumerate(barymeshes):
        no = impl.create_lgmap(m._topology_dm)
        m.init()
        o = impl.create_lgmap(m._topology_dm)
        m._topology_dm.setRefineLevel(i)
        lgmaps.append((no, o))

    d = mesh.topological_dimension()
    bary_coarse_to_fine_cells = []
    bary_fine_to_coarse_cells = [None]
    for (coarseu, fineu), (coarse, fine), (clgmaps, flgmaps), uniform_coarse_to_fine \
        in zip(zip(meshes[:-1], meshes[1:]),
               zip(barymeshes[:-1], barymeshes[1:]),
               zip(lgmaps[:-1], lgmaps[1:]),
               coarse_to_fine_cells):

        cdm = coarseu._topology_dm
        fdm = fineu._topology_dm
        _, cn2o = impl.get_entity_renumbering(cdm, coarseu._cell_numbering, "cell")
        _, fn2o = impl.get_entity_renumbering(fdm, fineu._cell_numbering, "cell")
        plex_uniform_coarse_to_fine = numpy.empty_like(uniform_coarse_to_fine)
        for i, cells in enumerate(uniform_coarse_to_fine):
            plexcells = fn2o[cells]
            plex_uniform_coarse_to_fine[cn2o[i], :] = plexcells

        ncoarse, nfine = plex_uniform_coarse_to_fine.shape
        plex_coarse_bary_to_fine_bary = numpy.full((ncoarse*(d+1),
                                                    nfine*(d+1)), -1, dtype=PETSc.IntType)

        for c in range(ncoarse*(d+1)):
            uniform = c // (d+1)
            fine_cells = plex_uniform_coarse_to_fine[uniform]
            bary_cells = []
            for fc in fine_cells:
                bary_cells.extend(list(range(fc*(d+1), (fc+1)*(d+1))))
            plex_coarse_bary_to_fine_bary[c] = bary_cells

        cdm = coarse._topology_dm
        fdm = fine._topology_dm

        co2n, _ = impl.get_entity_renumbering(cdm, coarse._cell_numbering, "cell")
        fo2n, _ = impl.get_entity_renumbering(fdm, fine._cell_numbering, "cell")

        coarse_bary_to_fine_bary = numpy.empty_like(plex_coarse_bary_to_fine_bary)
        # Translate plex numbering to firedrake numbering
        for i, plex_cells in enumerate(plex_coarse_bary_to_fine_bary):
            coarse_bary_to_fine_bary[co2n[i]] = fo2n[plex_cells]

        bary_coarse_to_fine_cells.append(coarse_bary_to_fine_bary)

        # Not fast but seems to work
        fine_bary_to_coarse_bary = [[]]
        for i in range(numpy.max(coarse_bary_to_fine_bary)):
            fine_bary_to_coarse_bary.append([])
        for coarse in range(coarse_bary_to_fine_bary.shape[0]):
            for ifine in range(coarse_bary_to_fine_bary.shape[1]):
                # the coarse cell `coarse` is contained in the fine cell
                # `bary_coarse_to_fine_cells[0][coarse, ifine]` so we
                # should add it to the corresponding list
                fine_bary_to_coarse_bary[coarse_bary_to_fine_bary[coarse, ifine]].append(coarse)
        fine_bary_to_coarse_bary = numpy.asarray(fine_bary_to_coarse_bary, dtype=PETSc.IntType)

        bary_fine_to_coarse_cells.append(fine_bary_to_coarse_bary)

    #print(bary_coarse_to_fine_cells)
    #print(bary_fine_to_coarse_cells)

    coarse_to_fine_cells = dict((Fraction(i, refinements_per_level), c2f)
                                for i, c2f in enumerate(bary_coarse_to_fine_cells))
    fine_to_coarse_cells = dict((Fraction(i, refinements_per_level), f2c)
                                for i, f2c in enumerate(bary_fine_to_coarse_cells))
    return HierarchyBase(barymeshes, coarse_to_fine_cells, fine_to_coarse_cells,
                         refinements_per_level, nested=False)
示例#22
0
def test_box_constraint(pytestconfig):

    n = 5
    mesh = fd.UnitSquareMesh(n, n)
    T = mesh.coordinates.copy(deepcopy=True)
    (x, y) = fd.SpatialCoordinate(mesh)
    T.interpolate(T + fd.Constant((1, 0)) * x * y)
    mesh = fd.Mesh(T)

    Q = fs.FeControlSpace(mesh)
    inner = fs.LaplaceInnerProduct(Q, fixed_bids=[1])
    mesh_m = Q.mesh_m
    q = fs.ControlVector(Q, inner)
    if pytestconfig.getoption("verbose"):
        out = fd.File("domain.pvd")

        def cb():
            out.write(mesh_m.coordinates)
    else:

        def cb():
            pass

    lower_bound = Q.T.copy(deepcopy=True)
    lower_bound.interpolate(fd.Constant((-0.0, -0.0)))
    upper_bound = Q.T.copy(deepcopy=True)
    upper_bound.interpolate(fd.Constant((+1.3, +0.9)))

    J = fsz.MoYoBoxConstraint(1, [2],
                              Q,
                              lower_bound=lower_bound,
                              upper_bound=upper_bound,
                              cb=cb,
                              quadrature_degree=100)
    g = q.clone()
    J.gradient(g, q, None)
    taylor_result = J.checkGradient(q, g, 9, 1)

    for i in range(len(taylor_result) - 1):
        if taylor_result[i][3] > 1e-7:
            assert taylor_result[i + 1][3] <= taylor_result[i][3] * 0.11

    params_dict = {
        'Step': {
            'Type': 'Line Search',
            'Line Search': {
                'Descent Method': {
                    'Type': 'Quasi-Newton Step'
                }
            }
        },
        'General': {
            'Secant': {
                'Type': 'Limited-Memory BFGS',
                'Maximum Storage': 2
            }
        },
        'Status Test': {
            'Gradient Tolerance': 1e-10,
            'Step Tolerance': 1e-10,
            'Iteration Limit': 150
        }
    }

    params = ROL.ParameterList(params_dict, "Parameters")
    problem = ROL.OptimizationProblem(J, q)
    solver = ROL.OptimizationSolver(problem, params)
    solver.solve()
    Tvec = Q.T.vector()
    nodes = fd.DirichletBC(Q.V_r, fd.Constant((0.0, 0.0)), [2]).nodes
    assert np.all(Tvec[nodes, 0] <= 1.3 + 1e-4)
    assert np.all(Tvec[nodes, 1] <= 0.9 + 1e-4)
def test_radio_transport():
    solver_parameters = copy.deepcopy(default_solver_parameters)

    class pde_solver(PDESystem):
        def __init__(self, comp, mesh, parameters):
            PDESystem.__init__(self, comp, mesh, parameters)

        def setup_bcs(self):
            x, y = fd.SpatialCoordinate(self.mesh)

            bcu = [
                fd.DirichletBC(self.V['u'], fd.Constant((0, 0)),
                               (10, 12)),  # top-bottom
                fd.DirichletBC(self.V['u'],
                               ((1.0 * (y - 1) * (2 - y)) / (0.5**2), 0), 9)
            ]  # inflow
            bcp = [fd.DirichletBC(self.V['p'], fd.Constant(0), 11)]  # outflow

            self.bc['u'][0] = [bcu, None, None, None, 'fixed']
            self.bc['p'] = [[bcp, None, None, None, 'fixed']]

        def setup_constants(self):
            x, y = fd.SpatialCoordinate(self.mesh)
            self.constants = {
                'deltat':
                fd.Constant(self.prm['dt']),
                'Kd':
                fd.Constant(0.01),
                'k1':
                fd.Constant(0.005),
                'k2':
                fd.Constant(0.00005),
                'lamd1':
                fd.Constant(0.000005),
                'lamd2':
                fd.Constant(0.0),
                'rho_s':
                fd.Constant(1.),
                'L':
                fd.Constant(1.),
                'phi':
                fd.Constant(0.3),
                'n':
                fd.FacetNormal(self.mesh),
                'f':
                fd.Constant((0.0, 0.0)),
                'nu':
                fd.Constant(0.001),
                'frac':
                fd.Constant(1.),
                'source1':
                fd.conditional(
                    pow(x - 1, 2) + pow(y - 1.5, 2) < 0.25 * 0.25, 10.0, 0)
            }

    # update the parameters
    solver_parameters = recursive_update(
        solver_parameters, {
            'space': {
                'u': fd.VectorFunctionSpace,
                'c': fd.MixedFunctionSpace,
                'd': fd.MixedFunctionSpace
            },
            'degree': {
                'u': 2
            },
            'order': {
                'c': 3,
                'd': 3
            },
            'ksp_type': {
                'u': 'gmres',
                'p': 'gmres',
                'c': 'gmres',
                'd': 'gmres'
            },
            'precond': {
                'u': 'sor',
                'p': 'sor',
                'c': 'sor',
                'd': 'gmres'
            },
            'dt': 0.05,
            'T': 5.0
        })

    #load mesh
    mesh = fd.Mesh("meshes/step10.msh")
    solver = pde_solver([['u', 'p']], mesh, solver_parameters)
    solver.add_subsystem(['c', 'd'], solver_parameters)
    solver.setup_constants()
    solver.define(['u', 'p', 'u'], 'up', navier_stokes)
    solver.define(['c', 'd'], 'cd', radio_transport_coupled)
    solver.setup_bcs()
示例#24
0
from firedrake import sqrt, inner
import icepack.plot

parser = argparse.ArgumentParser()
parser.add_argument('--mesh')
parser.add_argument('--undamaged')
parser.add_argument('--damaged')
parser.add_argument('--output')
args = parser.parse_args()

def colorbar(figure, axes, mappable, *args, **kwargs):
    divider = make_axes_locatable(axes)
    cax = divider.append_axes('right', size='5%', pad=0.05)
    return figure.colorbar(mappable, *args, cax=cax, **kwargs)

mesh = firedrake.Mesh(args.mesh)
Q = firedrake.FunctionSpace(mesh, family='CG', degree=2)
V = firedrake.VectorFunctionSpace(mesh, family='CG', degree=2)
Δ = firedrake.FunctionSpace(mesh, family='DG', degree=1)

with firedrake.DumbCheckpoint(args.undamaged, mode=firedrake.FILE_READ) as chk:
    h_undamaged = firedrake.Function(Q)
    u_undamaged = firedrake.Function(V)
    chk.load(h_undamaged, name='h')
    chk.load(u_undamaged, name='u')

with firedrake.DumbCheckpoint(args.damaged, mode=firedrake.FILE_READ) as chk:
    h_damaged = firedrake.Function(Q)
    u_damaged = firedrake.Function(V)
    D = firedrake.Function(Δ)
    chk.load(h_damaged, name='h')
示例#25
0
def heat_exchanger_optimization(mu=0.03, n_iters=1000):

    output_dir = "2D/"

    path = os.path.abspath(__file__)
    dir_path = os.path.dirname(path)
    mesh = fd.Mesh(f"{dir_path}/2D_mesh.msh")
    # 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)
    phi_expr = sin(y * pi / 0.2) * cos(x * pi / 0.2) - fd.Constant(0.8)
    # 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
    mu = fd.Constant(mu)  # viscosity
    alphamin = 1e-12
    alphamax = 2.5 / (2e-4)
    parameters = {
        "mat_type": "aij",
        "ksp_type": "preonly",
        "ksp_converged_reason": None,
        "pc_type": "lu",
        "pc_factor_mat_solver_type": "mumps",
    }
    stokes_parameters = parameters
    temperature_parameters = parameters
    u_inflow = 2e-3
    tin1 = fd.Constant(10.0)
    tin2 = fd.Constant(100.0)

    P2 = fd.VectorElement("CG", mesh.ufl_cell(), 2)
    P1 = fd.FiniteElement("CG", mesh.ufl_cell(), 1)
    TH = P2 * P1
    W = fd.FunctionSpace(mesh, TH)

    U = fd.TrialFunction(W)
    u, p = fd.split(U)
    V = fd.TestFunction(W)
    v, q = fd.split(V)

    epsilon = fd.Constant(10000.0)

    def hs(phi, epsilon):
        return fd.Constant(alphamax) * fd.Constant(1.0) / (
            fd.Constant(1.0) + exp(-epsilon * phi)) + fd.Constant(alphamin)

    def stokes(phi, BLOCK_INLET_MOUTH, BLOCK_OUTLET_MOUTH):
        a_fluid = mu * inner(grad(u), grad(v)) - div(v) * p - q * div(u)
        darcy_term = inner(u, v)
        return (a_fluid * dx + hs(phi, epsilon) * darcy_term * dx(0) +
                alphamax * darcy_term *
                (dx(BLOCK_INLET_MOUTH) + dx(BLOCK_OUTLET_MOUTH)))

    # Dirichlet boundary conditions
    inflow1 = fd.as_vector([
        u_inflow * sin(
            ((y - (line_sep -
                   (dist_center + inlet_width))) * pi) / inlet_width),
        0.0,
    ])
    inflow2 = fd.as_vector([
        u_inflow * sin(((y - (line_sep + dist_center)) * pi) / inlet_width),
        0.0,
    ])

    noslip = fd.Constant((0.0, 0.0))

    # Stokes 1
    bcs1_1 = fd.DirichletBC(W.sub(0), noslip, WALLS)
    bcs1_2 = fd.DirichletBC(W.sub(0), inflow1, INLET1)
    bcs1_3 = fd.DirichletBC(W.sub(1), fd.Constant(0.0), OUTLET1)
    bcs1_4 = fd.DirichletBC(W.sub(0), noslip, INLET2)
    bcs1_5 = fd.DirichletBC(W.sub(0), noslip, OUTLET2)
    bcs1 = [bcs1_1, bcs1_2, bcs1_3, bcs1_4, bcs1_5]

    # Stokes 2
    bcs2_1 = fd.DirichletBC(W.sub(0), noslip, WALLS)
    bcs2_2 = fd.DirichletBC(W.sub(0), inflow2, INLET2)
    bcs2_3 = fd.DirichletBC(W.sub(1), fd.Constant(0.0), OUTLET2)
    bcs2_4 = fd.DirichletBC(W.sub(0), noslip, INLET1)
    bcs2_5 = fd.DirichletBC(W.sub(0), noslip, OUTLET1)
    bcs2 = [bcs2_1, bcs2_2, bcs2_3, bcs2_4, bcs2_5]

    # Forward problems
    U1, U2 = fd.Function(W), fd.Function(W)
    L = inner(fd.Constant((0.0, 0.0, 0.0)), V) * dx
    problem = fd.LinearVariationalProblem(stokes(-phi, INMOUTH2, OUTMOUTH2),
                                          L,
                                          U1,
                                          bcs=bcs1)
    solver_stokes1 = fd.LinearVariationalSolver(
        problem,
        solver_parameters=stokes_parameters,
        options_prefix="stokes_1")
    solver_stokes1.solve()
    problem = fd.LinearVariationalProblem(stokes(phi, INMOUTH1, OUTMOUTH1),
                                          L,
                                          U2,
                                          bcs=bcs2)
    solver_stokes2 = fd.LinearVariationalSolver(
        problem,
        solver_parameters=stokes_parameters,
        options_prefix="stokes_2")
    solver_stokes2.solve()

    # Convection difussion equation
    ks = fd.Constant(1e0)
    cp_value = 5.0e5
    cp = fd.Constant(cp_value)
    T = fd.FunctionSpace(mesh, "DG", 1)
    t = fd.Function(T, name="Temperature")
    w = fd.TestFunction(T)

    # Mesh-related functions
    n = fd.FacetNormal(mesh)
    h = fd.CellDiameter(mesh)
    u1, p1 = fd.split(U1)
    u2, p2 = fd.split(U2)

    def upwind(u):
        return (dot(u, n) + abs(dot(u, n))) / 2.0

    u1n = upwind(u1)
    u2n = upwind(u2)

    # Penalty term
    alpha = fd.Constant(500.0)
    # Bilinear form
    a_int = dot(grad(w), ks * grad(t) - cp * (u1 + u2) * t) * dx

    a_fac = (fd.Constant(-1.0) * ks * dot(avg(grad(w)), jump(t, n)) * dS +
             fd.Constant(-1.0) * ks * dot(jump(w, n), avg(grad(t))) * dS +
             ks("+") *
             (alpha("+") / avg(h)) * dot(jump(w, n), jump(t, n)) * dS)

    a_vel = (dot(
        jump(w),
        cp * (u1n("+") + u2n("+")) * t("+") - cp *
        (u1n("-") + u2n("-")) * t("-"),
    ) * dS + dot(w,
                 cp * (u1n + u2n) * t) * ds)

    a_bnd = (dot(w,
                 cp * dot(u1 + u2, n) * t) * (ds(INLET1) + ds(INLET2)) +
             w * t * (ds(INLET1) + ds(INLET2)) - w * tin1 * ds(INLET1) -
             w * tin2 * ds(INLET2) + alpha / h * ks * w * t *
             (ds(INLET1) + ds(INLET2)) - ks * dot(grad(w), t * n) *
             (ds(INLET1) + ds(INLET2)) - ks * dot(grad(t), w * n) *
             (ds(INLET1) + ds(INLET2)))

    aT = a_int + a_fac + a_vel + a_bnd

    LT_bnd = (alpha / h * ks * tin1 * w * ds(INLET1) +
              alpha / h * ks * tin2 * w * ds(INLET2) -
              tin1 * ks * dot(grad(w), n) * ds(INLET1) -
              tin2 * ks * dot(grad(w), n) * ds(INLET2))

    problem = fd.LinearVariationalProblem(derivative(aT, t), LT_bnd, t)
    solver_temp = fd.LinearVariationalSolver(
        problem,
        solver_parameters=temperature_parameters,
        options_prefix="temperature",
    )
    solver_temp.solve()
    # fd.solve(eT == 0, t, solver_parameters=temperature_parameters)

    # Cost function: Flux at the cold outlet
    scale_factor = 4e-4
    Jform = fd.assemble(
        fd.Constant(-scale_factor * cp_value) * inner(t * u1, n) * ds(OUTLET1))
    # Constraints: Pressure drop on each fluid
    power_drop = 1e-2
    Power1 = fd.assemble(p1 / power_drop * ds(INLET1))
    Power2 = fd.assemble(p2 / power_drop * ds(INLET2))

    phi_pvd = fd.File("phi_evolution.pvd")

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

    c = fda.Control(s)

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

    P2hat = LevelSetFunctional(Power2, c, phi)
    P2control = fda.Control(Power2)

    Jhat_v = Jhat(phi)
    print("Initial cost function value {:.5f}".format(Jhat_v), flush=True)
    print("Power drop 1 {:.5f}".format(Power1), flush=True)
    print("Power drop 2 {:.5f}".format(Power2), flush=True)

    beta_param = 0.08
    # Regularize the shape derivatives only in the domain marked with 0
    reg_solver = RegularizationSolver(S,
                                      mesh,
                                      beta=beta_param,
                                      gamma=1e5,
                                      dx=dx,
                                      design_domain=0)

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

    solver_parameters = {
        "reinit_solver": {
            "h_factor": 2.0,
        }
    }
    # Optimization problem
    problem = InfDimProblem(
        Jhat,
        reg_solver,
        ineqconstraints=[
            Constraint(P1hat, 1.0, P1control),
            Constraint(P2hat, 1.0, P2control),
        ],
        solver_parameters=solver_parameters,
    )
    results = nlspace_solve(problem, params)

    return results
示例#26
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
示例#27
0
def generate_mesh3D(model, G, comm):

    print('Entering mesh generation', flush=True)
    M = grid_point_to_mesh_point_converter_for_seismicmesh(model, G)
    method = model["opts"]["method"]

    Lz = model["mesh"]['Lz']
    lz = model['BCs']['lz']
    Lx = model["mesh"]['Lx']
    lx = model['BCs']['lx']
    Ly = model["mesh"]['Ly']
    ly = model['BCs']['ly']

    Real_Lz = Lz + lz
    Real_Lx = Lx + 2 * lx
    Real_Ly = Ly + 2 * ly

    minimum_mesh_velocity = model['testing_parameters'][
        'minimum_mesh_velocity']
    frequency = model["acquisition"]['frequency']
    lbda = minimum_mesh_velocity / frequency

    edge_length = lbda / M
    #print(Real_Lz)

    bbox = (-Real_Lz, 0.0, -lx, Real_Lx - lx, -ly, Real_Ly - ly)
    cube = SeismicMesh.Cube(bbox)

    if comm.comm.rank == 0:
        # Creating rectangular mesh
        points, cells = SeismicMesh.generate_mesh(domain=cube,
                                                  edge_length=edge_length,
                                                  mesh_improvement=False,
                                                  max_iter=75,
                                                  comm=comm.ensemble_comm,
                                                  verbose=0)

        points, cells = SeismicMesh.sliver_removal(points=points,
                                                   bbox=bbox,
                                                   domain=cube,
                                                   edge_length=edge_length,
                                                   preserve=True,
                                                   max_iter=200)

        print('entering spatial rank 0 after mesh generation')

        meshio.write_points_cells("meshes/3Dhomogeneous" + str(G) + ".msh",
                                  points, [("tetra", cells)],
                                  file_format="gmsh22",
                                  binary=False)
        meshio.write_points_cells("meshes/3Dhomogeneous" + str(G) + ".vtk",
                                  points, [("tetra", cells)],
                                  file_format="vtk")

    comm.comm.barrier()
    if method == "CG" or method == "KMV":
        mesh = fire.Mesh(
            "meshes/3Dhomogeneous" + str(G) + ".msh",
            distribution_parameters={
                "overlap_type": (fire.DistributedMeshOverlapType.NONE, 0)
            },
        )

    print('Finishing mesh generation', flush=True)
    return mesh
示例#28
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")
示例#29
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': {
示例#30
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()