void TPZAnalysis::DefineElementTable(int dimension, TPZVec<int> &GeoElIds, TPZVec<REAL> &points) { fTable.fDimension = dimension; fTable.fGeoElId = GeoElIds; fTable.fLocations = points; int numel = GeoElIds.NElements(); fTable.fCompElPtr.Resize(numel); int iel; for(iel=0; iel<numel; iel++) { TPZGeoEl *gel = (TPZGeoEl *) fGeoMesh->FindElement(GeoElIds[iel]); fTable.fCompElPtr[iel] = (gel) ? gel->Reference() : 0; } }
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 TPZAnalysisError::MathematicaPlot() { TPZGeoMesh *gmesh = fCompMesh->Reference(); TPZAdmChunkVector<TPZGeoNode> &listnodes = gmesh->NodeVec(); int64_t nnodes = gmesh->NNodes(); TPZAdmChunkVector<TPZGeoNode> nodes(listnodes); TPZVec<int64_t> nodeindex(0); int64_t keepindex; int64_t in; TPZGeoNode *nodei = 0; /// jorge 2017 - I think it's unnecessary, because if node is created its exists always for(in=0;in<nnodes;in++) { nodei = &nodes[in]; REAL xi; if(nodei) xi = nodei->Coord(0); else continue; keepindex = in; for(int64_t jn=in;jn<nnodes;jn++) { TPZGeoNode *nodej = &nodes[jn]; REAL xj; if(nodej) xj = nodej->Coord(0); else continue; if(xj < xi) { keepindex = jn; xi = xj; } } if(keepindex!=in) { TPZGeoNode commut = nodes[in]; nodes[in] = nodes[keepindex]; nodes[keepindex] = commut; } } ofstream mesh("Malha.dat"); ofstream graph("Graphic.nb"); mesh << "\nDistribuicao de nos\n\n"; int64_t i; for(i=0;i<nnodes;i++) { nodei = &nodes[i]; if(nodei) mesh << nodei->Coord(0) << endl; } //2a parte TPZVec<int64_t> locnodid(nnodes,0); TPZVec<TPZGeoEl *> gelptr(nnodes); int64_t nel = gmesh->NElements(); int64_t count = 0; for(in=0;in<nnodes;in++) { nodei = &nodes[in]; if(!nodei) continue; for(int64_t iel=0;iel<nel;iel++) { TPZGeoEl *gel = gmesh->ElementVec()[iel]; if(!gel || !gel->Reference() || gel->MaterialId() < 0) continue; //int numnodes = gel->NNodes(); int ic=0;//for(int ic=0;ic<numnodes;ic++) if(in==nnodes-1) ic = 1; if(nodei->Id() == gel->NodePtr(ic)->Id()) { gelptr[count] = gel; locnodid[count++] = ic; break; } } } TPZVec<int64_t> connects(nnodes); int64_t iel; for(iel=0;iel<nnodes;iel++) { //if(!gelptr[iel] || !(gelptr[iel]->Reference())) continue; connects[iel] = gelptr[iel]->Reference()->ConnectIndex(locnodid[iel]); } TPZVec<STATE> sol(nnodes); for(i=0; i<nnodes; i++) { TPZConnect *df = &fCompMesh->ConnectVec()[connects[i]]; if(!df) { cout << "\nError in structure of dates\n"; mesh << "\nError in structure of dates\n"; return;//exit(-1); } int64_t seqnum = df->SequenceNumber(); int64_t pos = fCompMesh->Block().Position(seqnum); sol[i] = fCompMesh->Solution()(pos,0); } mesh << "\nSolucao nodal\n\n"; for(i=0;i<nnodes;i++) { mesh << sol[i] << endl; } // expanding solution int64_t numsols = 5*(nnodes-1)+1; // 5 values by element: 3 interpolated (interior) + 2 over corners TPZVec<STATE> expand_sol(numsols); TPZVec<REAL> expand_nodes(numsols); TPZVec<REAL> qsi(1); int64_t exp_iel = -1; for(iel=0;iel<nnodes-1;iel++) { TPZManVector<STATE> locsol(1); exp_iel++; expand_sol[exp_iel] = sol[iel]; qsi[0] = -1.; expand_nodes[exp_iel] = nodes[iel].Coord(0); REAL h = h_Parameter(gelptr[iel]->Reference()); for(int i=1;i<5;i++) { exp_iel++; expand_nodes[exp_iel] = i*h/5. + nodes[iel].Coord(0); qsi[0] += .4; gelptr[iel]->Reference()->Solution(qsi,0,locsol); expand_sol[exp_iel] = locsol[0]; } } expand_nodes[numsols-1] = nodes[nnodes-1].Coord(0); expand_sol[numsols-1] = sol[nnodes-1]; // Mathematica output format graph << "list = {" << endl; for(int64_t isol=0;isol<numsols;isol++) { if(isol > 0) graph << ","; STATE expandsol = expand_sol[isol]; if(fabs(expandsol) < 1.e-10) expandsol = 0.; graph << "{" << expand_nodes[isol] << "," << expandsol << "}"; if( !((isol+1)%5) ) graph << endl; } graph << "\n};\n"; graph << "ListPlot[list, PlotJoined->True, PlotRange->All];" << endl; }
TPZCompMesh *TPZAdaptMesh::CreateCompMesh (TPZCompMesh *mesh, //malha a refinar TPZVec<TPZGeoEl *> &gelstack, // TPZVec<int> &porders) { //Cria um ponteiro para a malha geom�trica de mesh TPZGeoMesh *gmesh = mesh->Reference(); if(!gmesh) { cout << "TPZAdaptMesh::CreateCompMesh encountered no geometric mesh\n"; return 0; } //Reseta as refer�ncias do ponteiro para a malha geom�trica criada //e cria uma nova malha computacional baseada nesta malha geom�trica gmesh->ResetReference(); TPZCompMesh *cmesh = new TPZCompMesh(gmesh); // int nmat = mesh->MaterialVec().size(); // int m; //Cria um clone do vetor de materiais da malha mesh mesh->CopyMaterials(*cmesh); /* for(m=0; m<nmat; m++) { TPZMaterial * mat = mesh->MaterialVec()[m]; if(!mat) continue; mat->Clone(cmesh->MaterialVec()); } */ //Idenifica o vetor de elementos computacionais de mesh // TPZAdmChunkVector<TPZCompEl *> &elementvec = mesh->ElementVec(); int el,nelem = gelstack.NElements(); // cmesh->SetName("Antes PRefine"); // cmesh->Print(cout); for(el=0; el<nelem; el++) { //identifica os elementos geom�tricos passados em gelstack TPZGeoEl *gel = gelstack[el]; if(!gel) { cout << "TPZAdaptMesh::CreateCompMesh encountered an null element\n"; continue; } long celindex; //Cria um TPZIntel baseado no gel identificado TPZInterpolatedElement *csint; csint = dynamic_cast<TPZInterpolatedElement *> (cmesh->CreateCompEl(gel,celindex)); if(!csint) continue; //Refina em p o elemento criado // cmesh->SetName("depois criar elemento"); // cmesh->Print(cout); csint->PRefine(porders[el]); // cmesh->SetName("depois prefine no elemento"); // cmesh->Print(cout); } #ifndef CLONEBCTOO nelem = gmesh->NElements(); for (el=0; el<nelem; el++) { TPZGeoEl *gel = gmesh->ElementVec()[el]; if (!gel || gel->Reference()) { continue; } int matid = gel->MaterialId(); if (matid < 0) { TPZStack<TPZCompElSide> celstack; int ns = gel->NSides(); TPZGeoElSide gelside(gel,ns-1); gelside.HigherLevelCompElementList2(celstack, 1, 1); if (celstack.size()) { TPZStack<TPZGeoEl *> subels; gel->Divide(subels); } } } nelem = gmesh->NElements(); for (el=0; el<nelem; el++) { TPZGeoEl *gel = gmesh->ElementVec()[el]; if (!gel || gel->Reference()) { continue; } int matid = gel->MaterialId(); if (matid < 0) { TPZStack<TPZCompElSide> celstack; int ns = gel->NSides(); TPZGeoElSide gelside(gel,ns-1); gelside.EqualLevelCompElementList(celstack, 1, 0); if (celstack.size()) { long index; cmesh->CreateCompEl(gel, index); } } } #endif //Mais einh!! // cmesh->SetName("Antes Adjust"); // cmesh->Print(cout); cmesh->AdjustBoundaryElements(); // cmesh->SetName("Depois"); // cmesh->Print(cout); return cmesh; }
void TPZAdaptMesh::BuildReferencePatch() { // the fGeoRef elements are a partition of the computational domain (should be) // create a computational element based on each reference element TPZGeoMesh *gmesh = fReferenceCompMesh->Reference(); gmesh->ResetReference(); TPZCompMesh *tmpcmesh = new TPZCompMesh (gmesh); int i,j; for (i=0;i<fGeoRef.NElements();i++){ long index; tmpcmesh->CreateCompEl(fGeoRef[i],index); } tmpcmesh->CleanUpUnconnectedNodes(); tmpcmesh->ExpandSolution(); TPZStack <long> patchelindex; TPZStack <TPZGeoEl *> toclonegel; TPZStack<long> elgraph; TPZVec<long> n2elgraph; TPZVec<long> n2elgraphid; TPZVec<long> elgraphindex; tmpcmesh->GetNodeToElGraph(n2elgraph,n2elgraphid,elgraph,elgraphindex); // we use the node to elgraph structure to decide which elements will be included int clnel = tmpcmesh->NElements(); // clnel corresponds to the number of patches // fPatch and fPatchIndex form a compacted list which form the patches. // Boundary elements will be added to each patch. fPatchIndex.Push(0); for (int ipatch=0; ipatch<clnel; ipatch++){ tmpcmesh->GetElementPatch(n2elgraph,n2elgraphid,elgraph,elgraphindex,ipatch,patchelindex); for (j=0; j<patchelindex.NElements(); j++){ TPZGeoEl *gel = tmpcmesh->ElementVec()[patchelindex[j]]->Reference(); // int count = 0; if(gel) fPatch.Push(gel); } int sum = fPatch.NElements(); fPatchIndex.Push(sum); } #ifdef DEBUG2 // CAJU TOOL { std::string filename("cMeshVtk."); { std::stringstream finalname; finalname << filename << 0 << ".vtk"; ofstream file(finalname.str().c_str()); /** @brief Generate an output of all geometric elements that have a computational counterpart to VTK */ //static void PrintCMeshVTK(TPZGeoMesh *gmesh, std::ofstream &file, bool matColor = false); TPZVTKGeoMesh::PrintCMeshVTK(gmesh,file,true); } for (int ip=0; ip<clnel; ip++) { int firstindex = fPatchIndex[ip]; int lastindex = fPatchIndex[ip+1]; gmesh->ResetReference(); tmpcmesh->LoadReferences(); std::set<TPZGeoEl *> loaded; for (int ind=firstindex; ind<lastindex; ind++) { TPZGeoEl *gel = fPatch[ind]; loaded.insert(gel); } int ngel = gmesh->NElements(); for (int el=0; el<ngel; el++) { TPZGeoEl *gel = gmesh->ElementVec()[el]; if (!gel) { continue; } if (gel->Reference() && loaded.find(gel) == loaded.end()) { gel->ResetReference(); } } std::stringstream finalname; finalname << filename << ip+1 << ".vtk"; ofstream file(finalname.str().c_str()); /** @brief Generate an output of all geometric elements that have a computational counterpart to VTK */ //static void PrintCMeshVTK(TPZGeoMesh *gmesh, std::ofstream &file, bool matColor = false); TPZVTKGeoMesh::PrintCMeshVTK(gmesh,file,true); } } #endif // cleaning reference to computational elements into temporary cmesh gmesh->ResetReference(); delete tmpcmesh; // loading references between geometric and computational meshes (originals) fReferenceCompMesh->LoadReferences(); }