void TPZStepSolver<TVar>::Solve(const TPZFMatrix<TVar> &F, TPZFMatrix<TVar> &result, TPZFMatrix<TVar> *residual){ if(!this->Matrix()) { cout << "TPZMatrixSolver::Solve called without a matrix pointer\n"; DebugStop(); } TPZAutoPointer<TPZMatrix<TVar> > mat = this->Matrix(); // update the matrix to which the preconditioner refers if(fPrecond) { fPrecond->UpdateFrom(this->Matrix()); } if(result.Rows() != mat->Rows() || result.Cols() != F.Cols()) { result.Redim(mat->Rows(),F.Cols()); } if(this->fScratch.Rows() != result.Rows() || this->fScratch.Cols() != result.Cols()) { this->fScratch.Redim(result.Rows(),result.Cols()); } TVar tol = fTol; int numiterations = fNumIterations; switch(fSolver) { case TPZStepSolver::ENoSolver: default: cout << "TPZMatrixSolver::Solve called without initialized solver, Jacobi used\n"; SetJacobi(1,0.,0); case TPZStepSolver::EJacobi: // cout << "fScratch dimension " << fScratch.Rows() << ' ' << fScratch.Cols() << endl; mat->SolveJacobi(numiterations,F,result,residual,this->fScratch,tol,fFromCurrent); break; case TPZStepSolver::ESOR: mat->SolveSOR(numiterations,F,result,residual,this->fScratch,fOverRelax,tol,fFromCurrent); break; case TPZStepSolver::ESSOR: mat->SolveSSOR(numiterations,F,result,residual,this->fScratch,fOverRelax,tol,fFromCurrent); break; case TPZStepSolver::ECG: mat->SolveCG(numiterations,*fPrecond,F,result,residual,tol,fFromCurrent); #ifdef LOG4CXX { std::stringstream sout; sout << "Number of equations " << mat->Rows() << std::endl; sout << "Number of CG iterations " << numiterations << " tol = " << tol; LOGPZ_DEBUG(logger,sout.str().c_str()); } #endif break; case TPZStepSolver::EGMRES: { TPZFMatrix<TVar> H(fNumVectors+1,fNumVectors+1,0.); mat->SolveGMRES(numiterations,*fPrecond,H,fNumVectors,F,result,residual,tol,fFromCurrent); if(numiterations == fNumIterations || tol >= fTol) { std::cout << "GMRes tolerance was not achieved : numiter " << numiterations << " tol " << tol << endl; } #ifdef LOG4CXX { std::stringstream sout; sout << "Number of GMRES iterations " << numiterations << " tol = " << tol; LOGPZ_DEBUG(logger,sout.str().c_str()); } #endif } break; case TPZStepSolver::EBICGSTAB: mat->SolveBICGStab(numiterations, *fPrecond, F, result,residual,tol,fFromCurrent); if(numiterations == fNumIterations || tol >= fTol) { std::cout << "BiCGStab tolerance was not achieved : numiter " << numiterations << " tol " << tol << endl; } #ifdef LOG4CXX { std::stringstream sout; sout << "Number of BiCGStab iterations " << numiterations << " tol = " << tol; LOGPZ_DEBUG(logger,sout.str().c_str()); } #endif break; case TPZStepSolver::EDirect: result = F; mat->SolveDirect(result,fDecompose,fSingular); if(residual) residual->Redim(F.Rows(),F.Cols()); break; case TPZStepSolver::EMultiply: mat->Multiply(F,result); if(residual) mat->Residual(result,F,*residual); } }
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; }