Exemplo n.º 1
0
    /// 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);
			}
		}
	}
}