Esempio n. 1
0
/* J_ee Stress Function 
   See declaration in Duda & Hart
   the matrix M is a (pointcount*DIM)x1 matrix (a parameter vector). 
--------------------------------------------------*/
double J_ee(matrix M)
{
	double res,d,d_i,sqrt(),res_i,tot_delta,cons_add,Dij();
	int i,j,k;
	static double coeff;

	res=0.0;
	tot_delta = 0.0;

	for (i=1; i<=pointcount; i++) 
	   for (j=1 ; j<i; j++) {

	      	if (delta[i][j] != LARGE_COEFF)  {
			res_i = Dij(M,i,j) - delta[i][j];
			res_i = res_i*res_i;
			res +=  res_i;
			tot_delta += delta[i][j]*delta[i][j];
		}
	   }
 	res = res/tot_delta;
/*
	cons_add = parr_coeff*parr_penalty(M) + line_coeff*line_penalty(M,Dim);
        res += cons_add;
*/
        return(res);
}
Esempio n. 2
0
int main(){
	int i,j,k;
	scanf("%d %d",&ss,&ee);
	scanf("%d %d",&n,&m);
	for (i=1;i<=n;i++){
		scanf("%s %d %d %d",s1,r+i,&T[i][0],&T[i][1]);
		if (s1[0]=='B') col[i]=0;else col[i]=1;
	}
	memset(gn,0,sizeof(gn));
	memset(d,0,sizeof(d));
	for (;m>0;m--){
		scanf("%d %d %d",&i,&j,&k);
		g[i][gn[i]++]=j;
		g[j][gn[j]++]=i;
		d[i][j]=d[j][i]=k;
	}
	if (!Dij(ss,ee)) printf("0\n");
	return 0;
}
	void GeomData::transferDijData(pMesh theMesh){
		dblarray Dij(3,.0);
		double dij[3];
		int ndom = getNumDomains();
		for (int i=0; i<ndom; i++){
			int dom = domainList[i];
			int row = 0;

			if (dim==2){
				EIter eit = M_edgeIter(theMesh);
				while ( pEdge edge = EIter_next(eit) ){
					if ( edgeBelongToDomain(edge,dom) ){
						if (belongsToBoundary(edge)){
							getDij(edge,dom,Dij);
							dij[0] = Dij[0];
							dij[1] = Dij[1];
							dij[2] = Dij[2];
							setDij(i,row,dij);
							row++;
						}
					}
				}
				EIter_delete(eit);
			}
			else{
				FIter fit = M_faceIter(theMesh);
				while ( pFace face = FIter_next(fit) ){
					if ( faceBelongToDomain(face,dom) ){
						if (belongsToBoundary(face)){
							getDij(face,dom,dij);
							setDij(i,row,dij);
							row++;
						}
					}
				}
				FIter_delete(fit);
			}
		}
	}
Esempio n. 4
0
/* DJ_ee differential of the Stress Function 
   See declaration in Duda & Hart
   the matrix M is a (pointcount*DIM)x1 matrix
----------------------------------------------*/
void DJ_ee(matrix M,matrix D)
{
   	int i,j,k,q;
	double tot_delta,stat_coeff,Dij();
	double coeff_i,d_kj;
	matrix Y_k=NULL,Y_j=NULL,vec_kj=NULL,diff_k=NULL;
	 
	
	tot_delta = 0.0;
   	for (i=1; i<=pointcount; i++) 
		for (j=1 ; j<i; j++)  
			if (delta[i][j] != LARGE_COEFF)  
				tot_delta += delta[i][j]*delta[i][j];
	stat_coeff = 2.0/tot_delta;

	for (k=1; k<=pointcount; k++)  {

		Y_k = mtx_ver_cut(M,Sentry(k,Dim),Eentry(k,Dim));
		alloc_mtx(&diff_k,Dim,1);

		for (j=1; j<=pointcount; j++)  {
			if ((j!=k) && (delta[k][j] != LARGE_COEFF) ){
				d_kj = Dij(M,k,j);
				coeff_i = (d_kj - delta[k][j])/d_kj;
				Y_j = mtx_ver_cut(M,Sentry(j,Dim),Eentry(j,Dim));
				vec_kj = sub_mtx(Y_k,Y_j);
				mul_scalar_in_mtx(vec_kj,coeff_i);
				add_in_mtx(diff_k,vec_kj,1,1);

				free_all_mtx(2,&Y_j,&vec_kj);
			}
		}
		mul_scalar_in_mtx(diff_k,stat_coeff);
		for (q=1; q<=Dim; q++)  
			VecEntry(D,Dim,k,q) = diff_k[q][1] ;
		free_all_mtx(2,&Y_k,&diff_k);
	}
}
Esempio n. 5
0
// calculates: Cij, Dij and nodal volume
int EBFV1_preprocessor_2D(pMesh theMesh, void *pData, int &ndom){
#ifdef TRACKING_PROGRAM_STEPS
	cout << "TRACKING_PROGRAM_STEPS: EBFV1_preprocessor_2D\tIN\n";
#endif

	GeomData *pGCData = (GeomData*)pData;
	pGCData->setMeshDim(theMesh->getDim());

	theMesh->modifyState(2,1);	// create edge data structure
	theMesh->modifyState(0,2);	// create adjacency around nodes
	theMesh->modifyState(1,2);	// create faces around edge

	//cout << "Mesh dimension: 2D\n";
	int i,j,flag,dom;
	double edgeCenter[3], I[3], J[3];

	std::vector<double> Cij(3), Dij(3);
	pEntity edge, face, node;

	/// initialize coefficients
	initializeCoefficients(theMesh,pGCData);

	std::set<int> setOfDomain;

	// for each face, calculate all data needed and attach them to the its edges
	FIter fit = M_faceIter(theMesh);
	while ( (face = FIter_next(fit)) ){
		// look up only for leave elements (without children)
		if ( !theMesh->getRefinementDepth(face) ){
			dom = EN_getFlag(face);
			char dom_string[256]; sprintf(dom_string,"dom_str_%d",dom);

			if (!dom){
				throw Exception(__LINE__,__FILE__,"dom = 0\n");
			}

			setOfDomain.insert(dom);		// store every new domain
			double faceCenter[3] = {.0, .0, .0};
			getFCenter(face,faceCenter);

			// loop over all three face's edges to calculate Cij and Dij
			for (i=0; i<3; i++){
				edge = F_edge(face, i);

				// set edge belonging to domain 'dom'
				EN_attachDataInt(edge,MD_lookupMeshDataId( dom_string ),1);

				edgeCenter[0] = edgeCenter[1] = .0;
				E_center(edge,edgeCenter);				// edge centroid
				V_coord(edge->get(0,0),I);
				V_coord(edge->get(0,1),J);

				int id0 = EN_id(edge->get(0,0));
				int id1 = EN_id(edge->get(0,1));

				// edge vector, used as a reference vector
				double IJ[2] = {J[0]-I[0], J[1]-I[1]};

				// vector IJ must point from the smaller vertex ID to the greater
				if ( id0 > id1 ){
					for (j=0; j<2; j++){
						IJ[j] = -IJ[j];
					}
				}

				// vector: from element center to edge middle point, used as a reference vector
				double v[2] = {edgeCenter[0]-faceCenter[0],edgeCenter[1]-faceCenter[1]};

				// Cij is orthogonal to v
				for (j=0; j<2; j++){
					Cij[j] = .0;
				}

				// Cij must point as if I inside the CV and J outside
				double innerprod = v[1]*IJ[0] + (-v[0])*IJ[1];
				if ( innerprod <= .0 ){
					for (j=0; j<2; j++){
						v[j] = -v[j];
					}
				}

				// associate Cij coefficient to edge
				pGCData->getCij(edge,dom,Cij);
				Cij[0] += v[1];
				Cij[1] += -v[0];

				pGCData->setCij(edge,dom,Cij);
				//cout << "Cij = " << Cij[0] << "\t" << Cij[1] << "\t" << Cij[2] << "\n";
#ifdef __ADAPTATION_DEBUG__
		if (Cij[0]==.0 && Cij[1]==.0){
			char msg[256]; sprintf(msg,"Edge %d-%d has Cij coefficient NULL Cij[0]=Cij[1]=0.0",id0,id1);
			throw Exception(__LINE__,__FILE__,msg);
		}
#endif
			}

			// calculate volume of control volume and associate it to elements nodes
			const double porosity = .0;
			double A = F_area(face)/3.0;	// element area
			//cout << "area = " << A << endl;
			for (j=0; j<3; j++){
				node = face->get(0,j);
				EN_attachDataInt(node,MD_lookupMeshDataId( dom_string ),1);
				double v1 = pGCData->getVolume(node,dom);
				double v2 = pGCData->getWeightedVolume(node);
				v1 += A;
				v2 += A*porosity;
				pGCData->setVolume(node,dom,v1);
				pGCData->setWeightedVolume(node,v2);
			}
		}
	}
	FIter_delete(fit);

	int numBE = 0;
	// Calculate Dij coefficient only for boundary edges.
	EIter eit = M_edgeIter(theMesh);
	while ( (edge = EIter_next(eit)) ){
		if ( !theMesh->getRefinementDepth(edge) ){
 			flag = EN_getFlag(edge);
 			std::set<int>::iterator iter = setOfDomain.find( flag );
 			if (iter == setOfDomain.end()){		// this line is for general (h**o/hetero) adaptation
				numBE++;
				double I[3] = {.0,.0,.0}, J[3] = {.0,.0,.0};
				V_coord(edge->get(0,0),I);
				V_coord(edge->get(0,1),J);

				// Dij vector is orthogonal to edge (it's unknown Dij orientation)
				Dij[0] = -(J[1]-I[1])/2.0;
				Dij[1] =  (J[0]-I[0])/2.0;

				// make Dij points to outside domain. First, take face that uses edge and its flag
				int domains[2] = {0,0};
				for (i=0; i<E_numFaces(edge); i++){
					face = E_face(edge,i);
					if (!face){
						throw Exception(__LINE__,__FILE__,"Null face!\n");
					}
					domains[i] = EN_getFlag(face);
				}
				// that the reference face to make Dij points to outside
				face = E_face(edge, 0);

				if (!face){
					throw Exception(__LINE__,__FILE__,"Null face!\n");
				}

				// now, get face's center and edge's center
				double faceCenter[3] = {.0, .0, .0}, edgeCenter[3] = {.0, .0, .0};
				getFCenter(face,faceCenter);	// element centroid
				E_center(edge,edgeCenter);		// edge centroid

				// vector: from element center to edge middle point, used as a reference vector
				double v[2] = {edgeCenter[0]-faceCenter[0],edgeCenter[1]-faceCenter[1]};

				// Dij must point to outside element
				double innerprod = Dij[0]*v[0] + Dij[1]*v[1];
				if (  innerprod <= .0 ){
					for (j=0; j<2; j++){
						Dij[j] = -Dij[j];
					}
				}
				// associate to edge domains flags to wjich it belongs
				EN_attachDataInt(edge,MD_lookupMeshDataId("dom1"),domains[0]);
				EN_attachDataInt(edge,MD_lookupMeshDataId("dom1"),domains[1]);
				pGCData->setDij(edge,domains[0],domains[1],Dij);
			}
		}
	}
	EIter_delete(eit);
	//cout << "preprocessor: Number of Boundary edges = " << numBE << endl;
	calculateEdgeLength(theMesh,pGCData);
	calculateCijNorm(theMesh,pGCData,setOfDomain);

	// For 2-D domains, multiply volume by reservoir height (H) for 2D/3D simulations (physics occurs only on 2-D but reservoir volume is considered)
	double vt = .0;
	double vol,wvol;
	std::set<int>::iterator iter = setOfDomain.begin();
	for(;iter!=setOfDomain.end();iter++){
		VIter vit = M_vertexIter(theMesh);
		while (pEntity node = VIter_next(vit)){
			// do not divide vol by number of remote copies!
			vol = pGCData->getVolume(node,*iter);
			vt += vol;
			wvol = 0.2*vol;
			pGCData->setWeightedVolume(node,wvol);
		}
		VIter_delete(vit);
	}
	pGCData->setTotalReservoirVolume(vt);
	//cout << "Number of domains: " << setOfDomain.size() << ". They are: ";
//	for( iter = setOfDomain.begin(); iter!=setOfDomain.end(); iter++){
//		cout << *iter << "  ";
//	}
//	cout << endl;

	validete_coefficients(theMesh,setOfDomain,pGCData);

#ifdef TRACKING_PROGRAM_STEPS
	cout << "TRACKING_PROGRAM_STEPS: EBFV1_preprocessor_2D\tOUT\n";
#endif
	return 0;
}
Esempio n. 6
0
void validete_coefficients(pMesh theMesh, std::set<int>& setOfDomain, GeomData* pGCData){

#ifdef TRACKING_PROGRAM_STEPS
	cout << "TRACKING_PROGRAM_STEPS: validate pre-processor coefficient calculation\tIN\n";
#endif


	cout << setprecision(8) << scientific;
	pEntity edge;
	std::vector<double> Cij(3), Dij(3);
	std::map<int,double*> coeff_sum;

	std::set<int>::iterator iter = setOfDomain.begin();

	for(;iter!=setOfDomain.end(); iter++){
		int dom = *iter;

		// initialize all nodes for domain "dom"
		double* p;
		VIter vit = M_vertexIter(theMesh);
		while (pEntity node = VIter_next(vit)){
			p = new double[3];
			p[0] = p[1] = p[2] = .0;
			coeff_sum[EN_id(node)] = p;
		}
		VIter_delete(vit);


		// calculate summation of coefficients
		EIter eit = M_edgeIter(theMesh);
		while ( (edge = EIter_next(eit)) ){
			int I = EN_id(edge->get(0,0));
			int J = EN_id(edge->get(0,1));
			pGCData->getCij(edge,dom,Cij);
			double sign = (I>J)?-1.0:1.0;


			p = coeff_sum[I];
			p[0] += sign*Cij[0];
			p[1] += sign*Cij[1];
			p[2] += sign*Cij[2];
			if (pGCData->getDij(edge,dom,Dij)){
				p[0] += Dij[0];
				p[1] += Dij[1];
				p[2] += Dij[2];
			}

			p = coeff_sum[J];
			p[0] += -sign*Cij[0];
			p[1] += -sign*Cij[1];
			p[2] += -sign*Cij[2];
			if (pGCData->getDij(edge,dom,Dij)){
				p[0] += Dij[0];
				p[1] += Dij[1];
				p[2] += Dij[2];
			}
		}
		EIter_delete(eit);

		double summation[3] = {.0,.0,.0};
		cout << "Domain: " << dom << endl;
		//cout << "ID:\t" << "Summ:\n";
		std::map<int,double*>::iterator miter = coeff_sum.begin();
		for(;miter!=coeff_sum.end();miter++){
			//int ID = miter->first;
			p = miter->second;
			//cout << ID << "\t" << p[0] << " " << p[1] << " " << p[2] << endl;
			summation[0] += p[0];
			summation[1] += p[1];
			summation[2] += p[2];
			dealloc_DOUBLE_vector(p);
		}
		cout <<  "\n\nSummation of all summations (Cij/Dij):  " << summation[0] << " " << summation[1] << " " << summation[2] << "\n";

		double vol_control = 0;
		vit = M_vertexIter(theMesh);
		while (pEntity node = VIter_next(vit)){
			vol_control += pGCData->getVolume(node,dom);
		}
		VIter_delete(vit);
		cout <<  "Total Volume                         :  " << vol_control << "\n\n\n";

	}
#ifdef TRACKING_PROGRAM_STEPS
	cout << "TRACKING_PROGRAM_STEPS: validate pre-processor coefficient calculation\tOUT\n";
#endif

}
Esempio n. 7
0
// Calculates Cij, Dij(boundary faces) and nodal volume. It also works for multi domains meshes
int EBFV1_preprocessor_3D(pMesh theMesh, void *pData, int &ndom){
	PetscPrintf(PETSC_COMM_WORLD,"Starting EBFV1-3D pre-processor...");

	GeomData *pGCData = (GeomData*)pData;
	pGCData->setMeshDim(theMesh->getDim());
	if (theMesh->getDim() != 3){
		throw Exception(__LINE__,__FILE__,"Only 3-D meshes are allowed. Exiting...\n");
	}

	theMesh->modifyState(3,2);
	theMesh->modifyState(2,3);

	pEntity tetra, edge, face;
	int i,j,k,K,m;
	double tCenter[3], eCenter[3], v[3], *vec[2], val, *tetraFCenter[4];
	double normal[3], I[3], J[3], IJ[3], proj[3];

	// allocate vectors
	for (i=0; i<4; i++) tetraFCenter[i] = new double[3];
	for (i=0; i<2; i++) vec[i] = new double[3];

	// Search over all tetrahedra flags set to define domains. Store all flags on a list and initialize Cij vector
	std::set<int> setOfDomain;
	std::vector<double> Cij(3,.0);
	RIter rit = M_regionIter(theMesh);
	while ( (tetra = RIter_next(rit)) ){
		int flag = GEN_tag(tetra->getClassification());
		setOfDomain.insert( flag );
		for (i=0; i<6; i++){
			edge = (pEntity)tetra->get(1,i);
			pGCData->setCij(edge,flag,Cij);
		}
	}
	RIter_delete(rit);

	// mark faces (boundary)
	bool detectBdryFaces = false;
	std::set<int>::iterator iter = setOfDomain.begin();
	for (; iter != setOfDomain.end(); iter++){
		int countBDRYFaces = 0;
		int dom = *iter;
		char dom_string[256]; sprintf(dom_string,"dom_str_%d",dom);
		RIter rit = M_regionIter(theMesh);
		while ( (tetra = RIter_next(rit)) ){
			int tetraflag = GEN_tag(tetra->getClassification());
			if (tetraflag==dom){
				for (i=0;i<4;i++){
					face = (pFace)tetra->get(2,i);
					int faceflag = GEN_tag(face->getClassification());
					// if flags are different, then face in on boundary
					if (faceflag!=tetraflag){
						detectBdryFaces = true;
						countBDRYFaces++;
						// set edge belonging to domain 'dom'
						EN_attachDataInt(face,MD_lookupMeshDataId( dom_string ),1);
					}
				}
			}
		}
		RIter_delete(rit);
	}
	//throw 1;

	if (!detectBdryFaces){
		throw Exception(__LINE__,__FILE__,"Any boundary face (triangles) were detected. Boundary elements MUST have different flag of internal elements.");
	}

	/// initialize weighted volume
	VIter vit = M_vertexIter(theMesh);
	while (pEntity v = VIter_next(vit))
		pGCData->setWeightedVolume(v,0.0);
	VIter_delete(vit);

	vector<pVertex> tetraVertex(4), edgeVertex(2);
	double vt = .0; // total volume

	// loop over elements
	// for each element:	1 - calculate Cij for each edge and store them on the respective edge
	//						2 - calculate element contribution to volume of control volume
//	PetscPrintf(PETSC_COMM_WORLD,"Loop over tetras - start...  ");MPI_Barrier(MPI_COMM_WORLD);
	rit = M_regionIter(theMesh);
	while ( (tetra = RIter_next(rit)) ){
		// get all four tetrahedron's vertices
		for (i=0; i<4; i++){
			tetraVertex[i] = (pEntity)tetra->get(0,i);
		}

		int tetraFaces[4][3] = { {EN_id(tetraVertex[0]),EN_id(tetraVertex[1]),EN_id(tetraVertex[2])},
				{EN_id(tetraVertex[0]),EN_id(tetraVertex[1]),EN_id(tetraVertex[3])},
				{EN_id(tetraVertex[0]),EN_id(tetraVertex[2]),EN_id(tetraVertex[3])},
				{EN_id(tetraVertex[1]),EN_id(tetraVertex[2]),EN_id(tetraVertex[3])}};

		getFCenter(tetraVertex[0], tetraVertex[1], tetraVertex[2], tetraFCenter[0]);
		getFCenter(tetraVertex[0], tetraVertex[1], tetraVertex[3], tetraFCenter[1]);
		getFCenter(tetraVertex[0], tetraVertex[2], tetraVertex[3], tetraFCenter[2]);
		getFCenter(tetraVertex[1], tetraVertex[2], tetraVertex[3], tetraFCenter[3]);

		// get tetrahedron center
		tCenter[0] = tCenter[1] = tCenter[2] = .0;
		R_center(tetra,tCenter);

		double coord1[3]; V_coord(tetraVertex[0],coord1);
		double coord2[3]; V_coord(tetraVertex[1],coord2);
		double coord3[3]; V_coord(tetraVertex[2],coord3);
		double coord4[3]; V_coord(tetraVertex[3],coord4);

		// step #1: Cij
		// identify which domain the current tetrahedron belongs to
		// edges on domain's partition have differents Cij, one for each domain
		const int dom = GEN_tag(tetra->getClassification());
		char dom_string[256]; sprintf(dom_string,"dom_str_%d",dom);
		markTetraBdryFaces(theMesh,tetra,dom);
		setOfDomain.insert(dom); // store every new domain

		for (int pos1=0; pos1<3; pos1++){
			for (int pos2=pos1+1; pos2<4; pos2++){
				edge = (pEdge)theMesh->getEdge((mVertex*)tetraVertex[pos1],(mVertex*)tetraVertex[pos2]);

				// set edge belonging to domain 'dom'
				EN_attachDataInt(edge,MD_lookupMeshDataId( dom_string ),1);


				//M_GetVertices(edge,edgeVertex);
				for (i=0; i<2; i++) edgeVertex[i] = (pEntity)edge->get(0,i);
				// edge's Cij is the sum of two vectors. Both are orthogonals to planes
				// defined by three vectors. They are:
				// v - ec->tc:		edge center to tetra center
				// vec[0] - ec->fcr:	edge center to right face center
				// vec[1] - ec->fcl:	edge center to left face center
				// Cij = (v)x(vec[0]) + (v)x(vec[1]), Cij points to outside of control volume

				// create vector v:
				for (i=0; i<3; i++) I[i] = J[i]= .0;
				V_coord(edgeVertex[0],I);
				V_coord(edgeVertex[1],J);

				double sign = ( EN_id(edgeVertex[0]) > EN_id(edgeVertex[1]) )?-1.0:1.0;
				for (i=0; i<3; i++){
					IJ[i] = sign*(J[i] - I[i]);
				}

				// get edge center
				eCenter[0] = eCenter[1] = eCenter[2] = .0;
				for (i=0; i<3; i++){
					eCenter[i] = .5*(I[i]+J[i]);
				}

				// create vector v: from edge middle point to tetrahedral centroid
				for (i=0; i<3; i++){
					v[i] = tCenter[i] - eCenter[i];
				}

				// search for tetra faces that share the same edge and get their centers. Of course, there are only two faces
				// sharing the same edge. FMDB can do this job easily, but for 3D big meshes a face structure has a high memory cost.

				K = 0;
				// loop over tetra's faces
				for (i=0; i<4; i++){
					// loop over face's vertices
					for (j=0; j<3; j++){
						if (EN_id(edgeVertex[0]) == tetraFaces[i][j]){
							for (k=0; k<3; k++){
								if (EN_id(edgeVertex[1])==tetraFaces[i][k]){
									for (m=0; m<3; m++) vec[K][m] = -eCenter[m] + tetraFCenter[i][m];
									K++;
								}
							}
						}
					}
				}

				// IJ vector is a reference to Cij. IJ points from node I to node J
				// where: I_id < J_id
				// vec projections on edge IJ must have the same orientation as IJ vector
				double n = sqrt( IJ[0]*IJ[0] + IJ[1]*IJ[1] + IJ[2]*IJ[2] ) ;

				// Cij calculation n ;
				for (j=0; j<3; j++){
					Cij[j] = .0;
				}
				pGCData->getCij(edge,dom,Cij);
				double normal1[3], normal2[3];
				cross(v,vec[0],normal1);
				cross(vec[1],v,normal2);

				for (j=0; j<3; j++){
					proj[j] = .0;
				}
				for (j=0; j<3; j++){
					normal[j] = .5*(normal1[j]+normal2[j]);
				}
				val = dot(normal,IJ)/(n*n);
				for (j=0; j<3; j++){
					proj[j] = val*IJ[j];
				}
				double sinal = (dot(proj,IJ)<.0)?-1.:1.;
				for (j=0; j<3; j++){
					Cij[j] += sinal*normal[j];
				}
				pGCData->setCij(edge,dom,Cij);
			}
		}

		// step #2: volume of control volume
		const double porosity = .0;
		const double tetraVolume = R_Volume(tetra);
		const double nodalVolume = .25*tetraVolume;
		vt = +tetraVolume;

		for (i=0; i<4; i++){
			// total nodal volume
			double v1 = pGCData->getVolume(tetraVertex[i],dom);
			v1 += nodalVolume;
			pGCData->setVolume(tetraVertex[i],dom,v1);
			double v2 = pGCData->getWeightedVolume(tetraVertex[i]);
			v2 += nodalVolume*porosity;
			pGCData->setWeightedVolume(tetraVertex[i],v2);
		}
	}
	RIter_delete(rit);	// END TETRAHEDRALS LOOP
	pGCData->setTotalReservoirVolume(vt);
	//PetscPrintf(PETSC_COMM_WORLD,"Finished\n");MPI_Barrier(MPI_COMM_WORLD);

	// deallocate vectors
	for (i=0; i<4; i++) delete[] tetraFCenter[i];
	for (i=0; i<2; i++) delete[] vec[i];

	/*
	 * Dij vector calculation. A loop over all boundary (external/internal) faces is made. Depending on how FMDB is used, faces on all
	 * tetrahedrals may be created and they must be filtered. If a face does not belong to boundary it will assume the tetrahedral domain
	 * flag. This value is greater than 3000 and is used to filter them from those provided by mesh file.
	 */

	int count = 0;
	dblarray Dij(3,.0);
	//PetscPrintf(PETSC_COMM_WORLD,"Loop over boundary faces - start... ");///MPI_Barrier(MPI_COMM_WORLD);
	if ( M_numFaces(theMesh) != 0 ){
		FIter fit = M_faceIter(theMesh);
		while ( (face = FIter_next(fit)) ){
			int flag = GEN_tag(face->getClassification());
			iter = setOfDomain.find(flag);
			// get only faces built over surfaces defined by user in geometric model
			// it only work if surface flags defined by user are different from those set to tetrahedrals
			if ( iter==setOfDomain.end() ){
				computeDij(theMesh,face,pGCData);
			}
		}
		FIter_delete(fit);
	}
	//PetscPrintf(PETSC_COMM_WORLD,"Finished\n");MPI_Barrier(MPI_COMM_WORLD);
	calculateEdgeLength(theMesh,pGCData);
	calculateCijNorm(theMesh,pGCData,setOfDomain);
	identifyBoundaryElements(theMesh,pGCData,setOfDomain);
	i = 0;
	ndom = (int)setOfDomain.size();
	int *domlist = new int[ndom];
	for(iter = setOfDomain.begin(); iter!=setOfDomain.end(); iter++){
		domlist[i++] =  *iter;
	}

	PetscPrintf(PETSC_COMM_WORLD," finished.\n");
	cout << "-------------------------------------------------------------------------------------------------------------------------\n\n";
	return 0;
}