示例#1
0
def solve_something(mesh):
    V = fd.FunctionSpace(mesh, "CG", 1)
    u = fd.Function(V)
    v = fd.TestFunction(V)

    x, y = fd.SpatialCoordinate(mesh)
    # f = fd.sin(x) * fd.sin(y) + x**2 + y**2
    # uex = x**4 * y**4
    uex = fd.sin(x) * fd.sin(y)  #*(x*y)**3
    # def source(xs, ys):
    #     return 1/((x-xs)**2+(y-ys)**2 + 0.1)
    # uex = source(0, 0)
    uex = uex - fd.assemble(uex * fd.dx) / fd.assemble(1 * fd.dx(domain=mesh))
    # f = fd.conditional(fd.ge(abs(x)-abs(y), 0), 1, 0)
    from firedrake import inner, grad, dx, ds, div, sym
    eps = fd.Constant(0.0)
    f = uex - div(grad(uex)) + eps * div(grad(div(grad(uex))))
    n = fd.FacetNormal(mesh)
    g = inner(grad(uex), n)
    g1 = inner(grad(div(grad(uex))), n)
    g2 = div(grad(uex))
    # F = 0.1 * inner(u, v) * dx + inner(grad(u), grad(v)) * dx + inner(grad(grad(u)), grad(grad(v))) * dx - f * v * dx - g * v * ds
    F = inner(u, v) * dx + inner(grad(u),
                                 grad(v)) * dx - f * v * dx - g * v * ds
    F += eps * inner(div(grad(u)), div(grad(v))) * dx
    F += eps * g1 * v * ds
    F -= eps * g2 * inner(grad(v), n) * ds
    # f = -div(grad(uex))
    # F = inner(grad(u), grad(v)) * dx - f * v * dx

    # bc = fd.DirichletBC(V, uex, "on_boundary")
    bc = None
    fd.solve(F == 0,
             u,
             bcs=bc,
             solver_parameters={
                 "ksp_type": "cg",
                 "ksp_atol": 1e-13,
                 "ksp_rtol": 1e-13,
                 "ksp_dtol": 1e-13,
                 "ksp_stol": 1e-13,
                 "pc_type": "jacobi",
                 "pc_factor_mat_solver_type": "mumps",
                 "snes_type": "ksponly",
                 "ksp_converged_reason": None
             })
    print("||u-uex||             =", fd.norm(u - uex))
    print("||grad(u-uex)||       =", fd.norm(grad(u - uex)))
    print("||grad(grad(u-uex))|| =", fd.norm(grad(grad(u - uex))))
    err = fd.Function(
        fd.TensorFunctionSpace(mesh, "DG",
                               V.ufl_element().degree() - 2)).interpolate(
                                   grad(grad(u - uex)))
    # err = fd.Function(fd.FunctionSpace(mesh, "DG", V.ufl_element().degree())).interpolate(u-uex)
    fd.File(outdir + "sln.pvd").write(u)
    fd.File(outdir + "err.pvd").write(err)
示例#2
0
def run_L2tracking_optimization(write_output=False):
    """ Test template for fsz.LevelsetFunctional."""

    # tool for developing new tests, allows storing shape iterates
    if write_output:
        out = fd.File("domain.pvd")

        def cb(*args):
            out.write(Q.mesh_m.coordinates)

        cb()
    else:
        cb = None

    # setup problem
    mesh = fd.UnitSquareMesh(30, 30)
    Q = fs.FeControlSpace(mesh)
    inner = fs.ElasticityInnerProduct(Q)
    q = fs.ControlVector(Q, inner)

    # setup PDE constraint
    mesh_m = Q.mesh_m
    e = PoissonSolver(mesh_m)

    # create PDEconstrained objective functional
    J_ = L2trackingObjective(e, Q, cb=cb)
    J = fs.ReducedObjective(J_, e)

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

    # assemble and solve ROL optimization problem
    params = ROL.ParameterList(params_dict, "Parameters")
    problem = ROL.OptimizationProblem(J, q)
    solver = ROL.OptimizationSolver(problem, params)
    solver.solve()

    # verify that the norm of the gradient at optimum is small enough
    state = solver.getAlgorithmState()
    assert (state.gnorm < 1e-4)
示例#3
0
    def retract(self, input_phi, delta_x, scaling=1):
        """input_phi is not modified,
            output_phi refers to problem.phi
        Args:
            input_phi ([type]): [description]
            delta_x ([type]): [description]
            scaling (int, optional): [description]. Defaults to 1.

        Returns:
            [type]: [description]
        """
        self.current_max_distance_at_t0 = self.current_max_distance
        self.hj_solver.ts.setMaxTime(scaling)
        try:
            output_phi = self.hj_solver.solve(input_phi)
        except:
            reason = self.hj_solver.ts.getConvergedReason()
            print(f"Time stepping of Hamilton Jacobi failed. Reason: {reason}")
            if self.output_dir:
                print(f"Printing last solution to {self.output_dir}")
                fd.File(f"{self.output_dir}/failed_hj.pvd").write(input_phi)

        max_vel = calculate_max_vel(delta_x)
        self.last_distance = max_vel * scaling

        conv = self.hj_solver.ts.getConvergedReason()
        rtol, atol = (
            self.hj_solver.parameters["ts_rtol"],
            self.hj_solver.parameters["ts_atol"],
        )
        max_steps = self.hj_solver.parameters.get("ts_max_steps", 800)
        current_time = self.hj_solver.ts.getTime()
        total_time = self.hj_solver.ts.getMaxTime()
        if conv == 2:
            warning = (
                f"Maximum number of time steps {self.hj_solver.ts.getStepNumber()} reached."
                f"Current time is only: {current_time} for total time: {total_time}."
                "Consider making the optimization time step dt shorter."
                "Restarting this step with more time steps and tighter tolerances if applicable."
            )
            fd.warning(warning)

            # Tighten tolerances if we are really far
            if current_time / total_time < 0.2:
                current_rtol, current_atol = self.hj_solver.ts.getTolerances()
                new_rtol, new_atol = max(rtol / 200, current_rtol / 10), max(
                    atol / 200, current_atol / 10)
                self.hj_solver.ts.setTolerances(rtol=new_rtol, atol=new_atol)

            # Relax max time steps
            current_max_steps = self.hj_solver.ts.getMaxSteps()
            new_max_steps = min(current_max_steps * 1.5, max_steps * 3)
            self.hj_solver.ts.setMaxSteps(new_max_steps)

            output_phi.assign(input_phi)
        elif conv == 1:
            self.hj_solver.ts.setTolerances(rtol=rtol, atol=atol)

        return output_phi
def test_equality_constraint(pytestconfig):
    mesh = fs.DiskMesh(0.05, radius=2.)

    Q = fs.FeControlSpace(mesh)
    inner = fs.ElasticityInnerProduct(Q, direct_solve=True)
    mesh_m = Q.mesh_m
    (x, y) = fd.SpatialCoordinate(mesh_m)

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

        def cb(*args):
            out.write(Q.mesh_m.coordinates)
    else:
        cb = None
    f = (pow(2 * x, 2)) + pow(y - 0.1, 2) - 1.2

    J = fsz.LevelsetFunctional(f, Q, cb=cb)
    vol = fsz.LevelsetFunctional(fd.Constant(1.0), Q)
    e = fs.EqualityConstraint([vol])
    emul = ROL.StdVector(1)

    params_dict = {
        'Step': {
            'Type': 'Augmented Lagrangian',
            'Augmented Lagrangian': {
                'Subproblem Step Type': 'Line Search',
                'Penalty Parameter Growth Factor': 2.,
                'Initial Penalty Parameter': 1.,
                'Subproblem Iteration Limit': 20,
            },
            'Line Search': {
                'Descent Method': {
                    'Type': 'Quasi-Newton Step'
                }
            },
        },
        'General': {
            'Secant': {
                'Type': 'Limited-Memory BFGS',
                'Maximum Storage': 5
            }
        },
        'Status Test': {
            'Gradient Tolerance': 1e-4,
            'Step Tolerance': 1e-10,
            'Iteration Limit': 10
        }
    }

    params = ROL.ParameterList(params_dict, "Parameters")
    problem = ROL.OptimizationProblem(J, q, econ=e, emul=emul)
    solver = ROL.OptimizationSolver(problem, params)
    solver.solve()

    state = solver.getAlgorithmState()
    assert (state.gnorm < 1e-4)
    assert (state.cnorm < 1e-6)
示例#5
0
    def load_inputs(self, in_dir):
        # Bed
        B = firedrake.Function(self.V_cg)
        firedrake.File(in_dir + "B.pvd") >> B
        # Ice thickness
        H = firedrake.Function(self.V_cg)
        firedrake.File(in_dir + "H.pvd") >> H
        # Melt
        m = firedrake.Function(self.V_cg)
        firedrake.File(in_dir + "m.pvd") >> m
        # Sliding speed
        u_b = firedrake.Function(self.V_cg)
        firedrake.File(in_dir + "u_b.pvd") >> u_b
        # Potential at 0 pressure
        phi_m = firedrake.Function(self.V_cg)
        firedrake.File(in_dir + "phi_m.pvd") >> phi_m
        # Potential at overburden pressure
        phi_0 = firedrake.Function(self.V_cg)
        firedrake.File(in_dir + "phi_0.pvd") >> phi_0
        # Ice overburden pressure
        p_i = firedrake.Function(self.V_cg)
        firedrake.File(in_dir + "p_i.pvd") >> p_i

        self.model_inputs["B"] = B
        self.model_inputs["H"] = H
        self.model_inputs["m"] = m
        self.model_inputs["u_b"] = u_b
        self.model_inputs["phi_m"] = phi_m
        self.model_inputs["phi_0"] = phi_0
        self.model_inputs["p_i"] = p_i
示例#6
0
    def write_outputs(self,
                      headers: bool,
                      checkpoint: bool = True,
                      vtk: bool = False,
                      plots: bool = False):
        """Write all outputs.
        
        This creates or appends the CSV report, 
        writes the latest solution, and plots (in 1D/2D case).
        Redefine this to control outputs.
        
        Args:
            write_headers (bool): Write header line to report if True.
                You may want to set this to False, for example, if the 
                header has already been written.
            checkpoint (bool): Write checkpoint if True.
            vtk (bool): Write solution to VTK if True.
            plots (bool): Write plots if True.
        """
        self = self.postprocess()

        sapphire.output.report(sim=self, write_header=headers)

        if checkpoint:

            self.write_checkpoint()

        if vtk:

            if self.vtk_solution_file is None:

                vtk_solution_filepath = self.output_directory_path.joinpath(
                    "solution").with_suffix(".pvd")

                self.vtk_solution_file = fe.File(str(vtk_solution_filepath))

            sapphire.output.write_solution_to_vtk(sim=self,
                                                  file=self.vtk_solution_file)

        if plots:

            if self.mesh.geometric_dimension() < 3:

                sapphire.output.writeplots(
                    **self.kwargs_for_writeplots(),
                    time=self.time.__float__(),
                    time_index=self.state["index"],
                    outdir_path=self.output_directory_path)

            elif self.mesh.geometric_dimension() == 3:
                # This could be done with VTK and PyVista, but VTK can be a
                # difficult dependency. It may be best to run a separate
                # program for generating 3D plots from the solution files.
                raise NotImplementedError()
示例#7
0
def mh_cb(mh_r):
    fd.File("output/fine_init.pvd").write(mh_r[-1].coordinates)
    fd.File("output/coarse_init.pvd").write(mh_r[0].coordinates)
    # sys.exit()
    d = distance_function(mh_r[0])
    mu = 0.01 / (d + 0.01)
    extension[0] = fs.ElasticityForm(mu=mu)
    if args.cr > 0:
        mu_cr = args.cr * mu
        extension[0] = fs.CauchyRiemannAugmentation(extension[0], mu=mu_cr)
    if args.htwo > 0:
        mu_c1 = fd.Constant(args.htwo)
        extension[0] = C1Regulariser(extension[0], mu=mu_c1)
    if args.surf:
        Q[0] = fs.ScalarFeMultiGridControlSpace(mh_r,
                                                extension[0],
                                                order=args.order,
                                                fixed_bids=fixed_bids)
    else:
        Q[0] = fs.FeMultiGridControlSpace(mh_r, order=args.order)
    return Q[0].mh_m
示例#8
0
def test_read_and_write_segy():
    vp_name = "velocity_models/test"
    segy_file = vp_name + ".segy"
    hdf5_file = vp_name + ".hdf5"
    mesh = fire.UnitSquareMesh(10, 10)
    mesh.coordinates.dat.data[:, 0] *= -1

    V = fire.FunctionSpace(mesh, 'CG', 3)
    x, y = fire.SpatialCoordinate(mesh)
    r = 0.2
    xc = -0.5
    yc = 0.5

    vp = fire.Function(V)

    c = fire.conditional((x - xc)**2 + (y - yc)**2 < r**2, 3.0, 1.5)

    vp.interpolate(c)

    xi, yi, zi = spyro.io.write_function_to_grid(vp, V, 10.0 / 1000.0)
    spyro.io.create_segy(zi, segy_file)
    write_velocity_model(segy_file, vp_name)

    model = {}

    model["opts"] = {
        "method": "CG",  # either CG or KMV
        "quadrature": "CG",  # Equi or KMV
        "degree": 3,  # p order
        "dimension": 2,  # dimension
    }
    model["mesh"] = {
        "Lz": 1.0,  # depth in km - always positive
        "Lx": 1.0,  # width in km - always positive
        "Ly": 0.0,  # thickness in km - always positive
        "meshfile": None,
        "initmodel": None,
        "truemodel": hdf5_file,
    }
    model["BCs"] = {
        "status": False,
    }

    vp_read = spyro.io.interpolate(model, mesh, V, guess=False)

    fire.File("velocity_models/test.pvd").write(vp_read)

    value_at_center = vp_read.at(xc, yc)
    test1 = math.isclose(value_at_center, 3.0)
    value_outside_circle = vp_read.at(xc + r + 0.1, yc)
    test2 = math.isclose(value_outside_circle, 1.5)
    assert all([test1, test2])
示例#9
0
def writereferenceresult(filename, mesh, icemodel, upc):
    assert filename.split('.')[-1] == 'pvd'
    variables = 'u,p,c,tau,nu,phydrostatic,jweight,velocitySIA'
    if mesh.comm.size > 1:
        variables += ',rank'
    fd.PETSc.Sys.Print('writing variables (%s) to output file %s ... ' \
                       % (variables,filename))
    u, p, c = upc.split()
    u.rename('velocity')
    p.rename('pressure')
    c.rename('displacement')
    tau, nu = stresses(mesh, icemodel, u)
    ph = phydrostatic(mesh)
    jw = jweight(mesh, icemodel, c)
    velocitySIA = siahorizontalvelocity(mesh)
    if mesh.comm.size > 1:
        # integer-valued element-wise process rank
        rank = fd.Function(fd.FunctionSpace(mesh, 'DG', 0))
        rank.dat.data[:] = mesh.comm.rank
        rank.rename('rank')
        fd.File(filename).write(u, p, c, tau, nu, ph, jw, velocitySIA, rank)
    else:
        fd.File(filename).write(u, p, c, tau, nu, ph, jw, velocitySIA)
    return 0
示例#10
0
    def write_outputs(self, write_headers, plotvars=None):

        self.output_directory_path.mkdir(parents=True, exist_ok=True)

        if self.solution_file is None:

            solution_filepath = self.output_directory_path.joinpath(
                "solution").with_suffix(".pvd")

            self.solution_file = fe.File(str(solution_filepath))

        self = self.postprocess()

        sapphire.output.report(sim=self, write_header=write_headers)

        sapphire.output.write_solution(sim=self, file=self.solution_file)

        sapphire.output.plot(sim=self, plotvars=plotvars)
示例#11
0
def writesolutiongeometry(filename, refmesh, mzfine, upc):
    # get fields on reference mesh
    u, p, c = upc.split()

    # compute h on base mesh as updated surface elevation
    #   h(x,y) = lambda(x,y) + c(x,y,lambda(x,y))
    lambase = surfaceelevation(refmesh)  # bounded below by Href; space Q1base
    cbase, Q1base = _surfacevalue(refmesh, c)
    hbase0 = fd.Function(Q1base).interpolate(lambase + cbase)
    hbase = fd.Function(Q1base)
    hbase.interpolate(fd.conditional(hbase0 > 0.0, hbase0, 0.0))

    # duplicate fine mesh and extend h onto it
    mesh = extrudedmesh(refmesh._base_mesh,
                        mzfine,
                        refine=-1,
                        temporary_height=1.0)
    h = extend(mesh, hbase)

    # change mesh coordinate to linear times h
    Vcoord = mesh.coordinates.function_space()
    if mesh._base_mesh.cell_dimension() == 1:
        x, z = fd.SpatialCoordinate(mesh)
        Xnew = fd.Function(Vcoord).interpolate(fd.as_vector([x, h * z]))
    elif mesh._base_mesh.cell_dimension() == 2:
        x, y, z = fd.SpatialCoordinate(mesh)
        Xnew = fd.Function(Vcoord).interpolate(fd.as_vector([x, y, h * z]))
    else:
        raise ValueError('applies only to 2D and 3D extruded meshes')
    mesh.coordinates.assign(Xnew)

    # interpolate velocity u and pressure p from refmesh onto mesh and write
    Vu, Vp, _ = vectorspaces(mesh)
    unew = fd.Function(Vu)
    pnew = fd.Function(Vp)
    unew.rename('velocity')
    pnew.rename('pressure')
    # note f.at() searches for element to evaluate (thanks L Mitchell)
    print(Xnew.dat.data_ro)  # FIXME shows inadmissible z: too high
    unew.dat.data[:] = u.at(Xnew.dat.data_ro)
    pnew.dat.data[:] = p.at(Xnew.dat.data_ro)
    fd.File(filename).write(unew, pnew)
    return 0
示例#12
0
def run_solver(r):
    mesh = fd.UnitSquareMesh(2**r, 2**r)
    P2 = fd.VectorElement("CG", mesh.ufl_cell(), 1)
    P1 = fd.FiniteElement("CG", mesh.ufl_cell(), 1)
    TH = P2 * P1
    W = fd.FunctionSpace(mesh, TH)
    (v, q) = fd.TestFunctions(W)

    # Stokes 1
    w_sol1 = fd.Function(W)
    nu = fd.Constant(0.05)
    F = NavierStokesBrinkmannForm(W, w_sol1, nu, beta_gls=2.0)

    from firedrake import sin, grad, pi, sym, div, inner

    x, y = fd.SpatialCoordinate(mesh)
    u_mms = fd.as_vector(
        [sin(2.0 * pi * x) * sin(pi * y),
         sin(pi * x) * sin(2.0 * pi * y)])
    p_mms = -0.5 * (u_mms[0]**2 + u_mms[1]**2)
    f_mms_u = (grad(u_mms) * u_mms + grad(p_mms) -
               2.0 * nu * div(sym(grad(u_mms))))
    f_mms_p = div(u_mms)
    F += -inner(f_mms_u, v) * dx - f_mms_p * q * dx
    bc1 = fd.DirichletBC(W.sub(0), u_mms, "on_boundary")
    bc2 = fd.DirichletBC(W.sub(1), p_mms, "on_boundary")

    solver_parameters = {"ksp_max_it": 200}

    problem1 = fd.NonlinearVariationalProblem(F, w_sol1, bcs=[bc1, bc2])
    solver1 = NavierStokesBrinkmannSolver(
        problem1,
        options_prefix="navier_stokes",
        solver_parameters=solver_parameters,
    )
    solver1.solve()
    u_sol, _ = w_sol1.split()
    fd.File("test_u_sol.pvd").write(u_sol)
    u_mms_func = fd.interpolate(u_mms, W.sub(0))
    error = fd.errornorm(u_sol, u_mms_func)
    print(f"Error: {error}")
    return error
示例#13
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # container for functional value
        self.J = 0

        # target solution, which also specifies rhs and DirBC
        mesh_m = self.Q.mesh_m
        x, y = fd.SpatialCoordinate(mesh_m)
        sin = fd.sin
        cos = fd.cos
        pi = fd.pi
        self.u_t = lambda t: sin(pi * x) * sin(pi * y) * cos(t)
        self.f = lambda t: sin(pi * x) * sin(pi * y) * (2 * pi**2 * cos(t) -
                                                        sin(t))

        # perturbed initial guess to be fixed by shape optimization
        V = fd.FunctionSpace(mesh_m, "CG", 1)
        self.u0 = fd.Function(V)
        perturbation = 0.25 * sin(x * pi) * sin(y * pi)**2
        self.u0.interpolate(sin(pi * x * (1 + perturbation)) * sin(pi * y))

        # define self.cb, which is always called after self.solvePDE
        self.File = fd.File("u0.pvd")
        self.cb = lambda: self.File.write(self.u0)

        # heat equation discretized with implicit Euler
        self.u = fd.Function(V)
        self.u_old = fd.Function(V)  # solution at previous time
        self.bcs = fd.DirichletBC(V, 0, "on_boundary")
        self.dx = fd.dx(metadata={"quadrature_degree": 1})
        self.dt = 0.125
        v = fd.TestFunction(V)
        self.F = lambda t, u, u_old: fd.inner((u-u_old)/self.dt, v)*self.dx \
            + fd.inner(fd.grad(u), fd.grad(v))*self.dx \
            - fd.inner(self.f(t+self.dt), v)*self.dx
示例#14
0
def test_cone_cg_2D():
    mesh = fd.UnitSquareMesh(100, 100)
    V = fd.FunctionSpace(mesh, "CG", 1)

    radius = 0.2
    x, y = fd.SpatialCoordinate(mesh)
    x_shift = 0.5
    phi_init = ((x - x_shift) * (x - x_shift) + (y - 0.5) * (y - 0.5) -
                radius**2)
    phi0 = fd.Function(V).interpolate(phi_init)

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

    reinit_solver = ReinitSolverCG(V)
    phin = reinit_solver.solve(phi0, iters=10)
    phi_pvd.write(phin)

    phi_solution = fd.interpolate(
        sqrt((x - x_shift) * (x - x_shift) + (y - 0.5) * (y - 0.5)) - radius,
        V,
    )
    error_numeri = fd.errornorm(phin, phi_solution)
    print(f"error: {error_numeri}")
    assert error_numeri < 1e-4
示例#15
0
    def __init__(self, model_inputs, in_dir=None):

        r"""Initialize model inputs and 
        Parameters
        ----------
        model_inputs: model input object

        """

        self.mesh = model_inputs["mesh"]
        self.V_cg = firedrake.FunctionSpace(self.mesh, "CG", 2)

        self.model_inputs = model_inputs

        # If an input directory is specified, load model inputs from there.
        # Otherwise use the specified model inputs dictionary.
        if in_dir:
            model_inputs = self.load_inputs(in_dir)

        # Ice thickness
        self.H = self.model_inputs["H"]
        # Bed elevation
        self.B = self.model_inputs["B"]
        # Basal sliding speed
        self.u_b = self.model_inputs["u_b"]
        # Melt rate
        self.m = self.model_inputs["m"]
        # Cavity gap height
        self.h = self.model_inputs["h_init"]
        # Potential
        self.phi_prev = self.model_inputs["phi_init"]
        # Potential at 0 pressure
        self.phi_m = self.model_inputs["phi_m"]
        # Ice overburden pressure
        self.p_i = self.model_inputs["p_i"]
        # Potential at overburden pressure
        self.phi_0 = self.model_inputs["phi_0"]
        # Dirichlet boundary conditions
        self.d_bcs = self.model_inputs["d_bcs"]
        # Channel areas
        self.S = self.model_inputs["S_init"]
        # Drainage width
        self.width = self.model_inputs["width"]
        # Output directory
        self.out_dir = self.model_inputs["out_dir"]

        # If there is a dictionary of physical constants specified, use it.
        # Otherwise use the defaults.
        if "constants" in self.model_inputs:
            self.pcs = self.model_inputs["constants"]
        else:
            self.pcs = pcs

        self.n_bcs = []
        if "n_bcs" in self.model_inputs:
            self.n_bcs = model_inputs["n_bcs"]

        ### Create some fields

        self.V_cg = firedrake.FunctionSpace(self.mesh, "CG", 1)

        # Potential
        self.phi = firedrake.Function(self.V_cg)
        # Effective pressure
        self.N = firedrake.Function(self.V_cg)
        # Stores the value of S**alpha.
        self.S_alpha = firedrake.Function(self.V_cg)
        self.update_S_alpha()
        # Water pressure
        self.p_w = firedrake.Function(self.V_cg)
        # Pressure as a fraction of overburden
        self.pfo = firedrake.Function(self.V_cg)
        # Current time
        self.t = 0.0

        ### Output files
        self.S_out = firedrake.File(self.out_dir + "S.pvd")
        self.h_out = firedrake.File(self.out_dir + "h.pvd")
        self.phi_out = firedrake.File(self.out_dir + "phi.pvd")
        self.pfo_out = firedrake.File(self.out_dir + "pfo.pvd")

        ### Create the solver objects
        # Potential solver
        self.phi_solver = PhiSolver(self)
        # Gap height solver
        self.hs_solver = HSSolver(self)
示例#16
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")
示例#17
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
        "Line Search": {
            "Descent Method": {
                "Type": "Quasi-Newton Step"
            }
        }
    },
    "Status Test": {
        "Gradient Tolerance": 1e-8,
        "Step Tolerance": 1e-8,
        "Iteration Limit": args.maxiter,
    },
}

outdir = "./output/annulus/base-%s-cr-%s-weighted-%s-rstar-%.2f/" % (
    args.base_inner, args.alpha, args.weighted, args.rstar)
out = fd.File(outdir + "domain.pvd")

params = ROL.ParameterList(params_dict, "Parameters")
problem = ROL.OptimizationProblem(J, q)
solver = ROL.OptimizationSolver(problem, params)
boundary_derivatives = []
gradient_norms = []
objective_values = []


def cb(*args):
    out.write(mesh_m.coordinates)
    gradient_norms.append(solver.getAlgorithmState().gnorm)
    objective_values.append(solver.getAlgorithmState().value)
    boundary_derivatives.append(fd.assemble(fd.inner(expr, expr) * fd.ds)**0.5)
示例#19
0
#
# Now we're ready to solve the variational problem. We define `w` to be a
# function to hold the solution on the mixed space.
w = fd.Function(W)

# solve
fd.solve(a == L, w, bcs=[bc0, bc1])

# %%
# Post-process and plot interesting fields
print('* post-process')

# collect fields
vel, press = w.split()
press.rename('pressure')

# Projecting velocity field to a continuous space (visualization purporse)
P1 = fd.VectorFunctionSpace(mesh, "CG", 1)
vel_proj = fd.project(vel, P1)
vel_proj.rename('velocity_proj')

# project permeability Kxx
kxx = fd.Function(DG)
kxx.rename('Kxx')
kxx.dat.data[...] = 1 / Kinv.dat.data[:, 0, 0]

# print results
fd.File("plots/darcy_rt.pvd").write(vel_proj, press, kxx)

print('* normal termination')
示例#20
0
def test_levelset(dim, inner_t, controlspace_t, use_extension, pytestconfig):
    verbose = pytestconfig.getoption("verbose")
    """ Test template for fsz.LevelsetFunctional."""

    clscale = 0.1 if dim == 2 else 0.2

    # make the mesh a bit coarser if we are using a multigrid control space as
    # we are refining anyway
    if controlspace_t == fs.FeMultiGridControlSpace:
        clscale *= 4

    if dim == 2:
        mesh = fs.DiskMesh(clscale)
    elif dim == 3:
        mesh = fs.SphereMesh(clscale)
    else:
        raise NotImplementedError

    if controlspace_t == fs.BsplineControlSpace:
        if dim == 2:
            bbox = [(-2, 2), (-2, 2)]
            orders = [2, 2]
            levels = [4, 4]
        else:
            bbox = [(-3, 3), (-3, 3), (-3, 3)]
            orders = [2, 2, 2]
            levels = [3, 3, 3]
        Q = fs.BsplineControlSpace(mesh, bbox, orders, levels)
    elif controlspace_t == fs.FeMultiGridControlSpace:
        Q = fs.FeMultiGridControlSpace(mesh, refinements=1, order=2)
    else:
        Q = controlspace_t(mesh)

    inner = inner_t(Q)
    # if running with -v or --verbose, then export the shapes
    if verbose:
        out = fd.File("domain.pvd")

        def cb(*args):
            out.write(Q.mesh_m.coordinates)

        cb()
    else:
        cb = None

    # levelset test case
    if dim == 2:
        (x, y) = fd.SpatialCoordinate(Q.mesh_m)
        f = (pow(x, 2)) + pow(1.3 * y, 2) - 1.
    elif dim == 3:
        (x, y, z) = fd.SpatialCoordinate(Q.mesh_m)
        f = (pow(x, 2)) + pow(0.8 * y, 2) + pow(1.3 * z, 2) - 1.

    else:
        raise NotImplementedError

    J = fsz.LevelsetFunctional(f, Q, cb=cb, scale=0.1)

    if use_extension == "w_ext":
        ext = fs.ElasticityExtension(Q.V_r)
    if use_extension == "w_ext_fixed_dim":
        ext = fs.ElasticityExtension(Q.V_r, fixed_dims=[0])
    else:
        ext = None

    q = fs.ControlVector(Q, inner, boundary_extension=ext)

    # these tolerances are not very stringent, but solutions are correct with
    # tighter tolerances,  the combination
    # FeMultiGridControlSpace-ElasticityInnerProduct fails because the mesh
    # self-intersects (one should probably be more careful with the opt params)
    grad_tol = 1e-1
    itlim = 15
    itlimsub = 15

    # Volume constraint
    vol = fsz.LevelsetFunctional(fd.Constant(1.0), Q, scale=1)
    initial_vol = vol.value(q, None)
    econ = fs.EqualityConstraint([vol], target_value=[initial_vol])
    emul = ROL.StdVector(1)

    # ROL parameters
    params_dict = {
        'Step': {
            'Type': 'Augmented Lagrangian',
            'Augmented Lagrangian': {
                'Subproblem Step Type': 'Line Search',
                'Penalty Parameter Growth Factor': 1.05,
                'Print Intermediate Optimization History': True,
                'Subproblem Iteration Limit': itlimsub
            },
            'Line Search': {
                'Descent Method': {
                    'Type': 'Quasi-Newton Step'
                }
            },
        },
        'General': {
            'Secant': {
                'Type': 'Limited-Memory BFGS',
                'Maximum Storage': 50
            }
        },
        'Status Test': {
            'Gradient Tolerance': grad_tol,
            'Step Tolerance': 1e-10,
            'Iteration Limit': itlim
        }
    }
    params = ROL.ParameterList(params_dict, "Parameters")
    problem = ROL.OptimizationProblem(J, q, econ=econ, emul=emul)
    solver = ROL.OptimizationSolver(problem, params)
    solver.solve()

    # verify that the norm of the gradient at optimum is small enough
    # and that the volume has not changed too much
    state = solver.getAlgorithmState()
    assert (state.gnorm < grad_tol)
    assert abs(vol.value(q, None) - initial_vol) < 1e-2
示例#21
0
bexpr = 2000.0 * (1 - fd.sqrt(minarg) / rl)
b.interpolate(bexpr)

alpha = args.alpha
theta = 0.5

PD = asQ.paradiag(form_function=form_function,
                  form_mass=form_mass,
                  W=W,
                  w0=w0,
                  dt=dt,
                  theta=theta,
                  alpha=alpha,
                  M=M,
                  solver_parameters=solver_parameters_diag,
                  circ="quasi")
PD.solve()

# write output:
file0 = fd.File("output/output1.pvd")
pun = fd.Function(W, name="pun")
puns = pun.split()

for i in range(M):
    walls = PD.w_all.split()[2 * i:2 * i + 2]
    for k in range(2):
        puns[k].assign(walls[k])
    u_out = puns[0]
    h_out = puns[1]
    file0.write(u_out, h_out)
示例#22
0
# Res.
R = F_p + F_s

prob = fd.NonlinearVariationalProblem(R, U, bcs=[bc0, bc1, bc3])
solver2ph = fd.NonlinearVariationalSolver(prob)

# %%
# 4) Solve problem
# initialize variables
xv, xp, xs = U.split()
vel = fd.project(u0, P1)
xp.rename('pressure')
xs.rename('saturation')
vel.rename('velocity')

outfile = fd.File(oFile)
it = 0
t = 0.0
while t < sim_time:
    t += dt
    print("*iteration= {:3d}, dtime= {:8.6f}, time={:8.6f}".format(it, dt, t))

    solver2ph.solve()

    # update solution
    U0.assign(U)

    # 5) print results
    if it % freq_res == 0 or t == sim_time:
        vel.assign(fd.project(U.sub(0), P1))
        xp.assign(U.sub(1))
示例#23
0
        fd.Constant(0.))

    # shock terms
    # F1 += vshock*fd.dot(fd.grad(w), fd.grad(c_mid))*fd.dx
    F1 += vshock * np.abs(R) * fd.inner(fd.grad(w), fd.grad(c_mid)) * fd.dx

F = F1

prob = fd.NonlinearVariationalProblem(F, c, bcs=t_bc)
transport = fd.NonlinearVariationalSolver(prob)

# %%
# 4) Solve problem
c0.assign(0.)
t = it = 0
outfile = fd.File("plots/adr_supg_shock.pvd")
c0.rename("c")

dt = CFL * fd.interpolate(h / vnorm, DG0).dat.data.min()
Dt.assign(dt)
dt0 = dt

Pe = vnorm * h / (2.0 * Diff)
print('Peclet = {}; dt = {}'.format(
    fd.interpolate(Pe, DG0).dat.data.mean(), dt))
D = fd.interpolate(vshock * np.abs(R), DG0)
D.rename("visc_shock")

while t < sim_time:
    # move next time step
    t += np.min([sim_time - t, dt])
    shock = fd.interpolate(vshock * np.abs(R), DG0)
    shock.rename('vshock')

F = F1

prob = fd.NonlinearVariationalProblem(F, c, bcs=t_bc)
transport = fd.NonlinearVariationalSolver(prob)

# %%
# 4) Solve problem
# -----------------
t = 0.0
it = 0
dt0 = dt
cfl_conditional = fd.conditional(fd.lt(np.abs(vnorm), tol), 1 / tol, h / vnorm)
outfile = fd.File("plots/sb_t_supg.pvd")

sol = fd.Function(W)
c0.assign(0.)
# initialize timestep
while t < sim_time:
    # move next time step
    print("* iteration= {:4d}, dtime= {:8.6f}, time={:8.6f}".format(it, dt, t))

    # SB
    idt.assign(1 / dt)
    fd.solve(a == L, sol, bcs=bcs)

    vel.assign(sol.sub(0))
    Pe = vnorm * h / (2.0 * fd.det(Diff))
    numCFL = dt / fd.interpolate(cfl_conditional, DG0).dat.data.min()
示例#25
0
if equation == "heat":
    nu = fd.Constant(0.1)  # for heat

M = fd.derivative(fd.inner(u, v) * fd.dx, u)
R = -(fd.inner(fd.grad(u) * u, v) + nu * fd.inner(fd.grad(u), fd.grad(v))) * fd.dx
if equation == "heat":
    R = -nu * fd.inner(fd.grad(u), fd.grad(v)) * fd.dx
F = fd.action(M, u_dot) - R

bc = fd.DirichletBC(V, (0.0, 0.0), "on_boundary")

t = 0.0
end = 0.1
tspan = (t, end)

state_out = fd.File("result/state.pvd")


def ts_monitor(ts, steps, time, X):
    state_out.write(u, time=time)


problem = firedrake_ts.DAEProblem(F, u, u_dot, tspan, bcs=bc)
solver = firedrake_ts.DAESolver(problem, monitor_callback=ts_monitor)

ts = solver.ts
ts.setTimeStep(0.01)
ts.setExactFinalTime(PETSc.TS.ExactFinalTime.MATCHSTEP)
ts.setSaveTrajectory()

ts.setType(PETSc.TS.Type.THETA)
示例#26
0
V = fire.FunctionSpace(mesh, finite_element_space, 1)

bc = fire.DirichletBC(V, fire.Constant(1.0), 1)

u = fire.Function(V)

# Initialize the transport solver
transport = rok.TransportSolver(method=method)
transport.setVelocity(v)
transport.setDiffusion(D)
transport.setSource(q)
transport.setBoundaryConditions([bc])

t = 0.0
step = 0

outfile = fire.File("results_demo-transport/u.pvd")
outfile.write(u)

while step < nsteps:

    transport.step(u, dt)

    t += dt
    step += 1

    if step % 1 == 0:
        outfile.write(u)
        print("t = {:<15.3f} step = {:<15}".format(t, step))
示例#27
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])
    "pc_sc_eliminate_fields": "0, 1",
    "condensed_field": {
        "ksp_type": "preonly",
        "pc_type": "lu",
        "pc_factor_mat_solver_type": "mumps"
    }
}

solver = fd.NonlinearVariationalSolver(problem,
                                       solver_parameters=hybrid_solver_params)

# -----------------
wave_speed = fd.conditional(fd.lt(np.abs(vnorm), tol), h / tol, h / vnorm)
# CFL
dt_ = fd.interpolate(wave_speed, DG1).dat.data.min() * cfl
outfile = fd.File(f"plots/adr-hdg-n-{refine}-p-{order}.pvd",
                  project_output=True)
dt = dt_  # dtime
dtc.assign(dt_)

# %%
# solve problem

# initialize timestep
t = 0.0
it = 0

p = 0
while t < sim_time:
    # check dt
    dt = np.min([sim_time - t, dt])
示例#29
0
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': {
        'Type': 'Line Search',
        'Line Search': {
            'Descent Method': {
示例#30
0
Q = fs.FeControlSpace(mesh)
inner = fs.LaplaceInnerProduct(Q, fixed_bids=[10, 11, 12])
q = fs.ControlVector(Q, inner)

# setup PDE constraint
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(Q.mesh_m, viscosity)

# save state variable evolution in file u2.pvd or u3.pvd
if mesh.topological_dimension() == 2:  # in 2D
    out = fd.File("solution/u2D.pvd")
elif mesh.topological_dimension() == 3:  # in 3D
    out = fd.File("solution/u3D.pvd")


def cb():
    return out.write(e.solution.split()[0])


# create PDEconstrained objective functional
J_ = PipeObjective(e, Q, cb=cb)
J = fs.ReducedObjective(J_, e)

# add regularization to improve mesh quality
Jq = fsz.MoYoSpectralConstraint(10, fd.Constant(0.5), Q)
J = J + Jq