void RefinElemComp(TPZCompMesh *cMesh, int indexEl) { TPZVec<int64_t > subindex; int64_t nel = cMesh->ElementVec().NElements(); for(int64_t el=0; el < nel; el++){ TPZCompEl * compEl = cMesh->ElementVec()[el]; if(!compEl) continue; int64_t ind = compEl->Index(); if(ind==indexEl){ compEl->Divide(indexEl, subindex, 1); } } }
int TPZAdaptMesh::HasTrueError(int clindex, REAL &minerror, TPZVec<REAL> &ervec){ TPZGeoCloneMesh *gmesh = dynamic_cast<TPZGeoCloneMesh *> (fCloneMeshes [clindex]->Reference()); int nref = gmesh->NReference(); int i; for (i=0;i<nref;i++){ TPZGeoEl *gel = gmesh->ReferenceElement(i); TPZCompEl *cel = gel->Reference(); if (!cel) continue; int celindex = cel->Index(); if (ervec[celindex] >= minerror) return 1; } return 0; }
void RefinUniformElemComp(TPZCompMesh *cMesh, int ndiv) { TPZVec<int64_t > subindex; for (int64_t iref = 0; iref < ndiv; iref++) { TPZAdmChunkVector<TPZCompEl *> elvec = cMesh->ElementVec(); int64_t nel = elvec.NElements(); for(int64_t el=0; el < nel; el++){ TPZCompEl * compEl = elvec[el]; if(!compEl) continue; int64_t ind = compEl->Index(); compEl->Divide(ind, subindex, 0); } } }
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; } }
//void DivideRecursive(TPZCompEl *locel,int index,TPZVec<int> indexsubs,int hn); void TPZAnalysisError::HPAdapt(REAL CurrentEtaAdmissible, std::ostream &out) { arq << "CurrentEtaAdmissible " << CurrentEtaAdmissible << endl; TPZAdmChunkVector<TPZCompEl *>&listel = Mesh()->ElementVec(); bool store_error = false; EvaluateError(CurrentEtaAdmissible,store_error, out); TPZVec<TPZCompElSide> SingLocal(fSingular); fSingular.Resize(0); int64_t nel = fElIndexes.NElements(); for(int64_t ielloc=0;ielloc<nel;ielloc++) { int64_t iel = fElIndexes[ielloc]; // if the element has already been treated (e.g. singularity) skip the process if(iel == -1) continue; TPZInterpolatedElement *elem = (TPZInterpolatedElement *) listel[iel]; if(!elem || elem->Material()->Id() < 0) { PZError << "TPZAnalysisError::HPAdapt boundary element with error?\n"; PZError.flush(); continue; } REAL csi = fElErrors[ielloc] / fAdmissibleError; // Verificar se o element atual e um elemento singular int64_t ising, nsing = SingLocal.NElements(); for(ising=0; ising<nsing; ising++) { if(elem == SingLocal[ising].Element()) { ZoomInSingularity(csi,SingLocal[ising]); break; } } // Go to the end of the loop if the element was handled by the singularity if(ising < nsing) continue; //calculo da ordem pn do elemento atual int nsides = elem->Reference()->NSides(); REAL pFo = double(elem->EffectiveSideOrder(nsides-1));//quadrilatero // Newton's Method -> compute pNew REAL pFn = pFo, res = 10.0, phi, del, dph, tol = 0.001; int64_t MaxIter = 100; int64_t iter=0; while (iter < MaxIter && res > tol) { phi = pFo+log(csi)-pFo*log(pFn/pFo); dph = pFn/(pFo+pFn); del = dph*(phi-pFn); if (del+pFn <= 0.0) // caiu fora do intervalo! del = 0.5 - pFn; res = fabs(del); pFn = del+pFn; iter++; } // end of Newton's Method if (iter == MaxIter) PZError << "\n - Newton's Method Failed at Element = " << elem->Reference()->Id() << endl; if(pFn < 1.) pFn = 1.; REAL factor = pow(csi,-1.0/pFn)*(pow(pFn/pFo,pFo/pFn)); if(factor <= 0.75) factor = 0.5; // refine h else factor = 1.0; // don't refine h // Newton's Method -> compute once again pNew pFn = pFo; iter = 0; res = 10.0; while (iter < MaxIter && res > tol) { phi = -pFn*log(factor)-log(csi)+pFo*log(pFn/pFo); dph = pFn/(pFo-pFn*log(factor)); del = -dph*phi; if (del+pFn <= 0.0) // caiu fora do intervalo! del = 0.5 - pFn; res = fabs(del); pFn = del+pFn; iter++; } // end of Newton's Method if (iter == MaxIter) PZError << "\n - Newton's Method Failed at Element = " << elem->Reference()->Id() << endl; if(pFn < 1.) pFn = 1.; int pNew = 0;//(int) floor(pFn + 0.5); // get the integer while(REAL(pNew) < (pFn+0.5)) pNew++; TPZVec<REAL> x(3),cs(2,0.); elem->Reference()->X(cs,x); elem->PRefine(pNew); TPZCompEl *locel = elem; //Divide elements if(factor == 0.5 ) { TPZVec<int64_t> indexsubs; int64_t index = locel->Index(); elem->Divide(index,indexsubs,1); } } }