def test_marking(): # PDE data # ======== # define source term and diffusion coefficient # f = Expression("10.*exp(-(pow(x[0] - 0.6, 2) + pow(x[1] - 0.4, 2)) / 0.02)", degree=3) f = Constant("1.0") diffcoeff = Constant("1.0") # setup multivector #================== # solution evaluation function def eval_poisson(vec=None): if vec == None: # set default vector for new indices # mesh0 = refine(Mesh(lshape_xml)) mesh0 = UnitSquare(4, 4) fs = FunctionSpace(mesh0, "CG", 1) vec = FEniCSVector(Function(fs)) pde = FEMPoisson() fem_A = pde.assemble_lhs(diffcoeff, vec.basis) fem_b = pde.assemble_rhs(f, vec.basis) solve(fem_A, vec.coeffs, fem_b) return vec # define active multiindices mis = [Multiindex([0]), Multiindex([1]), Multiindex([0, 1]), Multiindex([0, 2])] # setup initial multivector w = MultiVectorWithProjection() Marking.refine(w, {}, mis, eval_poisson) logger.info("active indices of after initialisation: %s", w.active_indices()) # define coefficient field # ======================== # define coefficient field a0 = Expression("1.0", element=FiniteElement('Lagrange', ufl.triangle, 1)) # a = [Expression('2.+sin(2.*pi*I*x[0]+x[1]) + 10.*exp(-pow(I*(x[0] - 0.6)*(x[1] - 0.3), 2) / 0.02)', I=i, degree=3, a = (Expression('A*cos(pi*I*x[0])*cos(pi*I*x[1])', A=1 / i ** 2, I=i, degree=2, element=FiniteElement('Lagrange', ufl.triangle, 1)) for i in count()) rvs = (NormalRV(mu=0.5) for _ in count()) coeff_field = ParametricCoefficientField(a, rvs, a0=a0) # refinement loop # =============== theta_eta = 0.3 theta_zeta = 0.8 min_zeta = 1e-10 maxh = 1 / 10 theta_delta = 0.8 refinements = 1 for refinement in range(refinements): logger.info("*****************************") logger.info("REFINEMENT LOOP iteration %i", refinement + 1) logger.info("*****************************") # evaluate residual and projection error estimates # ================================================ mesh_markers_R, mesh_markers_P, new_multiindices = Marking.estimate_mark(w, coeff_field, f, theta_eta, theta_zeta, theta_delta, min_zeta, maxh) mesh_markers = mesh_markers_R.copy() mesh_markers.update(mesh_markers_P) Marking.refine(w, mesh_markers, new_multiindices.keys(), eval_poisson) # show refined meshes plot_meshes = False if plot_meshes: for mu, vec in w.iteritems(): plot(vec.basis.mesh, title=str(mu), interactive=False, axes=True) plot(vec._fefunc) interactive()
def AdaptiveSolver(A, coeff_field, pde, mis, w0, mesh0, degree, gamma=0.9, cQ=1.0, ceta=6.0, # marking parameters theta_eta=0.4, # residual marking bulk parameter theta_zeta=0.1, # projection marking threshold factor min_zeta=1e-8, # minimal projection error to be considered maxh=0.1, # maximal mesh width for projection maximum norm evaluation newmi_add_maxm=20, # maximal search length for new new multiindices (to be added to max order of solution w) theta_delta=10.0, # number new multiindex activation bound max_Lambda_frac=1 / 10, # max fraction of |Lambda| for new multiindices marking_strategy="SEPARATE with CELLPROJECTION", # separate (as initially in EGSZ) or relative marking wrt overall error, projection refinement based on cell or mesh errors # residual error quadrature_degree= -1, # projection error projection_degree_increase=1, refine_projection_mesh=1, # pcg solver pcg_eps=1e-6, pcg_maxiter=100, # adaptive algorithm threshold error_eps=1e-2, # refinements max_refinements=5, max_dof=1e10, do_refinement={"RES":True, "PROJ":True, "MI":False}, do_uniform_refinement=False, w_history=None, sim_stats=None): # define store function for timings from functools import partial def _store_stats(val, key, stats): stats[key] = val # define tuple type EstimatorData = namedtuple('EstimatorData', ['xi', 'gamma', 'cQ', 'ceta']) # get rhs f = pde.f # setup w and statistics w = w0 if sim_stats is None: assert w_history is None or len(w_history) == 0 sim_stats = [] try: start_iteration = max(len(sim_stats) - 1, 0) except: start_iteration = 0 logger.info("START/CONTINUE EXPERIMENT at iteration %i", start_iteration) # data collection import resource refinement = None for refinement in range(start_iteration, max_refinements + 1): logger.info("************* REFINEMENT LOOP iteration %i (of %i or max_dof %i) *************", refinement, max_refinements, max_dof) # memory usage info logger.info("\n======================================\nMEMORY USED: " + str(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss) + "\n======================================\n") # pcg solve # --------- stats = {} with timing(msg="pcg_solve", logfunc=logger.info, store_func=partial(_store_stats, key="TIME-PCG", stats=stats)): w, zeta = pcg_solve(A, w, coeff_field, pde, stats, pcg_eps, pcg_maxiter) logger.info("DIM of w = %s", w.dim) if w_history is not None and (refinement == 0 or start_iteration < refinement): w_history.append(w) # error evaluation # ---------------- # residual and projection errors logger.debug("evaluating ResidualEstimator.evaluateError") with timing(msg="ResidualEstimator.evaluateError", logfunc=logger.info, store_func=partial(_store_stats, key="TIME-ESTIMATOR", stats=stats)): xi, resind, projind, mierror, estparts, errors, timing_stats = ResidualEstimator.evaluateError(w, coeff_field, pde, f, zeta, gamma, ceta, cQ, newmi_add_maxm, maxh, quadrature_degree, projection_degree_increase, refine_projection_mesh) reserrmu = [(mu, sqrt(sum(resind[mu].coeffs ** 2))) for mu in resind.keys()] projerrmu = [(mu, sqrt(sum(projind[mu].coeffs ** 2))) for mu in projind.keys()] res_part, proj_part, pcg_part = estparts[0], estparts[1], estparts[2] err_res, err_proj, err_pcg = errors[0], errors[1], errors[2] logger.info("Overall Estimator Error xi = %s while residual error is %s, projection error is %s, pcg error is %s", xi, res_part, proj_part, pcg_part) stats.update(timing_stats) stats["EST"] = xi stats["RES-PART"] = res_part stats["PROJ-PART"] = proj_part stats["PCG-PART"] = pcg_part stats["ERR-RES"] = err_res stats["ERR-PROJ"] = err_proj stats["ERR-PCG"] = err_pcg stats["ETA-ERR"] = errors[0] stats["DELTA-ERR"] = errors[1] stats["ZETA-ERR"] = errors[2] stats["RES-mu"] = reserrmu stats["PROJ-mu"] = projerrmu stats["PROJ-MAX-ZETA"] = 0 stats["PROJ-MAX-INACTIVE-ZETA"] = 0 stats["MARKING-RES"] = 0 stats["MARKING-PROJ"] = 0 stats["MARKING-MI"] = 0 stats["TIME-MARKING"] = 0 stats["MI"] = [(mu, vec.basis.dim) for mu, vec in w.iteritems()] if refinement == 0 or start_iteration < refinement: sim_stats.append(stats) # print "SIM_STATS:", sim_stats[refinement] logger.debug("squared error components: eta=%s delta=%s zeta=%", errors[0], errors[1], errors[2]) # exit when either error threshold or max_refinements or max_dof is reached if refinement > max_refinements: logger.info("SKIPPING REFINEMENT after FINAL SOLUTION in ITERATION %i", refinement) break if sim_stats[refinement]["DOFS"] >= max_dof: logger.info("REACHED %i DOFS, EXITING refinement loop", sim_stats[refinement]["DOFS"]) break if xi <= error_eps: logger.info("error reached requested accuracy, xi=%f", xi) break # marking # ------- if refinement < max_refinements: if not do_uniform_refinement: logger.debug("starting Marking.mark") estimator_data = EstimatorData(xi=xi, gamma=gamma, cQ=cQ, ceta=ceta) mesh_markers_R, mesh_markers_P, new_multiindices, proj_zeta, new_multiindices_all = Marking.mark(resind, projind, mierror, w.max_order, theta_eta, theta_zeta, theta_delta, min_zeta, maxh, max_Lambda_frac, estimator_data, marking_strategy) sim_stats[-1]["PROJ-MAX-ZETA"] = proj_zeta[0] sim_stats[-1]["PROJ-MAX-INACTIVE-ZETA"] = proj_zeta[1] sim_stats[-1]["PROJ-INACTIVE-ZETA"] = new_multiindices_all # assert len(new_multiindices_all) == 0 or proj_zeta[1] == max([v for v in new_multiindices_all.values()]) logger.info("PROJECTION error values: max_zeta = %s and max_inactive_zeta = %s with threshold factor theta_zeta = %s (=%s)", proj_zeta[0], proj_zeta[1], theta_zeta, theta_zeta * proj_zeta[0]) logger.info("MARKING will be carried out with %s (res) + %s (proj) cells and %s new multiindices", sum([len(cell_ids) for cell_ids in mesh_markers_R.itervalues()]), sum([len(cell_ids) for cell_ids in mesh_markers_P.itervalues()]), len(new_multiindices)) stats["MARKING-RES"] = sum([len(cell_ids) for cell_ids in mesh_markers_R.itervalues()]) stats["MARKING-PROJ"] = sum([len(cell_ids) for cell_ids in mesh_markers_P.itervalues()]) stats["MARKING-MI"] = len(new_multiindices) if do_refinement["RES"]: mesh_markers = mesh_markers_R.copy() else: mesh_markers = defaultdict(set) logger.info("SKIP residual refinement") if do_refinement["PROJ"]: for mu, cells in mesh_markers_P.iteritems(): if len(cells) > 0: mesh_markers[mu] = mesh_markers[mu].union(cells) else: logger.info("SKIP projection refinement") if not do_refinement["MI"] or refinement == max_refinements: new_multiindices = {} logger.info("SKIP new multiindex refinement") else: logger.info("UNIFORM REFINEMENT active") mesh_markers = {} for mu, vec in w.iteritems(): from dolfin import cells mesh_markers[mu] = list([c.index() for c in cells(vec._fefunc.function_space().mesh())]) new_multiindices = {} # carry out refinement of meshes with timing(msg="Marking.refine", logfunc=logger.info, store_func=partial(_store_stats, key="TIME-MARKING", stats=stats)): Marking.refine(w, mesh_markers, new_multiindices.keys(), partial(setup_vector, pde=pde, mesh=mesh0, degree=degree)) if refinement: logger.info("ENDED refinement loop after %i of %i refinements with %i dofs and %i active multiindices", refinement, max_refinements, sim_stats[refinement]["DOFS"], len(sim_stats[refinement]["MI"])) # except Exception as ex: # import pickle # logger.error("EXCEPTION during AdaptiveSolver: %s", str(ex)) # print "DIM of w:", w.dim # if not w_history is None: # w_history.append(w) # wname = "W-PCG-FAILED.pkl" # try: # with open(wname, 'wb') as fout: # pickle.dump(w, fout) # except Exception as ex: # logger.error("NEXT EXCEPTION %s", str(ex)) # logger.info("exported last multivector w to %s", wname) # finally: return w, sim_stats