/*********************************************************************/ /* File: integrator.cpp */ /* Author: Joachim Schoeberl */ /* Date: 10. Feb. 2002 */ /*********************************************************************/ /* Finite Element Integrators */ #include namespace ngfem { using namespace ngfem; Integrator :: Integrator() throw () { SetIntegrationOrder (-1); } /// Integrator :: ~Integrator() { ; } bool Integrator :: DefinedOn (int mat) const { if (definedon.Size()) return definedon.Test(mat); return 1; } void Integrator :: SetDefinedOn (const BitArray & adefinedon) { definedon = adefinedon; // (*testout) << "SetDefinedOn: " << definedon << endl; } string Integrator :: Name () const { return string("Integrator ") + typeid(*this).name(); } BilinearFormIntegrator :: BilinearFormIntegrator () throw() { ; } BilinearFormIntegrator :: ~BilinearFormIntegrator () { ; } void BilinearFormIntegrator :: AssembleElementMatrix (const FiniteElement & fel, const ElementTransformation & eltrans, FlatMatrix & elmat, LocalHeap & locheap) const { FlatMatrix rmat; AssembleElementMatrix (fel, eltrans, rmat, locheap); elmat.AssignMemory (rmat.Height(), rmat.Width(), locheap); elmat = rmat; } void BilinearFormIntegrator :: AssembleElementMatrixDiag (const FiniteElement & fel, const ElementTransformation & eltrans, FlatVector & diag, LocalHeap & lh) const { FlatMatrix<> elmat(diag.Size(), lh); AssembleElementMatrix (fel, eltrans, elmat, lh); for (int i = 0; i < diag.Size(); i++) diag(i) = elmat(i,i); } void BilinearFormIntegrator :: AssembleLinearizedElementMatrix (const FiniteElement & fel, const ElementTransformation & eltrans, FlatVector & elveclin, FlatMatrix & elmat, LocalHeap & locheap) const { AssembleElementMatrix (fel, eltrans, elmat, locheap); } void BilinearFormIntegrator :: AssembleLinearizedElementMatrix (const FiniteElement & fel, const ElementTransformation & eltrans, FlatVector & elveclin, FlatMatrix & elmat, LocalHeap & locheap) const { AssembleElementMatrix (fel, eltrans, elmat, locheap); } void BilinearFormIntegrator :: ApplyElementMatrix (const FiniteElement & fel, const ElementTransformation & eltrans, const FlatVector & elx, FlatVector & ely, LocalHeap & locheap) const { cout << "OJE" << endl; FlatMatrix mat; AssembleElementMatrix (fel, eltrans, mat, locheap); ely = mat * elx; } void BilinearFormIntegrator :: ApplyElementMatrix (const FiniteElement & fel, const ElementTransformation & eltrans, const FlatVector & elx, FlatVector & ely, LocalHeap & locheap) const { FlatMatrix mat; AssembleElementMatrix (fel, eltrans, mat, locheap); ely = mat * elx; } void BilinearFormIntegrator :: ApplyLinearizedElementMatrix (const FiniteElement & fel, const ElementTransformation & eltrans, const FlatVector & ellin, const FlatVector & elx, FlatVector & ely, LocalHeap & locheap) const { ApplyElementMatrix (fel, eltrans, elx, ely, locheap); } void BilinearFormIntegrator :: ApplyLinearizedElementMatrix (const FiniteElement & fel, const ElementTransformation & eltrans, const FlatVector & ellin, const FlatVector & elx, FlatVector & ely, LocalHeap & locheap) const { ApplyElementMatrix (fel, eltrans, elx, ely, locheap); } double BilinearFormIntegrator :: Energy (const FiniteElement & fel, const ElementTransformation & eltrans, const FlatVector & elx, LocalHeap & locheap) const { FlatVector ely (elx.Size(), locheap); ApplyElementMatrix (fel, eltrans, elx, ely, locheap); return 0.5 * InnerProduct (elx, ely); } double BilinearFormIntegrator :: Energy (const FiniteElement & fel, const ElementTransformation & eltrans, const FlatVector & elx, LocalHeap & locheap) const { cout << "error: Energy for Complex vector called" << endl; return 0; } FlatMatrix BilinearFormIntegrator :: AssembleMixedElementMatrix (const FiniteElement & fel1, const FiniteElement & fel2, const ElementTransformation & eltrans, LocalHeap & locheap) const { cerr << "AssembleMixedElementMatrix called for base class" << endl; return FlatMatrix (0,0,0); } /// void BilinearFormIntegrator :: ApplyMixedElementMatrix (const FiniteElement & fel1, const FiniteElement & fel2, const ElementTransformation & eltrans, const FlatVector & elx, FlatVector & ely, LocalHeap & locheap) const { ely = AssembleMixedElementMatrix (fel1, fel2, eltrans, locheap) * elx; } void BilinearFormIntegrator :: CalcFlux (const FiniteElement & fel, const ElementTransformation & eltrans, const IntegrationPoint & ip, const FlatVector & elx, FlatVector & flux, bool applyd, LocalHeap & lh) const { cerr << "calcflux called for class " << typeid(*this).name() << endl; } void BilinearFormIntegrator :: CalcFlux (const FiniteElement & fel, const ElementTransformation & eltrans, const IntegrationPoint & ip, const FlatVector & elx, FlatVector & flux, bool applyd, LocalHeap & lh) const { cerr << "calcflux called for base class " << typeid(*this).name() << endl; } void BilinearFormIntegrator :: CalcFlux (const FiniteElement & fel, const BaseSpecificIntegrationPoint & bsip, const FlatVector & elx, FlatVector & flux, bool applyd, LocalHeap & lh) const { cerr << "calcflux called for class " << typeid(*this).name() << endl; } void BilinearFormIntegrator :: CalcFlux (const FiniteElement & fel, const BaseSpecificIntegrationPoint & bsip, const FlatVector & elx, FlatVector & flux, bool applyd, LocalHeap & lh) const { cerr << "calcflux called for base class " << typeid(*this).name() << endl; } void BilinearFormIntegrator :: ApplyBTrans (const FiniteElement & fel, // const ElementTransformation & eltrans, // const IntegrationPoint & ip, const BaseSpecificIntegrationPoint & bsip, const FlatVector & elx, FlatVector & ely, LocalHeap & lh) const { cerr << "ApplyBTrans called for class " << typeid(*this).name() << endl; } void BilinearFormIntegrator :: ApplyBTrans (const FiniteElement & fel, // const ElementTransformation & eltrans, // const IntegrationPoint & ip, const BaseSpecificIntegrationPoint & bsip, const FlatVector & elx, FlatVector & ely, LocalHeap & lh) const { cerr << "ApplyBTrans called for class " << typeid(*this).name() << endl; } BlockBilinearFormIntegrator :: BlockBilinearFormIntegrator (BilinearFormIntegrator & abfi, int adim, int acomp) : bfi(abfi), dim(adim), comp(acomp) { ; } BlockBilinearFormIntegrator :: BlockBilinearFormIntegrator (BilinearFormIntegrator & abfi, int adim) : bfi(abfi), dim(adim), comp(-1) { ; } BlockBilinearFormIntegrator :: ~BlockBilinearFormIntegrator () { delete &bfi; } void BlockBilinearFormIntegrator :: AssembleElementMatrix (const FiniteElement & bfel, const ElementTransformation & eltrans, FlatMatrix & elmat, LocalHeap & locheap) const { FlatMatrix mat1; bfi.AssembleElementMatrix (bfel, eltrans, mat1, locheap); elmat.AssignMemory (mat1.Height()*dim, mat1.Width()*dim, locheap); elmat = 0; if (comp == -1) for (int i = 0; i < mat1.Height(); i++) for (int j = 0; j < mat1.Width(); j++) for (int k = 0; k < dim; k++) elmat(dim*i+k, dim*j+k) = mat1(i,j); else for (int i = 0; i < mat1.Height(); i++) for (int j = 0; j < mat1.Width(); j++) elmat(dim*i+comp, dim*j+comp) = mat1(i,j); } void BlockBilinearFormIntegrator :: AssembleElementMatrix (const FiniteElement & bfel, const ElementTransformation & eltrans, FlatMatrix & elmat, LocalHeap & locheap) const { FlatMatrix mat1; bfi.AssembleElementMatrix (bfel, eltrans, mat1, locheap); elmat.AssignMemory (mat1.Height()*dim, mat1.Width()*dim, locheap); elmat = 0; if (comp == -1) for (int i = 0; i < mat1.Height(); i++) for (int j = 0; j < mat1.Width(); j++) for (int k = 0; k < dim; k++) elmat(dim*i+k, dim*j+k) = mat1(i,j); else for (int i = 0; i < mat1.Height(); i++) for (int j = 0; j < mat1.Width(); j++) elmat(dim*i+comp, dim*j+comp) = mat1(i,j); } void BlockBilinearFormIntegrator :: ApplyElementMatrix (const FiniteElement & bfel, const ElementTransformation & eltrans, const FlatVector & elx, FlatVector & ely, LocalHeap & locheap) const { const int smallsizex = elx.Size()/dim; const int smallsizey = ely.Size()/dim; Vector small_elx(smallsizex); Vector small_ely(smallsizey); ely = 0; if(comp == -1) { for(int d=0; d & elx, FlatVector & ely, LocalHeap & locheap) const { const int smallsizex = elx.Size()/dim; const int smallsizey = ely.Size()/dim; Vector small_elx(smallsizex); Vector small_ely(smallsizey); ely = 0; if(comp == -1) { for(int d=0; d & elveclin, FlatMatrix & elmat, LocalHeap & locheap) const { const int smallsizelin = elveclin.Size()/dim; Vector small_elveclin(smallsizelin); FlatMatrix mat1; if (comp == -1) { bool allocated(false); for(int d=0; d & elveclin, FlatMatrix & elmat, LocalHeap & locheap) const { const int smallsizelin = elveclin.Size()/dim; Vector small_elveclin(smallsizelin); FlatMatrix mat1; if (comp == -1) { bool allocated(false); for(int d=0; d & elx, FlatVector & flux, bool applyd, LocalHeap & lh) const { if (comp >= 0) { FlatVector selx(elx.Size()/dim, lh); for (int i = 0; i < selx.Size(); i++) selx(i) = elx(dim*i+comp); bfi.CalcFlux (fel, eltrans, ip, selx, flux, applyd, lh); } else { FlatVector selx(elx.Size()/dim, lh); FlatVector sflux(bfi.DimFlux(), lh); flux.AssignMemory (DimFlux(), lh); for (int j = 0; j < dim; j++) { for (int i = 0; i < selx.Size(); i++) selx(i) = elx(dim*i+j); bfi.CalcFlux (fel, eltrans, ip, selx, sflux, applyd, lh); for (int i = 0; i < sflux.Size(); i++) flux(dim*i+j) = sflux(i); } } /* int i, j; int mincomp = 0; int maxcomp = dim-1; if (comp >= 0) mincomp = maxcomp = comp; FlatVector selx(elx.Size()/dim, lh); FlatVector sflux(bfi.DimFlux(), lh); flux.AssignMemory (DimFlux(), lh); for (j = mincomp; j <= maxcomp; j++) { for (i = 0; i < selx.Size(); i++) selx(i) = elx(dim*i+j); bfi.CalcFlux (fel, eltrans, ip, selx, sflux, applyd, lh); for (i = 0; i < sflux.Size(); i++) flux(dim*i+j) = sflux(i); } */ } void BlockBilinearFormIntegrator :: CalcFlux (const FiniteElement & fel, const ElementTransformation & eltrans, const IntegrationPoint & ip, const FlatVector & elx, FlatVector & flux, bool applyd, LocalHeap & lh) const { if (comp >= 0) { FlatVector selx(elx.Size()/dim, lh); for (int i = 0; i < selx.Size(); i++) selx(i) = elx(dim*i+comp); bfi.CalcFlux (fel, eltrans, ip, selx, flux, applyd, lh); } else { FlatVector selx(elx.Size()/dim, lh); FlatVector sflux(bfi.DimFlux(), lh); flux.AssignMemory (DimFlux(), lh); for (int j = 0; j < dim; j++) { for (int i = 0; i < selx.Size(); i++) selx(i) = elx(dim*i+j); bfi.CalcFlux (fel, eltrans, ip, selx, sflux, applyd, lh); for (int i = 0; i < sflux.Size(); i++) flux(dim*i+j) = sflux(i); } } /* int i, j; int mincomp = 0; int maxcomp = dim-1; if (comp >= 0) mincomp = maxcomp = comp; FlatVector selx(elx.Size()/dim, lh); FlatVector sflux(bfi.DimFlux(), lh); flux.AssignMemory (DimFlux(), lh); for (j = mincomp; j <= maxcomp; j++) { for (i = 0; i < selx.Size(); i++) selx(i) = elx(dim*i+j); bfi.CalcFlux (fel, eltrans, ip, selx, sflux, applyd, lh); for (i = 0; i < sflux.Size(); i++) flux(dim*i+j) = sflux(i); } */ } void BlockBilinearFormIntegrator :: CalcFlux (const FiniteElement & fel, const BaseSpecificIntegrationPoint & bsip, const FlatVector & elx, FlatVector & flux, bool applyd, LocalHeap & lh) const { if (comp >= 0) { FlatVector selx(elx.Size()/dim, lh); for (int i = 0; i < selx.Size(); i++) selx(i) = elx(dim*i+comp); bfi.CalcFlux (fel, bsip, selx, flux, applyd, lh); } else { FlatVector selx(elx.Size()/dim, lh); FlatVector sflux(bfi.DimFlux(), lh); flux.AssignMemory (DimFlux(), lh); for (int j = 0; j < dim; j++) { for (int i = 0; i < selx.Size(); i++) selx(i) = elx(dim*i+j); bfi.CalcFlux (fel, bsip, selx, sflux, applyd, lh); for (int i = 0; i < sflux.Size(); i++) flux(dim*i+j) = sflux(i); } } /* int i, j; int mincomp = 0; int maxcomp = dim-1; if (comp >= 0) mincomp = maxcomp = comp; FlatVector selx(elx.Size()/dim, lh); FlatVector sflux(bfi.DimFlux(), lh); flux.AssignMemory (DimFlux(), lh); for (j = mincomp; j <= maxcomp; j++) { for (i = 0; i < selx.Size(); i++) selx(i) = elx(dim*i+j); bfi.CalcFlux (fel, bsip, selx, sflux, applyd, lh); for (i = 0; i < sflux.Size(); i++) flux(dim*i+j) = sflux(i); } */ } void BlockBilinearFormIntegrator :: CalcFlux (const FiniteElement & fel, const BaseSpecificIntegrationPoint & bsip, const FlatVector & elx, FlatVector & flux, bool applyd, LocalHeap & lh) const { if (comp >= 0) { FlatVector selx(elx.Size()/dim, lh); for (int i = 0; i < selx.Size(); i++) selx(i) = elx(dim*i+comp); bfi.CalcFlux (fel, bsip, selx, flux, applyd, lh); } else { FlatVector selx(elx.Size()/dim, lh); FlatVector sflux(bfi.DimFlux(), lh); flux.AssignMemory (DimFlux(), lh); for (int j = 0; j < dim; j++) { for (int i = 0; i < selx.Size(); i++) selx(i) = elx(dim*i+j); bfi.CalcFlux (fel, bsip, selx, sflux, applyd, lh); for (int i = 0; i < sflux.Size(); i++) flux(dim*i+j) = sflux(i); } } /* int i, j; int mincomp = 0; int maxcomp = dim-1; if (comp >= 0) mincomp = maxcomp = comp; FlatVector selx(elx.Size()/dim, lh); FlatVector sflux(bfi.DimFlux(), lh); flux.AssignMemory (DimFlux(), lh); for (j = mincomp; j <= maxcomp; j++) { for (i = 0; i < selx.Size(); i++) selx(i) = elx(dim*i+j); bfi.CalcFlux (fel, bsip, selx, sflux, applyd, lh); for (i = 0; i < sflux.Size(); i++) flux(dim*i+j) = sflux(i); } */ } double BlockBilinearFormIntegrator :: Energy (const FiniteElement & fel, const ElementTransformation & eltrans, const FlatVector & elx, LocalHeap & lh) const { int i, j; int mincomp = 0; int maxcomp = dim-1; if (comp >= 0) mincomp = maxcomp = comp; double energy = 0; FlatVector selx(elx.Size()/dim, lh); for (j = mincomp; j <= maxcomp; j++) { for (i = 0; i < selx.Size(); i++) selx(i) = elx(dim*i+j); energy += bfi.Energy (fel, eltrans, selx, lh); } return energy; } void BlockBilinearFormIntegrator :: ApplyBTrans (const FiniteElement & fel, const BaseSpecificIntegrationPoint & bsip, const FlatVector & elx, FlatVector & ely, LocalHeap & lh) const { int i, j; int mincomp = 0; int maxcomp = dim-1; if (comp >= 0) mincomp = maxcomp = comp; FlatVector selx(elx.Size()/dim, lh); FlatVector sely(ely.Size()/dim, lh); for (j = mincomp; j <= maxcomp; j++) { for (i = 0; i < selx.Size(); i++) selx(i) = elx(dim*i+j); bfi.ApplyBTrans (fel, bsip, selx, sely, lh); for (i = 0; i < sely.Size(); i++) ely(dim*i+j) = sely(i); } } void BlockBilinearFormIntegrator :: ApplyBTrans (const FiniteElement & fel, const BaseSpecificIntegrationPoint & bsip, const FlatVector & elx, FlatVector & ely, LocalHeap & lh) const { int i, j; int mincomp = 0; int maxcomp = dim-1; if (comp >= 0) mincomp = maxcomp = comp; FlatVector selx(elx.Size()/dim, lh); FlatVector sely(ely.Size()/dim, lh); for (j = mincomp; j <= maxcomp; j++) { for (i = 0; i < selx.Size(); i++) selx(i) = elx(dim*i+j); bfi.ApplyBTrans (fel, bsip, selx, sely, lh); for (i = 0; i < sely.Size(); i++) ely(dim*i+j) = sely(i); } } string BlockBilinearFormIntegrator :: Name () const { return string ("BlockIntegrator (") + bfi.Name() + string (")"); } NormalBilinearFormIntegrator :: NormalBilinearFormIntegrator (const BilinearFormIntegrator & abfi) : bfi(abfi) { if (!bfi.BoundaryForm()) throw Exception ("NormalBilinearFormIntegrator: Only possible for boundary forms"); } void NormalBilinearFormIntegrator :: AssembleElementMatrix (const FiniteElement & bfel, const ElementTransformation & eltrans, FlatMatrix & elmat, LocalHeap & locheap) const { int i, j, k, l; FlatMatrix mat1; bfi.AssembleElementMatrix (bfel, eltrans, mat1, locheap); int ndof = mat1.Height(); int sdim = eltrans.SpaceDim(); elmat.AssignMemory (ndof*sdim, ndof*sdim, locheap); elmat = 0; FlatVector<> nv(sdim, locheap); FlatMatrix<> nvmat(sdim, ndof, locheap); const NodalFiniteElement & fel = dynamic_cast (bfel); const IntegrationRule & nodalrule = fel.NodalIntegrationRule(); for (i = 0; i < ndof; i++) { eltrans.CalcNormalVector (nodalrule.GetIP(i), nv, locheap); // nv = eltrans.NVMatrix() * eltrans.GetElement().GetShape (nodalrule.GetIP(i), locheap); for (j = 0; j < sdim; j++) nvmat(j, i) = nv(j); } for (i = 0; i < ndof; i++) for (j = 0; j < ndof; j++) for (k = 0; k < sdim; k++) for (l = 0; l < sdim; l++) elmat(i*sdim+k, j*sdim+l) = mat1(i,j) * nvmat(k,i) * nvmat(l,j); } ComplexBilinearFormIntegrator :: ComplexBilinearFormIntegrator (const BilinearFormIntegrator & abfi, Complex afactor) : bfi(abfi), factor(afactor) { ; } void ComplexBilinearFormIntegrator :: AssembleElementMatrix (const FiniteElement & fel, const ElementTransformation & eltrans, FlatMatrix & elmat, LocalHeap & locheap) const { throw Exception ("ComplexBilinearFormIntegrator: cannot assemble double matrix"); } void ComplexBilinearFormIntegrator :: AssembleElementMatrix (const FiniteElement & fel, const ElementTransformation & eltrans, FlatMatrix & elmat, LocalHeap & locheap) const { FlatMatrix rmat; bfi.AssembleElementMatrix (fel, eltrans, rmat, locheap); elmat.AssignMemory (rmat.Height(), rmat.Width(), locheap); elmat = factor * rmat; } void ComplexBilinearFormIntegrator :: ApplyElementMatrix (const FiniteElement & fel, const ElementTransformation & eltrans, const FlatVector & elx, FlatVector & ely, LocalHeap & locheap) const { // FlatVector hy(ely.Size(), locheap); // BilinearFormIntegrator::ApplyElementMatrix (fel, eltrans, elx, hy, locheap); bfi.ApplyElementMatrix (fel, eltrans, elx, ely, locheap); ely *= factor; /* hy -= ely; if (L2Norm (hy) >= 1e-10) { cout << "type = " << typeid(bfi).name() << endl; cout << "Complex different: " << hy << endl; } */ } void ComplexBilinearFormIntegrator :: CalcFlux (const FiniteElement & fel, const ElementTransformation & eltrans, const IntegrationPoint & ip, const FlatVector & elx, FlatVector & flux, bool applyd, LocalHeap & lh) const { bfi.CalcFlux (fel, eltrans, ip, elx, flux, applyd, lh); flux *= factor; } string ComplexBilinearFormIntegrator :: Name () const { return string ("ComplexIntegrator (") + bfi.Name() + string (")"); } CompoundBilinearFormIntegrator :: CompoundBilinearFormIntegrator (const BilinearFormIntegrator & abfi, int acomp) : bfi(abfi), comp(acomp) { ; } void CompoundBilinearFormIntegrator :: AssembleElementMatrix (const FiniteElement & bfel, const ElementTransformation & eltrans, FlatMatrix & elmat, LocalHeap & locheap) const { const CompoundFiniteElement & fel = dynamic_cast (bfel); int i, j; FlatMatrix mat1; bfi.AssembleElementMatrix (fel[comp], eltrans, mat1, locheap); elmat.AssignMemory (fel.GetNDof(), fel.GetNDof(), locheap); elmat = 0; int base = 0; for (i = 0; i < comp; i++) base += fel[i].GetNDof(); for (i = 0; i < mat1.Height(); i++) for (j = 0; j < mat1.Width(); j++) elmat(base+i, base+j) = mat1(i,j); } void CompoundBilinearFormIntegrator :: AssembleElementMatrix (const FiniteElement & bfel, const ElementTransformation & eltrans, FlatMatrix & elmat, LocalHeap & locheap) const { const CompoundFiniteElement & fel = dynamic_cast (bfel); int i, j; FlatMatrix mat1; bfi.AssembleElementMatrix (fel[comp], eltrans, mat1, locheap); elmat.AssignMemory (fel.GetNDof(), fel.GetNDof(), locheap); elmat = 0; int base = 0; for (i = 0; i < comp; i++) base += fel[i].GetNDof(); for (i = 0; i < mat1.Height(); i++) for (j = 0; j < mat1.Width(); j++) elmat(base+i, base+j) = mat1(i,j); } void CompoundBilinearFormIntegrator :: AssembleLinearizedElementMatrix (const FiniteElement & bfel, const ElementTransformation & eltrans, FlatVector & ellin, FlatMatrix & elmat, LocalHeap & locheap) const { const CompoundFiniteElement & fel = dynamic_cast (bfel); int i, j; FlatMatrix mat1; int nd = fel[comp].GetNDof(); FlatVector ellin1(nd, locheap); int base = 0; for (i = 0; i < comp; i++) base += fel[i].GetNDof(); for (j = 0; j < nd; j++) ellin1(j) = ellin(base+j); bfi.AssembleLinearizedElementMatrix (fel[comp], eltrans, ellin1, mat1, locheap); elmat.AssignMemory (fel.GetNDof(), fel.GetNDof(), locheap); elmat = 0; for (i = 0; i < mat1.Height(); i++) for (j = 0; j < mat1.Width(); j++) elmat(base+i, base+j) = mat1(i,j); } void CompoundBilinearFormIntegrator :: AssembleLinearizedElementMatrix (const FiniteElement & bfel, const ElementTransformation & eltrans, FlatVector & ellin, FlatMatrix & elmat, LocalHeap & locheap) const { const CompoundFiniteElement & fel = dynamic_cast (bfel); int i, j; FlatMatrix mat1; int nd = fel[comp].GetNDof(); FlatVector ellin1(nd, locheap); int base = 0; for (i = 0; i < comp; i++) base += fel[i].GetNDof(); for (j = 0; j < nd; j++) ellin1(j) = ellin(base+j); bfi.AssembleLinearizedElementMatrix (fel[comp], eltrans, ellin1, mat1, locheap); elmat.AssignMemory (fel.GetNDof(), fel.GetNDof(), locheap); elmat = 0; for (i = 0; i < mat1.Height(); i++) for (j = 0; j < mat1.Width(); j++) elmat(base+i, base+j) = mat1(i,j); } void CompoundBilinearFormIntegrator :: ApplyElementMatrix (const FiniteElement & bfel, const ElementTransformation & eltrans, const FlatVector & elx, FlatVector & ely, LocalHeap & locheap) const { const CompoundFiniteElement & fel = dynamic_cast (bfel); int i, j; int nd = fel[comp].GetNDof(); FlatVector elx1(nd, locheap); FlatVector ely1(nd, locheap); int base = 0; for (i = 0; i < comp; i++) base += fel[i].GetNDof(); for (j = 0; j < nd; j++) elx1(j) = elx(base+j); bfi.ApplyElementMatrix (fel[comp], eltrans, elx1, ely1, locheap); ely = 0; for (j = 0; j < nd; j++) ely(base+j) = ely1(j); } void CompoundBilinearFormIntegrator :: ApplyElementMatrix (const FiniteElement & bfel, const ElementTransformation & eltrans, const FlatVector & elx, FlatVector & ely, LocalHeap & locheap) const { // FlatVector hy(ely.Size(), locheap); // BilinearFormIntegrator::ApplyElementMatrix (bfel, eltrans, elx, hy, locheap); const CompoundFiniteElement & fel = dynamic_cast (bfel); int i, j; int nd = fel[comp].GetNDof(); FlatVector elx1(nd, locheap); FlatVector ely1(nd, locheap); int base = 0; for (i = 0; i < comp; i++) base += fel[i].GetNDof(); for (j = 0; j < nd; j++) elx1(j) = elx(base+j); bfi.ApplyElementMatrix (fel[comp], eltrans, elx1, ely1, locheap); ely = 0; for (j = 0; j < nd; j++) ely(base+j) = ely1(j); /* hy -= ely; if (L2Norm (hy) >= 1e-10) { cout << "type = " << typeid(bfi).name() << endl; cout << "elx1 = " << elx1 << endl; cout << "ely1 = " << ely1 << endl; cout << "Compound different: " << hy << endl; } */ } void CompoundBilinearFormIntegrator :: ApplyLinearizedElementMatrix (const FiniteElement & bfel, const ElementTransformation & eltrans, const FlatVector & ellin, const FlatVector & elx, FlatVector & ely, LocalHeap & locheap) const { const CompoundFiniteElement & fel = dynamic_cast (bfel); int i, j; int nd = fel[comp].GetNDof(); FlatVector ellin1(nd, locheap); FlatVector elx1(nd, locheap); FlatVector ely1(nd, locheap); int base = 0; for (i = 0; i < comp; i++) base += fel[i].GetNDof(); for (j = 0; j < nd; j++) { ellin1(j) = ellin(base+j); elx1(j) = elx(base+j); } bfi.ApplyLinearizedElementMatrix (fel[comp], eltrans, ellin1, elx1, ely1, locheap); ely = 0; for (j = 0; j < nd; j++) ely(base+j) = ely1(j); } void CompoundBilinearFormIntegrator :: ApplyLinearizedElementMatrix (const FiniteElement & bfel, const ElementTransformation & eltrans, const FlatVector & ellin, const FlatVector & elx, FlatVector & ely, LocalHeap & locheap) const { // FlatVector hy(ely.Size(), locheap); // BilinearFormIntegrator::ApplyElementMatrix (bfel, eltrans, elx, hy, locheap); const CompoundFiniteElement & fel = dynamic_cast (bfel); int i, j; int nd = fel[comp].GetNDof(); FlatVector ellin1(nd, locheap); FlatVector elx1(nd, locheap); FlatVector ely1(nd, locheap); int base = 0; for (i = 0; i < comp; i++) base += fel[i].GetNDof(); for (j = 0; j < nd; j++) { ellin1(j) = ellin(base+j); elx1(j) = elx(base+j); } bfi.ApplyLinearizedElementMatrix (fel[comp], eltrans, ellin1, elx1, ely1, locheap); ely = 0; for (j = 0; j < nd; j++) ely(base+j) = ely1(j); /* hy -= ely; if (L2Norm (hy) >= 1e-10) { cout << "type = " << typeid(bfi).name() << endl; cout << "elx1 = " << elx1 << endl; cout << "ely1 = " << ely1 << endl; cout << "Compound different: " << hy << endl; } */ } void CompoundBilinearFormIntegrator :: CalcFlux (const FiniteElement & bfel, const ElementTransformation & eltrans, const IntegrationPoint & ip, const FlatVector & elx, FlatVector & flux, bool applyd, LocalHeap & lh) const { const CompoundFiniteElement & fel = dynamic_cast (bfel); FlatVector selx(fel[comp].GetNDof(), lh); int base = 0; for (int i = 0; i < comp; i++) base += fel[i].GetNDof(); for (int i = 0; i < selx.Size(); i++) selx(i) = elx(base+i); bfi.CalcFlux (fel[comp], eltrans, ip, selx, flux, applyd, lh); } void CompoundBilinearFormIntegrator :: CalcFlux (const FiniteElement & bfel, const ElementTransformation & eltrans, const IntegrationPoint & ip, const FlatVector & elx, FlatVector & flux, bool applyd, LocalHeap & lh) const { const CompoundFiniteElement & fel = dynamic_cast (bfel); FlatVector selx(fel[comp].GetNDof(), lh); int base = 0; for (int i = 0; i < comp; i++) base += fel[i].GetNDof(); for (int i = 0; i < selx.Size(); i++) selx(i) = elx(base+i); bfi.CalcFlux (fel[comp], eltrans, ip, selx, flux, applyd, lh); } string CompoundBilinearFormIntegrator :: Name () const { return string ("CompoundIntegrator (") + bfi.Name() + string (")"); } BlockLinearFormIntegrator :: BlockLinearFormIntegrator (const LinearFormIntegrator & alfi, int adim, int acomp) : lfi(alfi), dim(adim), comp(acomp) { ; } void BlockLinearFormIntegrator :: AssembleElementVector (const FiniteElement & bfel, const ElementTransformation & eltrans, FlatVector & elvec, LocalHeap & locheap) const { FlatVector vec1; lfi.AssembleElementVector (bfel, eltrans, vec1, locheap); elvec.AssignMemory (vec1.Size()*dim, locheap); elvec = 0; for (int i = 0; i < vec1.Size(); i++) elvec(dim*i+comp) = vec1(i); } Integrators::IntegratorInfo:: IntegratorInfo (const string & aname, int aspacedim, int anumcoeffs, Integrator* (*acreator)(ARRAY&)) : name(aname), spacedim(aspacedim), numcoeffs(anumcoeffs), creator(acreator) { ; } Integrators :: Integrators () { ; } Integrators :: ~Integrators() { for (int i = 0; i < bfis.Size(); i++) delete bfis[i]; for (int i = 0; i < lfis.Size(); i++) delete lfis[i]; } void Integrators :: AddBFIntegrator (const string & aname, int aspacedim, int anumcoeffs, Integrator* (*creator)(ARRAY&)) { bfis.Append (new IntegratorInfo(aname, aspacedim, anumcoeffs, creator)); } const Integrators::IntegratorInfo * Integrators::GetBFI(const string & name, int spacedim) const { for (int i = 0; i < bfis.Size(); i++) { if (name == bfis[i]->name && spacedim == bfis[i]->spacedim) return bfis[i]; } throw Exception (string ("GetBFI: Unknown integrator") + name + "\n"); } BilinearFormIntegrator * Integrators::CreateBFI(const string & name, int dim, ARRAY & coeffs) const { return dynamic_cast (GetBFI(name, dim)->creator(coeffs)); } void Integrators :: AddLFIntegrator (const string & aname, int aspacedim, int anumcoeffs, Integrator* (*creator)(ARRAY&)) { lfis.Append (new IntegratorInfo(aname, aspacedim, anumcoeffs, creator)); } const Integrators::IntegratorInfo * Integrators::GetLFI(const string & name, int spacedim) const { for (int i = 0; i < lfis.Size(); i++) { if (name == lfis[i]->name && spacedim == lfis[i]->spacedim) return lfis[i]; } throw Exception (string ("GetLFI: Unknown integrator") + name + "\n"); // return 0; } void Integrators :: Print (ostream & ost) const { int i; ost << endl << "Bilinear-form integrators:" << endl; ost << "--------------------------" << endl; ost << setw(20) << "Name" << setw(4) << "dim" << setw(4) << "nco" << endl; for (i = 0; i < bfis.Size(); i++) ost << setw(20) << bfis[i]->name << setw(4) << bfis[i]->spacedim << setw(4) << bfis[i]->numcoeffs << endl; ost << endl << "Linear-form integrators:" << endl; ost << "------------------------" << endl; ost << setw(20) << "Name" << setw(4) << "dim" << setw(4) << "nco" << endl; for (i = 0; i < lfis.Size(); i++) ost << setw(20) << lfis[i]->name << setw(4) << lfis[i]->spacedim << setw(4) << lfis[i]->numcoeffs << endl; } Integrators & GetIntegrators () { static Integrators itgs; return itgs; } }