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); }
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); }