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") }
/// Compute the contribution at an integration point to the stiffness matrix of the HDiv formulation void TPZMatPoisson3d::ContributeHDiv(TPZMaterialData &data,REAL weight,TPZFMatrix<STATE> &ek,TPZFMatrix<STATE> &ef) { /** monta a matriz |A B^T | = |0 | |B 0 | |f | **/ //TPZVec<REAL> &x = data.x; STATE fXfLoc = fXf; if(fForcingFunction) { // phi(in, 0) = phi_in TPZManVector<STATE> res(1); fForcingFunction->Execute(data.x,res); // dphi(i,j) = dphi_j/dxi fXfLoc = res[0]; } int numvec = data.fVecShapeIndex.NElements(); int numdual = data.numberdualfunctions; int numprimalshape = data.phi.Rows()-numdual; int i,j; REAL kreal = 0.; #ifdef STATE_COMPLEX kreal = fK.real(); #else kreal = fK; #endif REAL ratiok = 1./kreal; for(i=0; i<numvec; i++) { int ivecind = data.fVecShapeIndex[i].first; int ishapeind = data.fVecShapeIndex[i].second; for (j=0; j<numvec; j++) { int jvecind = data.fVecShapeIndex[j].first; int jshapeind = data.fVecShapeIndex[j].second; REAL prod = data.fNormalVec(0,ivecind)*data.fNormalVec(0,jvecind)+ data.fNormalVec(1,ivecind)*data.fNormalVec(1,jvecind)+ data.fNormalVec(2,ivecind)*data.fNormalVec(2,jvecind);//faz o produto escalar entre u e v--> Matriz A ek(i,j) += weight*ratiok*data.phi(ishapeind,0)*data.phi(jshapeind,0)*prod; } TPZFNMatrix<3> ivec(3,1); ivec(0,0) = data.fNormalVec(0,ivecind); ivec(1,0) = data.fNormalVec(1,ivecind); ivec(2,0) = data.fNormalVec(2,ivecind); TPZFNMatrix<3> axesvec(3,1); data.axes.Multiply(ivec,axesvec); int iloc; REAL divwq = 0.; for(iloc=0; iloc<fDim; iloc++) { divwq += axesvec(iloc,0)*data.dphix(iloc,ishapeind); } for (j=0; j<numdual; j++) { REAL fact = (-1.)*weight*data.phi(numprimalshape+j,0)*divwq;//calcula o termo da matriz B^T e B ek(i,numvec+j) += fact; ek(numvec+j,i) += fact;//-div } } for(i=0; i<numdual; i++) { ef(numvec+i,0) += (STATE)((-1.)*weight*data.phi(numprimalshape+i,0))*fXfLoc;//calcula o termo da matriz f #ifdef LOG4CXX if (logger->isDebugEnabled()) { std::stringstream sout; sout<< "Verificando termo fonte\n"; sout << " pto " <<data.x << std::endl; sout<< " fpto " <<fXfLoc <<std::endl; LOGPZ_DEBUG(logger,sout.str()) } #endif }