Beispiel #1
0
__forceinline__ __device__ float sourceTermWest(float (&U)[height][width],
        float (&B)[height][width],
        float (&RUx)[height][width],
        float (&RBx)[height][width],
        unsigned int p, unsigned int q) {
	float bx;
	float h;

	h = U[q][p]-RUx[q][p]-RBx[q][p];
	bx = RBx[q][p+1]-RBx[q][p];
	
	return sourceTerm(h, bx);
}
Beispiel #2
0
__forceinline__ __device__ float sourceTermSouth(float (&U)[height][width],
        float (&B)[height][width],
        float (&RUy)[height][width],
        float (&RBy)[height][width],
        unsigned int p, unsigned int q) {
	float bx;
	float h;

	h = U[q][p]-RUy[q][p]-RBy[q][p];
	bx = RBy[q+1][p]-RBy[q][p];

	return sourceTerm(h, bx);
}
Beispiel #3
0
Domain CN( Domain T )
{
	cout << endl << "Iterating domain using CN method..."<<endl;
	for( int it = 0; it < T.settings.nsteps; it++)
	{
		// Starting timer...
		clock_t start, end;
		double cpu_time_used;
		start = clock();
		
		T.updateBC( it );
		cout << endl;
		cout << "t = " << it << endl;
		show_sample( T );	
		
		double C = T.settings.dt * T.settings.alpha / 2;
		double diag = 1 + 2*C / pow(T.settings.dx, 2) + 2*C / pow(T.settings.dy,2) + 2*C/pow(T.settings.dz,2);
		double xdiag = - C / pow(T.settings.dx,2);
		double ydiag = - C / pow(T.settings.dy,2);
		double zdiag = - C / pow(T.settings.dz,2);
		int xs;
		int ys;
		int zs;
		int length = (T.settings.p_x) * (T.settings.p_y) * (T.settings.p_z);
		
		// Creation of A
		vector<vector<double> > A;
		A.resize(length);
		for( int i = 0; i < length; i++ )
		{
			A[i].resize(length);
			for( int j = 0; j < length; j++ )
			{
				// Main diagonal
				if( i == j )
					A[i][j] = diag;
				
				// Z diagonals
				else if( j == i - 9 )
				{
					if( i < T.settings.p_x * T.settings.p_y )	
						A[i][j] = 0;
					else
						A[i][j] = zdiag;
				}
				else if( j == i + 9 )
				{
					if( i > length - T.settings.p_z )
						A[i][j] = 0;
					else
						A[i][j] = zdiag;
				}
				
				// Y diagonals
				else if( j == i - 3 )
				{
					if( ( i / T.settings.p_x ) % T.settings.p_y == 0 )
						A[i][j] = 0;
					else
						A[i][j] = ydiag;
				}
				else if( j == i + 3 )
				{
					if( ( i / T.settings.p_x ) % T.settings.p_y == T.settings.p_y - 1 )
						A[i][j] = 0 ;
					else
						A[i][j] = ydiag;	
				}
				
				// X diagonals
				else if( j == i - 1 )
				{	
					if( i % T.settings.p_x == 0 )
						A[i][j] = 0;
					else
						A[i][j] = xdiag;
				}
				else if( j == i + 1 )
				{
					if( i % T.settings.p_x == T.settings.p_x - 1 )
						A[i][j] = 0;
					else
						A[i][j] = xdiag;
				}

				else
					A[i][j] = 0;
			}
		}
		

		// Initialization of x	
		vector<double> x;
		x.resize(length);
		
/*		
		// print upper left of A
		for( int i = 0; i < 20; i++ )
		{
			if( i % 10 == 0)
				cout << endl;	
			for( int j = 0; j < 20; j++ )
			{
				if( j % 10 == 0 )
					cout << "  ";
				cout << setw(9) <<  A[i][j] <<" ";		
			}
			cout << endl;
		}
*/
		// Initialization / Update of b
		vector<double> b;
		b.resize(length+1);

		for( int i = 0; i < length; i++ )
		{
			xs = i % T.settings.p_x + 1;
			ys = ( i / T.settings.p_x ) % T.settings.p_y + 1;
			zs = ( ( i / T.settings.p_x ) / T.settings.p_y ) % T.settings.p_z + 1;
			
			double term1 = C / pow(T.settings.dx,2) * (T.m[xs+1][ys][zs] - 2*T.m[xs][ys][zs] + T.m[xs-1][ys][zs]);
			double term2 = C / pow(T.settings.dy,2) * (T.m[xs][ys+1][zs] - 2*T.m[xs][ys][zs] + T.m[xs][ys-1][zs]);
			double term3 = C / pow(T.settings.dz,2) * (T.m[xs][ys][zs+1] - 2*T.m[xs][ys][zs] + T.m[xs][ys][zs-1]);
			b[i] = T.m[xs][ys][zs] + term1 + term2 + term3 + sourceTerm(xs, ys, zs);
		}

		// GAUSSIAN ELIMINATION
		
		// GE - upper-triangulate
		double scale;
		for (int j=0;j<length;++j)           /* loop over columns */
			for (int i=j+1;i<length;++i)      /* loop over rows beneath pivot */
			{
				if (A[i][j] != 0)
				{
					scale = A[i][j]/A[j][j];  /* zero out based on pivot */
					for (int k=0;k<length;++k)
						A[i][k] = A[i][k] - A[j][k]*scale;
					b[i] = b[i] - b[j]*scale; /* same for b */
				}
			}
		
		// GE - Back substitution
		x[length-1] = b[length-1]/A[length-1][length-1];
		for (int i=length-2;i>=0;--i)
		{
			x[i] = b[i];
			for (int j=i+1;j<length;++j)
			{
				x[i] -= A[i][j]*x[j];
			}
			x[i]/=A[i][i];
		}

		// SOLUTION CALCULATED - stored in x vector.
		
		// loads solution vector (x) back into the 3-D Domain
		for( int i = 0; i < length ; i++ )
		{
			xs = i % T.settings.p_x + 1;
			ys = ( i / T.settings.p_x ) % T.settings.p_y + 1;
			zs = ( ( i / T.settings.p_x ) / T.settings.p_y ) % T.settings.p_z + 1;
			T.m[xs][ys][zs] = x[i];
		}
		
		// Ending timer...
		end = clock();
		cpu_time_used = ( (double) (end - start ) ) / CLOCKS_PER_SEC;
		cout << "Iterating Domain of dimension "<<T.settings.p_x<<"x";
		cout << T.settings.p_y<<"x"<<T.settings.p_z<<" took ";
		cout << cpu_time_used<<" seconds."<<endl;

	}
	return T;
}