void CSysMatrix::ComputeLU_SGSPreconditioner(const CSysVector & vec, CSysVector & prod) {
  unsigned long iPoint, iVar;

  /*--- There are two approaches to the parallelization (AIAA-2000-0927):
   1. Use a special scheduling algorithm which enables data parallelism by regrouping edges. This method has the
      advantage of producing exactly the same result as the single processor case, but it suffers from severe overhead
      penalties for parallel loop initiation, heavy interprocessor communications and poor load balance.
   2. Split the computational domain into several nonoverlapping regions according to the number of processors, and apply
      the SGS method inside of each region with (or without) some special interprocessor boundary treatment. This approach
      may suffer from convergence degradation but takes advantage of minimal parallelization overhead and good load balance. ---*/

    /*--- First part of the symmetric iteration: (D+L).x* = b ---*/
    /*cout <<"--ComputLU_SGSPreconditioner--" << endl;
    cout << "n_dims: " << nVar << ", nPointDomain: " << nPointDomain << endl;
    cout << "--paused--" << endl; cin.get();*/
    for (iPoint = 0; iPoint < nPointDomain; iPoint++) {
        LowerProduct(prod, iPoint);                                        // Compute L.x*
        for (iVar = 0; iVar < nVar; iVar++)
            aux_vector[iVar] = vec[iPoint*nVar+iVar] - prod_row_vector[iVar]; // Compute aux_vector = b - L.x*
        Gauss_Elimination(iPoint, aux_vector);                            // Solve D.x* = aux_vector
        for (iVar = 0; iVar < nVar; iVar++)
            prod[iPoint*nVar+iVar] = aux_vector[iVar];                       // Assesing x* = solution
        /*if(iPoint%500==0) {
            cout << "** pause **" << endl;
            cin.get();
        }*/
    }

    /*--- Inner send-receive operation the solution vector ---*/
    //SendReceive_Solution(prod, geometry, config);

    /*--- Second part of the symmetric iteration: (D+U).x_(1) = D.x* ---*/
    for (iPoint = nPointDomain-1; (int)iPoint >= 0; iPoint--) {
        DiagonalProduct(prod, iPoint);                 // Compute D.x*
        for (iVar = 0; iVar < nVar; iVar++)
            aux_vector[iVar] = prod_row_vector[iVar];   // Compute aux_vector = D.x*
        UpperProduct(prod, iPoint);                    // Compute U.x_(n+1)
        for (iVar = 0; iVar < nVar; iVar++)
            aux_vector[iVar] -= prod_row_vector[iVar];  // Compute aux_vector = D.x*-U.x_(n+1)
        Gauss_Elimination(iPoint, aux_vector);        // Solve D.x* = aux_vector
        for (iVar = 0; iVar < nVar; iVar++)
            prod[iPoint*nVar + iVar] = aux_vector[iVar]; // Assesing x_(1) = solution
    }

  /*--- Final send-receive operation the solution vector (redundant in CFD simulations) ---*/
    //SendReceive_Solution(prod, geometry, config);

}
Exemplo n.º 2
0
void CSysMatrix::ComputeLU_SGSPreconditioner(const CSysVector & vec, CSysVector & prod, CGeometry *geometry, CConfig *config) {
  unsigned long iPoint, iVar;
  
  /*--- First part of the symmetric iteration: (D+L).x* = b ---*/
  
  for (iPoint = 0; iPoint < nPointDomain; iPoint++) {
    LowerProduct(prod, iPoint);                                        // Compute L.x*
    for (iVar = 0; iVar < nVar; iVar++)
      aux_vector[iVar] = vec[iPoint*nVar+iVar] - prod_row_vector[iVar]; // Compute aux_vector = b - L.x*
    Gauss_Elimination(iPoint, aux_vector);                            // Solve D.x* = aux_vector
    for (iVar = 0; iVar < nVar; iVar++)
      prod[iPoint*nVar+iVar] = aux_vector[iVar];                       // Assesing x* = solution
  }
  
  /*--- MPI Parallelization ---*/
  
  SendReceive_Solution(prod, geometry, config);

  /*--- Second part of the symmetric iteration: (D+U).x_(1) = D.x* ---*/
  
  for (iPoint = nPointDomain-1; (int)iPoint >= 0; iPoint--) {
    DiagonalProduct(prod, iPoint);                 // Compute D.x*
    for (iVar = 0; iVar < nVar; iVar++)
      aux_vector[iVar] = prod_row_vector[iVar];   // Compute aux_vector = D.x*
    UpperProduct(prod, iPoint);                    // Compute U.x_(n+1)
    for (iVar = 0; iVar < nVar; iVar++)
      aux_vector[iVar] -= prod_row_vector[iVar];  // Compute aux_vector = D.x*-U.x_(n+1)
    Gauss_Elimination(iPoint, aux_vector);        // Solve D.x* = aux_vector
    for (iVar = 0; iVar < nVar; iVar++)
      prod[iPoint*nVar + iVar] = aux_vector[iVar]; // Assesing x_(1) = solution
  }

  /*--- MPI Parallelization ---*/
  
  SendReceive_Solution(prod, geometry, config);
  
}
void CSysMatrix::InverseDiagonalBlock(unsigned long block_i, double **invBlock) {
	unsigned long iVar, jVar;
  
	for (iVar = 0; iVar < nVar; iVar++) {
		for (jVar = 0; jVar < nVar; jVar++)
			aux_vector[jVar] = 0.0;
		aux_vector[iVar] = 1.0;
    
		/*--- Compute the i-th column of the inverse matrix ---*/
		Gauss_Elimination(block_i, aux_vector);
		for (jVar = 0; jVar < nVar; jVar++)
			invBlock[jVar][iVar] = aux_vector[jVar];
	}
  
}