コード例 #1
0
def test_diffusion(params):
    E_true = firedrake.interpolate(E_surface + q_bed / α * h * (1 - ζ), Q)
    E = firedrake.interpolate(Constant(480), Q)

    # Subclass the heat transport model and turn off advection so that we can
    # test diffusion by itself
    class DiffusionTransportModel(icepack.models.HeatTransport3D):
        def __init__(self):
            super(DiffusionTransportModel, self).__init__()

        def advective_flux(self, **kwargs):
            E = kwargs['energy']
            h = kwargs['thickness']
            Q = E.function_space()
            ψ = firedrake.TestFunction(Q)
            return firedrake.Constant(0) * ψ * h * dx

    model = DiffusionTransportModel()
    solver = icepack.solvers.HeatTransportSolver(model,
                                                 solver_parameters=params)

    dt = 250.0
    final_time = 6000
    num_steps = int(final_time / dt) + 1
    for step in range(num_steps):
        E = solver.solve(dt,
                         energy=E,
                         thickness=h,
                         energy_surface=Constant(E_surface),
                         heat=Constant(0),
                         heat_bed=Constant(q_bed))

    assert assemble((E - E_true)**2 * ds_t) / assemble(E_true**2 * ds_t) < 1e-3
    assert assemble((E - E_true)**2 * ds_b) / assemble(E_true**2 * ds_b) < 1e-3
コード例 #2
0
def compute_inf_sup_constant(spaces, b, inner_products):
    V, Q = spaces
    m, n = inner_products

    Z = V * Q
    u, p = firedrake.TrialFunctions(Z)
    v, q = firedrake.TestFunctions(Z)

    A = assemble(-(m(u, v) + b(v, p) + b(u, q)), mat_type='aij').M.handle
    M = assemble(n(p, q), mat_type='aij').M.handle

    opts = PETSc.Options()
    opts.setValue('eps_gen_hermitian', None)
    opts.setValue('eps_target_real', None)
    opts.setValue('eps_smallest_magnitude', None)
    opts.setValue('st_type', 'sinvert')
    opts.setValue('st_ksp_type', 'preonly')
    opts.setValue('st_pc_type', 'lu')
    opts.setValue('st_pc_factor_mat_solver_type', 'mumps')
    opts.setValue('eps_tol', 1e-8)

    num_values = 1
    eigensolver = SLEPc.EPS().create(comm=firedrake.COMM_WORLD)
    eigensolver.setDimensions(num_values)
    eigensolver.setOperators(A, M)
    eigensolver.setFromOptions()
    eigensolver.solve()

    Vr, Vi = A.getVecs()
    λ = eigensolver.getEigenpair(0, Vr, Vi)
    return λ
コード例 #3
0
def test_advection():
    E_initial = firedrake.interpolate(E_surface + q_bed / α * h * (1 - ζ), Q)
    E = E_initial.copy(deepcopy=True)

    u0 = 100.0
    du = 100.0
    u_expr = as_vector((u0 + du * x / Lx, 0))
    u = firedrake.interpolate(u_expr, V)
    w = firedrake.interpolate((-du / Lx + dh / Lx / h * u[0]) * ζ, W)

    dt = 10.0
    final_time = Lx / u0
    num_steps = int(final_time / dt) + 1
    model = icepack.models.HeatTransport3D()
    for step in range(num_steps):
        model._advect(dt,
                      E=E,
                      u=u,
                      w=w,
                      h=h,
                      s=s,
                      E_inflow=E_initial,
                      E_surface=Constant(E_surface))

    error_surface = assemble((E - E_surface)**2 * ds_t)
    assert error_surface / assemble(E_surface**2 * ds_t(mesh)) < 1e-2
    error_bed = assemble((E - E_initial)**2 * ds_b)
    assert error_bed / assemble(E_initial**2 * ds_b(mesh)) < 1e-2
コード例 #4
0
    def form_function(ts, t, X, F):
        r"""Form the residual for this problem

        :arg ts: a PETSc TS object
        :arg t: the time at step/stage being solved
        :arg X: state vector
        :arg F: function vector
        """
        dm = ts.getDM()
        ctx = dmhooks.get_appctx(dm)
        # X may not be the same vector as the vec behind self._problem.phi_n, so
        # copy guess in from X.
        with ctx._problem.phi_n.dat.vec_wo as v:
            X.copy(v)

        b1 = assemble(ctx._problem.L1)
        ctx._problem.solver1.solve(ctx._problem.p1, b1)

        b2 = assemble(ctx._problem.L2)
        ctx._problem.solver2.solve(ctx._problem.p2, b2)

        b3 = assemble(ctx._problem.Lb)
        ctx._problem.solver_b.solve(ctx._F, b3)

        # F may not be the same vector as self._F, so copy
        # residual out to F.
        with ctx._F.dat.vec_ro as v:
            v.copy(F)
コード例 #5
0
def _newton_solve(z, E, scale, tolerance=1e-6, armijo=1e-4, max_iterations=50):
    F = derivative(E, z)
    H = derivative(F, z)

    Q = z.function_space()
    bc = firedrake.DirichletBC(Q, 0, 'on_boundary')
    p = firedrake.Function(Q)
    for iteration in range(max_iterations):
        firedrake.solve(H == -F, p, bc,
            solver_parameters={'ksp_type': 'preonly', 'pc_type': 'lu'})

        dE_dp = assemble(action(F, p))
        α = 1.0
        E0 = assemble(E)
        Ez = assemble(replace(E, {z: z + firedrake.Constant(α) * p}))
        while (Ez > E0 + armijo * α * dE_dp) or np.isnan(Ez):
            α /= 2
            Ez = assemble(replace(E, {z: z + firedrake.Constant(α) * p}))

        z.assign(z + firedrake.Constant(α) * p)
        if abs(dE_dp) < tolerance * assemble(scale):
            return z

    raise ValueError("Newton solver failed to converge after {0} iterations"
                     .format(max_iterations))
コード例 #6
0
    def _ad_convert_type(self, value, options=None):
        from firedrake import Function, TrialFunction, TestFunction, assemble

        options = {} if options is None else options
        riesz_representation = options.get("riesz_representation", "l2")

        if riesz_representation == "l2":
            return Function(self.function_space(), val=value)

        elif riesz_representation == "L2":
            ret = Function(self.function_space())
            u = TrialFunction(self.function_space())
            v = TestFunction(self.function_space())
            M = assemble(firedrake.inner(u, v) * firedrake.dx)
            firedrake.solve(M, ret, value)
            return ret

        elif riesz_representation == "H1":
            ret = Function(self.function_space())
            u = TrialFunction(self.function_space())
            v = TestFunction(self.function_space())
            M = assemble(
                firedrake.inner(u, v) * firedrake.dx +
                firedrake.inner(firedrake.grad(u), firedrake.grad(v)) *
                firedrake.dx)
            firedrake.solve(M, ret, value)
            return ret

        elif callable(riesz_representation):
            return riesz_representation(value)

        else:
            raise NotImplementedError("Unknown Riesz representation %s" %
                                      riesz_representation)
コード例 #7
0
 def __init__(self, V, fixed_dims=[], direct_solve=False):
     if isinstance(fixed_dims, int):
         fixed_dims = [fixed_dims]
     self.V = V
     self.fixed_dims = fixed_dims
     self.direct_solve = direct_solve
     self.zero = fd.Constant(V.mesh().topological_dimension() * (0, ))
     u = fd.TrialFunction(V)
     v = fd.TestFunction(V)
     self.zero_fun = fd.Function(V)
     self.a = 1e-2 * \
         fd.inner(u, v) * fd.dx + fd.inner(fd.sym(fd.grad(u)),
                                           fd.sym(fd.grad(v))) * fd.dx
     self.bc_fun = fd.Function(V)
     if len(self.fixed_dims) == 0:
         bcs = [fd.DirichletBC(self.V, self.bc_fun, "on_boundary")]
     else:
         bcs = []
         for i in range(self.V.mesh().topological_dimension()):
             if i in self.fixed_dims:
                 bcs.append(fd.DirichletBC(self.V.sub(i), 0, "on_boundary"))
             else:
                 bcs.append(
                     fd.DirichletBC(self.V.sub(i), self.bc_fun.sub(i),
                                    "on_boundary"))
     self.A_ext = fd.assemble(self.a, bcs=bcs, mat_type="aij")
     self.ls_ext = fd.LinearSolver(self.A_ext,
                                   solver_parameters=self.get_params())
     self.A_adj = fd.assemble(self.a,
                              bcs=fd.DirichletBC(self.V, self.zero,
                                                 "on_boundary"),
                              mat_type="aij")
     self.ls_adj = fd.LinearSolver(self.A_adj,
                                   solver_parameters=self.get_params())
コード例 #8
0
 def _update_centroids(self, field):
     """
     Update centroid values
     """
     assemble(inner(field, TestFunction(self.P0)) * dx,
              tensor=self.centroids_rhs)
     self.centroid_solver.solve(self.centroids, self.centroids_rhs)
コード例 #9
0
ファイル: diagnostics.py プロジェクト: firedrakeproject/gusto
 def area(self, mesh):
     if not hasattr(self, "_area"):
         V = FunctionSpace(mesh, "DG", 0)
         self.expr = TestFunction(V)*dx
         self._area = Function(V)
     assemble(self.expr, tensor=self._area)
     return self._area
コード例 #10
0
def test_advection_diffusion():
    E_initial = firedrake.interpolate(E_surface + q_bed / α * h * (1 - ζ), Q)
    E = E_initial.copy(deepcopy=True)

    u0 = 100.0
    du = 100.0
    u_expr = as_vector((u0 + du * x / Lx, 0))
    u = firedrake.interpolate(u_expr, V)
    w = firedrake.interpolate((-du / Lx + dh / Lx / h * u[0]) * ζ, W)

    dt = 10.0
    final_time = Lx / u0
    num_steps = int(final_time / dt) + 1
    model = icepack.models.HeatTransport3D()
    solver = icepack.solvers.HeatTransportSolver(model)
    for step in range(num_steps):
        E = solver.solve(
            dt,
            energy=E,
            velocity=u,
            vertical_velocity=w,
            thickness=h,
            surface=s,
            heat=Constant(0),
            heat_bed=Constant(q_bed),
            energy_inflow=E_initial,
            energy_surface=Constant(E_surface),
        )

    rms = np.sqrt(assemble(E**2 * h * dx) / assemble(h * dx))
    assert (E_surface - 5 < rms) and (rms < E_surface + 5 + q_bed / α * h0)
コード例 #11
0
 def callback(inverse_solver):
     E, R = inverse_solver.objective, inverse_solver.regularization
     misfit = firedrake.assemble(E) / area
     regularization = firedrake.assemble(R) / area
     q = inverse_solver.parameter
     error = firedrake.norm(q - q_true) / np.sqrt(area)
     print(misfit, regularization, error, flush=True)
コード例 #12
0
def calculate_Pi0(state, theta0, rho0):
    # exner function
    Vr = rho0.function_space()
    Pi = Function(Vr).interpolate(thermodynamics.pi(state.parameters, rho0, theta0))
    Pi0 = assemble(Pi*dx)/assemble(Constant(1)*dx(domain=state.mesh))

    return Pi0
コード例 #13
0
ファイル: preconditioners.py プロジェクト: wei-pan/firedrake
def get_trace_nullspace_vecs(forward, nullspace, V, V_d, TraceSpace):
    """Gets the nullspace vectors corresponding to the Schur complement
    system for the multipliers.

    :arg forward: A Slate expression denoting the forward elimination
                  operator.
    :arg nullspace: A nullspace for the original mixed problem
    :arg V: The original "unbroken" space.
    :arg V_d: The broken space.
    :arg TraceSpace: The space of approximate traces.

    Returns: A list of vectors describing the nullspace of the multiplier
             system
    """
    from firedrake import project, assemble, Function

    vecs = nullspace.getVecs()
    tmp = Function(V)
    tmp_b = Function(V_d)
    tnsp_tmp = Function(TraceSpace)
    forward_action = forward * tmp_b
    new_vecs = []
    for v in vecs:
        with tmp.dat.vec as t:
            v.copy(t)

        project(tmp, tmp_b)
        assemble(forward_action, tensor=tnsp_tmp)
        with tnsp_tmp.dat.vec_ro as v:
            new_vecs.append(v.copy())

    return new_vecs
コード例 #14
0
def L2_error(solution, true_solution, integration_measure):

    dx = integration_measure

    w_h = solution.split()

    if len(w_h) == 1:

        u_h = w_h[0]

        u = true_solution

        e = math.sqrt(fe.assemble(fe.inner(u_h - u, u_h - u) * dx))

    else:

        e = 0.

        for u_h, u in zip(w_h, true_solution):

            e += fe.assemble(fe.inner(u_h - u, u_h - u) * dx)

        e = math.sqrt(e)

    return e
コード例 #15
0
def test_advection_diffusion():
    E_initial = firedrake.interpolate(E_surface + q_bed / α * h * (1 - ζ), Q)
    E = E_initial.copy(deepcopy=True)

    u0 = 100.0
    du = 100.0
    u_expr = as_vector((u0 + du * x / Lx, 0))
    u = firedrake.interpolate(u_expr, V)
    w = firedrake.interpolate((-du / Lx + dh / Lx / h * u[0]) * ζ, W)

    dt = 10.0
    final_time = Lx / u0
    num_steps = int(final_time / dt) + 1
    model = icepack.models.HeatTransport3D()
    for step in range(num_steps):
        E = model.solve(dt,
                        E0=E,
                        u=u,
                        w=w,
                        h=h,
                        s=s,
                        q=Constant(0),
                        q_bed=q_bed,
                        E_inflow=E_initial,
                        E_surface=Constant(E_surface))

    rms = np.sqrt(assemble(E**2 * h * dx) / assemble(h * dx))
    assert (E_surface - 5 < rms) and (rms < E_surface + 5 + q_bed / α * h0)
コード例 #16
0
def qoi_eval(prob,this_qoi,comm):
    """Helper function that evaluates qois.

    prob - Helmholtz problem (or, for testing purposes only, a float)

    this_qoi - string, one of ['testing','integral','origin']

    comm - the communicator for spatial parallelism.

    output - the value of the qoi for this realisation of the
    problem. None if this_qoi is not in the list above.

    """
    if this_qoi == 'testing':
        output = prob

    elif this_qoi == 'integral':
        # This is currently a bit of a hack, because there's a bug
        # in complex firedrake.
        # It's also non-obvious why this works in parallel....
        V = prob.u_h.function_space()
        func_real = fd.Function(V)
        func_imag = fd.Function(V)
        func_real.dat.data[:] = np.real(prob.u_h.dat.data)
        func_imag.dat.data[:] = np.imag(prob.u_h.dat.data)
        output = fd.assemble(func_real * fd.dx) + 1j * fd.assemble(func_imag * fd.dx)
        
    elif this_qoi == 'origin':
        # This gives the value of the function at (0,0).
        output = eval_at_mesh_point(prob.u_h,np.array([0.0,0.0]),comm)

    elif this_qoi == 'top_right':
        # This gives the value of the function at (1,1).
        output = eval_at_mesh_point(prob.u_h,np.array([1.0,1.0]),comm)

    elif this_qoi == 'gradient_top_right':
        # This gives the gradient of the solution at the
        # top-right-hand corner of the domain.
        gradient = fd.grad(prob.u_h)

        DG_spaces = [fd.FunctionSpace(prob.V.mesh(),"DG",1) for ii in range(len(gradient))]

        DG_functions = [fd.Function(DG_space) for DG_space in DG_spaces]

        for ii in range(len(DG_functions)):
            DG_functions[ii].interpolate(gradient[ii])

        point = tuple([1.0 for ii in range(len(gradient))])

        # A bit funny because output needs to be a column vector
        #output = np.array([eval_at_mesh_point(DG_fun,point,comm) for DG_fun in DG_functions],ndmin=2).transpose()

        # For now, set the output to be the first component of the gradient
        output = eval_at_mesh_point(DG_functions[0],point,comm)

    else:
        output = None

    return output
コード例 #17
0
 def setup(self, state):
     if not self._initialised:
         super(CourantNumber, self).setup(state)
         # set up area computation
         V = state.spaces("DG0")
         test = TestFunction(V)
         self.area = Function(V)
         assemble(test*dx, tensor=self.area)
コード例 #18
0
def calculate_exner0(state, theta0, rho0):
    # exner function
    Vr = rho0.function_space()
    exner = Function(Vr).interpolate(
        thermodynamics.exner_pressure(state.parameters, rho0, theta0))
    exner0 = assemble(exner * dx) / assemble(
        Constant(1) * dx(domain=state.mesh))

    return exner0
コード例 #19
0
def callback(solver):
    q = solver.search_direction
    dJ = solver.gradient
    dJ_dq = firedrake.action(dJ, q)
    decrement = firedrake.assemble(dJ_dq, **fc_params) / area

    error = firedrake.assemble(solver.objective) / area
    penalty = firedrake.assemble(solver.regularization) / area
    print(f'{error:10.4g} | {penalty:10.4g} | {decrement:10.4g}')
コード例 #20
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)
コード例 #21
0
def run(problem, tensor, size_factor, degree):
    formname = problem.__name__
    cellname = 'cube' if tensor else 'simplex'
    PETSc.Sys.Print("%s: %s, degree=%d" % (formname, cellname, degree))
    num_cells = COMM_WORLD.size * max(1, 1e7 * size_factor / (degree + 1)**{'spectral': 4, 'coffee': 6}[args.mode])
    h = int(floor(cbrt(num_cells / COMM_WORLD.size)))
    w = int(floor(sqrt(num_cells / h)))
    d = int(round(num_cells / (w * h)))
    num_cells = w * d * h

    if tensor:
        mesh = ExtrudedMesh(UnitSquareMesh(w, d, quadrilateral=True), h)
    else:
        mesh = UnitCubeMesh(w, d, h)
    comm = mesh.comm
    J = problem(mesh, int(degree))

    # Warmup and allocate
    A = assemble(J, mat_type="matfree", form_compiler_parameters={'mode': args.mode})
    A.force_evaluation()
    Ap = A.petscmat
    x, y = Ap.createVecs()
    assert x.size == y.size
    num_dofs = x.size
    Ap.mult(x, y)
    stage = PETSc.Log.Stage("%s(%d) %s" % (formname, degree, cellname))
    with stage:
        assemble(J, mat_type="matfree", form_compiler_parameters={'mode': args.mode}, tensor=A)
        A.force_evaluation()
        Ap = A.petscmat
        for _ in range(num_matvecs):
            Ap.mult(x, y)

        parloop = parloop_event.getPerfInfo()
        matmult = matmult_event.getPerfInfo()
        assert parloop["count"] == 2 * num_matvecs
        assert matmult["count"] == num_matvecs
        parloop_time = comm.allreduce(parloop["time"], op=MPI.SUM) / (comm.size * num_matvecs)
        matmult_time = comm.allreduce(matmult["time"], op=MPI.SUM) / (comm.size * num_matvecs)

        matfree_overhead = (1 - parloop_time / matmult_time)
        PETSc.Sys.Print("Matrix-free action overhead: %.1f%%" % (matfree_overhead * 100,))

    if COMM_WORLD.rank == 0:
        header = not os.path.exists(filepath)
        data = {"num_cells": num_cells,
                "num_dofs": num_dofs,
                "num_procs": comm.size,
                "tsfc_mode": args.mode,
                "problem": formname,
                "cell_type": cellname,
                "degree": degree,
                "matmult_time": matmult_time,
                "parloop_time": parloop_time}
        df = pandas.DataFrame(data, index=[0])
        df.to_csv(filepath, index=False, mode='a', header=header)
コード例 #22
0
 def derivative(self, out):
     """
     Assemble partial directional derivative wrt ControlSpace perturbations.
     """
     v = fd.TestFunction(self.V_control)
     fd.assemble(self.derivative_form(v),
                 tensor=self.deriv_r,
                 form_compiler_parameters=self.params)
     out.fun.assign(self.deriv_r)
     out.scale(self.scale)
コード例 #23
0
def estimate_timestep(mesh, V, c, estimate_max_eigenvalue=True):
    """Estimate the maximum stable timestep based on the spectral radius
    using optionally the Gershgorin Circle Theorem to estimate the
    maximum generalized eigenvalue. Otherwise computes the maximum
    generalized eigenvalue exactly

    ONLY WORKS WITH KMV ELEMENTS
    """

    u, v = fire.TrialFunction(V), fire.TestFunction(V)
    quad_rule = finat.quadrature.make_quadrature(V.finat_element.cell,
                                                 V.ufl_element().degree(),
                                                 "KMV")
    dxlump = fire.dx(rule=quad_rule)
    A = fire.assemble(u * v * dxlump)
    ai, aj, av = A.petscmat.getValuesCSR()
    av_inv = []
    for value in av:
        if value == 0:
            av_inv.append(0.0)
        else:
            av_inv.append(1 / value)
    Asp = scipy.sparse.csr_matrix((av, aj, ai))
    Asp_inv = scipy.sparse.csr_matrix((av_inv, aj, ai))

    K = fire.assemble(c * c * dot(grad(u), grad(v)) * dxlump)
    ai, aj, av = K.petscmat.getValuesCSR()
    Ksp = scipy.sparse.csr_matrix((av, aj, ai))

    # operator
    Lsp = Asp_inv.multiply(Ksp)
    if estimate_max_eigenvalue:
        # absolute maximum of diagonals
        max_eigval = np.amax(np.abs(Lsp.diagonal()))
    else:
        print(
            "Computing exact eigenvalues is extremely computationally demanding!",
            flush=True,
        )
        max_eigval = scipy.sparse.linalg.eigs(Ksp,
                                              M=Asp,
                                              k=1,
                                              which="LM",
                                              return_eigenvectors=False)[0]

    # print(max_eigval)
    if np.sqrt(max_eigval) > 0.0:
        max_dt = np.float(2 / np.sqrt(max_eigval))
    else:
        max_dt = 100000000
    #print(
    #    f"Maximum stable timestep should be about: {np.float(2 / np.sqrt(max_eigval))} seconds",
    #    flush=True,
    #)
    return max_dt
コード例 #24
0
ファイル: projection.py プロジェクト: jwallwork23/firedrake
 def apply_massinv(self):
     if not self.constant_jacobian:
         firedrake.assemble(self.A.a, tensor=self.A, bcs=self.bcs,
                            form_compiler_parameters=self.form_compiler_parameters)
     if self.use_slate_for_inverse:
         def solve(x, b):
             with x.dat.vec_wo as x_, b.dat.vec_ro as b_:
                 self.A.petscmat.mult(b_, x_)
         return solve
     else:
         return self.solver.solve
コード例 #25
0
 def apply_massinv(self):
     if not self.constant_jacobian:
         firedrake.assemble(self.A.a, tensor=self.A, bcs=self.bcs,
                            form_compiler_parameters=self.form_compiler_parameters)
     if self.use_slate_for_inverse:
         def solve(x, b):
             self.A.force_evaluation()
             with x.dat.vec_wo as x_, b.dat.vec_ro as b_:
                 self.A.petscmat.mult(b_, x_)
         return solve
     else:
         return self.solver.solve
コード例 #26
0
 def stepInfo(solver):
     """Printer summary information from solver
     Parameters
     ----------
     solver : firedrake solver
         solver function
     """
     E = firedrake.assemble(solver.objective)
     R = firedrake.assemble(solver.regularization)
     area = firedrake.assemble(firedrake.Constant(1) * firedrake.dx(mesh))
     Print(f'{E/area:g}, {R/area:g} '
           f'{datetime.now().strftime("%H:%M:%S")}  {area:10.3e}')
コード例 #27
0
def parameterInfo(solver, area, message=''):
    """
    Print various statistics
    """
    floating = solver.problem.diagnostic_solve_kwargs['floating']
    grounded = solver.problem.diagnostic_solve_kwargs['grounded']
    areaFloating = firedrake.assemble(floating * firedrake.dx)
    areaGrounded = firedrake.assemble(grounded * firedrake.dx)
    avgFloat = firedrake.assemble(solver.parameter * floating *
                                  firedrake.dx) / areaFloating
    avgGrounded = firedrake.assemble(solver.parameter * grounded *
                                     firedrake.dx) / areaGrounded
    Print(f'{message} grounded {avgGrounded:9.2e} floating {avgFloat:9.2e}')
コード例 #28
0
    def solvePDE(self):
        """Solve the heat equation and evaluate the objective function."""
        self.J = 0
        t = 0
        self.u.assign(self.u0)
        self.J += fd.assemble(self.dt * (self.u - self.u_t(t))**2 * self.dx)

        for ii in range(10):
            self.u_old.assign(self.u)
            fd.solve(self.F(t, self.u, self.u_old) == 0, self.u, bcs=self.bcs)
            t += self.dt
            self.J += fd.assemble(self.dt * (self.u - self.u_t(t))**2 *
                                  self.dx)
コード例 #29
0
ファイル: enthalpy_porosity.py プロジェクト: mfkiwl/sapphire
    def postprocess(self):

        p, u, T = self.solution.split()

        div = fe.div

        self.velocity_divergence = fe.assemble(div(u) * self.dx)

        phil = self.liquid_volume_fraction(temperature=T)

        self.liquid_area = fe.assemble(phil * self.dx)

        return self
コード例 #30
0
def write_output(diag, t, counter, dfr, nc_h5_dfr, outf, outf_ll, fld_out,
                 fld_out_ll):
    """Function to write vtu, txt output"""

    # Update and output diagnostics
    energy = e_form(un, Dn)
    En.interpolate(energy)
    if 'Energy' in diag.keys():
        diag['Energy'] = assemble(energy * dx)
    if 'Mass' in diag.keys():
        diag['Mass'] = assemble(Dn * dx)
    if 'Enstrophy' in diag.keys():
        diag['Enstrophy'] = assemble(qn**2 * Dn * dx)
    if 'L2_error_D' in diag.keys():
        diag['L2_error_D'] = sqrt(assemble((Dn - D0) * (Dn - D0) * dx))
    if 'L2_error_u' in diag.keys():
        diag['L2_error_u'] = sqrt(assemble(inner(un - u0, un - u0) * dx))

    _c = 0
    for k in diag:
        nc_temp[counter % nc_h5_dfr][_c] = diag[k]
        _c += 1

    # Save I/O time by not writing at each timestep
    if (counter % nc_h5_dfr) == nc_h5_dfr - 1:

        if COMM_WORLD.Get_rank() == 0:
            print("Timestep nr", counter, ": Writing nc files at", ctime())
            write_to_nc_file(t, nc_temp)
            if nc_safe:
                write_to_nc_file(t, nc_temp, '_bckp')

        # Write to checkpoint
        chkpt.store(xn)
        chkpt.write_attribute("/", "time", t)
        if h5_safe:
            chkpt_bckp.store(xn)
            chkpt_bckp.write_attribute("/", "time", t)

    # Output vtu file
    if t in field_dumptimes:
        #q2Dn.project(qn**2*Dn)
        #eta_out.interpolate(Dn + b)
        #vortsolver.solve()
        u_err.assign(un - u0)
        D_err.assign(Dn - D0)
        q_err.assign(qn - q0)
        outf.write(*fld_out)
        if write_latlon:
            outf_ll.write(*fld_out_ll)
コード例 #31
0
ファイル: function.py プロジェクト: kinjald/firedrake
    def _ad_dot(self, other, options=None):
        from firedrake import assemble

        options = {} if options is None else options
        riesz_representation = options.get("riesz_representation", "l2")
        if riesz_representation == "l2":
            return self.vector().inner(other.vector())
        elif riesz_representation == "L2":
            return assemble(firedrake.inner(self, other)*firedrake.dx)
        elif riesz_representation == "H1":
            return assemble((firedrake.inner(self, other)
                            + firedrake.inner(firedrake.grad(self), other))*firedrake.dx)
        else:
            raise NotImplementedError(
                "Unknown Riesz representation %s" % riesz_representation)
コード例 #32
0
    def derivative(self, out):
        """
        Assemble partial directional derivative wrt ControlSpace perturbations.

        First, assemble directional derivative (wrt FEspace V_m) and
        store it in self.deriv_m. This automatically updates self.deriv_r,
        which is then converted to the directional derivative wrt
        ControSpace perturbations restrict.
        """
        v = fd.TestFunction(self.V_m)
        fd.assemble(self.derivative_form(v),
                    tensor=self.deriv_m,
                    form_compiler_parameters=self.params)
        out.from_first_derivative(self.deriv_r)
        out.scale(self.scale)
コード例 #33
0
 def A(self):
     u = firedrake.TrialFunction(self.target.function_space())
     v = firedrake.TestFunction(self.target.function_space())
     a = firedrake.inner(u, v)*firedrake.dx
     if self.use_slate_for_inverse:
         a = firedrake.Tensor(a).inv
     A = firedrake.assemble(a, bcs=self.bcs,
                            form_compiler_parameters=self.form_compiler_parameters)
     return A
コード例 #34
0
    def _construct_centroid_solver(self):
        """
        Constructs a linear problem for computing the centroids

        :return: LinearSolver instance
        """
        u = TrialFunction(self.P0)
        v = TestFunction(self.P0)
        a = assemble(u * v * dx)
        return LinearSolver(a, solver_parameters={'ksp_type': 'preonly',
                                                  'pc_type': 'bjacobi',
                                                  'sub_pc_type': 'ilu'})
コード例 #35
0
 def DG_inv_mass(self, DG):
     """
     Inverse DG mass matrix
     :arg DG: the DG space
     :returns: A PETSc Mat.
     """
     key = DG.dim()
     try:
         return self._DG_inv_mass[key]
     except KeyError:
         M = firedrake.assemble(firedrake.Tensor(firedrake.inner(firedrake.TestFunction(DG),
                                                                 firedrake.TrialFunction(DG))*firedrake.dx).inv)
         M.force_evaluation()
         return self._DG_inv_mass.setdefault(key, M.petscmat)
コード例 #36
0
 def V_DG_mass(self, V, DG):
     """
     Mass matrix from between V and DG spaces.
     :arg V: a function space
     :arg DG: the DG space
     :returns: A PETSc Mat mapping from V -> DG
     """
     key = V.dim()
     try:
         return self._V_DG_mass[key]
     except KeyError:
         M = firedrake.assemble(firedrake.inner(firedrake.TestFunction(DG),
                                                firedrake.TrialFunction(V))*firedrake.dx)
         M.force_evaluation()
         return self._V_DG_mass.setdefault(key, M.petscmat)
コード例 #37
0
ファイル: massinv.py プロジェクト: firedrakeproject/firedrake
    def initialize(self, pc):
        from firedrake import TrialFunction, TestFunction, dx, assemble, inner, parameters
        prefix = pc.getOptionsPrefix()
        options_prefix = prefix + "Mp_"
        # we assume P has things stuffed inside of it
        _, P = pc.getOperators()
        context = P.getPythonContext()

        test, trial = context.a.arguments()

        if test.function_space() != trial.function_space():
            raise ValueError("MassInvPC only makes sense if test and trial space are the same")

        V = test.function_space()

        mu = context.appctx.get("mu", 1.0)

        u = TrialFunction(V)
        v = TestFunction(V)
        # Handle vector and tensor-valued spaces.

        # 1/mu goes into the inner product in case it varies spatially.
        a = inner(1/mu * u, v)*dx

        opts = PETSc.Options()
        mat_type = opts.getString(options_prefix + "mat_type",
                                  parameters["default_matrix_type"])

        A = assemble(a, form_compiler_parameters=context.fc_params,
                     mat_type=mat_type, options_prefix=options_prefix)
        A.force_evaluation()

        Pmat = A.petscmat
        Pmat.setNullSpace(P.getNullSpace())
        tnullsp = P.getTransposeNullSpace()
        if tnullsp.handle != 0:
            Pmat.setTransposeNullSpace(tnullsp)

        ksp = PETSc.KSP().create(comm=pc.comm)
        ksp.incrementTabLevel(1, parent=pc)
        ksp.setOperators(Pmat)
        ksp.setOptionsPrefix(options_prefix)
        ksp.setFromOptions()
        ksp.setUp()
        self.ksp = ksp
コード例 #38
0
 def V_approx_inv_mass(self, V, DG):
     """
     Approximate inverse mass.  Computes (cellwise) (V, V)^{-1} (V, DG).
     :arg V: a function space
     :arg DG: the DG space
     :returns: A PETSc Mat mapping from V -> DG.
     """
     key = V.dim()
     try:
         return self._V_approx_inv_mass[key]
     except KeyError:
         a = firedrake.Tensor(firedrake.inner(firedrake.TestFunction(V),
                                              firedrake.TrialFunction(V))*firedrake.dx)
         b = firedrake.Tensor(firedrake.inner(firedrake.TestFunction(V),
                                              firedrake.TrialFunction(DG))*firedrake.dx)
         M = firedrake.assemble(a.inv * b)
         M.force_evaluation()
         return self._V_approx_inv_mass.setdefault(key, M.petscmat)
コード例 #39
0
 def V_inv_mass_ksp(self, V):
     """
     A KSP inverting a mass matrix
     :arg V: a function space.
     :returns: A PETSc KSP for inverting (V, V).
     """
     key = V.dim()
     try:
         return self._V_inv_mass_ksp[key]
     except KeyError:
         M = firedrake.assemble(firedrake.inner(firedrake.TestFunction(V),
                                                firedrake.TrialFunction(V))*firedrake.dx)
         M.force_evaluation()
         ksp = PETSc.KSP().create(comm=V.comm)
         ksp.setOperators(M.petscmat)
         ksp.setOptionsPrefix("{}_prolongation_mass_".format(V.ufl_element()._short_name))
         ksp.setType("preonly")
         ksp.pc.setType("cholesky")
         ksp.setFromOptions()
         ksp.setUp()
         return self._V_inv_mass_ksp.setdefault(key, ksp)
コード例 #40
0
print("END: Read in reservoir fields")

# Permeability field harmonic interpolation to facets
Kx_facet = fd.conditional(fd.gt(fd.avg(Kx), 0.0), Kx('+')*Kx('-') / fd.avg(Kx), 0.0)
Ky_facet = fd.conditional(fd.gt(fd.avg(Ky), 0.0), Ky('+')*Ky('-') / fd.avg(Ky), 0.0)
Kz_facet = fd.conditional(fd.gt(fd.avg(Kz), 0.0), Kz('+')*Kz('-') / fd.avg(Kz), 0.0)

# We can now define the bilinear and linear forms for the left and right
dx = fd.dx
KdivU = fd.as_vector((Kx_facet*u.dx(0), Ky_facet*u.dx(1), Kz_facet*u.dx(2)))
a = (fd.dot(KdivU, fd.grad(v))) * dx
m = u * v * phi * dx

# Defining the eigenvalue problem

petsc_a = fd.assemble(a).M.handle
petsc_m = fd.assemble(m).M.handle

num_eigenvalues = 3

# Set solver options
opts = PETSc.Options()
opts.setValue("eps_gen_hermitian", None)
#opts.setValue("st_pc_factor_shift_type", "NONZERO")
opts.setValue("eps_type", "krylovschur")
#opts.setValue("eps_smallest_magnitude", None)
opts.setValue("eps_target_magnitude", None)
opts.setValue("eps_target", 1e-8)
opts.setValue("eps_tol", 1e-10)

# Solve for eigenvalues
コード例 #41
0
 def _update_centroids(self, field):
     """
     Update centroid values
     """
     assemble(TestFunction(self.P0) * field * dx, tensor=self.centroids_rhs)
     self.centroid_solver.solve(self.centroids, self.centroids_rhs)
コード例 #42
0
 def _update_centroids(self, field):
     """
     Update centroid values
     """
     b = assemble(TestFunction(self.P0) * field * dx)
     self.centroid_solver.solve(self.centroids, b)
コード例 #43
0
    def initialize(self, pc):
        _, P = pc.getOperators()
        assert P.type == "python"
        context = P.getPythonContext()
        (self.J, self.bcs) = (context.a, context.row_bcs)

        test, trial = self.J.arguments()
        if test.function_space() != trial.function_space():
            raise NotImplementedError("test and trial spaces must be the same")

        Pk = test.function_space()
        element = Pk.ufl_element()
        shape = element.value_shape()
        mesh = Pk.ufl_domain()
        if len(shape) == 0:
            P1 = firedrake.FunctionSpace(mesh, "CG", 1)
        elif len(shape) == 1:
            P1 = firedrake.VectorFunctionSpace(mesh, "CG", 1, dim=shape[0])
        else:
            P1 = firedrake.TensorFunctionSpace(mesh, "CG", 1, shape=shape,
                                               symmetry=element.symmetry())

        # TODO: A smarter low-order operator would also interpolate
        # any coefficients to the coarse space.
        mapper = ArgumentReplacer({test: firedrake.TestFunction(P1),
                                   trial: firedrake.TrialFunction(P1)})
        self.lo_J = map_integrands.map_integrand_dags(mapper, self.J)

        lo_bcs = []
        for bc in self.bcs:
            # Don't actually need the value, since it's only used for
            # killing parts of the restriction matrix.
            lo_bcs.append(firedrake.DirichletBC(P1, firedrake.zero(P1.shape),
                                                bc.sub_domain,
                                                method=bc.method))

        self.lo_bcs = tuple(lo_bcs)

        mat_type = PETSc.Options().getString(pc.getOptionsPrefix() + "lo_mat_type",
                                             firedrake.parameters["default_matrix_type"])
        self.lo_op = firedrake.assemble(self.lo_J, bcs=self.lo_bcs,
                                        mat_type=mat_type)
        self.lo_op.force_evaluation()
        A, P = pc.getOperators()
        nearnullsp = P.getNearNullSpace()
        if nearnullsp.handle != 0:
            # Actually have a near nullspace
            tmp = firedrake.Function(Pk)
            low = firedrake.Function(P1)
            vecs = []
            for vec in nearnullsp.getVecs():
                with tmp.dat.vec as v:
                    vec.copy(v)
                low.interpolate(tmp)
                with low.dat.vec_ro as v:
                    vecs.append(v.copy())
            nullsp = PETSc.NullSpace().create(vectors=vecs, comm=pc.comm)
            self.lo_op.petscmat.setNearNullSpace(nullsp)
        lo = PETSc.PC().create(comm=pc.comm)
        lo.incrementTabLevel(1, parent=pc)
        lo.setOperators(self.lo_op.petscmat, self.lo_op.petscmat)
        lo.setOptionsPrefix(pc.getOptionsPrefix() + "lo_")
        lo.setFromOptions()
        self.lo = lo
        self.restriction = restriction_matrix(Pk, P1, self.bcs, self.lo_bcs)

        self.work = self.lo_op.petscmat.createVecs()
        if len(self.bcs) > 0:
            bc_nodes = numpy.unique(numpy.concatenate([bc.nodes for bc in self.bcs]))
            bc_nodes = bc_nodes[bc_nodes < Pk.dof_dset.size]
            bc_iset = PETSc.IS().createBlock(numpy.prod(shape), bc_nodes,
                                             comm=PETSc.COMM_SELF)
            self.bc_indices = bc_iset.getIndices()
            bc_iset.destroy()
        else:
            self.bc_indices = numpy.empty(0, dtype=numpy.int32)
コード例 #44
0
    def initialize(self, pc):
        from firedrake import TrialFunction, TestFunction, dx, \
            assemble, inner, grad, split, Constant, parameters
        from firedrake.assemble import allocate_matrix, create_assembly_callable
        prefix = pc.getOptionsPrefix() + "pcd_"

        # we assume P has things stuffed inside of it
        _, P = pc.getOperators()
        context = P.getPythonContext()

        test, trial = context.a.arguments()
        if test.function_space() != trial.function_space():
            raise ValueError("Pressure space test and trial space differ")

        Q = test.function_space()

        p = TrialFunction(Q)
        q = TestFunction(Q)

        mass = p*q*dx

        # Regularisation to avoid having to think about nullspaces.
        stiffness = inner(grad(p), grad(q))*dx + Constant(1e-6)*p*q*dx

        opts = PETSc.Options()
        # we're inverting Mp and Kp, so default them to assembled.
        # Fp only needs its action, so default it to mat-free.
        # These can of course be overridden.
        # only Fp is referred to in update, so that's the only
        # one we stash.
        default = parameters["default_matrix_type"]
        Mp_mat_type = opts.getString(prefix+"Mp_mat_type", default)
        Kp_mat_type = opts.getString(prefix+"Kp_mat_type", default)
        self.Fp_mat_type = opts.getString(prefix+"Fp_mat_type", "matfree")

        Mp = assemble(mass, form_compiler_parameters=context.fc_params,
                      mat_type=Mp_mat_type)
        Kp = assemble(stiffness, form_compiler_parameters=context.fc_params,
                      mat_type=Kp_mat_type)

        Mp.force_evaluation()
        Kp.force_evaluation()

        # FIXME: Should we transfer nullspaces over.  I think not.

        Mksp = PETSc.KSP().create()
        Mksp.setOptionsPrefix(prefix + "Mp_")
        Mksp.setOperators(Mp.petscmat)
        Mksp.setUp()
        Mksp.setFromOptions()
        self.Mksp = Mksp

        Kksp = PETSc.KSP().create()
        Kksp.setOptionsPrefix(prefix + "Kp_")
        Kksp.setOperators(Kp.petscmat)
        Kksp.setUp()
        Kksp.setFromOptions()
        self.Kksp = Kksp

        state = context.appctx["state"]

        Re = context.appctx.get("Re", 1.0)

        velid = context.appctx["velocity_space"]

        u0 = split(state)[velid]
        fp = 1.0/Re * inner(grad(p), grad(q))*dx + inner(u0, grad(p))*q*dx

        self.Re = Re
        self.Fp = allocate_matrix(fp, form_compiler_parameters=context.fc_params,
                                  mat_type=self.Fp_mat_type)
        self._assemble_Fp = create_assembly_callable(fp, tensor=self.Fp,
                                                     form_compiler_parameters=context.fc_params,
                                                     mat_type=self.Fp_mat_type)
        self._assemble_Fp()
        self.Fp.force_evaluation()
        Fpmat = self.Fp.petscmat
        self.workspace = [Fpmat.createVecLeft() for i in (0, 1)]
コード例 #45
0
 def update(self, pc):
     firedrake.assemble(self.lo_J, bcs=self.lo_bcs, tensor=self.lo_op)
     self.lo_op.force_evaluation()
コード例 #46
0
ファイル: diagnostics.py プロジェクト: firedrakeproject/gusto
 def l2(f):
     return sqrt(assemble(dot(f, f)*dx))