Beispiel #1
0
def test_shear(scheme, nu_interp, postprocessor):
    #set_log_level(WARNING)
    assert scheme == "SemiDecoupled"

    dt = 0.0  # solve as the stationary problem

    # Read parameters
    scriptdir = os.path.dirname(os.path.realpath(__file__))
    prm_file = os.path.join(scriptdir, "interface-parameters.xml")
    mpset.read(prm_file)

    # Adjust parameters
    c = postprocessor.get_coefficients()
    mpset["model"]["eps"] = c[r"\eps"]
    mpset["model"]["rho"]["1"] = c[r"\rho_1"]
    mpset["model"]["rho"]["2"] = c[r"\rho_2"]
    mpset["model"]["nu"]["1"] = c[r"\nu_1"]
    mpset["model"]["nu"]["2"] = c[r"\nu_2"]
    mpset["model"]["chq"]["L"] = c[r"L_0"]
    mpset["model"]["chq"]["V"] = c[r"V_0"]
    mpset["model"]["chq"]["rho"] = c[r"\rho_0"]
    mpset["model"]["mobility"]["M0"] = 1.0e+0
    mpset["model"]["sigma"]["12"] = 1.0e-0
    #mpset.show()

    cc = wrap_coeffs_as_constants(c)

    # Names and directories
    basename = postprocessor.basename
    label = "{}_{}".format(basename, nu_interp)
    outdir = postprocessor.outdir

    for level in range(2, 3):
        # Prepare domain and discretization
        mesh, boundary_markers, pinpoint, periodic_bnd = create_domain(
            level, "crossed")
        del periodic_bnd
        DS, div_v = create_discretization(scheme, mesh, div_projection=True)
        DS.parameters["PTL"] = 1
        DS.setup()

        # Prepare initial and boundary conditions
        load_initial_conditions(DS, c)
        bcs = create_bcs(DS, boundary_markers, pinpoint)  # for Dirichlet
        p_h = create_hydrostatic_pressure(mesh, cc)  # for Neumann

        # Force applied on the top plate
        B = 0.0 if dt == 0.0 else 1.0
        applied_force = df.Expression(
            ("A*(1.0 - B*exp(-alpha*t))", "0.0"),
            degree=DS.subspace("v", 0).ufl_element().degree(),
            t=0.0,
            alpha=1.0,
            A=1.0,
            B=B)

        # Prepare model
        model = ModelFactory.create("Incompressible", DS, bcs)
        model.parameters["THETA2"] = 0.0
        #model.parameters["rho"]["itype"] = "lin"
        #model.parameters["rho"]["trunc"] = "minmax"
        model.parameters["nu"]["itype"] = nu_interp
        model.parameters["nu"]["trunc"] = "minmax"
        #model.parameters["nu"]["trunc"] = "clamp_hard"
        #model.parameters["mobility"]["cut"] = True

        # Prepare external source term
        g_a = c[r"g_a"]
        g_a /= mpset["model"]["chq"]["V"]**2.0 * mpset["model"]["chq"]["L"]
        f_src = df.Constant((0.0, -g_a), cell=mesh.ufl_cell(), name="f_src")
        model.load_sources(f_src)

        # Create forms
        forms = model.create_forms()

        # Add boundary integrals
        n = DS.facet_normal()
        ds = df.Measure("ds", subdomain_data=boundary_markers)
        test = DS.test_functions()

        forms["lin"]["rhs"] +=\
          df.inner(applied_force, test["v"]) * ds(3)     # driving force
        forms["lin"]["rhs"] -=\
          p_h * df.inner(n, test["v"]) * (ds(2) + ds(4)) # hydrostatic balance

        # Prepare solver
        solver = SolverFactory.create(model, forms, fix_p=False)

        # Prepare time-stepping algorithm
        comm = mesh.mpi_comm()
        pv = DS.primitive_vars_ctl()
        modulo_factor = 1
        xfields = list(zip(pv["phi"].split(), ("phi", )))
        xfields.append((pv["p"].dolfin_repr(), "p"))
        if scheme == "FullyDecoupled":
            xfields += list(zip(pv["v"].split(), ("v1", "v2")))
        else:
            xfields.append((pv["v"].dolfin_repr(), "v"))
        if div_v is not None:
            xfields.append((div_v, "div_v"))
        functionals = {"t": [], "E_kin": [], "Psi": [], "mean_p": []}
        hook = prepare_hook(model, applied_force, functionals, modulo_factor,
                            div_v)
        logfile = "log_{}.dat".format(label)
        TS = TimeSteppingFactory.create("ConstantTimeStep",
                                        comm,
                                        solver,
                                        hook=hook,
                                        logfile=logfile,
                                        xfields=xfields,
                                        outdir=outdir)
        TS.parameters["xdmf"]["folder"] = "XDMF_{}".format(label)
        TS.parameters["xdmf"]["modulo"] = modulo_factor
        TS.parameters["xdmf"]["flush"] = True
        TS.parameters["xdmf"]["iconds"] = True

        # Time-stepping
        with Timer("Time stepping") as tmr_tstepping:
            result = TS.run(0.0, 2.0, dt, OTD=1)

        # Pre-process results
        v = pv["v"].dolfin_repr()
        p = pv["p"].dolfin_repr()
        phi = pv["phi"].split()[0]

        w_diff = DS.solution_ctl()[0].copy(True)
        w0 = DS.solution_ptl(0)[0]
        w_diff.vector().axpy(-1.0, w0.vector())
        phi_diff = w_diff.split(True)[0]
        phi_diff.rename("phi_diff", "phi_tstep_difference")
        xdmfdir = \
          os.path.join(outdir, TS.parameters["xdmf"]["folder"], "phi_diff.xdmf")
        with df.XDMFFile(xdmfdir) as file:
            file.write(phi_diff, 0.0)

        D_12 = df.project(0.5 * v.sub(0).dx(1), div_v.function_space())

        if nu_interp in [
                "har",
        ]:
            deg = DS.subspace("phi", 0).ufl_element().degree()
            V_nu = df.FunctionSpace(mesh, "DG", deg)
        else:
            V_nu = DS.subspace("phi", 0, deepcopy=True)
        nu_0 = df.project(model.coeffs["nu"], V_nu)
        T_12 = df.project(model.coeffs["nu"] * v.sub(0).dx(1), V_nu)

        #p_ref = df.project(p_h, df.FunctionSpace(mesh, W.sub(1).ufl_element()))

        # Save results
        make_cut = postprocessor._make_cut
        rs = dict(level=level,
                  r_dens=c[r"r_dens"],
                  r_visc=c[r"r_visc"],
                  nu_interp=nu_interp)
        rs[r"$v_1$"] = make_cut(v.sub(0))
        rs[r"$p$"] = make_cut(p)
        rs[r"$\phi$"] = make_cut(phi)
        rs[r"$D_{12}$"] = make_cut(D_12)
        rs[r"$T_{12}$"] = make_cut(T_12)
        rs[r"$\nu$"] = make_cut(nu_0)
        print(label, level)

        # Send to posprocessor
        comm = mesh.mpi_comm()
        rank = df.MPI.rank(comm)
        postprocessor.add_result(rank, rs)

    # Save results into a binary file
    filename = "results_{}.pickle".format(label)
    postprocessor.save_results(filename)

    # Flush plots as we now have data for all level values
    postprocessor.flush_plots()

    # Cleanup
    df.set_log_level(df.INFO)
    gc.collect()
Beispiel #2
0
    basename = postprocessor.basename
    outdir = postprocessor.outdir

    # Scheme-dependent variables
    k = 1  #if scheme == "FullyDecoupled" else 1

    for level in range(2):  # CHANGE #1: set " level in range(4)"
        dividing_factor = 0.5**level
        modulo_factor = 1 if level == 0 else 2**(level - 1) * 1
        eps = dividing_factor * 0.04
        gamma = dividing_factor * 4e-5
        dt = dividing_factor * 0.008  # CHANGE #2: use smaller time step if needed
        # NOTE: smaller time step required by 'FullyDecoupled' scheme (case #2)
        label = "case_{}_{}_level_{}_k_{}_dt_{}_{}".format(
            case, scheme, level, k, dt, basename)
        with Timer("Prepare") as tmr_prepare:
            # Prepare space discretization
            mesh, boundary_markers, periodic_boundary = create_domain(level)
            periodic_boundary = None  # leave uncommented to use free-slip
            DS = create_discretization(scheme, mesh, k, periodic_boundary)
            DS.parameters["PTL"] = OTD  #if scheme == "FullyDecoupled" else 1
            DS.setup()

            # Prepare initial conditions
            load_initial_conditions(DS, eps)

            # Prepare boundary conditions
            bcs = create_bcs(DS, boundary_markers, periodic_boundary)

            # Set up variable model parameters
            mpset["model"]["eps"] = 2.0 * (2.0**0.5) * eps
Beispiel #3
0
def test_scaling_mesh(pcd_variant, ls, matching_p, postprocessor):
    """
    Compute convergence rates for fixed time step and gradually refined mesh or
    increasing element order.
    """
    set_log_level(WARNING)

    degrise = 3  # degree rise for computation of errornorm

    # Read parameters
    scriptdir = os.path.dirname(os.path.realpath(__file__))
    prm_file = os.path.join(scriptdir, "mms-parameters.xml")
    mpset.read(prm_file)

    # Fixed parameters
    OTD = postprocessor.OTD
    dt = postprocessor.dt
    t_end = postprocessor.t_end
    test_type = postprocessor.test

    # Discretization
    scheme = "SemiDecoupled"

    # Names and directories
    basename = postprocessor.basename
    outdir = postprocessor.outdir

    # Mesh independent predefined quantities
    msol = create_manufactured_solution()
    ic = create_initial_conditions(msol)

    # Iterate over refinement level
    for it in range(1, 6):  # CHANGE #1: set "it in range(1, 8)"
        # Decide which test to perform
        if test_type == "ref":
            level = it
            k = 1
        elif test_type == "ord":
            level = 1
            k = it
        label = "{}_{}_level_{}_k_{}_{}".format(pcd_variant, ls, level, k,
                                                basename)
        with Timer("Prepare") as tmr_prepare:
            # Prepare discretization
            mesh, boundary_markers = create_domain(level)
            DS = create_discretization(scheme, mesh, k)
            DS.parameters["PTL"] = OTD
            DS.setup()
            DS.load_ic_from_simple_cpp(ic)
            esol = create_exact_solution(msol, DS.finite_elements(), degrise)
            bcs = create_bcs(DS, boundary_markers, esol)

            # Prepare model
            model = ModelFactory.create("Incompressible", DS, bcs)
            cell = DS.mesh().ufl_cell()
            t_src_ctl = Constant(0.0, cell=cell, name="t_src_ctl")
            t_src_ptl = Constant(0.0, cell=cell, name="t_src_ptl")
            f_src_ctl, g_src_ctl = \
              create_source_terms(t_src_ctl, mesh, model, msol, matching_p)
            f_src_ptl, g_src_ptl = \
              create_source_terms(t_src_ptl, mesh, model, msol, matching_p)
            # NOTE: Source terms are time-dependent. Updates to these terms
            #       are possible via 't_src.assign(Constant(t))', where 't'
            #       denotes the actual time value.
            t_src = [
                t_src_ctl,
            ]
            f_src = [
                f_src_ctl,
            ]
            g_src = [
                g_src_ctl,
            ]
            if OTD == 2:
                t_src.append(t_src_ptl)
                g_src.append(g_src_ptl)
            model.load_sources(f_src, g_src)
            forms = model.create_forms(matching_p)

            # NOTE: Here is the possibility to modify forms, e.g. by adding
            #       boundary integrals.

            # Prepare solver
            comm = mesh.mpi_comm()
            solver = SolverFactory.create(model, forms, fix_p=True)
            solver.data["solver"]["NS"] = \
              create_pcd_solver(comm, pcd_variant, ls, mumps_debug=False)

            # PETScOptions.set("ksp_monitor")
            # solver.data["solver"]["NS"].set_from_options()

            # Prepare time-stepping algorithm
            xfields = None
            # NOTE: Uncomment the following block of code to get XDMF output
            # pv = DS.primitive_vars_ctl()
            # phi, chi, v, p = pv["phi"], pv["chi"], pv["v"], pv["p"]
            # phi_, chi_, v_ = phi.split(), chi.split(), v.split()
            # xfields = list(zip(phi_, len(phi_)*[None,])) \
            #         + list(zip(v_, len(v_)*[None,])) \
            #         + [(p.dolfin_repr(), None),]
            hook = prepare_hook(t_src, model, esol, degrise, {})
            logfile = "log_{}.dat".format(label)
            #info("BREAK POINT %ia" % level)
            TS = TimeSteppingFactory.create("ConstantTimeStep",
                                            comm,
                                            solver,
                                            hook=hook,
                                            logfile=logfile,
                                            xfields=xfields,
                                            outdir=outdir)
            #info("BREAK POINT %ib" % level) <-- not reached for level == 2
            #                                    when running in parallel

        # Time-stepping
        t_beg = 0.0
        with Timer("Time stepping") as tmr_tstepping:
            result = TS.run(t_beg, t_end, dt, OTD)

        # Get number of Krylov iterations if relevant
        try:
            krylov_it = solver.iters["NS"][0]
        except AttributeError:
            krylov_it = 0

        # Prepare results
        name = logfile[4:-4]
        x_var = k if test_type == "ord" else mesh.hmin()
        result.update(scheme=scheme,
                      pcd_variant=pcd_variant,
                      ls=ls,
                      krylov_it=krylov_it,
                      ndofs=DS.num_dofs(),
                      dt=dt,
                      t_end=t_end,
                      OTD=OTD,
                      err=hook.err,
                      x_var=x_var,
                      tmr_prepare=tmr_prepare.elapsed()[0],
                      tmr_tstepping=tmr_tstepping.elapsed()[0])
        print(name, result["ndofs"], result["it"], result["krylov_it"],
              result["tmr_tstepping"])

        # Send to posprocessor
        rank = MPI.rank(comm)
        postprocessor.add_result(rank, result)

        # Save results into a binary file
        filename = "results_{}.pickle".format(label)
        postprocessor.save_results(filename)

    # Pop results that we do not want to report at the moment
    postprocessor.pop_items(["ndofs", "scheme", "tmr_prepare"])

    # Flush plots as we now have data for all level values
    postprocessor.flush_plots()

    # Store timings
    #datafile = os.path.join(outdir, "timings.xml")
    #dump_timings_to_xml(datafile, TimingClear_clear)

    # Cleanup
    set_log_level(INFO)
    #mpset.write(comm, prm_file) # uncomment to save parameters
    mpset.refresh()
    gc.collect()
Beispiel #4
0
def test_scaling_time(scheme, matching_p, postprocessor):
    """
    Compute convergence rates for fixed element order, fixed mesh and
    gradually decreasing time step.
    """
    # Additional test configuration w.r.t. chosen scheme
    if scheme == "SemiDecoupled":
        OTD = 1
        method = "it"
    elif scheme == "FullyDecoupled":
        OTD = 2
        method = "lu" # iterative solvers not yet supported
    else:
        assert False

    # Run test
    set_log_level(WARNING)

    degrise = 3 # degree rise for computation of errornorm

    # Read parameters
    scriptdir = os.path.dirname(os.path.realpath(__file__))
    prm_file = os.path.join(scriptdir, "mms-parameters.xml")
    mpset.read(prm_file)

    # Fixed parameters
    level = postprocessor.level
    k = postprocessor.OPA
    t_end = postprocessor.t_end

    # Names and directories
    basename = postprocessor.basename
    outdir = postprocessor.outdir

    # Mesh independent predefined quantities
    msol = create_manufactured_solution()
    ic = create_initial_conditions(msol)

    # Prepare space discretization, exact solution and bcs
    mesh, boundary_markers = create_domain(level)
    DS = create_discretization(scheme, mesh, k)
    DS.parameters["PTL"] = OTD
    DS.setup()
    esol = create_exact_solution(msol, DS.finite_elements(), degrise)
    bcs = create_bcs(DS, boundary_markers, esol, method)

    # Iterate over time step
    for m in range(6): # CHANGE #1: set "m in range(7)"
        dt = 0.1*0.5**m
        label = "{}_dt_{}_{}".format(scheme, dt, basename)
        with Timer("Prepare") as tmr_prepare:
            # Reset sol_ptl[0] back to initial conditions
            DS.load_ic_from_simple_cpp(ic)

            # Prepare model
            model = ModelFactory.create("Incompressible", DS, bcs)
            cell = DS.mesh().ufl_cell()
            t_src_ctl = Constant(0.0, cell=cell, name="t_src_ctl")
            t_src_ptl = Constant(0.0, cell=cell, name="t_src_ptl")
            f_src_ctl, g_src_ctl = \
              create_source_terms(t_src_ctl, mesh, model, msol, matching_p)
            f_src_ptl, g_src_ptl = \
              create_source_terms(t_src_ptl, mesh, model, msol, matching_p)
            t_src = [t_src_ctl,]
            f_src = [f_src_ctl,]
            g_src = [g_src_ctl,]
            if OTD == 2 and scheme in ["Monolithic", "SemiDecoupled"]:
                t_src.append(t_src_ptl)
                g_src.append(g_src_ptl)
                if scheme == "Monolithic":
                    f_src.append(f_src_ptl)
            model.load_sources(f_src, g_src)
            forms = model.create_forms(matching_p)

            # Prepare solver
            comm = mesh.mpi_comm()
            solver = SolverFactory.create(model, forms, fix_p=(method == "it"))
            if method == "it":
                solver.data["solver"]["CH"]["lin"] = \
                  create_ch_solver(comm, "bjacobi")
                solver.data["solver"]["NS"] = \
                  create_pcd_solver(comm, "BRM1", "iterative")
                # prefix_ch = solver.data["solver"]["CH"]["lin"].get_options_prefix()
                # PETScOptions.set(prefix_ch+"ksp_monitor_true_residual")
                # solver.data["solver"]["CH"]["lin"].set_from_options()
                # prefix_ns = solver.data["solver"]["NS"].get_options_prefix()
                # PETScOptions.set(prefix_ns+"ksp_monitor")
                # solver.data["solver"]["NS"].set_from_options()

            # Prepare time-stepping algorithm
            xfields = None
            # NOTE: Uncomment the following block of code to get XDMF output
            # pv = DS.primitive_vars_ctl()
            # phi, chi, v, p = pv["phi"], pv["chi"], pv["v"], pv["p"]
            # phi_, chi_, v_ = phi.split(), chi.split(), v.split()
            # xfields = list(zip(phi_, len(phi_)*[None,])) \
            #         + list(zip(v_, len(v_)*[None,])) \
            #         + [(p.dolfin_repr(), None),]
            hook = prepare_hook(t_src, model, esol, degrise, {})
            logfile = "log_{}.dat".format(label)
            TS = TimeSteppingFactory.create("ConstantTimeStep", comm, solver,
                   hook=hook, logfile=logfile, xfields=xfields, outdir=outdir)

        # Time-stepping
        t_beg = 0.0
        with Timer("Time stepping") as tmr_tstepping:
            it = 0
            if OTD == 2:
                if scheme == "FullyDecoupled":
                    dt0 = dt
                    result = TS.run(t_beg, dt0, dt0, OTD=1, it=it)
                    t_beg = dt
                elif scheme == "Monolithic":
                    dt0 = 1.0e-4*dt
                    result = TS.run(t_beg, dt0, dt0, OTD=1, it=it)
                    if dt - dt0 > 0.0:
                        it = 0.5
                        result = TS.run(dt0, dt, dt - dt0, OTD=2, it=it)
                    t_beg = dt
                    it = 1
            result = TS.run(t_beg, t_end, dt, OTD, it)

        # Prepare results
        name = logfile[4:-4]
        result.update(
            method=method,
            ndofs=DS.num_dofs(),
            scheme=scheme,
            dt=dt,
            t_end=t_end,
            OTD=OTD,
            err=hook.err,
            level=level,
            k=k,
            tmr_prepare=tmr_prepare.elapsed()[0],
            tmr_tstepping=tmr_tstepping.elapsed()[0]
        )
        print(name, result["ndofs"], result["tmr_prepare"],
              result["tmr_solve"], result["it"], result["tmr_tstepping"])

        # Send to posprocessor
        rank = MPI.rank(comm)
        postprocessor.add_result(rank, result)

        # Save results into a binary file
        filename = "results_{}.pickle".format(label)
        postprocessor.save_results(filename)

    # Pop results that we do not want to report at the moment
    postprocessor.pop_items(["ndofs", "tmr_prepare", "tmr_solve", "it", "OTD"])

    # Flush plots as we now have data for all level values
    postprocessor.flush_plots()

    # Store timings
    #datafile = os.path.join(outdir, "timings.xml")
    #dump_timings_to_xml(datafile, TimingClear_clear)

    # Cleanup
    set_log_level(INFO)
    #mpset.write(comm, prm_file) # uncomment to save parameters
    mpset.refresh()
    gc.collect()
Beispiel #5
0
def test_scaling_mesh(nu, pcd_variant, ls, postprocessor):
    #set_log_level(WARNING)

    # Read parameters
    scriptdir = os.path.dirname(os.path.realpath(__file__))
    prm_file = os.path.join(scriptdir, "step-parameters.xml")
    mpset.read(prm_file)

    # Adjust parameters
    mpset["model"]["nu"]["1"] = nu
    mpset["model"]["nu"]["2"] = nu

    # Parameters for setting up MUFLON components
    dt = postprocessor.dt
    t_end = postprocessor.t_end   # final time of the simulation
    scheme = "SemiDecoupled"
    OTD = 1
    k = 1
    modulo_factor = 2

    # Names and directories
    outdir = postprocessor.outdir

    # Mesh independent predefined quantities
    ic = SimpleCppIC()
    ic.add("phi", "1.0")

    # Prepare figure for plotting the vorticity
    fig_curl = pyplot.figure()
    gs = gridspec.GridSpec(2, 2, height_ratios=[3, 1], width_ratios=[0.01, 1], hspace=0.05)
    ax_curl = fig_curl.add_subplot(gs[0, 1])
    ax_curl.set_xlabel(r"time $t$")
    ax_curl.set_ylabel(r"$\omega_\Omega = \int_\Omega \nabla \times \mathbf{v}$")
    del gs

    for level in range(4):
        with Timer("Prepare") as tmr_prepare:
            # Prepare space discretization
            mesh, boundary_markers = create_domain(level)
            #pyplot.figure(); plot(mesh)
            #pyplot.savefig(os.path.join(outdir, "mesh.pdf"))
            if dt is None:
                hh = mesh.hmin()/(2.0**0.5) # mesh size in the direction of inflow
                umax = 1.0                  # max velocity at the inlet
                dt = 0.8*hh/umax            # automatically computed time step
                del hh, umax
            label = "level_{}_nu_{}_{}_{}_dt_{}_{}".format(
                level, nu, pcd_variant, ls, dt, postprocessor.basename)

            DS = create_discretization(scheme, mesh, k)
            DS.setup()
            DS.load_ic_from_simple_cpp(ic)

            # Prepare boundary conditions
            bcs, inflow = create_bcs(DS, boundary_markers, pcd_variant) #, t0=10*dt

            # Prepare model
            model = ModelFactory.create("Incompressible", DS, bcs)
            #model.parameters["THETA2"] = 0.0

            # Create forms
            forms = model.create_forms()
            if ls == "direct":
                forms["pcd"]["a_pc"] = None

            # Add boundary integrals
            n = DS.facet_normal()
            ds_marked = Measure("ds", subdomain_data=boundary_markers)
            test = DS.test_functions()
            trial = DS.trial_functions()
            pv = DS.primitive_vars_ctl(indexed=True)
            pv0 = DS.primitive_vars_ptl(0, indexed=True)
            cc = model.coeffs

            w = cc["rho"]*pv0["v"] + cc["THETA2"]*cc["J"]
            a_surf = (
                0.5*inner(w, n)*inner(trial["v"], test["v"])
              - cc["nu"]*inner(dot(grad(trial["v"]).T, n), test["v"])
            )*ds_marked(2)
            forms["lin"]["lhs"] += a_surf
            if forms["pcd"]["a_pc"] is not None:
                forms["pcd"]["a_pc"] += a_surf

            if pcd_variant == "BRM2":
                forms["pcd"]["kp"] -= \
                  (1.0/cc["nu"])*inner(w, n)*test["p"]*trial["p"]*ds_marked(1)
                # TODO: Is this beneficial?
                # forms["pcd"]["kp"] -= \
                #   (1.0/cc["nu"])*inner(w, n)*test["p"]*trial["p"]*ds_marked(0)

                # TODO: Alternatively try:
                # forms["pcd"]["kp"] -= \
                #   (1.0/cc["nu"])*inner(w, n)*test["p"]*trial["p"]*ds

            # Prepare solver
            comm = mesh.mpi_comm()
            solver = SolverFactory.create(model, forms)
            prefix = "LU"
            solver.data["solver"]["NS"] = \
              create_pcd_solver(comm, pcd_variant, ls, mumps_debug=False)
            prefix = solver.data["solver"]["NS"].get_options_prefix()

            #PETScOptions.set(prefix+"ksp_monitor")
            #solver.data["solver"]["NS"].set_from_options()

            # Prepare time-stepping algorithm
            pv = DS.primitive_vars_ctl()
            xfields = list(zip(pv["phi"].split(), ("phi",)))
            xfields.append((pv["p"].dolfin_repr(), "p"))
            xfields.append((pv["v"].dolfin_repr(), "v"))
            functionals = {"t": [], "vorticity": []}
            hook = prepare_hook(DS, functionals, modulo_factor, inflow)
            logfile = "log_{}.dat".format(label)
            TS = TimeSteppingFactory.create("ConstantTimeStep", comm, solver,
                   hook=hook, logfile=logfile, xfields=xfields, outdir=outdir)
            TS.parameters["xdmf"]["folder"] = "XDMF_{}".format(label)
            TS.parameters["xdmf"]["modulo"] = modulo_factor
            TS.parameters["xdmf"]["flush"]  = True
            TS.parameters["xdmf"]["iconds"] = True

        # Time-stepping
        t_beg = 0.0
        with Timer("Time stepping") as tmr_tstepping:
            result = TS.run(t_beg, t_end, dt, OTD)

        # Get number of Krylov iterations if relevant
        try:
            krylov_it = solver.iters["NS"][0]
        except AttributeError:
            krylov_it = 0

        # Prepare results (already contains dt, it, t_end, tmr_solve)
        result.update(
            nu=nu,
            pcd_variant=pcd_variant,
            ls=ls,
            krylov_it=krylov_it,
            ndofs=DS.num_dofs(),
            level=level,
            h_min=mesh.hmin(),
            tmr_prepare=tmr_prepare.elapsed()[0],
            tmr_tstepping=tmr_tstepping.elapsed()[0],
            scheme=scheme,
            OTD=OTD,
            k=k,
            t=functionals["t"],
            vorticity=functionals["vorticity"]
        )
        print(label, prefix, result["ndofs"], result["it"],
              result["tmr_tstepping"], result["krylov_it"])

        # Send to posprocessor
        rank = MPI.rank(comm)
        postprocessor.add_result(rank, result)

        # Add vorticity plot
        ax_curl.plot(functionals["t"], functionals["vorticity"], label=label)
        ax_curl.legend(bbox_to_anchor=(0, -0.2), loc=2, borderaxespad=0,
                fontsize='x-small', ncol=1)

    # Save results into a binary file
    filename = "results_{}.pickle".format(label)
    postprocessor.save_results(filename)

    # Pop results that we do not want to report at the moment
    postprocessor.pop_items([
        "level", "h_min", "tmr_prepare", "tmr_tstepping",
        "scheme", "OTD", "k", "t", "vorticity"])

    # Flush plots as we now have data for all level values
    postprocessor.flush_plots()
    fig_curl.savefig(os.path.join(outdir, "fig_vorticity_{}.pdf".format(label)))

    # # Plot last obtained solution
    # pv = DS.primitive_vars_ctl()
    # v = as_vector(pv["v"].split())
    # p = pv["p"].dolfin_repr()
    # #phi = pv["phi"].split()
    # size = MPI.size(mesh.mpi_comm())
    # rank = MPI.rank(mesh.mpi_comm())
    # pyplot.figure()
    # pyplot.subplot(2, 1, 1)
    # plot(v, title="velocity")
    # pyplot.subplot(2, 1, 2)
    # plot(p, title="pressure")
    # pyplot.savefig(os.path.join(outdir, "fig_v_p_size{}_rank{}.pdf".format(size, rank)))
    # pyplot.figure()
    # plot(p, title="pressure", mode="warp")
    # pyplot.savefig(os.path.join(outdir, "fig_warp_size{}_rank{}.pdf".format(size, rank)))

    # Store timings
    #datafile = os.path.join(outdir, "timings.xml")
    #dump_timings_to_xml(datafile, TimingClear_clear)

    # Cleanup
    set_log_level(INFO)
    #mpset.write(comm, prm_file) # uncomment to save parameters
    mpset.refresh()
    gc.collect()
Beispiel #6
0
def test_stokes_pool(augmentedTH, div_projection, calibrate, postprocessor):
    #set_log_level(WARNING)

    degrise = 3  # degree rise for computation of errornorm

    # Set parameters
    nu1 = Constant(1.002e-3, name="nu1")
    nu2 = Constant(1.78e-5, name="nu2")
    rho1 = Constant(998.207, name="rho1")
    rho2 = Constant(1.2041, name="rho2")

    # Fixed parameters
    t_end = postprocessor.t_end

    # Names and directories
    basename = postprocessor.basename
    outdir = postprocessor.outdir

    # Order of finite elements
    k = 1

    for level in range(1, 2):
        dividing_factor = 0.5**level
        modulo_factor = 1 if level == 0 else 2**(level - 1)
        dt = dividing_factor * 0.008
        label = "level_{}_k_{}_dt_{}_{}".format(level, k, dt, basename)
        with Timer("Prepare") as tmr_prepare:
            # Prepare space discretization
            mesh, boundary_markers, periodic_boundary = create_domain(level)
            w, w0, div_v, phi, null_fcn, null_space, q_aux, p_aux = create_functions(
                mesh, k, augmentedTH, calibrate, periodic_boundary,
                div_projection)

            # Prepare variable density and viscosity
            eps = 6.0 * mesh.hmin()
            initialize_phi(phi, eps)
            nu = project((nu1 - nu2) * phi + nu2, phi.function_space())
            rho = project((rho1 - rho2) * phi + rho2, phi.function_space())
            nu.rename("nu", "viscosity")
            rho.rename("rho", "density")

            # tol = 1e-4
            # assert near(nu(0.5, 0.01), float(nu1), tol)
            # assert near(nu(0.5, 0.99), float(nu2), tol)
            # assert near(rho(0.5, 0.01), float(rho1), tol)
            # assert near(rho(0.5, 0.99), float(rho2), tol)
            # del tol
            # pyplot.figure(); plot(nu, mode="warp", title="viscosity")
            # pyplot.figure(); plot(rho, mode="warp", title="density")
            # pyplot.show(); exit()

            # Prepare source terms
            g0 = 9.8
            f_src = Constant((0.0, -g0), name="f_src")

            # Prepare exact pressure for error computations
            v, p = w.split()
            p_ex = create_exact_solution(eps, float(rho1), float(rho2), g0,
                                         calibrate, degrise,
                                         rho.function_space().ufl_element())
            p_err = Function(
                FunctionSpace(mesh,
                              p.function_space().ufl_element()))
            p_err.rename("p_err", "p_error")

            # Prepare boundary conditions
            bcs = create_bcs(w.function_space(), boundary_markers, p_ex,
                             calibrate)

            # Create forms
            a, L, a_pc, a_aux, L_aux = create_forms(dt, w, w0, rho, nu, f_src,
                                                    q_aux, p_aux)

            # Prepare solver
            solver = LUSolver("mumps")
            # solver = PETScKrylovSolver("minres", "hypre_amg")
            # prm = solver.parameters
            # prm["monitor_convergence"] = True
            # #prm["relative_tolerance"] = 1e-8
            # prm["maximum_iterations"] = 100
            # info(prm, True)

            # Prepare time-stepping algorithm
            comm = mesh.mpi_comm()
            xfields = [(v, "v"), (p, "p"), (rho, "rho"), (p_err, "p_err"),
                       (q_aux, "q_aux")]
            if div_v is not None:
                xfields.append((div_v, "div_v"))
            functionals = {"t": [], "E_kin": [], "err_p": [], "mean_p": []}
            hook = prepare_hook(mesh, rho, v, p, p_ex, p_err, functionals,
                                modulo_factor, degrise, div_v)
            logfile = "log_{}.dat".format(label)
            TS = CustomizedTimeStepping(comm,
                                        solver,
                                        hook=hook,
                                        logfile=logfile,
                                        xfields=xfields,
                                        outdir=outdir,
                                        a=a,
                                        a_pc=a_pc,
                                        L=L,
                                        bcs=bcs,
                                        w=w,
                                        w0=w0,
                                        rho=rho,
                                        f_src=f_src,
                                        q_aux=q_aux,
                                        p_aux=p_aux,
                                        a_aux=a_aux,
                                        L_aux=L_aux,
                                        null_fcn=null_fcn,
                                        null_space=null_space,
                                        domain_size=assemble(
                                            Constant(1.0) * dx(mesh)))
            TS.parameters["xdmf"]["folder"] = "XDMF_{}".format(label)
            TS.parameters["xdmf"]["modulo"] = modulo_factor
            TS.parameters["xdmf"]["flush"] = True
            TS.parameters["xdmf"]["iconds"] = True

        # Time-stepping
        t_beg = 0.0
        with Timer("Time stepping") as tmr_tstepping:
            result = TS.run(t_beg, t_end, dt)

        # Prepare results
        result.update(ndofs=w.function_space().dim(),
                      level=level,
                      h_min=mesh.hmin(),
                      k=k,
                      t=hook.functionals["t"],
                      E_kin=hook.functionals["E_kin"],
                      err_p=hook.functionals["err_p"],
                      mean_p=hook.functionals["mean_p"],
                      tmr_prepare=tmr_prepare.elapsed()[0],
                      tmr_tstepping=tmr_tstepping.elapsed()[0])
        print(label, result["ndofs"], result["h_min"], result["tmr_prepare"],
              result["tmr_solve"], result["it"], result["tmr_tstepping"])

        # Send to posprocessor
        rank = MPI.rank(comm)
        postprocessor.add_result(rank, result)

    # Save results into a binary file
    filename = "results_{}.pickle".format(label)
    postprocessor.save_results(filename)

    # Pop results that we do not want to report at the moment
    postprocessor.pop_items(
        ["ndofs", "tmr_prepare", "tmr_solve", "tmr_tstepping", "it", "h_min"])

    # Flush plots as we now have data for all level values
    postprocessor.flush_plots()

    # Store timings
    #datafile = os.path.join(outdir, "timings.xml")
    #dump_timings_to_xml(datafile, TimingClear_clear)

    # Cleanup
    set_log_level(INFO)
    gc.collect()
Beispiel #7
0
    def _tstepping_loop(self, t_beg, t_end, dt, OTD=1, it=0):
        prm = self.parameters
        logger = self._logger
        solver = self._solver

        t = t_beg
        while t < t_end and not near(t, t_end, 0.1 * dt):
            # Move to the current time level
            t += dt  # update time
            it += 1  # update iteration number

            # User defined instructions
            if self._hook is not None:
                self._hook.head(t, it, logger)

            # Solve
            info("t = %g, step = %g, dt = %g" % (t, it, dt))
            with Timer("Solve (per time step)") as tmr_solve:
                begin("Prediction step")
                # Solve the auxiliary system
                b_aux = assemble(self.L_aux)
                q_aux, p_aux = self.q_aux, self.p_aux
                self.solver_aux.solve(q_aux.vector(), b_aux)
                # Calibrate the auxiliary pressure
                q_corr = assemble(q_aux * dx) / self.domain_size
                q_aux.assign(q_aux - q_corr * self.q_ones)
                #q_aux.vector().axpy(-q_corr, self.q_ones.vector())
                # Project to pressure function space
                p_aux.assign(project(q_aux, p_aux.function_space()))
                end()

                begin("Correction step")
                # Assemble matrices
                A = assemble(self.a)  # FIXME: constant in this special case
                b = assemble(self.L)
                for bc in self.bcs:
                    bc.apply(A, b)
                #A, b = assemble_system(self.a, self.L, self.bcs)
                #P, d = assemble_system(self.a_pc, self.L, self.bcs); del d

                if self.null_space:
                    # Attach null space to PETSc matrix
                    as_backend_type(A).set_nullspace(self.null_space)
                    # Orthogonalize RHS vector b with respect to the null space
                    self.null_space.orthogonalize(b)

                # Solve the problem
                solver.set_operator(A)
                #solver.set_operators(A, P)
                solver.solve(self.w.vector(), b)
                end()

                # Calibrate pressure
                if self.null_fcn:
                    v, p = split(self.w)
                    p_corr = assemble(p * dx) / self.domain_size
                    self.w.vector().axpy(-p_corr, self.null_fcn.vector())

            # User defined instructions
            if self._hook is not None:
                self._hook.tail(t, it, logger)

            # Save results
            if it % prm["xdmf"]["modulo"] == 0:
                if hasattr(self, "_xdmf_writer"):
                    self._xdmf_writer.write(t)

            # Update variables at previous time levels
            self.w0.assign(self.w)  # t^(n-0) <-- t^(n+1)

        # Flush output from logger
        self._logger.dump_to_file()

        result = {
            "dt": dt,
            "it": it,
            "t_end": t_end,
            "tmr_solve": tmr_solve.elapsed()[0]
        }

        return result