Esempio n. 1
0
void CSysMatrix::MatrixVectorProduct(const CSysVector & vec, CSysVector & prod, CGeometry *geometry, CConfig *config) {
  
  unsigned long prod_begin, vec_begin, mat_begin, index, iVar, jVar, row_i;
  
  /*--- Some checks for consistency between CSysMatrix and the CSysVectors ---*/
  if ( (nVar != vec.GetNVar()) || (nVar != prod.GetNVar()) ) {
    cerr << "CSysMatrix::MatrixVectorProduct(const CSysVector&, CSysVector): "
    << "nVar values incompatible." << endl;
    throw(-1);
  }
  if ( (nPoint != vec.GetNBlk()) || (nPoint != prod.GetNBlk()) ) {
    cerr << "CSysMatrix::MatrixVectorProduct(const CSysVector&, CSysVector): "
    << "nPoint and nBlk values incompatible." << endl;
    throw(-1);
  }
  
  prod = 0.0; // set all entries of prod to zero
  for (row_i = 0; row_i < nPointDomain; row_i++) {
    prod_begin = row_i*nVar; // offset to beginning of block row_i
    for (index = row_ptr[row_i]; index < row_ptr[row_i+1]; index++) {
      vec_begin = col_ind[index]*nVar; // offset to beginning of block col_ind[index]
      mat_begin = (index*nVar*nVar); // offset to beginning of matrix block[row_i][col_ind[indx]]
      for (iVar = 0; iVar < nVar; iVar++) {
        for (jVar = 0; jVar < nVar; jVar++) {
          prod[(const unsigned int)(prod_begin+iVar)] += matrix[(const unsigned int)(mat_begin+iVar*nVar+jVar)]*vec[(const unsigned int)(vec_begin+jVar)];
        }
      }
    }
  }
  
  /*--- MPI Parallelization ---*/
  SendReceive_Solution(prod, geometry, config);
  
}
Esempio n. 2
0
void CSysSolve::SetExternalSolve(CSysMatrix & Jacobian, CSysVector & LinSysRes, CSysVector & LinSysSol, CGeometry *geometry, CConfig *config){

#ifdef CODI_REVERSE_TYPE
  
  unsigned long size = LinSysRes.GetLocSize();
  unsigned long i, nBlk = LinSysRes.GetNBlk(),
                nVar = LinSysRes.GetNVar(),
                nBlkDomain = LinSysRes.GetNBlkDomain();

  /*--- Arrays to store the indices of the input/output of the linear solver.
     * Note: They will be deleted in the CSysSolve_b::Delete_b routine. ---*/

  int *LinSysRes_Indices = new int[size];
  int *LinSysSol_Indices = new int[size];

  for (i = 0; i < size; i++){

    /*--- Register the solution of the linear system (could already be registered when using multigrid) ---*/

    if (LinSysSol[i].getGradientData() == 0){
      AD::globalTape.registerInput(LinSysSol[i]);
    }

    /*--- Store the indices ---*/

    LinSysRes_Indices[i] = LinSysRes[i].getGradientData();
    LinSysSol_Indices[i] = LinSysSol[i].getGradientData();
  }

  /*--- Push the data to the checkpoint handler for access in the reverse sweep ---*/

  AD::CheckpointHandler* dataHandler = new AD::CheckpointHandler;

  dataHandler->addData(LinSysRes_Indices);
  dataHandler->addData(LinSysSol_Indices);
  dataHandler->addData(size);
  dataHandler->addData(nBlk);
  dataHandler->addData(nVar);
  dataHandler->addData(nBlkDomain);
  dataHandler->addData(&Jacobian);
  dataHandler->addData(geometry);
  dataHandler->addData(config);

  /*--- Build preconditioner for the transposed Jacobian ---*/

  switch(config->GetKind_DiscAdj_Linear_Prec()){
    case ILU:
      Jacobian.BuildILUPreconditioner(true);
      break;
    case JACOBI:
      Jacobian.BuildJacobiPreconditioner(true);
      break;
    default:
      cout << "The specified preconditioner is not yet implemented for the discrete adjoint method." << endl;
      exit(EXIT_FAILURE);
  }

  /*--- Push the external function to the AD tape ---*/

  AD::globalTape.pushExternalFunction(&CSysSolve_b::Solve_b, dataHandler, &CSysSolve_b::Delete_b);

#endif
}