int TPZTransform::Compare(TPZTransform &t,REAL tol){ if(fCol != t.fCol || fRow != t.fRow) return 1; int i,j; for(i=0;i<fRow;i++){ if(fabs(fSum(i,0) - t.fSum(i,0)) > tol) return 1; for(j=0;j<fCol;j++){ if(fabs(fMult(i,j) - t.fMult(i,j)) > tol) return 1; } } return 0; }
int TPZCheckGeom::CheckSideTransform(TPZGeoEl *gel, int sidefrom, int sideto){ int check = 0; int nsides = gel->NSides(); TPZIntPoints *integ = gel->CreateSideIntegrationRule(sidefrom,2); TPZTransform trans = gel->SideToSideTransform(sidefrom,sideto); TPZTransform trans1 = gel->SideToSideTransform(sidefrom,nsides-1); TPZTransform trans2 = gel->SideToSideTransform(sideto,nsides-1); int sidefromdim = gel->SideDimension(sidefrom); int sidetodim = gel->SideDimension(sideto); int geldim = gel->Dimension(); TPZVec<REAL> intpoint(sidefromdim); TPZVec<REAL> sidetopoint(sidetodim); TPZVec<REAL> elpoint1(geldim),elpoint2(geldim); TPZVec<REAL> x1(3),x2(3); int nintpoints = integ->NPoints(); int ip; REAL w; for(ip=0; ip<nintpoints; ip++) { integ->Point(ip,intpoint,w); trans.Apply(intpoint,sidetopoint); trans1.Apply(intpoint,elpoint1); trans2.Apply(sidetopoint,elpoint2); gel->X(elpoint1,x1); gel->X(elpoint2,x2); REAL dif = 0; int nx = x1.NElements(); int ix; for(ix=0; ix<nx; ix++) dif += (x1[ix]-x2[ix])*(x1[ix]-x2[ix]); if(dif > 1.e-6) { PZError << "TPZCheckGeom::CheckSideTransform sidefrom = "<< sidefrom << " sideto = " << sideto << " dif = " << dif << endl; gel->Print(); check = 1; } } delete integ; return check; }
int CompareShapeFunctions(TPZCompElSide celsideA, TPZCompElSide celsideB) { TPZGeoElSide gelsideA = celsideA.Reference(); TPZGeoElSide gelsideB = celsideB.Reference(); int sideA = gelsideA.Side(); int sideB = gelsideB.Side(); TPZCompEl *celA = celsideA.Element(); TPZCompEl *celB = celsideB.Element(); TPZMultiphysicsElement *MFcelA = dynamic_cast<TPZMultiphysicsElement *>(celA); TPZMultiphysicsElement *MFcelB = dynamic_cast<TPZMultiphysicsElement *>(celB); TPZInterpolatedElement *interA = dynamic_cast<TPZInterpolatedElement *>(MFcelA->Element(0)); TPZInterpolatedElement *interB = dynamic_cast<TPZInterpolatedElement *>(MFcelB->Element(0)); TPZMaterialData dataA; TPZMaterialData dataB; interA->InitMaterialData(dataA); interB->InitMaterialData(dataB); TPZTransform<> tr = gelsideA.NeighbourSideTransform(gelsideB); TPZGeoEl *gelA = gelsideA.Element(); TPZTransform<> trA = gelA->SideToSideTransform(gelsideA.Side(), gelA->NSides()-1); TPZGeoEl *gelB = gelsideB.Element(); TPZTransform<> trB = gelB->SideToSideTransform(gelsideB.Side(), gelB->NSides()-1); int dimensionA = gelA->Dimension(); int dimensionB = gelB->Dimension(); int nSideshapeA = interA->NSideShapeF(sideA); int nSideshapeB = interB->NSideShapeF(sideB); int is; int firstShapeA = 0; int firstShapeB = 0; for (is=0; is<sideA; is++) { firstShapeA += interA->NSideShapeF(is); } for (is=0; is<sideB; is++) { firstShapeB += interB->NSideShapeF(is); } TPZIntPoints *intrule = gelA->CreateSideIntegrationRule(gelsideA.Side(), 4); int nwrong = 0; int npoints = intrule->NPoints(); int ip; for (ip=0; ip<npoints; ip++) { TPZManVector<REAL,3> pointA(gelsideA.Dimension()),pointB(gelsideB.Dimension()), pointElA(gelA->Dimension()),pointElB(gelB->Dimension()); REAL weight; intrule->Point(ip, pointA, weight); int sidedim = gelsideA.Dimension(); TPZFNMatrix<9> jacobian(sidedim,sidedim),jacinv(sidedim,sidedim),axes(sidedim,3); REAL detjac; gelsideA.Jacobian(pointA, jacobian, jacinv, detjac, jacinv); TPZManVector<REAL,3> normal(3,0.), xA(3),xB(3); normal[0] = axes(0,1); normal[1] = -axes(0,0); tr.Apply(pointA, pointB); trA.Apply(pointA, pointElA); trB.Apply(pointB, pointElB); gelsideA.Element()->X(pointElA, xA); gelsideB.Element()->X(pointElB, xB); for (int i=0; i<3; i++) { if(fabs(xA[i]- xB[i])> 1.e-6) DebugStop(); } int nshapeA = 0, nshapeB = 0; interA->ComputeRequiredData(dataA, pointElA); interB->ComputeRequiredData(dataB, pointElB); nshapeA = dataA.phi.Rows(); nshapeB = dataB.phi.Rows(); if(nSideshapeA != nSideshapeB) DebugStop(); TPZManVector<REAL> shapesA(nSideshapeA), shapesB(nSideshapeB); int nwrongkeep(nwrong); int i,j; for(i=firstShapeA,j=firstShapeB; i<firstShapeA+nSideshapeA; i++,j++) { int Ashapeind = i; int Bshapeind = j; int Avecind = -1; int Bvecind = -1; // if A or B are boundary elements, their shapefunctions come in the right order if (dimensionA != sidedim) { Ashapeind = dataA.fVecShapeIndex[i].second; Avecind = dataA.fVecShapeIndex[i].first; } if (dimensionB != sidedim) { Bshapeind = dataB.fVecShapeIndex[j].second; Bvecind = dataB.fVecShapeIndex[j].first; } if (dimensionA != sidedim && dimensionB != sidedim) { // vefify that the normal component of the normal vector corresponds Avecind = dataA.fVecShapeIndex[i].first; Bvecind = dataB.fVecShapeIndex[j].first; REAL vecnormalA = dataA.fNormalVec(0,Avecind)*normal[0]+dataA.fNormalVec(1,Avecind)*normal[1]; REAL vecnormalB = dataB.fNormalVec(0,Bvecind)*normal[0]+dataB.fNormalVec(1,Bvecind)*normal[1]; if(fabs(vecnormalA-vecnormalB) > 1.e-6) { nwrong++; LOGPZ_ERROR(logger, "normal vectors aren't equal") } } shapesA[i-firstShapeA] = dataA.phi(Ashapeind,0); shapesB[j-firstShapeB] = dataB.phi(Bshapeind,0); REAL valA = dataA.phi(Ashapeind,0); REAL valB = dataB.phi(Bshapeind,0); REAL diff = valA-valB; REAL decision = fabs(diff)-1.e-6; if(decision > 0.) { nwrong ++; std::cout << "valA = " << valA << " valB = " << valB << " Avecind " << Avecind << " Bvecind " << Bvecind << " Ashapeind " << Ashapeind << " Bshapeind " << Bshapeind << " sideA " << sideA << " sideB " << sideB << std::endl; LOGPZ_ERROR(logger, "shape function values are different") }
REAL TPZMGAnalysis::ElementError(TPZInterpolatedElement *fine, TPZInterpolatedElement *coarse, TPZTransform &tr, void (*f)(TPZVec<REAL> &loc, TPZVec<REAL> &val, TPZFMatrix<REAL> &deriv),REAL &truerror){ // accumulates the transfer coefficients between the current element and the // coarse element into the transfer matrix, using the transformation t int locnod = fine->NConnects(); int cornod = coarse->NConnects(); int locmatsize = fine->NShapeF(); int cormatsize = coarse->NShapeF(); REAL error = 0.; truerror = 0.; REAL loclocmatstore[500] = {0.},loccormatstore[500] = {0.}; TPZFMatrix<REAL> loclocmat(locmatsize,locmatsize,loclocmatstore,500); TPZFMatrix<REAL> loccormat(locmatsize,cormatsize,loccormatstore,500); TPZAutoPointer<TPZIntPoints> intrule = fine->GetIntegrationRule().Clone(); int dimension = fine->Dimension(); int numdof = fine->Material()->NStateVariables(); TPZBlock<REAL> &locblock = fine->Mesh()->Block(); TPZFMatrix<REAL> &locsolmesh = fine->Mesh()->Solution(); TPZBlock<REAL> &corblock = coarse->Mesh()->Block(); TPZFMatrix<REAL> &corsolmesh = coarse->Mesh()->Solution(); TPZVec<REAL> locsol(numdof); TPZFMatrix<REAL> locdsol(dimension,numdof); TPZVec<REAL> corsol(numdof); TPZFMatrix<REAL> cordsol(dimension,numdof); TPZManVector<int> prevorder(dimension), order(dimension); intrule->GetOrder(prevorder); TPZManVector<int> interpolation(dimension); fine->GetInterpolationOrder(interpolation); // compute the interpolation order of the shapefunctions squared int dim; int maxorder = interpolation[0]; for(dim=0; dim<interpolation.NElements(); dim++) { maxorder = interpolation[dim] < maxorder ? maxorder : interpolation[dim]; } for(dim=0; dim<dimension; dim++) { order[dim] = 20; } intrule->SetOrder(order); REAL locphistore[50]={0.},locdphistore[150]={0.}; TPZFMatrix<REAL> locphi(locmatsize,1,locphistore,50); TPZFMatrix<REAL> locdphi(dimension,locmatsize,locdphistore,150),locdphix(dimension,locmatsize); // derivative of the shape function // in the master domain REAL corphistore[50]={0.},cordphistore[150]={0.}; TPZFMatrix<REAL> corphi(cormatsize,1,corphistore,50); TPZFMatrix<REAL> cordphi(dimension,cormatsize,cordphistore,150), cordphix(dimension,cormatsize); // derivative of the shape function // in the master domain REAL jacobianstore[9], axesstore[9]; TPZManVector<REAL> int_point(dimension), coarse_int_point(dimension); TPZFMatrix<REAL> jacfine(dimension,dimension,jacobianstore,9),jacinvfine(dimension,dimension); TPZFMatrix<REAL> axesfine(3,3,axesstore,9); TPZManVector<REAL> xfine(3); TPZFMatrix<REAL> jaccoarse(dimension,dimension),jacinvcoarse(dimension,dimension); TPZFMatrix<REAL> axescoarse(3,3), axesinner(dimension,dimension); TPZManVector<REAL> xcoarse(3); REAL jacdetcoarse; int numintpoints = intrule->NPoints(); REAL weight; int i,j,k; TPZVec<REAL> truesol(numdof); TPZFMatrix<REAL> truedsol(dimension,numdof); for(int int_ind = 0; int_ind < numintpoints; ++int_ind) { intrule->Point(int_ind,int_point,weight); REAL jacdetfine; fine->Reference()->Jacobian( int_point, jacfine , axesfine, jacdetfine, jacinvfine); fine->Reference()->X(int_point, xfine); if(f) f(xfine,truesol,truedsol); fine->Shape(int_point,locphi,locdphi); tr.Apply(int_point,coarse_int_point); coarse->Shape(coarse_int_point,corphi,cordphi); coarse->Reference()->Jacobian( coarse_int_point,jaccoarse,axescoarse, jacdetcoarse, jacinvcoarse); coarse->Reference()->X(coarse_int_point,xcoarse); REAL dist = (xfine[0]-xcoarse[0])*(xfine[0]-xcoarse[0])+(xfine[1]-xcoarse[1])*(xfine[1]-xcoarse[1])+(xfine[2]-xcoarse[2])*(xfine[2]-xcoarse[2]); if(dist > 1.e-6) cout << "TPZMGAnalysis::ElementError transformation between fine and coarse is wrong\n"; for(i=0; i<dimension; i++) { for(j=0; j<dimension; j++) { axesinner(i,j) = 0.; for(k=0; k<3; k++) axesinner(i,j) += axesfine(i,k)*axescoarse(j,k); } } if(fabs(axesinner(0,0)-1.) > 1.e-6 || fabs(axesinner(1,1)-1.) > 1.e-6 || fabs(axesinner(0,1)) > 1.e-6 || fabs(axesinner(1,0)) > 1.e-6) { cout << "TPZMGAnalysis axesinner is not identify?\n"; } weight *= fabs(jacdetfine); locdphix.Zero(); int ieq,d; switch(dim) { case 0: //dphix.Redim(1,1); //dphix(0,0) = dphi(0,0); break; case 1: for(d=0; d<dimension; d++) { for(ieq=0; ieq<locmatsize; ieq++) locdphix(d,ieq) = locdphi(d,ieq)*(1./jacdetfine); for(ieq=0; ieq<cormatsize; ieq++) cordphix(d,ieq) = cordphi(d,ieq)*(axesinner(0,0)/jacdetcoarse); } break; case 2: for(ieq = 0; ieq < locmatsize; ieq++) { locdphix(0,ieq) = jacinvfine(0,0)*locdphi(0,ieq) + jacinvfine(1,0)*locdphi(1,ieq); locdphix(1,ieq) = jacinvfine(0,1)*locdphi(0,ieq) + jacinvfine(1,1)*locdphi(1,ieq); REAL tmp[2]; tmp[0] = locdphix(0,ieq)*axesfine(0,0)+locdphix(1,ieq)*axesfine(1,0); tmp[1] = locdphix(0,ieq)*axesfine(0,1)+locdphix(1,ieq)*axesfine(1,1); locdphix(0,ieq) = tmp[0]; locdphix(1,ieq) = tmp[1]; } for(ieq = 0; ieq < cormatsize; ieq++) { cordphix(0,ieq) = jacinvcoarse(0,0)*cordphi(0,ieq) + jacinvcoarse(1,0)*cordphi(1,ieq); cordphix(1,ieq) = jacinvcoarse(0,1)*cordphi(0,ieq) + jacinvcoarse(1,1)*cordphi(1,ieq); REAL tmp[2]; tmp[0] = cordphix(0,ieq)*axescoarse(0,0)+cordphix(1,ieq)*axescoarse(1,0); tmp[1] = cordphix(0,ieq)*axescoarse(0,1)+cordphix(1,ieq)*axescoarse(1,1); cordphix(0,ieq) = tmp[0]; cordphix(1,ieq) = tmp[1]; } break; case 3: for(ieq = 0; ieq < locmatsize; ieq++) { locdphix(0,ieq) = jacinvfine(0,0)*locdphi(0,ieq) + jacinvfine(0,1)*locdphi(1,ieq) + jacinvfine(0,2)*locdphi(2,ieq); locdphix(1,ieq) = jacinvfine(1,0)*locdphi(0,ieq) + jacinvfine(1,1)*locdphi(1,ieq) + jacinvfine(1,2)*locdphi(2,ieq); locdphix(2,ieq) = jacinvfine(2,0)*locdphi(0,ieq) + jacinvfine(2,1)*locdphi(1,ieq) + jacinvfine(2,2)*locdphi(2,ieq); } for(ieq = 0; ieq < cormatsize; ieq++) { cordphix(0,ieq) = jacinvcoarse(0,0)*cordphi(0,ieq) + jacinvcoarse(0,1)*cordphi(1,ieq) + jacinvcoarse(0,2)*cordphi(2,ieq); cordphix(1,ieq) = jacinvcoarse(1,0)*cordphi(0,ieq) + jacinvcoarse(1,1)*cordphi(1,ieq) + jacinvcoarse(1,2)*cordphi(2,ieq); cordphix(2,ieq) = jacinvcoarse(2,0)*cordphi(0,ieq) + jacinvcoarse(2,1)*cordphi(1,ieq) + jacinvcoarse(2,2)*cordphi(2,ieq); REAL tmp[3]; tmp[0] = cordphix(0,ieq)*axesinner(0,0)+cordphix(1,ieq)*axesinner(0,1)+cordphix(2,ieq)*axesinner(0,2); tmp[1] = cordphix(0,ieq)*axesinner(1,0)+cordphix(1,ieq)*axesinner(1,1)+cordphix(2,ieq)*axesinner(1,2); tmp[2] = cordphix(0,ieq)*axesinner(2,0)+cordphix(1,ieq)*axesinner(2,1)+cordphix(2,ieq)*axesinner(2,2); cordphix(0,ieq) = tmp[0]; cordphix(1,ieq) = tmp[1]; cordphix(2,ieq) = tmp[2]; } break; default: PZError << "pzintel.c please implement the " << dim << "d Jacobian and inverse\n"; PZError.flush(); } int iv=0; locsol.Fill(0.); locdsol.Zero(); iv=0; int in; for(in=0; in<locnod; in++) { TPZConnect *df = &fine->Connect(in); int dfseq = df->SequenceNumber(); int dfvar = locblock.Size(dfseq); int pos = locblock.Position(dfseq); for(int jn=0; jn<dfvar; jn++) { locsol[iv%numdof] += locphi(iv/numdof,0)*locsolmesh(pos+jn,0); for(d=0; d<dim; d++) locdsol(d,iv%numdof) += locdphix(d,iv/numdof)*locsolmesh(pos+jn,0); iv++; } } corsol.Fill(0.); cordsol.Zero(); iv=0; for(in=0; in<cornod; in++) { TPZConnect *df = &coarse->Connect(in); int dfseq = df->SequenceNumber(); int dfvar = corblock.Size(dfseq); int pos = corblock.Position(dfseq); for(int jn=0; jn<dfvar; jn++) { corsol[iv%numdof] += corphi(iv/numdof,0)*corsolmesh(pos+jn,0); for(d=0; d<dim; d++) cordsol(d,iv%numdof) += cordphix(d,iv/numdof)*corsolmesh(pos+jn,0); iv++; } } int jn; for(jn=0; jn<numdof; jn++) { // error += (locsol[jn]-corsol[jn])*(locsol[jn]-corsol[jn])*weight; // if(f) truerror += (corsol[jn]-truesol[jn])*(corsol[jn]-truesol[jn])*weight; for(d=0; d<dim; d++) { error += (locdsol(d,jn)-cordsol(d,jn))*(locdsol(d,jn)-cordsol(d,jn))*weight; if(f) truerror += (cordsol(d,jn)-truedsol(d,jn))*(cordsol(d,jn)-truedsol(d,jn))*weight; } } } intrule->SetOrder(prevorder); return error; }
int TPZCheckGeom::CheckSubFatherTransform(TPZGeoEl *subel, int sidesub) { int check = 0; TPZGeoElSide father = subel->Father2(sidesub); if(!father.Exists()) return check; TPZIntPoints *integ = subel->CreateSideIntegrationRule(sidesub,2); int subsidedim = subel->SideDimension(sidesub); int subdim = subel->Dimension(); TPZTransform trans(subsidedim); trans = subel->BuildTransform2(sidesub,father.Element(),trans); int fathsidedim = father.Dimension(); int fathdim = father.Element()->Dimension(); int nsubsides = subel->NSides(); int nfathsides = father.Element()->NSides(); TPZTransform trans1 = subel->SideToSideTransform(sidesub,nsubsides-1); TPZTransform trans2 = father.Element()->SideToSideTransform(father.Side(),nfathsides-1); TPZVec<REAL> intpoint(subsidedim); TPZVec<REAL> sidetopoint(fathsidedim); TPZVec<REAL> elpoint1(subdim),elpoint2(fathdim); TPZVec<REAL> x1(3),x2(3); int nintpoints = integ->NPoints(); int ip; REAL w; for(ip=0; ip<nintpoints; ip++) { integ->Point(ip,intpoint,w); trans.Apply(intpoint,sidetopoint); trans1.Apply(intpoint,elpoint1); trans2.Apply(sidetopoint,elpoint2); subel->X(elpoint1,x1); father.Element()->X(elpoint2,x2); int otherfatherside = father.Element()->WhichSide(elpoint2); if(otherfatherside != father.Side()) { int son = subel->WhichSubel(); PZError << "TPZCheckGeom::CheckSubFatherTransform son " << son << " sidesub = "<< sidesub << " fathside = " << father.Side() << " otherfatherside = " << otherfatherside << endl; check=1; } REAL dif = 0; int nx = x1.NElements(); int ix; for(ix=0; ix<nx; ix++) dif += (x1[ix]-x2[ix])*(x1[ix]-x2[ix]); if(dif > 1.e-6) { int son = subel->WhichSubel(); PZError << "TPZCheckGeom::CheckSubFatherTransform son " << son << " sidesub = "<< sidesub << " fathside = " << father.Side() << " dif = " << dif << endl; // subel->Print(); check = 1; TPZTransform t = subel->ComputeParamTrans(father.Element(),father.Side(),sidesub); t.PrintInputForm(cout); cout << endl; trans.PrintInputForm(cout); cout << endl; check = 1; } } if(check == 0) { TPZTransform t = subel->ComputeParamTrans(father.Element(),father.Side(),sidesub); check = t.Compare(trans); if(check == 1){ int son = subel->WhichSubel(); PZError << "TPZCheckGeom::CheckSubFatherTransform son " << son << " sidesub = "<< sidesub << " fathside = " << father.Side() << endl; t.PrintInputForm(cout); cout << endl; trans.PrintInputForm(cout); cout << endl; } // compare t with trans } delete integ; return check; }