def test1(): # deprecated print "TEST 1" mesh1 = UnitSquare(5, 5) mesh2 = refine(mesh1) V1 = FunctionSpace(mesh1, 'CG', 1) V2 = FunctionSpace(mesh2, 'CG', 1) ex1 = Expression('a*x[0]+b*x[1]', a=1, b=1) ex2 = Expression('sin(a*pi*x[0])+sin(b*pi*x[1])', a=1, b=1) for ex in (ex1, ex2): f2 = interpolate(ex, V2) f21 = interpolate(f2, V1) f212 = interpolate(f21, V2) print "L2", errornorm(f2, f21, 'L2'), errornorm(f2, f212, 'L2') print "H1", errornorm(f2, f21, 'H1'), errornorm(f2, f212, 'H1') mis = (Multiindex(), Multiindex([1]), Multiindex([0, 1])) mv = MultiVectorWithProjection() mv[mis[0]] = FEniCSVector(f2) mv[mis[1]] = FEniCSVector(Function(V1)) mv[mis[2]] = FEniCSVector(Function(V2)) f2p1 = mv.get_back_projection(mis[0], mis[1])._fefunc f2p2 = mv.get_back_projection(mis[0], mis[2])._fefunc print "L2", errornorm(f2, f2p1, 'L2'), errornorm(f2, f2p2, 'L2') print "H1", errornorm(f2, f2p1, 'H1'), errornorm(f2, f2p2, 'H1') plot(mv[mis[0]]._fefunc, title="f2") plot(f2p1, title="f2p1") plot(f2p2, title="f2p2") interactive()
def test_mvwp_project(): def pr(src, dest): return 2 * src + dest mv1 = MultiVectorWithProjection(project=pr) mi1 = Multiindex([1, 2, 1]) mi2 = Multiindex([3, 2, 1, 7]) v1 = FlatVector([7, 10, 6]) v2 = FlatVector([2, 6, 13]) mv1[mi1] = v1 mv1[mi2] = v2 assert_equal(mv1.get_projection(mi1, mi2), pr(v1, v2)) assert_equal(mv1.get_back_projection(mi1, mi2), pr(pr(v1, v2), v1))
def test4(): print "TEST 4" mis = (Multiindex(), Multiindex([1]), Multiindex([0, 1]), Multiindex([1, 1])) mv = MultiVectorWithProjection() V1 = FEniCSBasis(FunctionSpace(UnitSquare(5, 5), 'CG', 1)) V2, _, _ = V1.refine() V3, _, _ = V2.refine() V4 = V1.refine_maxh(1 / 30, uniform=True) print "mesh1", V1.mesh, "maxh,minh=", V1.maxh, V1.minh print "mesh2", V2.mesh, "maxh,minh=", V2.maxh, V2.minh print "mesh3", V3.mesh, "maxh,minh=", V3.maxh, V3.minh print "mesh4", V4.mesh, "maxh,minh=", V4.maxh, V4.minh F2 = FEniCSVector.from_basis(V2) F3 = FEniCSVector.from_basis(V3) F4 = FEniCSVector.from_basis(V4) mv[mis[0]] = FEniCSVector.from_basis(V1) mv[mis[1]] = F2 mv[mis[2]] = F3 mv[mis[3]] = F4 for j, ex in enumerate(EX): print "ex[", j, "] ==================" for degree in range(1, 4): print "\t=== degree ", degree, "===" F2.interpolate(ex) F3.interpolate(ex) F4.interpolate(ex) err1 = mv.get_projection_error_function(mis[1], mis[0], degree, refine_mesh=False) err2 = mv.get_projection_error_function(mis[2], mis[0], degree, refine_mesh=False) err3 = mv.get_projection_error_function(mis[3], mis[0], degree, refine_mesh=False) print "\t[NO DESTINATION MESH REFINEMENT]" print "\t\tV2 L2", norm(err1._fefunc, 'L2'), "H1", norm(err1._fefunc, 'H1') print "\t\tV3 L2", norm(err2._fefunc, 'L2'), "H1", norm(err2._fefunc, 'H1') print "\t\tV4 L2", norm(err3._fefunc, 'L2'), "H1", norm(err3._fefunc, 'H1') err1 = mv.get_projection_error_function(mis[1], mis[0], degree, refine_mesh=True) err2 = mv.get_projection_error_function(mis[2], mis[0], degree, refine_mesh=True) err3 = mv.get_projection_error_function(mis[3], mis[0], degree, refine_mesh=True) print "\t[WITH DESTINATION MESH REFINEMENT]" print "\t\tV2 L2", norm(err1._fefunc, 'L2'), "H1", norm(err1._fefunc, 'H1') print "\t\tV3 L2", norm(err2._fefunc, 'L2'), "H1", norm(err2._fefunc, 'H1') print "\t\tV4 L2", norm(err3._fefunc, 'L2'), "H1", norm(err3._fefunc, 'H1')
def test_estimator(): # setup solution multi vector mis = [Multiindex([0]), Multiindex([1]), Multiindex([0, 1]), Multiindex([0, 2])] mesh = UnitSquare(4, 4) fs = FunctionSpace(mesh, "CG", 1) F = [interpolate(Expression("*".join(["x[0]"] * i)), fs) for i in range(1, 5)] vecs = [FEniCSVector(f) for f in F] w = MultiVectorWithProjection() for mi, vec in zip(mis, vecs): w[mi] = vec # v = A * w # define coefficient field aN = 4 a = [Expression('2.+sin(20.*pi*I*x[0]*x[1])', I=i, degree=3, element=fs.ufl_element()) for i in range(1, aN)] rvs = [UniformRV(), NormalRV(mu=0.5)] coeff_field = ListCoefficientField(a[0], a[1:], rvs) # define source term f = Constant("1.0") # evaluate residual and projection error estimators resind, reserr = ResidualEstimator.evaluateResidualEstimator(w, coeff_field, f) projind, projerr = ResidualEstimator.evaluateProjectionError(w, coeff_field) print resind[mis[0]].as_array().shape, projind[mis[0]].as_array().shape print "RESIDUAL:", resind[mis[0]].as_array() print "PROJECTION:", projind[mis[0]].as_array() print "residual error estimate for mu" for mu in reserr: print "\t eta", mu, " is ", reserr[mu] print "\t delta", mu, " is ", projerr[mu] assert_equal(w.active_indices(), resind.active_indices()) print "active indices are ", resind.active_indices()
def test_mvwp_copy(): # compares equal to copied MultiVectorWP but not to MultiVector mv0 = MultiVector() mv1 = MultiVectorWithProjection() mis1 = MultiindexSet.createCompleteOrderSet(3, 4) mv0.set_defaults(mis1, FlatVector([3, 4, 5])) mv1.set_defaults(mis1, FlatVector([3, 4, 5])) mv2 = mv1.copy() assert_equal(mv2, mv1) assert_not_equal(mv2, mv0) # compares equal if project methods match, make sure project method is copied mv3 = MultiVectorWithProjection(project=lambda : None) mv3.set_defaults(mis1, FlatVector([3, 4, 5])) mv4 = mv3.copy() assert_not_equal(mv2, mv3) assert_equal(mv4, mv3)
def test_estimator_refinement(): # define source term f = Constant("1.0") # f = Expression("10.*exp(-(pow(x[0] - 0.6, 2) + pow(x[1] - 0.4, 2)) / 0.02)", degree=3) # set default vector for new indices mesh0 = refine(Mesh(lshape_xml)) fs0 = FunctionSpace(mesh0, "CG", 1) B = FEniCSBasis(fs0) u0 = Function(fs0) diffcoeff = Constant("1.0") pde = FEMPoisson() fem_A = pde.assemble_lhs(diffcoeff, B) fem_b = pde.assemble_rhs(f, B) solve(fem_A, u0.vector(), fem_b) vec0 = FEniCSVector(u0) # setup solution multi vector mis = [Multiindex([0]), Multiindex([1]), Multiindex([0, 1]), Multiindex([0, 2])] N = len(mis) # meshes = [UnitSquare(i + 3, 3 + N - i) for i in range(N)] meshes = [refine(Mesh(lshape_xml)) for _ in range(N)] fss = [FunctionSpace(mesh, "CG", 1) for mesh in meshes] # solve Poisson problem w = MultiVectorWithProjection() for i, mi in enumerate(mis): B = FEniCSBasis(fss[i]) u = Function(fss[i]) pde = FEMPoisson() fem_A = pde.assemble_lhs(diffcoeff, B) fem_b = pde.assemble_rhs(f, B) solve(fem_A, u.vector(), fem_b) w[mi] = FEniCSVector(u) # plot(w[mi]._fefunc) # 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 # =============== refinements = 3 for refinement in range(refinements): print "*****************************" print "REFINEMENT LOOP iteration ", refinement + 1 print "*****************************" # evaluate residual and projection error estimates # ================================================ maxh = 1 / 10 resind, reserr = ResidualEstimator.evaluateResidualEstimator(w, coeff_field, f) projind, projerr = ResidualEstimator.evaluateProjectionError(w, coeff_field, maxh) # testing --> projglobal, _ = ResidualEstimator.evaluateProjectionError(w, coeff_field, maxh, local=False) for mu, val in projglobal.iteritems(): print "GLOBAL Projection Error for", mu, "=", val # <-- testing # ============== # MARK algorithm # ============== # setup marking sets mesh_markers = defaultdict(set) # residual marking # ================ theta_eta = 0.8 global_res = sum([res[1] for res in reserr.items()]) allresind = list() for mu, resmu in resind.iteritems(): allresind = allresind + [(resmu.coeffs[i], i, mu) for i in range(len(resmu.coeffs))] allresind = sorted(allresind, key=itemgetter(1)) # TODO: check that indexing and cell ids are consistent (it would be safer to always work with cell indices) marked_res = 0 for res in allresind: if marked_res >= theta_eta * global_res: break mesh_markers[res[2]].add(res[1]) marked_res += res[0] print "RES MARKED elements:\n", [(mu, len(cell_ids)) for mu, cell_ids in mesh_markers.iteritems()] # projection marking # ================== theta_zeta = 0.8 min_zeta = 1e-10 max_zeta = max([max(projind[mu].coeffs) for mu in projind.active_indices()]) print "max_zeta =", max_zeta if max_zeta >= min_zeta: for mu, vec in projind.iteritems(): indmu = [i for i, p in enumerate(vec.coeffs) if p >= theta_zeta * max_zeta] mesh_markers[mu] = mesh_markers[mu].union(set(indmu)) print "PROJ MARKING", len(indmu), "elements in", mu print "FINAL MARKED elements:\n", [(mu, len(cell_ids)) for mu, cell_ids in mesh_markers.iteritems()] else: print "NO PROJECTION MARKING due to very small projection error!" # new multiindex activation # ========================= # determine possible new indices theta_delta = 0.9 maxm = 10 a0_f = coeff_field.mean_func Ldelta = {} Delta = w.active_indices() deltaN = int(ceil(0.1 * len(Delta))) # max number new multiindices for mu in Delta: norm_w = norm(w[mu].coeffs, 'L2') for m in count(): mu1 = mu.inc(m) if mu1 not in Delta: if m > maxm or m >= coeff_field.length: # or len(Ldelta) >= deltaN break am_f, am_rv = coeff_field[m] beta = am_rv.orth_polys.get_beta(1) # determine ||a_m/\overline{a}||_{L\infty(D)} (approximately) f = Function(w[mu]._fefunc.function_space()) f.interpolate(a0_f) min_a0 = min(f.vector().array()) f.interpolate(am_f) max_am = max(f.vector().array()) ainfty = max_am / min_a0 assert isinstance(ainfty, float) # print "A***", beta[1], ainfty, norm_w # print "B***", beta[1] * ainfty * norm_w # print "C***", theta_delta, max_zeta # print "D***", theta_delta * max_zeta # print "E***", bool(beta[1] * ainfty * norm_w >= theta_delta * max_zeta) if beta[1] * ainfty * norm_w >= theta_delta * max_zeta: val1 = beta[1] * ainfty * norm_w if mu1 not in Ldelta.keys() or (mu1 in Ldelta.keys() and Ldelta[mu1] < val1): Ldelta[mu1] = val1 print "POSSIBLE NEW MULTIINDICES ", sorted(Ldelta.iteritems(), key=itemgetter(1), reverse=True) Ldelta = sorted(Ldelta.iteritems(), key=itemgetter(1), reverse=True)[:min(len(Ldelta), deltaN)] # add new multiindices to solution vector for mu, _ in Ldelta: w[mu] = vec0 print "SELECTED NEW MULTIINDICES ", Ldelta # create new refined (and enlarged) multi vector # ============================================== for mu, cell_ids in mesh_markers.iteritems(): vec = w[mu].refine(cell_ids, with_prolongation=False) fs = vec._fefunc.function_space() B = FEniCSBasis(fs) u = Function(fs) pde = FEMPoisson() fem_A = pde.assemble_lhs(diffcoeff, B) fem_b = pde.assemble_rhs(f, B) solve(fem_A, vec.coeffs, fem_b) w[mu] = vec
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()