
	// Compute Mass matrix on one thread
	static void* stiffness_thread(void* data);

/*================================================================================================
 stiffness_thread
================================================================================================== */


void* cMCF::stiffness_thread(void* data)
{
	int threadid = *((int *) data);

	int N1    = Mat[threadid].N1;
	int N2    = Mat[threadid].N2;
	int n     = Mat[threadid].n;

	int idxA, idxB;
	double val = 1.0/2.;
	double val2, cotC, cotD;

	HalfEdgeIter hAB, hBA;
	Vector A, B, C, D;
	Vector u, v;

	std::memset(Mat[threadid].Diag, 0, n*sizeof(double));

	for (int pair = N1; pair < N2; pair++)
	{
		hAB = Mat[threadid].mesh->edges[pair].he;
		hBA = hAB->flip;

		idxA = hAB->vertex->index;
		idxB = hBA->vertex->index;

		A = hAB->vertex->position2;
		B = hAB->next->vertex->position2;
		C = hAB->prev->vertex->position2;
		D = hBA->prev->vertex->position2;

		u = A-C;
		v = B-C;
		cotC = dot(u,v)/cross(u,v).norm();

		u = A-D;
		v = B-D;
		cotD = dot(u,v)/cross(u,v).norm();

		val2 = val*(cotC+cotD);

		Stiff.coeffRef(idxA, idxB) = val2;
		Stiff.coeffRef(idxB, idxA) = val2;

		Mat[threadid].Diag[idxA] -= val2;
		Mat[threadid].Diag[idxB] -= val2;

	}
	return 0;
}

/*================================================================================================
 Stiffness
================================================================================================== */

void cMCF::computeStiffness(Mesh& mesh)
{
	int nthreads = sysconf( _SC_NPROCESSORS_ONLN );
	if(nthreads==0) nthreads = 1;

	int Npair = mesh.edges.size();
	int nval = Npair / nthreads;
	int N1, N2;
	int n  = mesh.vertices.size();

	for(int i = 0; i < nthreads; i++) 
	{
		N1 = i*nval;
		N2 = N1 + nval;
		if(i == nthreads-1) N2 = Npair;
		threadids[i]=i;
		Mat[i].N1 = N1;
		Mat[i].N2 = N2;
		Mat[i].n  = n;
		Mat[i].mesh  = &mesh;
		double *Diag = new double[n];
		Mat[i].Diag = Diag;

		pthread_create(&threads[i], NULL, stiffness_thread, (void*) &threadids[i]);
	}
	
/*      ==========================================================================================
	Join all the threads (to make sure they are all finished)
        ========================================================================================== */

	double *Diag = new double[n];
	std::memset(Diag, 0, n*sizeof(double));
	double alpha = 1.0;
	int inc = 1;
	for (int i=0; i < nthreads; i++)
	{
		pthread_join(threads[i], NULL);
		daxpy_(&n, &alpha, Mat[i].Diag, &inc, Diag, &inc);
	}

	for(VertexIter v_iter = mesh.vertices.begin(); v_iter != mesh.vertices.end(); v_iter++)
	{
		int i = v_iter->index;
		Stiff.coeffRef(i, i) = Diag[i];
	}

	delete [] Diag;

}
