def test1(): # setup meshes P = 0.3 ref1 = 4 ref2 = 14 mesh1 = UnitSquare(2, 2) mesh2 = UnitSquare(2, 2) # refinement loops for level in range(ref1): mesh1 = refine(mesh1) for level in range(ref2): # mark and refine markers = CellFunction("bool", mesh2) markers.set_all(False) # randomly refine mesh for i in range(mesh2.num_cells()): if random() <= P: markers[i] = True mesh2 = refine(mesh2, markers) # create joint meshes mesh1j, parents1 = create_joint_mesh([mesh2], mesh1) mesh2j, parents2 = create_joint_mesh([mesh1], mesh2) # evaluate errors joint meshes ex1 = Expression("sin(2*A*x[0])*sin(2*A*x[1])", A=10) V1 = FunctionSpace(mesh1, "CG", 1) V2 = FunctionSpace(mesh2, "CG", 1) V1j = FunctionSpace(mesh1j, "CG", 1) V2j = FunctionSpace(mesh2j, "CG", 1) f1 = interpolate(ex1, V1) f2 = interpolate(ex1, V2) # interpolate on respective joint meshes f1j = interpolate(f1, V1j) f2j = interpolate(f2, V2j) f1j1 = interpolate(f1j, V1) f2j2 = interpolate(f2j, V2) # evaluate error with regard to original mesh e1 = Function(V1) e2 = Function(V2) e1.vector()[:] = f1.vector() - f1j1.vector() e2.vector()[:] = f2.vector() - f2j2.vector() print "error on V1:", norm(e1, "L2") print "error on V2:", norm(e2, "L2") plot(f1j, title="f1j") plot(f2j, title="f2j") plot(mesh1, title="mesh1") plot(mesh2, title="mesh2") plot(mesh1j, title="joint mesh from mesh1") plot(mesh2j, title="joint mesh from mesh2", interactive=True)
def get_projection_error_function(self, mu_src, mu_dest, reference_degree, refine_mesh=0): """Construct projection error function by projecting mu_src vector to mu_dest space of dest_degree. From this, the projection of mu_src onto the mu_dest space, then to the mu_dest space of dest_degree is subtracted. If refine_mesh > 0, the destination mesh is refined uniformly n times.""" from spuq.fem.fenics.fenics_utils import create_joint_mesh from dolfin import FunctionSpace, VectorFunctionSpace from spuq.fem.fenics.fenics_basis import FEniCSBasis # get joint mesh based on destination space basis_src = self[mu_src].basis basis_dest = self[mu_dest].basis mesh_reference, parents = create_joint_mesh([basis_src.mesh], basis_dest.mesh) # create function space on destination mesh if basis_dest._fefs.num_sub_spaces() > 0: fs_reference = VectorFunctionSpace(mesh_reference, basis_dest._fefs.ufl_element().family(), reference_degree) else: fs_reference = FunctionSpace(mesh_reference, basis_dest._fefs.ufl_element().family(), reference_degree) basis_reference = FEniCSBasis(fs_reference, basis_dest._ptype) # project both vectors to reference space w_reference = basis_reference.project_onto(self[mu_src]) w_dest = self.get_projection(mu_src, mu_dest) w_dest = basis_reference.project_onto(w_dest) # define summation function to get values on original destination mesh from function space on joint mesh def sum_up(vals): sum_vals = [sum(vals[v]) for _, v in parents.iteritems()] return np.array(sum_vals) return w_dest - w_reference, sum_up
def apply(self, w): """Apply operator to vector which has to live in the same domain.""" v = 0 * w Lambda = w.active_indices() maxm = w.max_order if len(self._coeff_field) < maxm: logger.warning("insufficient length of coefficient field for MultiVector (%i instead of %i", len(self._coeff_field), maxm) maxm = len(self._coeff_field) # assert self._coeff_field.length >= maxm # ensure coeff_field expansion is sufficiently long # construct global joint mesh if self._assembly_type == ASSEMBLY_TYPE.JOINT_GLOBAL: meshes = [w[m].basis.mesh for m in Lambda] mesh = create_joint_mesh(meshes) Vfine = w[Lambda[0]].basis.copy(mesh=mesh) for mu in Lambda: if self._assembly_type != ASSEMBLY_TYPE.JOINT_GLOBAL: # create joint mesh and basis if (self._assembly_type == ASSEMBLY_TYPE.JOINT_MU and hasattr(w[mu].basis, "mesh")): # identify active multi indices mus = set([mu]) mus = mus.union([mu.inc(m) for m in range(maxm)]) mus = mus.union([mu.dec(m) for m in range(maxm)]) mus = mus.intersection(Lambda) logger.debug("apply on mu = %s with joint mesh for %s", str(mu), str(mus)) meshes = [w[m].basis.mesh for m in mus] mesh, _ = create_joint_mesh(meshes) Vfine = w[mu].basis.copy(mesh=mesh) else: Vfine = w[mu].basis # deterministic part a0_f = self._coeff_field.mean_func A0 = self._assemble_0(Vfine, a0_f) cur_v = A0 * Vfine.project_onto(w[mu]) # iterate related multiindices for m in range(maxm): logger.debug("with m = %i", m) # assemble A for \mu and a_m am_f, am_rv = self._coeff_field[m] Am = self._assemble_m(Vfine, am_f) # prepare polynom coefficients beta = am_rv.orth_polys.get_beta(mu[m]) # mu cur_w = -beta[0] * Vfine.project_onto(w[mu]) # mu+1 mu1 = mu.inc(m) if mu1 in Lambda: cur_w += beta[1] * Vfine.project_onto(w[mu1]) # mu-1 mu2 = mu.dec(m) if mu2 in Lambda: cur_w += beta[-1] * Vfine.project_onto(w[mu2]) # apply discrete operator cur_v += Am * cur_w v[mu] = w[mu].basis.project_onto(cur_v) return v
def run_MC(opts, conf): # propagate config values _G = globals() for sec in conf.keys(): if sec == "LOGGING": continue secconf = conf[sec] for key, val in secconf.iteritems(): print "CONF_" + key + "= secconf['" + key + "'] =", secconf[key] _G["CONF_" + key] = secconf[key] # exec "CONF_" + key + "= secconf['" + key + "']" # setup logging _G["LOG_LEVEL"] = eval("logging." + conf["LOGGING"]["level"]) print "LOG_LEVEL = logging." + conf["LOGGING"]["level"] # exec "LOG_LEVEL = logging." + conf["LOGGING"]["level"] setup_logging(LOG_LEVEL, logfile=CONF_experiment_name + "_MC") # determine path of this module path = os.path.dirname(__file__) # ============================================================ # PART A: Setup Problem # ============================================================ # get boundaries mesh0, boundaries, dim = SampleDomain.setupDomain(CONF_domain, initial_mesh_N=CONF_initial_mesh_N) # define coefficient field coeff_types = ("EF-square-cos", "EF-square-sin", "monomials", "constant") from itertools import count if CONF_mu is not None: muparam = (CONF_mu, (0 for _ in count())) else: muparam = None coeff_field = SampleProblem.setupCF(coeff_types[CONF_coeff_type], decayexp=CONF_decay_exp, gamma=CONF_gamma, freqscale=CONF_freq_scale, freqskip=CONF_freq_skip, rvtype="uniform", scale=CONF_coeff_scale, secondparam=muparam) # setup boundary conditions and pde # initial_mesh_N = CONF_initial_mesh_N pde, Dirichlet_boundary, uD, Neumann_boundary, g, f = SampleProblem.setupPDE(CONF_boundary_type, CONF_domain, CONF_problem_type, boundaries, coeff_field) # define multioperator A = MultiOperator(coeff_field, pde.assemble_operator, pde.assemble_operator_inner_dofs, assembly_type=eval("ASSEMBLY_TYPE." + CONF_assembly_type)) # ============================================================ # PART B: Import Solution # ============================================================ import pickle LOAD_SOLUTION = os.path.join(opts.basedir, CONF_experiment_name) logger.info("loading solutions from %s" % os.path.join(LOAD_SOLUTION, 'SFEM-SOLUTIONS.pkl')) # load solutions with open(os.path.join(LOAD_SOLUTION, 'SFEM-SOLUTIONS.pkl'), 'rb') as fin: w_history = pickle.load(fin) # load simulation data logger.info("loading statistics from %s" % os.path.join(LOAD_SOLUTION, 'SIM-STATS.pkl')) with open(os.path.join(LOAD_SOLUTION, 'SIM-STATS.pkl'), 'rb') as fin: sim_stats = pickle.load(fin) logger.info("active indices of w after initialisation: %s", w_history[-1].active_indices()) # ============================================================ # PART C: MC Error Sampling # ============================================================ MC_N = CONF_N MC_HMAX = CONF_max_h if CONF_runs > 0: # determine reference mesh w = w_history[-1] ref_mesh, _ = create_joint_mesh([w[mu].mesh for mu in w.active_indices()]) for _ in range(CONF_ref_mesh_refine): ref_mesh = refine(ref_mesh) ref_maxm = CONF_sampling_order if CONF_sampling_order > 0 else w.max_order + CONF_sampling_order_increase for i, w in enumerate(w_history): # if i == 0: # continue logger.info("MC error sampling for w[%i] (of %i)", i, len(w_history)) # memory usage info import resource logger.info("\n======================================\nMEMORY USED: " + str(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss) + "\n======================================\n") MC_start = 0 old_stats = sim_stats[i] if opts.continueMC: try: MC_start = sim_stats[i]["MC-N"] logger.info("CONTINUING MC of %s for solution (iteration) %s of %s", LOAD_SOLUTION, i, len(w_history)) except: logger.info("STARTING MC of %s for solution (iteration) %s of %s", LOAD_SOLUTION, i, len(w_history)) if MC_start <= 0: sim_stats[i]["MC-N"] = 0 sim_stats[i]["MC-L2ERR"] = 0 sim_stats[i]["MC-H1ERR"] = 0 sim_stats[i]["MC-L2ERR_a0"] = 0 sim_stats[i]["MC-H1ERR_a0"] = 0 MC_RUNS = max(CONF_runs - MC_start, 0) if MC_RUNS > 0: logger.info("STARTING %s MC RUNS", MC_RUNS) # L2err, H1err, L2err_a0, H1err_a0, N = sample_error_mc(w, pde, A, coeff_field, mesh0, ref_maxm, MC_RUNS, MC_N, MC_HMAX) L2err, H1err, L2err_a0, H1err_a0, N = sample_error_mc(w, pde, A, coeff_field, ref_mesh, ref_maxm, MC_RUNS, MC_N, MC_HMAX) # combine current and previous results sim_stats[i]["MC-N"] = N + old_stats["MC-N"] sim_stats[i]["MC-L2ERR"] = (L2err * N + old_stats["MC-L2ERR"]) / sim_stats[i]["MC-N"] sim_stats[i]["MC-H1ERR"] = (H1err * N + old_stats["MC-H1ERR"]) / sim_stats[i]["MC-N"] sim_stats[i]["MC-L2ERR_a0"] = (L2err_a0 * N + old_stats["MC-L2ERR_a0"]) / sim_stats[i]["MC-N"] sim_stats[i]["MC-H1ERR_a0"] = (H1err_a0 * N + old_stats["MC-H1ERR_a0"]) / sim_stats[i]["MC-N"] print "MC-H1ERR (N:%i) = %f" % (sim_stats[i]["MC-N"], sim_stats[i]["MC-H1ERR"]) else: logger.info("SKIPPING MC RUN since sufficiently many samples are available") # ============================================================ # PART D: Export Updated Data and Plotting # ============================================================ # save updated data if opts.saveData: # save updated statistics import pickle SAVE_SOLUTION = os.path.join(opts.basedir, CONF_experiment_name) try: os.makedirs(SAVE_SOLUTION) except: pass logger.info("saving statistics into %s" % os.path.join(SAVE_SOLUTION, 'SIM-STATS.pkl')) with open(os.path.join(SAVE_SOLUTION, 'SIM-STATS.pkl'), 'wb') as fout: pickle.dump(sim_stats, fout) # plot residuals if opts.plotEstimator and len(sim_stats) > 1: try: from matplotlib.pyplot import figure, show, legend x = [s["DOFS"] for s in sim_stats] L2 = [s["L2"] for s in sim_stats] H1 = [s["H1"] for s in sim_stats] errest = [sqrt(s["EST"]) for s in sim_stats] res_part = [s["RES-PART"] for s in sim_stats] proj_part = [s["PROJ-PART"] for s in sim_stats] pcg_part = [s["PCG-PART"] for s in sim_stats] _reserrmu = [s["RES-mu"] for s in sim_stats] _projerrmu = [s["PROJ-mu"] for s in sim_stats] if CONF_runs > 0: mcL2 = [s["MC-L2ERR"] for s in sim_stats] mcH1 = [s["MC-H1ERR"] for s in sim_stats] mcL2_a0 = [s["MC-L2ERR_a0"] for s in sim_stats] mcH1_a0 = [s["MC-H1ERR_a0"] for s in sim_stats] effest = [est / err for est, err in zip(errest, mcH1)] mi = [s["MI"] for s in sim_stats] num_mi = [len(m) for m in mi] reserrmu = defaultdict(list) for rem in _reserrmu: for mu, v in rem: reserrmu[mu].append(v) print "errest", errest if CONF_runs > 0: print "mcH1", mcH1 print "efficiency", [est / err for est, err in zip(errest, mcH1)] # -------- # figure 2 # -------- fig2 = figure() fig2.suptitle("residual estimator") ax = fig2.add_subplot(111) if CONF_refine_Lambda: ax.loglog(x, num_mi, '--y+', label='active mi') ax.loglog(x, errest, '-g<', label='error estimator') ax.loglog(x, res_part, '-.cx', label='residual part') ax.loglog(x[1:], proj_part[1:], '-.m>', label='projection part') ax.loglog(x, pcg_part, '-.b>', label='pcg part') if MC_RUNS > 0: ax.loglog(x, mcH1, '-b^', label='MC H1 error') ax.loglog(x, mcL2, '-ro', label='MC L2 error') # ax.loglog(x, H1, '-b^', label='H1 residual') # ax.loglog(x, L2, '-ro', label='L2 residual') legend(loc='upper right') # -------- # figure 3 # -------- fig3 = figure() fig3.suptitle("efficiency residual estimator") ax = fig3.add_subplot(111) ax.loglog(x, errest, '-g<', label='error estimator') if MC_RUNS > 0: ax.loglog(x, mcH1, '-b^', label='MC H1 error') ax.loglog(x, effest, '-ro', label='efficiency') legend(loc='upper right') # # -------- # # figure 4 # # -------- # fig4 = figure() # fig4.suptitle("residual contributions") # ax = fig4.add_subplot(111) # for mu, v in reserrmu.iteritems(): # ms = str(mu) # ms = ms[ms.find('=') + 1:-1] # ax.loglog(x[-len(v):], v, '-g<', label=ms) # legend(loc='upper right') show() # this invalidates the figure instances... except: import traceback print traceback.format_exc() logger.info("skipped plotting since matplotlib is not available...")