int SubStructure(TPZAutoPointer<TPZCompMesh> cmesh, REAL height) { int nelem = cmesh->NElements(); TPZManVector<int> subindex(nelem,-1); int iel; int nsub = 0; for (iel=0; iel<nelem; iel++) { TPZCompEl *cel = cmesh->ElementVec()[iel]; if (!cel) { continue; } TPZGeoEl *gel = cel->Reference(); if (!gel) { continue; } int nsides = gel->NSides(); TPZManVector<REAL> center(gel->Dimension(),0.), xco(3,0.); gel->CenterPoint(nsides-1,center); gel->X(center,xco); REAL z = xco[2]; int floor = (int) z/height; nsub = (floor+1) > nsub ? (floor+1) : nsub; subindex[iel] = floor; } #ifdef DEBUG { TPZGeoMesh *gmesh = cmesh->Reference(); int nelgeo = gmesh->NElements(); TPZVec<int> domaincolor(nelgeo,-999); int cel; int nel = cmesh->NElements(); for (cel=0; cel<nel; cel++) { TPZCompEl *compel = cmesh->ElementVec()[cel]; if(!compel) continue; TPZGeoEl *gel = compel->Reference(); if (!gel) { continue; } domaincolor[gel->Index()] = subindex[cel]; } ofstream vtkfile("partition.vtk"); TPZVTKGeoMesh::PrintGMeshVTK(gmesh, vtkfile, domaincolor); } #endif int isub; TPZManVector<TPZSubCompMesh *> submeshes(nsub,0); for (isub=0; isub<nsub; isub++) { int index; std::cout << '^'; std::cout.flush(); submeshes[isub] = new TPZSubCompMesh(cmesh,index); if (index < subindex.NElements()) { subindex[index] = -1; } } for (iel=0; iel<nelem; iel++) { int domindex = subindex[iel]; if (domindex >= 0) { TPZCompEl *cel = cmesh->ElementVec()[iel]; if (!cel) { continue; } submeshes[domindex]->TransferElement(cmesh.operator->(),iel); } } cmesh->ComputeNodElCon(); for (isub=0; isub<nsub; isub++) { submeshes[isub]->MakeAllInternal(); std::cout << '*'; std::cout.flush(); } cmesh->ComputeNodElCon(); cmesh->CleanUpUnconnectedNodes(); return nsub; }
int main1(int argc, char *argv[]) { #ifdef LOG4CXX InitializePZLOG(); #endif TPZTimer total; total.start(); std::cout << "COMECA O TEMPO"<< std::endl; int dimension = 3; int dim = 2; int maxlevel = 5; int sublevel = 3; int plevel = 1; TPZPairStructMatrix::gNumThreads = 20; int numthreads = 20; // tempo.fNumthreads = numthreads; // alimenta timeTemp com o numero de threads TPZGeoMesh *gmesh = 0; { TPZCompEl::SetgOrder(plevel); TPZAutoPointer<TPZCompMesh> cmesh; if(0) { TPZGenSubStruct sub(dim,maxlevel,sublevel); cmesh = sub.GenerateMesh(); cmesh->SetDimModel(dim); gmesh = cmesh->Reference(); } else { dim = 3; if (1) // Predio Viscoso { int dimension = 3; gmesh = MalhaPredio(); cmesh = new TPZCompMesh(gmesh); cmesh->SetDimModel(3); cmesh->SetDefaultOrder(plevel); cmesh->SetAllCreateFunctionsContinuousWithMem(dimension); InsertViscoElasticity(cmesh); cmesh->AutoBuild(); } else // Cubo Viscoso { int dimension = 3; gmesh = MalhaCubo(); cmesh = new TPZCompMesh(gmesh); cmesh->SetDimModel(3); cmesh->SetDefaultOrder(plevel); cmesh->SetAllCreateFunctionsContinuousWithMem(dimension); InsertViscoElasticityCubo(cmesh); cmesh->AutoBuild(); } } std::cout << "Numero de equacoes " << cmesh->NEquations() << std::endl; int numthread_assemble = 20; int numthread_decompose = 20; TPZAutoPointer<TPZCompMesh> cmeshauto(cmesh); TPZDohrStructMatrix dohrstruct(cmeshauto); dohrstruct.IdentifyExternalConnectIndexes(); std::cout << "Substructuring the mesh\n"; // TPZfTime timetosub; // init of timer //REAL height = Height(gmesh); //int nsubstruct = SubStructure(cmesh, height/2); dohrstruct.SubStructure(16); // tempo.ft0sub = timetosub.ReturnTimeDouble(); // end of timer // std::cout << tempo.ft0sub << std::endl; // sub.SubStructure(); //Teste Skyline /* TPZSkylineStructMatrix skyl(cmesh); TPZFMatrix<REAL> rhsfake(cmesh->NEquations(),1,0); int numsubmesh = cmesh->NElements(); TPZAutoPointer<TPZGuiInterface> fakegui = new TPZGuiInterface; int nel = cmesh->NElements(); for (int iel = 0 ; iel < nel ; iel++) { TPZSubCompMesh *subcompmesh = dynamic_cast<TPZSubCompMesh*>(cmesh->ElementVec()[iel]); if(subcompmesh) { subcompmesh->SetAnalysisSkyline(0,0,fakegui); } } TPZMatrix<REAL> *stiff2 = skyl.CreateAssemble(rhsfake, fakegui,numthread_assemble,numthread_decompose); */ #ifdef LOG4CXX { std::stringstream str; cmesh->Print(str); LOGPZ_DEBUG(logger,str.str()); } #endif dohrstruct.SetNumThreads(numthreads); TPZAutoPointer<TPZGuiInterface> gui; TPZFMatrix<STATE> rhs(cmesh->NEquations(),1,0.); TPZMatrix<STATE> *matptr = dohrstruct.Create(); dohrstruct.Assemble(*matptr,rhs,gui,numthread_assemble,numthread_decompose); TPZAutoPointer<TPZMatrix<STATE> > dohr = matptr; TPZAutoPointer<TPZMatrix<STATE> > precond = dohrstruct.Preconditioner(); { std::ofstream out("DohrCerta2.txt"); TPZFMatrix<REAL> Subtract(dohr->Rows(),dohr->Rows()), unitary(dohr->Rows(),dohr->Rows()); unitary.Identity(); TPZFMatrix<REAL> result; dohr->Multiply(unitary, result); result.Print("DohrCerta2", out); } /* #ifdef LOG4CXX { std::ofstream out("DohrErrada.txt"), outRhsCerto("RhsSkyl.txt"), outRhsErrado("RhsDohrmann.txt"); TPZFMatrix<REAL> Subtract(dohr->Rows(),dohr->Rows()), unitary(dohr->Rows(),dohr->Rows()); unitary.Identity(); TPZFMatrix<REAL> result; dohr->Multiply(unitary, result); std::ofstream out2("Dohr_Certa.txt"); result.Print("DohrCerta",out2); for (int i = 0 ; i < dohr->Rows(); i++) { for (int j = 0 ; j < dohr->Rows(); j++) { double temp = result(i,j) - stiff2->Get(i,j); if (temp < 1e-10) { temp = 0; } Subtract(i,j) = temp; } } std::stringstream str; result.Print("DohrmannErrada", out); stiff2->Print("Skyl",out); Subtract.Print("Subtract", out); rhsfake.Print("RhsSkyl", outRhsCerto); rhs.Print("RhsDohrmann", outRhsErrado); LOGPZ_DEBUG(logger,str.str()); } #endif */ int neq = dohr->Rows(); TPZFMatrix<STATE> diag(neq,1,0.), produto(neq,1); std::cout << "Numero de equacoes " << neq << std::endl; TPZStepSolver<STATE> pre(precond); pre.SetMultiply(); TPZStepSolver<STATE> cg(dohr); // void SetCG(const int numiterations,const TPZMatrixSolver &pre,const STATE tol,const int FromCurrent); cg.SetCG(500,pre,5.e-6,0); cg.Solve(rhs,diag); diag.Print("diag"); TPZDohrMatrix<STATE,TPZDohrSubstructCondense<STATE> > *dohrptr = dynamic_cast<TPZDohrMatrix<STATE,TPZDohrSubstructCondense<STATE> > *> (dohr.operator->()); if (!dohrptr) { DebugStop(); } dohrptr->AddInternalSolution(diag); TPZMaterial * mat = cmeshauto->FindMaterial(1); int nstate = mat->NStateVariables(); int nscal = 0, nvec = 0; if(nstate ==1) { nscal = 1; } else { nvec = 1; } TPZManVector<std::string> scalnames(nscal),vecnames(nvec); if(nscal == 1) { scalnames[0]="state"; } else { vecnames[0] = "state"; } //cmeshauto->Solution().Print(); std::string postprocessname("ugabuga.vtk"); TPZVTKGraphMesh vtkmesh(cmesh.operator->(),dim,mat,scalnames,vecnames); vtkmesh.SetFileName(postprocessname); vtkmesh.SetResolution(0); int numcases = 1; // Iteracoes de tempo int istep = 0, nsteps = 80; vtkmesh.DrawMesh(numcases); vtkmesh.DrawSolution(istep, 1.); typedef std::list<TPZAutoPointer<TPZDohrSubstructCondense<STATE> > > subtype; const subtype &sublist = dohrptr->SubStructures(); subtype::const_iterator it = sublist.begin(); int subcount=0; while (it != sublist.end()) { TPZFMatrix<STATE> subext,subu; dohrptr->fAssembly->Extract(subcount,diag,subext); (*it)->UGlobal(subext,subu); TPZCompMesh *submesh = SubMesh(cmeshauto, subcount); submesh->LoadSolution(subu); subu.Print(); std::map<int ,TPZMaterial * > materialmap(submesh->MaterialVec()); std::map<int ,TPZMaterial * >::iterator itmat; for (itmat = materialmap.begin(); itmat != materialmap.end() ; itmat++) { TPZMaterial * mat = itmat->second; TPZViscoelastic *vmat = dynamic_cast< TPZViscoelastic *> (mat); if(vmat) { vmat->SetUpdateMem(); } } subcount++; it++; } /* #ifdef LOG4CXX { std::stringstream sout; diag.Print("Resultado do processo iterativo",sout); LOGPZ_INFO(loggernathan,sout.str()) } #endif */ //ViscoElastico vtkmesh.DrawMesh(numcases); vtkmesh.DrawSolution(istep+1, 1.); std::cout << "To seguindo!!!" << std::endl; for (istep = 2 ; istep < nsteps ; istep++) { TPZAutoPointer<TPZGuiInterface> guifake; dohrstruct.Assemble(rhs, guifake); cg.Solve(rhs,diag); dohrptr->AddInternalSolution(diag); // Colocando a solucao na malha typedef std::list<TPZAutoPointer<TPZDohrSubstructCondense<STATE> > > subtype; const subtype &sublist = dohrptr->SubStructures(); subtype::const_iterator it = sublist.begin(); int subcount=0; while (it != sublist.end()) { TPZFMatrix<STATE> subext,subu; dohrptr->fAssembly->Extract(subcount,diag,subext); (*it)->UGlobal(subext,subu); TPZCompMesh *submesh = SubMesh(cmeshauto, subcount); submesh->LoadSolution(subu); subcount++; it++; } vtkmesh.DrawMesh(numcases); vtkmesh.DrawSolution(istep, 1.); } } total.stop(); std::cout << "TEMPO = " << total.seconds() << std::endl; delete gmesh; return EXIT_SUCCESS; }