void TPZAnalysisError::ExpandConnected(TPZStack<TPZCompElSide> &singel){ int64_t nelem = singel.NElements(); TPZStack<TPZGeoElSide> gelstack; TPZStack<TPZCompElSide> celstack; int64_t iel; for(iel=0; iel<nelem; iel++) { TPZCompElSide celside = singel[iel]; TPZGeoElSide gelside; gelside = celside.Reference(); if(!gelside.Exists()) continue; gelstack.Resize(0); cout << "This part needs to be fixed\n"; // gelside.Element()->LowerDimensionSides(gelside.Side(),gelstack); while(gelstack.NElements()) { TPZGeoElSide gelsideloc; gelsideloc = gelstack.Pop(); gelsideloc.EqualLevelCompElementList(celstack,1,0); while(celstack.NElements()) { TPZCompElSide celsideloc = celstack.Pop(); if(! celsideloc.Exists()) continue; int64_t nelsing = singel.NElements(); int64_t smel; for(smel=0; smel<nelsing; smel++) if(singel[smel].Element() == celsideloc.Element()) break; if(smel != nelsing) singel.Push(celsideloc); } } } }
int TPZErrorIndicator::GetRefSide(TPZCompEl *cel, int sidedim, int sidestate, TPZMatrix *errormat){ int e,s,nsides = cel->Reference()->NSides(); REAL sum = 0.; int side = -1; for (s=0;s<nsides;s++){ TPZCompElSide celside (cel,s); if (celside.Reference().Dimension() != sidedim) continue; TPZStack<TPZCompElSide> elsidevec; celside.EqualLevelElementList(elsidevec,0,0); REAL auxsum = 0; int neigbyside = elsidevec.NElements(); for (e=0;e<neigbyside;e++){ int index = elsidevec[e].Element()->Index(); double val = 0.; val = errormat->Get(e,sidestate); auxsum += val; } auxsum /= ((REAL) neigbyside); if(auxsum > sum){ sum = auxsum; side = s; } } return side; }
void ChecarIterface(TPZCompMesh *mphysics){ int nel = mphysics->NElements(); for(int i = 0; i< nel; i++){ TPZCompEl *cel = mphysics->ElementVec()[i]; if(!cel) continue; TPZMultiphysicsElement *mphel = dynamic_cast<TPZMultiphysicsElement *>(cel); TPZMultiphysicsInterfaceElement *mpintel = dynamic_cast<TPZMultiphysicsInterfaceElement *>(cel); if(mphel){ int nsides = mphel->Reference()->NSides(); std::cout <<"\n\n For the element of index = " << i; for(int is = 0; is<nsides; is++){ bool isinterface; isinterface = mphel->ExistsInterface(is); std::cout <<"\n There is interface by side = " << is << " ? ==> " << isinterface; } } if(mpintel){ TPZCompElSide leftel; TPZCompElSide rightel; mpintel->GetLeftRightElement(leftel,rightel); leftel.Element()->Print(); rightel.Element()->Print(); } } }
TPZInterpolatedElement * TPZAdaptMesh::LargeElement(TPZInterpolatedElement *cint) { int nc = cint->NConnects(); int side; TPZInterpolatedElement *result = cint; for(side=0; side<nc; side++) { if(cint->Connect(side).HasDependency()) { TPZCompElSide cintside(cint,side); TPZCompElSide large = cintside.LowerLevelElementList(1); if(!large.Exists()) { cout << "TPZAdaptMesh::DeleteElements I dont understand\n"; large = cintside.LowerLevelElementList(1); return cint; } result = dynamic_cast<TPZInterpolatedElement *> (large.Element()); break; } } return result; }
void TPZMGAnalysis::MeshError(TPZCompMesh *fine, TPZCompMesh *coarse, TPZVec<REAL> &ervec, void (*f)(TPZVec<REAL> &loc, TPZVec<REAL> &val, TPZFMatrix<REAL> &deriv),TPZVec<REAL> &truervec){ coarse->Reference()->ResetReference(); coarse->LoadReferences(); int dim = fine->MaterialVec().begin()->second->Dimension(); ervec.Resize(coarse->NElements()); if(f) { truervec.Resize(coarse->NElements()); truervec.Fill(0.,0); } ervec.Fill(0.,0); TPZCompEl *cel; TPZAdmChunkVector<TPZCompEl *> &elementvec = fine->ElementVec(); int numel = elementvec.NElements(); int el; for(el=0; el<numel; el++) { cel = elementvec[el]; if (!cel) continue; TPZInterpolatedElement *cint = dynamic_cast<TPZInterpolatedElement *> (cel); if(!cint) continue; int ncon = cint->NConnects(); TPZGeoElSide gelside(cint->Reference(),ncon-1); if(gelside.Dimension() != dim) continue; TPZGeoElSide gellarge(gelside); while(!gellarge.Reference().Exists() && gellarge.Father2().Exists()) gellarge = gellarge.Father2(); if(!gellarge.Reference().Exists()) { cout << "TPZMGAnalsysis::BuildTransferMatrix element " << el << " found no corresponding element\n"; continue; } TPZCompElSide cellargeside = gellarge.Reference(); TPZCompEl *cellarge = cellargeside.Element(); TPZInterpolatedElement *cintlarge = (TPZInterpolatedElement *) cellarge; TPZTransform transform(gelside.Dimension(),gellarge.Dimension()); gelside.SideTransform3(gellarge,transform); int index = cellarge->Index(); REAL truerror = 0.; ervec[index] += ElementError(cint,cintlarge,transform,f,truerror); if(f) truervec[index] += truerror; } }
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") }
TPZMultiphysicsInterfaceElement * TPZMultiphysicsElement::CreateInterface(int side) { // LOGPZ_INFO(logger, "Entering CreateInterface"); TPZMultiphysicsInterfaceElement * newcreatedinterface = NULL; TPZGeoEl *ref = Reference(); if(!ref) { LOGPZ_WARN(logger, "Exiting CreateInterface Null reference reached - NULL interface returned"); return newcreatedinterface; } TPZCompElSide thisside(this,side); TPZStack<TPZCompElSide> list; list.Resize(0); thisside.EqualLevelElementList(list,0,0);//retorna distinto ao atual ou nulo int64_t size = list.NElements(); //espera-se ter os elementos computacionais esquerdo e direito //ja criados antes de criar o elemento interface // try to create an interface element between myself and an equal sized neighbour for (int64_t is=0; is<size; is++) { //Interface has the same material of the neighbour with lesser dimension. //It makes the interface have the same material of boundary conditions (TPZCompElDisc with interface dimension) int matid; int thisdim = this->Dimension(); int neighbourdim = list[is].Element()->Dimension(); if(thisdim != neighbourdim) { if (thisdim < neighbourdim) { // return the material id of boundary condition IF the associated material is derived from bndcond TPZMaterial *mat = this->Material(); TPZBndCond *bnd = dynamic_cast<TPZBndCond *>(mat); if(bnd) { matid = this->Material()->Id(); } else { matid = this->Mesh()->Reference()->InterfaceMaterial(this->Reference()->MaterialId(),list[0].Element()->Reference()->MaterialId()); continue; } } else { TPZMaterial *mat = list[is].Element()->Material(); TPZBndCond *bnd = dynamic_cast<TPZBndCond *>(mat); if (bnd) { matid = bnd->Id(); } else { matid = this->Mesh()->Reference()->InterfaceMaterial(this->Reference()->MaterialId(), list[0].Element()->Reference()->MaterialId()); continue; } } }else { matid = this->Mesh()->Reference()->InterfaceMaterial(this->Reference()->MaterialId(), list[0].Element()->Reference()->MaterialId()); if(matid == GMESHNOMATERIAL) { continue; } } int64_t index; TPZGeoEl *gel = ref->CreateBCGeoEl(side,matid); //isto acertou as vizinhanas da interface geometrica com o atual if(!gel){ DebugStop(); #ifdef LOG4CXX if (logger->isDebugEnabled()) { std::stringstream sout; sout << "CreateBCGeoEl devolveu zero!@@@@"; LOGPZ_DEBUG(logger,sout.str()); } #endif } bool withmem = fMesh->ApproxSpace().NeedsMemory(); if(Dimension() > list[is].Reference().Dimension()) { //o de volume eh o direito caso um deles seja BC //a normal aponta para fora do contorno TPZCompElSide thiscompelside(this, thisside.Side()); TPZCompElSide neighcompelside(list[is]); if (!withmem) { newcreatedinterface = new TPZMultiphysicsInterfaceElement(*fMesh,gel,index,thiscompelside,neighcompelside); } else { newcreatedinterface = new TPZCompElWithMem<TPZMultiphysicsInterfaceElement>(*fMesh,gel,index,thiscompelside,neighcompelside); } } else { //caso contrario ou caso ambos sejam de volume TPZCompElSide thiscompelside(this, thisside.Side()); TPZCompElSide neighcompelside(list[is]); if (!withmem) { newcreatedinterface = new TPZMultiphysicsInterfaceElement(*fMesh,gel,index,neighcompelside,thiscompelside); } else { newcreatedinterface = new TPZCompElWithMem<TPZMultiphysicsInterfaceElement>(*fMesh,gel,index,neighcompelside,thiscompelside); } } return newcreatedinterface; } //If there is no equal or lower level element, we try the lower elements. //Higher elements will not be considered by this method. In that case the interface must be created by the neighbour. TPZCompElSide lower = thisside.LowerLevelElementList(0); if(lower.Exists()){ //Interface has the same material of the neighbour with lesser dimension. //It makes the interface has the same material of boundary conditions (TPZCompElDisc with interface dimension) int matid = GMESHNOMATERIAL; int thisdim = this->Dimension(); int neighbourdim = lower.Element()->Dimension(); matid = this->Mesh()->Reference()->InterfaceMaterial(this->Material()->Id(), lower.Element()->Material()->Id() ); if (matid == GMESHNOMATERIAL && thisdim == neighbourdim){ // matid = this->Material()->Id(); //break; } else if(matid == GMESHNOMATERIAL && thisdim != neighbourdim) { if (thisdim < neighbourdim) { // return the material id of boundary condition IF the associated material is derived from bndcond TPZMaterial *mat = this->Material(); TPZBndCond *bnd = dynamic_cast<TPZBndCond *>(mat); if(bnd) { matid = this->Material()->Id(); } else { //continue; } } else { TPZMaterial *mat = lower.Element()->Material(); TPZBndCond *bnd = dynamic_cast<TPZBndCond *>(mat); if (bnd) { matid = bnd->Id(); } else { //continue; } } } // return zero if(matid == GMESHNOMATERIAL) { return newcreatedinterface; } TPZCompEl *lowcel = lower.Element(); //int lowside = lower.Side(); //existem esquerdo e direito: this e lower TPZGeoEl *gel = ref->CreateBCGeoEl(side,matid); int64_t index; bool withmem = fMesh->ApproxSpace().NeedsMemory(); if(Dimension() > lowcel->Dimension()){ //para que o elemento esquerdo seja de volume TPZCompElSide thiscompelside(this, thisside.Side()); TPZCompElSide lowcelcompelside(lower); if (!withmem) { newcreatedinterface = new TPZMultiphysicsInterfaceElement(*fMesh,gel,index,thiscompelside,lowcelcompelside); } else { newcreatedinterface = new TPZCompElWithMem<TPZMultiphysicsInterfaceElement>(*fMesh,gel,index,thiscompelside,lowcelcompelside); } } else { TPZCompElSide thiscompelside(this, thisside.Side()); TPZCompElSide lowcelcompelside(lower); #ifdef LOG4CXX_KEEP if (logger->isDebugEnabled()) { std::stringstream sout; sout << __PRETTY_FUNCTION__ << " left element"; sout << lowcelcompelside << thiscompelside; sout << "Left Element "; lowcelcompelside.Element()->Print(sout); sout << "Right Element "; thiscompelside.Element()->Print(sout); LOGPZ_DEBUG(logger,sout.str()) } #endif if (!withmem) { newcreatedinterface = new TPZMultiphysicsInterfaceElement(*fMesh,gel,index,lowcelcompelside,thiscompelside); } else { newcreatedinterface = new TPZCompElWithMem<TPZMultiphysicsInterfaceElement>(*fMesh,gel,index,lowcelcompelside,thiscompelside); } }
//SingularElements(..) void TPZAnalysisError::ZoomInSingularity(REAL csi, TPZCompElSide elside, REAL singularity_strength) { REAL hn = 1./pow(csi,1./singularity_strength); REAL Q=2.; REAL NcReal = log( 1.+(1./hn - 1.)*(Q - 1.) )/log(Q); int Nc = 0; while(REAL(Nc) < (NcReal+0.5)) Nc++; int minporder = 2; TPZStack<TPZCompElSide> ElToRefine; TPZStack<int> POrder; TPZStack<TPZGeoElSide> subelements; TPZStack<int64_t> csubindex; ElToRefine.Push(elside); POrder.Push(Nc); while(ElToRefine.NElements()) { /** Take the next element and its interpolation order from the stack*/ TPZCompElSide curelside = ElToRefine.Pop(); int curporder = POrder.Pop(); if(!curelside.Exists()) continue; int64_t cindex = curelside.Element()->Index(); if(cindex < 0) continue; /** Cast the element to an interpolated element if possible*/ TPZCompEl *cel = curelside.Element(); TPZInterpolatedElement *cintel = 0; cintel = dynamic_cast<TPZInterpolatedElement *> (cel); /** If the element is not interpolated, nothing to do */ if(!cintel) continue; /** Set the interpolation order of the current element to curporder*/ if(curporder == minporder) { cintel->PRefine(Nc); fSingular.Push(curelside); } else { cintel->PRefine(curporder); cintel->Divide(cindex,csubindex,1); /** Identify the subelements along the side and push them on the stack*/ } TPZGeoElSide gelside = curelside.Reference(); if(!gelside.Exists()) continue; gelside.GetSubElements2(subelements); int64_t ns = subelements.NElements(); curporder--; int64_t is; for(is=0; is<ns; is++) { TPZGeoElSide sub = subelements[is]; TPZCompElSide csub = sub.Reference(); if(csub.Exists()) { ElToRefine.Push(csub); POrder.Push(curporder); } } } ExpandConnected(fSingular); /* REAL H1_error,L2_error,estimate; TPZBlock *flux=0; int64_t nel = fElIndexes.NElements(); for(int64_t elloc=0;elloc<nel;elloc++) { int64_t el = fElIndexes[elloc]; estimate = fElErrors[elloc]; REAL csi = estimate / fAdmissibleError; REAL h = h_Parameter(intellist[el]); REAL hn = h/pow(csi,1./.9); REAL Nc = log( 1.+(h/hn - 1.)*(Q - 1.) )/log(Q); if(hn > 1.3*h) hn = 2.0*h*hn / (h + hn); REAL hsub = h;//100.0;//pode ser = h ; Cedric TPZCompEl *locel = intellist[el]; //obter um subelemento que contem o ponto singular e tem tamanho <= hn TPZAdmChunkVector<TPZCompEl *> sublist; while(hsub > hn) { TPZVec<int64_t> indexsubs; int64_t index = locel->Index(); locel->Divide(index,indexsubs,1); int64_t nsub = indexsubs.NElements(); TPZAdmChunkVector<TPZCompEl *> listsub(0); for(int64_t k=0;k<nsub;k++) { index = listsub.AllocateNewElement(); listsub[index] = Mesh()->ElementVec()[indexsubs[k]]; } //existe um unico filho que contem o ponto singular SingularElement(point,listsub,sublist); hsub = h_Parameter(sublist[0]); } TPZInterpolatedElement *intel = (TPZInterpolatedElement *) locel; intel->PRefine(Nc+1); indexlist.Push(intel->Index()); //os elemento viz devem ter ordens menores a cel quanto mais longe de point TPZInterpolatedElement *neighkeep,*neigh; //feito s�para o caso 1d , extender para o caso geral int dim = intel->Dimension(); if(dim != 1) { cout << "TPZAnalysisError::Step3 not dimension implemented , dimension = " << intellist[el]->Dimension() << endl; return ;//exit(1); } for(int side=0;side<2;side++) { int ly = 1; TPZGeoElSide neighside = intel->Reference()->Neighbour(side); TPZGeoElSide neighsidekeep = neighside; TPZCompElSide neighsidecomp(0,0); TPZStack<TPZCompElSide> elvec(0); TPZCompElSide thisside(intel,side); if(!neighsidekeep.Exists()) thisside.HigherLevelElementList(elvec,1,1); if(!neighsidekeep.Exists() && elvec.NElements() == 0) { neighsidekeep = thisside.LowerLevelElementList(1).Reference(); } else if(elvec.NElements() != 0) { neighsidekeep = elvec[0].Reference(); } while(ly < (Nc+1) && neighsidekeep.Exists() && neighsidekeep.Element()->Reference()->Material()->Id() > -1) { neigh = (TPZInterpolatedElement *) neighsidekeep.Element()->Reference(); if(neigh) { neigh->PRefine(ly); int otherside = (neighsidekeep.Side()+1)%2; neighsidekeep.SetSide(otherside); indexlist.Push(neighsidekeep.Reference().Element()->Index()); } neighside = neighsidekeep.Neighbour(); while(!neighside.Exists()) { neighsidecomp = neighsidekeep.Reference(); neighsidecomp.HigherLevelElementList(elvec,1,1); if(elvec.NElements()) { neighside = elvec[0].Reference(); break; } neighside = neighsidecomp.LowerLevelElementList(1).Reference(); if(!neighside.Exists()) break; } neighsidekeep = neighside; ly++; } } }//for Mesh()->InitializeBlock(); */ }