示例#1
0
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);
  
}
示例#2
0
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]);

	}

}
示例#3
0
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;
}