Click here to Skip to main content
15,892,805 members
Please Sign up or sign in to vote.
3.00/5 (2 votes)
See more:
hello everyone.
I am trying to assemble the finite element stiffness matrix in CSR format using MPI. I drived the node connectivity and three csr 1d arrays(row_ptr,col_ind and noz_zero value) for each chunk of elements in the function attached. But I'm not getting the right answer. Beside I get the error " process exited without calling finalize". I wonder whether I'm using mpi in a right way or not.

What I have tried:

void csr_assembly(int n,double *x,double *y,int **connectivity, double **coordinate,double *NN_vallocal)
{
	int num_procs, myrank;
	MPI_Status status;
	MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
	MPI_Comm_rank(MPI_COMM_WORLD, &myrank);


	int node_0, node_1, node_2;
	int counter[n_node];
	int node_connec[n_node][n_node] = { 0 };

	for (int i = 0; i < n_node; i++)
	{
		counter[i] = 0;
	}

	for (int i = 0; i < n; i++)
	{
		node_0 = connectivity[i][1];
		node_1 = connectivity[i][2];
		node_2 = connectivity[i][3];

		counter[node_0] = counter[node_0] + 1;
		node_connec[node_0][counter[node_0]] = node_0 + 1;
		counter[node_0] = counter[node_0] + 1;
		node_connec[node_0][counter[node_0]] = node_1 + 1;
		counter[node_0] = counter[node_0] + 1;
		node_connec[node_0][counter[node_0]] = node_2 + 1;

		counter[node_1] = counter[node_1] + 1;
		node_connec[node_1][counter[node_1]] = node_1 + 1;
		counter[node_1] = counter[node_1] + 1;
		node_connec[node_1][counter[node_1]] = node_2 + 1;
		counter[node_1] = counter[node_1] + 1;
		node_connec[node_1][counter[node_1]] = node_0 + 1;

		counter[node_2] = counter[node_2] + 1;
		node_connec[node_2][counter[node_2]] = node_2 + 1;
		counter[node_2] = counter[node_2] + 1;
		node_connec[node_2][counter[node_2]] = node_1 + 1;
		counter[node_2] = counter[node_2] + 1;
		node_connec[node_2][counter[node_2]] = node_0 + 1;
	}
	int r = sizeof(node_connec[0]) / sizeof(node_connec[0][0]);
	int cc = sizeof(node_connec) / sizeof((node_connec[0]));

	sortRowWise(node_connec, r, cc);
	/**********************number of non_zero element in each row*****************/
	int nnz[n_node];

	for (int i = 0; i < n_node; i++)
	{
		int counter = 0;
		for (int j = 0; j < n_node; j++)
		{

			if (node_connec[i][j] != 0)
			{
				counter = counter + 1;

			}

			nnz[i] = counter;

		}

	}

	//defining 2d vector and saving non-zero element

	vector<vector<int>> vec(n_node);

	for (int i = 0; i < n_node; i++)
	{

		int col = { nnz[i] };

		vec[i] = vector<int>(col);
		for (int j = 0; j < col; j++)
		{

			for (int z = 0; z < n_node; z++)
			{

				if (node_connec[i][z] != 0)
				{
					vec[i][j] = node_connec[i][z];
					j = j + 1;

				}
			}
		}
	}

	// removing duplicate 

	for (int i = 0; i < n_node; i++)
	{
		int prev = 0;

		for (int j = 0; j < vec[i].size(); j++)
		{
			vec[i].erase(std::unique(vec[i].begin(), vec[i].end()), vec[i].end());
		}

	}

	// backing to zero base


	for (int i = 0; i < n_node; i++)
	{
		for (int j = 0; j < vec[i].size(); j++)
		{
			vec[i][j] = vec[i][j] - 1;
		}

	}


	fstream network;
	network.open("node_connec.txt", fstream::out);

	network << std::endl;

	for (int i = 0; i < n_node; i++)
	{
		for (int j = 0; j < vec[i].size(); j++)
		{

			network << vec[i][j] << "\t";

		}

		network << std::endl;
	}

	network.close();

	/*****************row_ptr*******************/

	int row_ptr[n_node + 1];
	row_ptr[0] = 0;

	for (int i = 1; i < n_node + 1; i++)
	{

		row_ptr[i] = row_ptr[i - 1] + vec[i - 1].size();

	}


	for (int i = 0; i < n_node + 1; i++)
	{

		cout << "i= " << i << " " << row_ptr[i] << endl;
	}

	/********************col_ind****************************/


	for (int i = 0; i < n_node; i++)
	{

		n_nz += vec[i].size();


	}

	cout << "The number of non-zero element is=  " << n_nz << endl;
	int *col_ind = VecToArr(vec);

	for (int i = 0; i < n_node; i++)
	{
		std::cout << col_ind[i] << "\n";
	}

	for (int i = 0; i < n; i++)
	{
		int node_0 = connectivity[i][1];
		int node_1 = connectivity[i][2];
		int node_2 = connectivity[i][3];

		// element area will drive from detJ= x13*y23- y13*x23, Ae=0.5*|J|
		double a, b, c, d;


		elem_area[i] = abs(0.5*(((x[node_0] - x[node_2])*(y[node_1] - y[node_2])) - ((y[node_0] - y[node_2])*(x[node_1] - x[node_2]))));


		a = x[node_0] - x[node_1];
		b = y[node_0] - y[node_1];
		c = x[node_0] - x[node_2];
		d = y[node_0] - y[node_2];

		gx1 = (d - b) / (a*d - c * b);
		gy1 = (c - d) / (b*c - a * d);

		a = x[node_1] - x[node_2];
		b = y[node_1] - y[node_2];
		c = x[node_1] - x[node_0];
		d = y[node_1] - y[node_0];

		gx2 = (d - b) / (a*d - c * b);
		gy2 = (c - d) / (b*c - a * d);

		a = x[node_2] - x[node_0];
		b = y[node_2] - y[node_0];
		c = x[node_2] - x[node_1];
		d = y[node_2] - y[node_1];

		gx3 = (d - b) / (a*d - c * b);
		gy3 = (c - d) / (b*c - a * d);

		Nx[i][0] = gx1;
		Ny[i][0] = gy1;

		Nx[i][1] = gx2;
		Ny[i][1] = gy2;

		Nx[i][2] = gx3;
		Ny[i][2] = gy3;

		NN_e[0][0] = (1.0 / 6)  * elem_area[i];
		NN_e[0][1] = (1.0 / 12) * elem_area[i];
		NN_e[0][2] = (1.0 / 12) * elem_area[i];
		NN_e[1][0] = (1.0 / 12) * elem_area[i];
		NN_e[1][1] = (1.0 / 6)  * elem_area[i];
		NN_e[1][2] = (1.0 / 12) * elem_area[i];
		NN_e[2][0] = (1.0 / 12) * elem_area[i];
		NN_e[2][1] = (1.0 / 12) * elem_area[i];
		NN_e[2][2] = (1.0 / 6)  * elem_area[i];



		for (int n_sh = 0; n_sh < 3; n_sh++)
		{
			int row = connectivity[i][n_sh + 1];
			int col_begin = row_ptr[row];
			int col_end = row_ptr[row + 1] - 1;
			for (int n_v = 0; n_v < 3; n_v++)
			{
				int col = connectivity[i][n_v + 1];

				for (int j = col_begin; j <= col_end; j++)
				{
					if (col_ind[j] == col)
					{
						NN_vallocal[j] += NN_e[n_sh][n_v];

					}

				}
			}
		}
	}


}

int* VecToArr(std::vector<std::vector<int>> vec)
{
	std::size_t totalsize = 0;

	for (int i = 0; i < vec.size(); i++)
	{
		totalsize += vec[i].size();
	}

	int* newarr = new int[totalsize];
	int* walkarr = newarr;

	for (int i = 0; i < vec.size(); i++)
	{
		std::copy(vec[i].begin(), vec[i].end(), walkarr);
		walkarr += vec[i].size();
	}

	return newarr;
}

void sortRowWise(int m[][n_node], int r, int c)
{

	for (int i = 0; i < r; i++)
	{

		for (int j = 0; j < c; j++)
		{

			for (int k = 0; k < c - j - 1; k++)
			{
				if (m[i][k] > m[i][k + 1])
				{

					swap(m[i][k], m[i][k + 1]);
				}
			}
		}
	}

	fstream rowwisesorted_nodeconnec;
	rowwisesorted_nodeconnec.open("node_connecm1.txt", fstream::out);

	rowwisesorted_nodeconnec << std::endl;

	for (int i = 0; i < n_node; i++)
	{
		for (int j = 0; j < n_node; j++)
		{

			rowwisesorted_nodeconnec << m[i][j] << "\t";

		}

		rowwisesorted_nodeconnec << std::endl;
	}

	rowwisesorted_nodeconnec.close();
}
Posted

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900