/// Constructor SinglePvtDeadSpline::SinglePvtDeadSpline(const table_t& pvd_table, const int samples) { const int region_number = 0; if (pvd_table.size() != 1) { THROW("More than one PVT-region"); } // Copy data const int sz = pvd_table[region_number][0].size(); std::vector<double> press(sz); std::vector<double> B_inv(sz); std::vector<double> visc(sz); for (int i = 0; i < sz; ++i) { press[i] = pvd_table[region_number][0][i]; B_inv[i] = 1.0 / pvd_table[region_number][1][i]; visc[i] = pvd_table[region_number][2][i]; } buildUniformMonotoneTable(press, B_inv, samples, one_over_B_); buildUniformMonotoneTable(press, visc, samples, viscosity_); // Dumping the created tables. // static int count = 0; // std::ofstream os((std::string("dump-") + boost::lexical_cast<std::string>(count++)).c_str()); // os.precision(15); // os << "1/B\n\n" << one_over_B_ // << "\n\nvisc\n\n" << viscosity_ << std::endl; }
void ApplicationOP2A::TimeIntegrateImplicitPoint() { int VAR = grid.cells[1].data1D(0).numData; int index_J_inv_plus = 0; int index_J_inv_minus = 1; // [PRE] Initialize Matrix Math::MATRIX matrix_temp1(VAR, VAR, false); matrix_temp1.zeros(); Math::MATRIX matrix_temp2(VAR, 1, false); matrix_temp2.zeros(); vector<Math::MATRIX> M_cl(grid.NCM+1, matrix_temp1); vector<Math::MATRIX> B(grid.NCM+1, matrix_temp1); vector<Math::MATRIX> B_inv(grid.NCM+1, matrix_temp1); vector<Math::MATRIX> R(grid.NCM+1, matrix_temp2); vector<Math::MATRIX> X(grid.NCM+1, matrix_temp2); // STEP 1: Set-up matrix M_CL and R_CL if (problem_setup.is_axisymmetric == true) { #pragma omp parallel for for (int c = 1; c <= grid.NCM; c++) { double Vol = grid.cells[c].geo.S * Math::fabs<double>(grid.cells[c].geo.x[1]); double Vol_dt = Vol / dt; #pragma ivdep for (int r = 0; r <= VAR-1; r++) { #pragma ivdep for (int l = 0; l <= VAR-1; l++) { M_cl[c](r, l) = -grid.cells[c].data2D(1)(r,l); } } #pragma ivdep for (int r = 0; r <= VAR-1; r++) { M_cl[c](r, r) += Vol_dt; } #pragma ivdep for (int r = 0; r <= VAR-1; r++) { R[c](r,0) = -grid.cells[c].data1D(indexResidue)(r); } } } else { #pragma omp parallel for for (int c = 1; c <= grid.NCM; c++) { double Vol = grid.cells[c].geo.S; double Vol_dt = Vol / dt; #pragma ivdep for (int r = 0; r <= VAR-1; r++) { #pragma ivdep for (int l = 0; l <= VAR-1; l++) { M_cl[c](r, l) = -grid.cells[c].data2D(1)(r,l); } } #pragma ivdep for (int r = 0; r <= VAR-1; r++) { M_cl[c](r, r) += Vol_dt; } #pragma ivdep for (int r = 0; r <= VAR-1; r++) { R[c](r,0) = -grid.cells[c].data1D(indexResidue)(r); } } } // SETP 2: ADD Viscous/inviscid Jacobian #pragma omp parallel for for (int c = 1; c <= grid.NCM; c++) { for (int f = 0; f <= grid.cells[c].geo.NF-1; f++) { if (grid.cells[c].geo.face_list[f]->geo.cl[0]->geo.ID == grid.cells[c].geo.ID) { for (int j = 0; j <= VAR-1; j++) { for (int k = 0; k <= VAR-1; k++) { M_cl[c](j, k) += grid.cells[c].geo.face_list[f]->data2D(index_J_inv_plus)(j,k); } } } if (grid.cells[c].geo.face_list[f]->geo.cr[0]->geo.ID == grid.cells[c].geo.ID) { for (int j = 0; j <= VAR-1; j++) { for (int k = 0; k <= VAR-1; k++) { M_cl[c](j, k) += -grid.cells[c].geo.face_list[f]->data2D(index_J_inv_minus)(j,k); } } } } } // @todo: Need to add Viscous // STEP 6 SOLVE BLOCK TRI-DIAGONAL MATRIX // 6.1. Initialize B = M_cl; #pragma omp parallel for for (int i = 1; i <= grid.NCM; i++) { B_inv[i] = MATRIX_Inv(B[i]); } // 6.2 Solve // 1. Initial solution #pragma omp parallel for num_threads(CFD_NT) for (int i = 1; i <= grid.NCM; i++) { X[i] = B_inv[i] * R[i]; #pragma ivdep for (int r = 0; r <= VAR-1; r++) { if(X[i](r,0) != X[i](r,0)) { std::ostringstream oss; oss << "It has NaN value: [Cell ID]: " << i << " [VAR]: " << r; throw Common::ExceptionNaNValue (FromHere(), oss.str()); } } } #pragma omp parallel for num_threads(CFD_NT) for (int c = 1; c <= grid.NCM; c++) { #pragma ivdep for (int j = 0; j <= VAR-1; j++) { grid.cells[c].data1D(indexdQ)(j) = X[c](j, 0); } } for (int p = 1; p <= 3; p++) { #pragma omp parallel for num_threads(CFD_NT) for (int c = 1; c <= grid.NCM; c++) { #pragma ivdep for (int r = 0; r <= VAR-1; r++) { R[c](r,0) = -grid.cells[c].data1D(indexResidue)(r); } } // STep 2 Communication (FOR MPI) // @todo: Need to update for MPI // Step 3. Update R(n, p) #pragma omp parallel for num_threads(CFD_NT) for (int c = 1; c <= grid.NCM; c++) { for (int k = 0; k <= grid.cells[c].geo.NF-1; k++) { if (grid.cells[c].geo.face_list[k]->geo.cl[0]->geo.ID == grid.cells[c].geo.ID) { if (grid.cells[c].geo.face_list[k]->geo.cr[0]->geo.ID > 0) { #pragma ivdep for (int j = 0; j <= VAR-1; j++) { double aux = 0.0; for (int l = 0; l <= VAR-1; l++) { aux += grid.cells[c].geo.face_list[k]->data2D(index_J_inv_minus)(j,l) * grid.cells[c].geo.face_list[k]->geo.cr[0]->data1D(indexdQ)(l); } R[c](j, 0) -= aux; } } } if (grid.cells[c].geo.face_list[k]->geo.cr[0]->geo.ID == grid.cells[c].geo.ID) { if (grid.cells[c].geo.face_list[k]->geo.cl[0]->geo.ID > 0) { #pragma ivdep for (int j = 0; j <= VAR-1; j++) { double aux = 0.0; for (int l = 0; l <= VAR-1; l++) { aux += grid.cells[c].geo.face_list[k]->data2D(index_J_inv_plus)(j,l) * grid.cells[c].geo.face_list[k]->geo.cl[0]->data1D(indexdQ)(l); } R[c](j, 0) += aux; } } } } } #pragma omp parallel for num_threads(CFD_NT) for (int i = 1; i <= grid.NCM; i++) { X[i] = B_inv[i] * R[i]; } #pragma omp parallel for num_threads(CFD_NT) for (int i = 1; i <= grid.NCM; i++) { #pragma ivdep for (int r = 0; r <= VAR-1; r++) { if(X[i](r,0) != X[i](r,0)) { std::ostringstream oss; oss << "It has NaN value: [Cell ID]: " << i << " [VAR]: " << r; throw Common::ExceptionNaNValue (FromHere(), oss.str()); } grid.cells[i].data1D(indexdQ)(r) = X[i](r,0); } } } }