def pcg_solve(A, w, coeff_field, pde, stats, pcg_eps, pcg_maxiter): b = prepare_rhs(A, w, coeff_field, pde) P = PreconditioningOperator(coeff_field.mean_func, pde.assemble_solve_operator) w, zeta, numit = pcg(A, b, P, w0=w, eps=pcg_eps, maxiter=pcg_maxiter) logger.info("PCG finished with zeta=%f after %i iterations", zeta, numit) b2 = A * w stats["RESIDUAL-L2"] = error_norm(b, b2, "L2") stats["RESIDUAL-H1A"] = error_norm(b, b2, pde.energy_norm) stats["DOFS"] = sum([b[mu]._fefunc.function_space().dim() for mu in b.keys()]) stats["CELLS"] = sum([b[mu]._fefunc.function_space().mesh().num_cells() for mu in b.keys()]) logger.info("[pcg] Residual = [%s (L2)] [%s (H1A)] with [%s dofs] and [%s cells]", stats["RESIDUAL-L2"], stats["RESIDUAL-H1A"], stats["DOFS"], stats["CELLS"]) return w, zeta
def run_mc(err, w, pde, A, coeff_field, mesh0, ref_maxm, MC_N, MC_HMAX, param_sol_cache=None, direct_sol_cache=None, stored_rv_samples=None, quadrature_degree = -1): # create reference mesh and function space sub_spaces = w[Multiindex()].basis.num_sub_spaces degree = w[Multiindex()].basis.degree projection_basis = get_projection_basis(mesh0, mesh_refinements=0, degree=degree, sub_spaces=sub_spaces) logger.info("projection_basis dim = %i \t hmin of mi[0] = %s, reference mesh = (%s, %s)", projection_basis.dim, w[Multiindex()].basis.minh, projection_basis.minh, projection_basis.maxh) # get realization of coefficient field err_L2, err_H1 = 0, 0 # set quadrature degree if quadrature_degree > -1: quadrature_degree_old = parameters["form_compiler"]["quadrature_degree"] parameters["form_compiler"]["quadrature_degree"] = quadrature_degree logger.debug("MC error sampling quadrature order = " + str(quadrature_degree)) # setup caches for sample solutions # param_sol_cache = None #param_sol_cache or MCCache() # direct_sol_cache = None #direct_sol_cache or MCCache() logger.info("---- MC caches %s/%s ----", param_sol_cache, direct_sol_cache) # main MC loop for i in range(MC_N): logger.info("---- MC Iteration %i/%i ----", i + 1 , MC_N) # create new samples if required or reuse existing samples if stored_rv_samples is None or len(stored_rv_samples) <= i: sample_rvs = coeff_field.sample_rvs() RV_samples = [sample_rvs[j] for j in range(max(w.max_order, ref_maxm))] if stored_rv_samples is not None: stored_rv_samples.append(RV_samples) else: RV_samples = stored_rv_samples[i] logger.info("-- RV_samples: %s", RV_samples) # evaluate solutions with timing(msg="parameteric sample solution", logfunc=logger.info): sample_sol_param = compute_parametric_sample_solution(RV_samples, coeff_field, w, projection_basis, param_sol_cache) with timing(msg="direct sample solution", logfunc=logger.info): sample_sol_direct = compute_direct_sample_solution(pde, RV_samples, coeff_field, A, ref_maxm, projection_basis, direct_sol_cache) # evaluate errors with timing(msg="L2_err_1", logfunc=logger.info): cerr_L2 = error_norm(sample_sol_param._fefunc, sample_sol_direct._fefunc, "L2") with timing(msg="H1A_err_1", logfunc=logger.info): cerr_H1 = error_norm(sample_sol_param._fefunc, sample_sol_direct._fefunc, pde.energy_norm) # cerr_H1 = errornorm(sample_sol_param._fefunc, sample_sol_direct._fefunc, "H1") logger.debug("-- current error L2 = %s H1A = %s", cerr_L2, cerr_H1) err_L2 += 1.0 / MC_N * cerr_L2 err_H1 += 1.0 / MC_N * cerr_H1 if i + 1 == MC_N: # deterministic part with timing(msg="direct a0", logfunc=logger.info): sample_sol_direct_a0 = compute_direct_sample_solution(pde, RV_samples, coeff_field, A, 0, projection_basis, direct_sol_cache) with timing(msg="L2_err_2", logfunc=logger.info): L2_a0 = error_norm(sample_sol_param._fefunc, sample_sol_direct_a0._fefunc, "L2") with timing(msg="H1A_err_2", logfunc=logger.info): H1_a0 = error_norm(sample_sol_param._fefunc, sample_sol_direct_a0._fefunc, pde.energy_norm) # H1_a0 = errornorm(sample_sol_param._fefunc, sample_sol_direct_a0._fefunc, "H1") logger.debug("-- DETERMINISTIC error L2 = %s H1A = %s", L2_a0, H1_a0) # stochastic part sample_sol_direct_am = sample_sol_direct - sample_sol_direct_a0 logger.debug("-- STOCHASTIC norm L2 = %s H1 = %s", sample_sol_direct_am.norm("L2"), sample_sol_direct_am.norm("H1")) # restore quadrature degree if quadrature_degree > -1: parameters["form_compiler"]["quadrature_degree"] = quadrature_degree_old logger.info("MC Error: L2: %s, H1A: %s", err_L2, err_H1) err.append((err_L2, err_H1, L2_a0, H1_a0))