# 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) #mpset.write(comm, prm_file) # uncomment to save parameters mpset.refresh() gc.collect() @pytest.fixture(scope='module') def postprocessor(request): t_end = 0.5 # CHANGE #3: Set to "t_end = 3.0" OTD = 2 # Order of Time Discretization rank = MPI.rank(mpi_comm_world()) scriptdir = os.path.dirname(os.path.realpath(__file__)) outdir = os.path.join(scriptdir, __name__) proc = Postprocessor(t_end, OTD, outdir) # Decide what should be plotted proc.register_fixed_variables((("t_end", t_end), ("OTD", OTD))) #proc.register_fixed_variables(
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()
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()
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()