/*********************************************************************/ /* File: hierarchicalee.cpp */ /* Author: Joachim Schoeberl */ /* Date: 12. May. 2003 */ /*********************************************************************/ /* Hierarchical error estimator */ #include namespace ngcomp { using namespace ngcomp; template void CalcErrorHierarchical (const MeshAccess & ma, const S_BilinearForm & bfa, const S_BilinearForm & bfa2, const S_LinearForm & lff, S_GridFunction & gfu, const FESpace & festest, FlatVector & err, LocalHeap & lh) { int i, j, k; int ne = ma.GetNE(); int nse = ma.GetNSE(); const FESpace & fes = gfu.GetFESpace(); const S_BaseVector & vecu = dynamic_cast&> (gfu.GetVector()); ElementTransformation eltrans; int dim = fes.GetDimension(); ARRAY dnums, dnumstest; VVector res(festest.GetNDof()); VVector diag(festest.GetNDof()); res = 0; diag = 0; for (i = 0; i < ne; i++) { lh.CleanUp(); const FiniteElement & fel = fes.GetFE(i, lh); const FiniteElement & feltest = festest.GetFE(i, lh); ma.GetElementTransformation (i, eltrans, lh); fes.GetDofNrs (i, dnums); festest.GetDofNrs (i, dnumstest); FlatVector elu(dnums.Size() * dim, lh); FlatVector elres(dnumstest.Size() * dim, lh); FlatVector eldiag(dnumstest.Size() * dim, lh); vecu.GetIndirect (dnums, elu); fes.TransformVec (i, 0, elu, TRANSFORM_SOL); elres = 0; eldiag = 0; for (j = 0; j < lff.NumIntegrators(); j++) { if (lff.GetIntegrator(j) -> BoundaryForm()) continue; FlatVector elvec; lff.GetIntegrator(j) -> AssembleElementVector (feltest, eltrans, elvec, lh); elres += elvec; } for (j = 0; j < bfa.NumIntegrators(); j++) { if (bfa.GetIntegrator(j) -> BoundaryForm()) continue; FlatVector elvec (dnumstest.Size()*dim, lh); bfa.GetIntegrator(j) -> ApplyMixedElementMatrix (fel, feltest, eltrans, elu, elvec, lh); elres -= elvec; } for (j = 0; j < bfa2.NumIntegrators(); j++) { if (bfa2.GetIntegrator(j) -> BoundaryForm()) continue; FlatVector elvec (dnumstest.Size()*dim, lh); bfa2.GetIntegrator(j) -> AssembleElementMatrixDiag (feltest, eltrans, elvec, lh); eldiag += elvec; } festest.TransformVec (i, 0, elres, TRANSFORM_RHS); res.AddIndirect (dnumstest, elres); diag.AddIndirect (dnumstest, eldiag); cout << "\rcompute element " << i << "/" << ne << flush; } (*testout) << "res = " << endl << res << endl; (*testout) << "diag = " << endl << diag << endl; for (i = 0; i < ne; i++) { lh.CleanUp(); festest.GetDofNrs (i, dnumstest); double sum = 0; for (j = 0; j < dnumstest.Size(); j++) { int di = dnumstest[j]; sum += abs (res(di)*res(di)/diag(di)); } err(i) = sum; } } template void CalcErrorHierarchical (const MeshAccess & ma, const S_BilinearForm & bfa, const S_BilinearForm & bfa2, const S_LinearForm & lff, S_GridFunction & bu, const FESpace & festest, FlatVector & err, LocalHeap & lh); }