void CWaveSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config) { unsigned short iVar; unsigned long iPoint, total_index, IterLinSol; /*--- Set maximum residual to zero ---*/ for (iVar = 0; iVar < nVar; iVar++) { SetRes_RMS(iVar, 0.0); SetRes_Max(iVar, 0.0, 0); } /*--- Build implicit system ---*/ for (iPoint = 0; iPoint < geometry->GetnPointDomain(); iPoint++) { /*--- Right hand side of the system (-Residual) and initial guess (x = 0) ---*/ for (iVar = 0; iVar < nVar; iVar++) { total_index = iPoint*nVar+iVar; LinSysSol[total_index] = 0.0; AddRes_RMS(iVar, LinSysRes[total_index]*LinSysRes[total_index]); AddRes_Max(iVar, fabs(LinSysRes[total_index]), geometry->node[iPoint]->GetGlobalIndex(), geometry->node[iPoint]->GetCoord()); } } /*--- Initialize residual and solution at the ghost points ---*/ for (iPoint = geometry->GetnPointDomain(); iPoint < geometry->GetnPoint(); iPoint++) { for (iVar = 0; iVar < nVar; iVar++) { total_index = iPoint*nVar + iVar; LinSysRes[total_index] = 0.0; LinSysSol[total_index] = 0.0; } } /*--- Solve or smooth the linear system ---*/ CSysSolve system; IterLinSol = system.Solve(Jacobian, LinSysRes, LinSysSol, geometry, config); /*--- Update solution (system written in terms of increments) ---*/ for (iPoint = 0; iPoint < geometry->GetnPointDomain(); iPoint++) { for (iVar = 0; iVar < nVar; iVar++) { node[iPoint]->AddSolution(iVar, config->GetLinear_Solver_Relax()*LinSysSol[iPoint*nVar+iVar]); } } /*--- MPI solution ---*/ Set_MPI_Solution(geometry, config); /*--- Compute the root mean square residual ---*/ SetResidual_RMS(geometry, config); }
void CElectricSolver::Solve_LinearSystem(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh) { unsigned long iPoint; unsigned short iVar = 0; double norm = 1E6; int iter_max = 10000; /*--- Build lineal system ---*/ for (iPoint = 0; iPoint < geometry->GetnPointDomain(); iPoint++) { LinSysRes[iPoint] = LinSysRes.GetBlock(iPoint, iVar); LinSysSol[iPoint] = node[iPoint]->GetSolution(iVar); } /*--- Solve the system ---*/ CMatrixVectorProduct* mat_vec = new CSysMatrixVectorProduct(StiffMatrix, geometry, config); StiffMatrix.BuildJacobiPreconditioner(); CPreconditioner* precond = NULL; Jacobian.BuildJacobiPreconditioner(); precond = new CJacobiPreconditioner(Jacobian, geometry, config); CSysSolve system; system.ConjugateGradient(LinSysRes, LinSysSol, *mat_vec, *precond, 1E-12, iter_max, true); delete mat_vec; delete precond; SetRes_RMS(0, norm); /*--- Update solution ---*/ for (iPoint = 0; iPoint < geometry->GetnPointDomain(); iPoint++) { node[iPoint]->SetSolution(0,LinSysSol[iPoint]); } }
void CHeatSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config) { unsigned short iVar; unsigned long iPoint, total_index; bool output; /*--- Build implicit system ---*/ for (iPoint = 0; iPoint < geometry->GetnPoint(); iPoint++) { /*--- Right hand side of the system (-Residual) and initial guess (x = 0) ---*/ for (iVar = 0; iVar < nVar; iVar++) { total_index = iPoint*nVar+iVar; LinSysSol[total_index] = 0.0; } } /*--- Initialize residual and solution at the ghost points ---*/ for (iPoint = geometry->GetnPointDomain(); iPoint < geometry->GetnPoint(); iPoint++) { for (iVar = 0; iVar < nVar; iVar++) { total_index = iPoint*nVar + iVar; LinSysRes[total_index] = 0.0; LinSysSol[total_index] = 0.0; } } /*--- Solve the linear system (Krylov subspace methods) ---*/ CMatrixVectorProduct* mat_vec = new CSysMatrixVectorProduct(Jacobian, geometry, config); CPreconditioner* precond = NULL; if (config->GetKind_Linear_Solver_Prec() == JACOBI) { Jacobian.BuildJacobiPreconditioner(); precond = new CJacobiPreconditioner(Jacobian, geometry, config); } else if (config->GetKind_Linear_Solver_Prec() == LU_SGS) { precond = new CLU_SGSPreconditioner(Jacobian, geometry, config); } else if (config->GetKind_Linear_Solver_Prec() == LINELET) { Jacobian.BuildJacobiPreconditioner(); Jacobian.BuildLineletPreconditioner(geometry, config); precond = new CLineletPreconditioner(Jacobian, geometry, config); } CSysSolve system; if (config->GetUnsteady_Simulation() == STEADY) output = true; else output = false; if (config->GetKind_Linear_Solver() == BCGSTAB) system.BCGSTAB(LinSysRes, LinSysSol, *mat_vec, *precond, config->GetLinear_Solver_Error(), config->GetLinear_Solver_Iter(), output); else if (config->GetKind_Linear_Solver() == FGMRES) system.FGMRES(LinSysRes, LinSysSol, *mat_vec, *precond, config->GetLinear_Solver_Error(), config->GetLinear_Solver_Iter(), output); delete mat_vec; delete precond; /*--- Update solution (system written in terms of increments) ---*/ for (iPoint = 0; iPoint < geometry->GetnPoint(); iPoint++) { for (iVar = 0; iVar < nVar; iVar++) { if (config->GetUnsteady_Simulation() == STEADY) node[iPoint]->SetSolution(iVar, LinSysSol[iPoint*nVar+iVar]); else node[iPoint]->AddSolution(iVar, LinSysSol[iPoint*nVar+iVar]); } } /*--- MPI solution ---*/ Set_MPI_Solution(geometry, config); /*--- Compute the residual Ax-f ---*/ Jacobian.ComputeResidual(LinSysSol, LinSysRes, LinSysAux); /*--- Set maximum residual to zero ---*/ for (iVar = 0; iVar < nVar; iVar++) { SetRes_RMS(iVar, 0.0); SetRes_Max(iVar, 0.0, 0); } /*--- Compute the residual ---*/ for (iPoint = 0; iPoint < geometry->GetnPoint(); iPoint++) { for (iVar = 0; iVar < nVar; iVar++) { total_index = iPoint*nVar+iVar; AddRes_RMS(iVar, LinSysAux[total_index]*LinSysAux[total_index]); AddRes_Max(iVar, fabs(LinSysAux[total_index]), geometry->node[iPoint]->GetGlobalIndex()); } } /*--- Compute the root mean square residual ---*/ SetResidual_RMS(geometry, config); }
void CSysSolve_b::Solve_b(AD::CheckpointHandler* data){ /*--- Extract data from the checkpoint handler ---*/ su2double::GradientData *LinSysRes_Indices; su2double::GradientData *LinSysSol_Indices; data->getData(LinSysRes_Indices); data->getData(LinSysSol_Indices); unsigned long nBlk, nVar, nBlkDomain, size, i; data->getData(size); data->getData(nBlk); data->getData(nVar); data->getData(nBlkDomain); CSysMatrix* Jacobian; data->getData(Jacobian); CGeometry* geometry; data->getData(geometry); CConfig* config; data->getData(config); CSysVector LinSysRes_b(nBlk, nBlkDomain, nVar, 0.0); CSysVector LinSysSol_b(nBlk, nBlkDomain, nVar, 0.0); su2double Residual; unsigned long MaxIter = config->GetLinear_Solver_Iter(); su2double SolverTol = config->GetLinear_Solver_Error(); /*--- Initialize the right-hand side with the gradient of the solution of the primal linear system ---*/ for (i = 0; i < size; i ++){ su2double::GradientData& index = LinSysSol_Indices[i]; LinSysRes_b[i] = AD::globalTape.getGradient(index); LinSysSol_b[i] = 0.0; AD::globalTape.gradient(index) = 0.0; } /*--- Set up preconditioner and matrix-vector product ---*/ CPreconditioner* precond = NULL; switch(config->GetKind_DiscAdj_Linear_Prec()){ case ILU: precond = new CILUPreconditioner(*Jacobian, geometry, config); break; case JACOBI: precond = new CJacobiPreconditioner(*Jacobian, geometry, config); break; } CMatrixVectorProduct* mat_vec = new CSysMatrixVectorProductTransposed(*Jacobian, geometry, config); CSysSolve *solver = new CSysSolve; /*--- Solve the system ---*/ switch(config->GetKind_DiscAdj_Linear_Solver()){ case FGMRES: solver->FGMRES_LinSolver(LinSysRes_b, LinSysSol_b, *mat_vec, *precond, SolverTol , MaxIter, &Residual, false); break; case BCGSTAB: solver->BCGSTAB_LinSolver(LinSysRes_b, LinSysSol_b, *mat_vec, *precond, SolverTol , MaxIter, &Residual, false); break; } /*--- Update the gradients of the right-hand side of the primal linear system ---*/ for (i = 0; i < size; i ++){ su2double::GradientData& index = LinSysRes_Indices[i]; AD::globalTape.gradient(index) += SU2_TYPE::GetValue(LinSysSol_b[i]); } delete mat_vec; delete precond; delete solver; }
void CSysSolve_b::Solve_b(AD::Tape* tape, AD::CheckpointHandler* data) { /*--- Extract data from the checkpoint handler ---*/ su2double::GradientData *LinSysRes_Indices; su2double::GradientData *LinSysSol_Indices; #if CODI_PRIMAL_INDEX_TAPE su2double::Real *oldValues; #endif data->getData(LinSysRes_Indices); data->getData(LinSysSol_Indices); #if CODI_PRIMAL_INDEX_TAPE data->getData(oldValues); #endif unsigned long nBlk = 0, nVar = 0, nBlkDomain = 0, size = 0, i = 0; data->getData(size); data->getData(nBlk); data->getData(nVar); data->getData(nBlkDomain); CSysMatrix* Jacobian = NULL; data->getData(Jacobian); CGeometry* geometry = NULL; data->getData(geometry); CConfig* config = NULL; data->getData(config); CSysVector LinSysRes_b(nBlk, nBlkDomain, nVar, 0.0); CSysVector LinSysSol_b(nBlk, nBlkDomain, nVar, 0.0); su2double Residual; unsigned long MaxIter = config->GetLinear_Solver_Iter(); su2double SolverTol = config->GetLinear_Solver_Error(); /*--- Initialize the right-hand side with the gradient of the solution of the primal linear system ---*/ for (i = 0; i < size; i ++) { su2double::GradientData& index = LinSysSol_Indices[i]; LinSysRes_b[i] = AD::globalTape.getGradient(index); LinSysSol_b[i] = 0.0; AD::globalTape.gradient(index) = 0.0; } /*--- Set up preconditioner and matrix-vector product ---*/ CPreconditioner* precond = NULL; switch(config->GetKind_DiscAdj_Linear_Prec()) { case ILU: precond = new CILUPreconditioner(*Jacobian, geometry, config); break; case JACOBI: precond = new CJacobiPreconditioner(*Jacobian, geometry, config); break; } CMatrixVectorProduct* mat_vec = new CSysMatrixVectorProductTransposed(*Jacobian, geometry, config); CSysSolve *solver = new CSysSolve; /*--- Solve the system ---*/ switch(config->GetKind_DiscAdj_Linear_Solver()) { case FGMRES: solver->FGMRES_LinSolver(LinSysRes_b, LinSysSol_b, *mat_vec, *precond, SolverTol , MaxIter, &Residual, false); break; case BCGSTAB: solver->BCGSTAB_LinSolver(LinSysRes_b, LinSysSol_b, *mat_vec, *precond, SolverTol , MaxIter, &Residual, false); break; case CONJUGATE_GRADIENT: solver->CG_LinSolver(LinSysRes_b, LinSysSol_b, *mat_vec, *precond, SolverTol, MaxIter, &Residual, false); break; } /*--- Update the gradients of the right-hand side of the primal linear system ---*/ for (i = 0; i < size; i ++) { su2double::GradientData& index = LinSysRes_Indices[i]; AD::globalTape.gradient(index) += SU2_TYPE::GetValue(LinSysSol_b[i]); } #if CODI_PRIMAL_INDEX_TAPE /*--- Set the old values that have been overwritten ---*/ for (i = 0; i < size; i ++) { AD::globalTape.setExternalValueChange(LinSysSol_Indices[i], oldValues[i]); } #endif delete mat_vec; delete precond; delete solver; }