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)
Пример #2
0
    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
Пример #3
0
    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
Пример #4
0
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...")