← Back to team overview

yade-dev team mailing list archive

[Branch ~yade-dev/yade/trunk] Rev 2329: - Added function to compute average cell velocity

 

------------------------------------------------------------
revno: 2329
committer: ecatalano <ecatalano@dt-rv019>
branch nick: trunk
timestamp: Thu 2010-07-08 11:11:42 +0200
message:
  - Added function to compute average cell velocity
  - Added function to apply sinusoidal external fluid pressures
modified:
  lib/triangulation/FlowBoundingSphere.cpp
  lib/triangulation/FlowBoundingSphere.h
  lib/triangulation/def_types.h
  pkg/dem/Engine/PartialEngine/FlowEngine.cpp
  pkg/dem/Engine/PartialEngine/FlowEngine.hpp


--
lp:yade
https://code.launchpad.net/~yade-dev/yade/trunk

Your team Yade developers is subscribed to branch lp:yade.
To unsubscribe from this branch go to https://code.launchpad.net/~yade-dev/yade/trunk/+edit-subscription
=== modified file 'lib/triangulation/FlowBoundingSphere.cpp'
--- lib/triangulation/FlowBoundingSphere.cpp	2010-06-17 12:30:19 +0000
+++ lib/triangulation/FlowBoundingSphere.cpp	2010-07-08 09:11:42 +0000
@@ -1,3 +1,9 @@
+/*************************************************************************
+*  Copyright (C) 2010 by Emanuele Catalano <catalano@xxxxxxxxxxxxxxx>    *
+*                                                                        *
+*  This program is free software; it is licensed under the terms of the  *
+*  GNU General Public License v2 or later. See file LICENSE for details. *
+*************************************************************************/
 
 #include "def_types.h"
 #include "CGAL/constructions/constructions_on_weighted_points_cartesian_3.h"
@@ -7,7 +13,7 @@
 #include <new>
 #include <utility>
 #include "vector"
-
+#include <assert.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 
@@ -23,12 +29,14 @@
 
 #define FAST
 #define TESS_BASED_FORCES
+#define FACET_BASED_FORCES 1
+// #define USE_FAST_MATH 1
 
 using namespace std;
 namespace CGT
 {
 
-const bool DEBUG_OUT = false;
+const bool DEBUG_OUT = true;
 
 
 const double ONE_THIRD = 1.0/3.0;
@@ -78,6 +86,8 @@
 	distance_correction = true;
 	meanK_LIMIT = true;
 	meanK_STAT = false; K_opt_factor=0;
+	noCache=true;
+	computeAllCells=true;//might be turned false IF the code is reorganized (we can make a separate function to compute unitForceVectors outside Compute_Permeability) AND it really matters for CPU time
 }
 
 void FlowBoundingSphere::Compute_Action()
@@ -203,6 +213,122 @@
 // }
 }
 
+int FlowBoundingSphere::Average_Cell_Velocity(int id_sphere, RTriangulation& Tri)
+{
+	Vecteur nullVect(0,0,0);
+	double pos_av_facet [3];
+	int num_cells = 0;
+	
+	double facet_flow_rate;
+	std::ofstream oFile( "Average_Cells_Velocity",std::ios::app);
+	
+	Finite_cells_iterator cell_end = Tri.finite_cells_end();
+	for (Finite_cells_iterator cell = Tri.finite_cells_begin(); cell != cell_end; cell++) {
+	  for (int h=0; h<3;h++) (cell->info().av_vel())[h]=0;}
+	
+	Tesselation::Vector_Cell tmp_cells;
+	tmp_cells.resize(1000);
+	Tesselation::VCell_iterator cells_it = tmp_cells.begin();
+	Tesselation::VCell_iterator cells_end = Tri.incident_cells(T[currentTes].vertexHandles[id_sphere],cells_it);
+	for (Tesselation::VCell_iterator it = tmp_cells.begin(); it != cells_end; it++)
+	{
+	  num_cells++;
+	  for (int i=0; i<4; i++)
+	  {
+// 	    oFile << endl << "FACET " << i << " -------------" << endl;
+	    for (int i2=0;i2<3;i2++) pos_av_facet[i2] = nullVect[i2];
+	    for (int j=0;j<3;j++)
+	    {
+	      pos_av_facet[j] += ((*it)->vertex(facetVertices[i][j])->point().x())/3 + ((*it)->vertex(facetVertices[i][j])->point().y())/3 +
+	      ((*it)->vertex(facetVertices[i][j])->point().z())/3;
+	    }
+// 	    oFile << "Average position = " ; for (int g=0; g<3; g++) oFile << pos_av_facet[g] << " "; oFile << endl;
+	    facet_flow_rate = ((*it)->info().k_norm())[i] * abs((*it)->info().p() - (*it)->neighbor(Tri.mirror_index((*it), i))->info().p());
+// 	    oFile << "Facet Flow Rate = " << facet_flow_rate << " (p1 = " << (*it)->info().p() << " ,p2 = " << (*it)->neighbor(Tri.mirror_index((*it), i))->info().p() << ", k = " << ((*it)->info().k_norm())[i] <<  ")." << endl;
+	    for (int y=0;y<3;y++) pos_av_facet[y] = pos_av_facet[y]*facet_flow_rate;
+	    for (int y2=0;y2<3;y2++)((*it)->info().av_vel())[y2] = ((*it)->info().av_vel())[y2] + pos_av_facet[y2];
+	  }
+	  for (int y2=0;y2<4;y2++) ((*it)->info().av_vel())[y2] = ((*it)->info().av_vel())[y2]/((*it)->info().volume());
+// 	  oFile << "Volume = " << (*it)->info().volume() << endl;
+	  oFile << ((*it)->info().av_vel())[0] << " " << ((*it)->info().av_vel())[1] << " " << ((*it)->info().av_vel())[2] << "    Cell Pressure = " << (*it)->info().p() << endl;
+	}
+	
+	oFile << endl << "Forces on grain = " << (T[currentTes].vertexHandles[id_sphere]->info().forces)[0] << " " << (T[currentTes].vertexHandles[id_sphere]->info().forces)[1] << " " << (T[currentTes].vertexHandles[id_sphere]->info().forces)[2] << " " << endl << endl;
+	oFile << "-----------------------------------------" << endl << endl << endl;
+	
+	return num_cells;
+}
+
+void FlowBoundingSphere::vtk_average_cell_velocity(RTriangulation &Tri, int id_sphere, int num_cells )
+{
+        static unsigned int number = 0;
+        char filename[80];
+	mkdir("./VTK", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
+        sprintf(filename,"./VTK/out_%d.vtk", number++);
+
+        basicVTKwritter vtkfile((unsigned int) 4*num_cells, (unsigned int) num_cells);
+
+        vtkfile.open(filename,"test");
+	
+	Tesselation::Vector_Cell tmp_cells;
+	tmp_cells.resize(1000);
+	Tesselation::VCell_iterator cells_it = tmp_cells.begin();
+	Tesselation::VCell_iterator cells_end = Tri.incident_cells(T[currentTes].vertexHandles[id_sphere],cells_it);
+	
+        vtkfile.begin_vertices();
+	for (Tesselation::VCell_iterator it = tmp_cells.begin(); it != cells_end; it++)
+	{
+	  for (int y2=0; y2<4; y2++){
+	    double x,y,z;
+	    x = (double)((*it)->vertex(y2)->point().point()[0]);
+	    y = (double)((*it)->vertex(y2)->point().point()[1]);
+	    z = (double)((*it)->vertex(y2)->point().point()[2]);
+	    vtkfile.write_point(x,y,z);}
+	}
+	
+        vtkfile.end_vertices();
+	
+        vtkfile.begin_cells();
+	for (Tesselation::VCell_iterator it = tmp_cells.begin(); it != cells_end; it++)
+	{
+		vtkfile.write_cell((*it)->vertex(0)->info().id()-id_offset, (*it)->vertex(1)->info().id()-id_offset, (*it)->vertex(2)->info().id()-id_offset, (*it)->vertex(3)->info().id()-id_offset);
+        }
+        vtkfile.end_cells();
+	
+// 	vtkfile.begin_data("Force",POINT_DATA,SCALARS,FLOAT);
+// 	vtkfile.write_data((T[currentTes].vertexHandles[id_sphere]->info().forces)[1]);
+// 	vtkfile.end_data();
+
+	vtkfile.begin_data("Velocity",CELL_DATA,SCALARS,FLOAT);
+
+	for (Tesselation::VCell_iterator it = tmp_cells.begin(); it != cells_end; it++)
+	{
+		vtkfile.write_data((*it)->info().av_vel()[1]);
+	}
+	vtkfile.end_data();
+}
+
+void FlowBoundingSphere::ApplySinusoidalPressure(RTriangulation& Tri, double Pressure, double load_intervals)
+{
+
+	double step = 1/load_intervals;
+	Tesselation::Vector_Cell tmp_cells;
+	tmp_cells.resize(1000);
+	Tesselation::VCell_iterator cells_it = tmp_cells.begin();
+	for (double alpha=0; alpha<1.001; alpha+=step)
+	{
+	  Tesselation::VCell_iterator cells_end = Tri.incident_cells(T[currentTes].vertexHandles[y_max_id],cells_it);
+	  for (Tesselation::VCell_iterator it = tmp_cells.begin(); it != cells_end; it++)
+	  {
+	    if(!Tri.is_infinite(*it)){
+	      Point& p1 = (*it)->info();
+	      Cell_handle& cell = *it;
+	      if (p1.x()>(alpha*(x_max-x_min)) && p1.x()<((alpha+step)*(x_max-x_min))){cell->info().p() = Pressure+cos(alpha*M_PI)*(Pressure);}
+	  }
+	  }
+	}
+}
+
 void FlowBoundingSphere::Interpolate(Tesselation& Tes, Tesselation& NewTes)
 {
         Cell_handle old_cell;
@@ -266,7 +392,7 @@
                 for (int j=0; j<4; j++) {
                         neighbour_cell = cell->neighbor(j);
                         p2 = neighbour_cell->info();
-                        if (!Tri.is_infinite(neighbour_cell) && neighbour_cell->info().isvisited==ref) {
+			if (!Tri.is_infinite(neighbour_cell) && (neighbour_cell->info().isvisited==ref || computeAllCells)) {
                                 pass+=1;
                                 Rhv = Compute_HydraulicRadius(Tri, cell, j);
                                 if (Rhv<0) NEG++;
@@ -379,7 +505,7 @@
 
         Real Vtotale = (x_max-x_min) * (y_max-y_min) * (z_max-z_min);
         if (DEBUG_OUT) {
-                cout<<grains<<"grains - " <<"Vtotale = " << Vtotale << " Vgrains = " << Vgrains << " Vporale1 = " << Vtotale-Vgrains << endl;
+                cout<<grains<<"grains - " <<"Vtotale = " << 2*Vtotale << " Vgrains = " << 2*Vgrains << " Vporale1 = " << 2*(Vtotale-Vgrains) << endl;
                 cout << "Vtotalissimo = " << Vtotalissimo << " Vsolid_tot = " << Vsolid_tot << " Vporale2 = " << Vporale  << " Ssolid_tot = " << Ssolid_tot << endl<< endl;
         }
 
@@ -471,24 +597,101 @@
                                 for (int y=0; y<3;y++) {
                                         cell->vertex(facetVertices[j][y])->info().forces = cell->vertex(facetVertices[j][y])->info().forces + Facet_Force*cell->info().solidSurfaces[j][y]/* + (cell->vertex(facetVertices[j][y])->info().isFictious ? 0 : facetNormal*(neighbour_cell->info().p()-cell->info().p())*crossSections[j][y])*/;
 				if (!cell->vertex(facetVertices[j][y])->info().isFictious)
-					cell->vertex(facetVertices[j][y])->info().forces = cell->vertex(facetVertices[j][y])->info().forces +
- 				 facetNormal*(neighbour_cell->info().p()-cell->info().p())*crossSections[j][y];
+				{cell->vertex(facetVertices[j][y])->info().forces = cell->vertex(facetVertices[j][y])->info().forces +
+ 				 facetNormal*(neighbour_cell->info().p()-cell->info().p())*crossSections[j][y];}
+				///TEST BEGING
+				//Conclusion, we can't easily get ordered vertices from mirror facet...
+// 				for (int y=0; y<3;y++) {
+// 					int id1 = cell->vertex(facetVertices[j][y])->info().id();
+// 					int id2 = neighbour_cell->vertex(facetVertices[Tri.mirror_index(cell,j)][y])->info().id();
+// 					cerr <<"id1/id2 : "<<id1<<" "<<id2<<endl;}
+								
+				///TEST END
                                 }
                         }
                 cell->info().isvisited=!ref;
         }
-        cout << "Facet scheme" <<endl;
-        Vecteur TotalForce = nullVect;
-        for (Finite_vertices_iterator v = Tri.finite_vertices_begin(); v != Tri.finite_vertices_end(); ++v) {
-                if (!v->info().isFictious) {
-                        TotalForce = TotalForce + v->info().forces;
-                        if (DEBUG_OUT) cout << "real_id = " << v->info().id() << " force = " << v->info().forces << endl;
-                } else {
-                        if (boundary(v->info().id()).flowCondition==1) TotalForce = TotalForce + v->info().forces;
-                        if (DEBUG_OUT) cout << "fictious_id = " << v->info().id() << " force = " << v->info().forces << endl;
-                }
-        }
-        cout << "TotalForce = "<< TotalForce << endl;
+         cout << "Facet scheme" <<endl;
+         Vecteur TotalForce = nullVect;
+         for (Finite_vertices_iterator v = Tri.finite_vertices_begin(); v != Tri.finite_vertices_end(); ++v) {
+                 if (!v->info().isFictious) {
+                         TotalForce = TotalForce + v->info().forces;
+//                          if (DEBUG_OUT) cout << "real_id = " << v->info().id() << " force = " << v->info().forces << endl;
+                 } else {
+                         if (boundary(v->info().id()).flowCondition==1) TotalForce = TotalForce + v->info().forces;
+                         if (DEBUG_OUT) cout << "fictious_id = " << v->info().id() << " force = " << v->info().forces << endl;
+                 }
+         }
+         cout << "TotalForce = "<< TotalForce << endl;
+}
+
+void FlowBoundingSphere::ComputeFacetForcesWithCache()
+{
+	RTriangulation& Tri = T[currentTes].Triangulation();
+	Finite_cells_iterator cell_end = Tri.finite_cells_end();
+	Vecteur nullVect(0,0,0);
+	bool ref = Tri.finite_cells_begin()->info().isvisited;
+	//reset forces
+	for (Finite_vertices_iterator v = Tri.finite_vertices_begin(); v != Tri.finite_vertices_end(); ++v) v->info().forces=nullVect;
+
+	Cell_handle neighbour_cell;
+	Vertex_handle mirror_vertex;
+	Vecteur tempVect;
+	if (noCache) for (Finite_cells_iterator cell = Tri.finite_cells_begin(); cell != cell_end; cell++) {
+		//reset cache
+		for (int k=0;k<4;k++) cell->info().unitForceVectors[k]=nullVect;
+		for (int j=0; j<4; j++) if (!Tri.is_infinite(cell->neighbor(j))) {
+			neighbour_cell = cell->neighbor(j);
+			const Vecteur& Surfk = cell->info().facetSurfaces[j];
+			//FIXME : later compute that fluidSurf only once in hydraulicRadius, for now keep full surface not modified in cell->info for comparison with other forces schemes
+			//The ratio void surface / facet surface
+			Real area = sqrt(Surfk.squared_length());
+			Vecteur facetNormal = Surfk/area;
+			const std::vector<Vecteur>& crossSections = cell->info().facetSphereCrossSections;
+			Real fluidSurfRatio = (area-crossSections[j][0]-crossSections[j][1]-crossSections[j][2])/area;
+			Vecteur fluidSurfk = cell->info().facetSurfaces[j]*fluidSurfRatio;
+			/// handle fictious vertex since we can get the projected surface easily here
+			if (cell->vertex(j)->info().isFictious) {
+				Real projSurf=abs(Surfk[boundary(cell->vertex(j)->info().id()).coordinate]);
+				tempVect=-projSurf*boundary(cell->vertex(j)->info().id()).normal;
+				cell->vertex(j)->info().forces = cell->vertex(j)->info().forces+tempVect*cell->info().p();
+				//define the cached value for later use with cache*p
+				cell->info().unitForceVectors[j]=cell->info().unitForceVectors[j]+ tempVect;
+			}
+			/// Apply weighted forces f_k=sqRad_k/sumSqRad*f
+			Vecteur Facet_Unit_Force = -fluidSurfk*cell->info().solidSurfaces[j][3];
+			Vecteur Facet_Force = cell->info().p()*Facet_Unit_Force;
+			for (int y=0; y<3;y++) {
+				cell->vertex(facetVertices[j][y])->info().forces = cell->vertex(facetVertices[j][y])->info().forces + Facet_Force*cell->info().solidSurfaces[j][y];
+				//add to cached value
+				cell->info().unitForceVectors[facetVertices[j][y]]=cell->info().unitForceVectors[facetVertices[j][y]]+Facet_Unit_Force*cell->info().solidSurfaces[j][y];
+				if (!cell->vertex(facetVertices[j][y])->info().isFictious) {
+					cell->vertex(facetVertices[j][y])->info().forces = cell->vertex(facetVertices[j][y])->info().forces -facetNormal*cell->info().p()*crossSections[j][y];
+					//add to cached value
+					cell->info().unitForceVectors[facetVertices[j][y]]=cell->info().unitForceVectors[facetVertices[j][y]]-facetNormal*crossSections[j][y];
+				}
+			}
+		
+		}
+	}
+	else //use cached values
+		for (Finite_cells_iterator cell = Tri.finite_cells_begin(); cell != cell_end; cell++)
+			for (int yy=0;yy<4;yy++) cell->vertex(yy)->info().forces = cell->vertex(yy)->info().forces + cell->info().unitForceVectors[yy]*cell->info().p();
+	noCache=false;//cache should always be defined after execution of this function
+	
+// 	cout << "Facet cached scheme" <<endl;
+// 	Vecteur TotalForce = nullVect;
+// 	for (Finite_vertices_iterator v = Tri.finite_vertices_begin(); v != Tri.finite_vertices_end(); ++v)
+// 	{
+// 		if (!v->info().isFictious) {
+// 			TotalForce = TotalForce + v->info().forces;
+// 			if (DEBUG_OUT) cout << "real_id = " << v->info().id() << " force = " << v->info().forces << endl;
+// 		} else {
+// 			if (boundary(v->info().id()).flowCondition==1) TotalForce = TotalForce + v->info().forces;
+// 			if (DEBUG_OUT) cout << "fictious_id = " << v->info().id() << " force = " << v->info().forces << endl;
+// 		}
+// 	}
+// 	cout << "TotalForce = "<< TotalForce << endl;
 }
 
 void FlowBoundingSphere::ComputeTetrahedralForces()
@@ -543,6 +746,7 @@
 
 void FlowBoundingSphere::Compute_Forces()
 {
+	
         RTriangulation& Tri = T[currentTes].Triangulation();
         Finite_cells_iterator cell_end = Tri.finite_cells_end();
         Vecteur nullVect(0,0,0);
@@ -575,8 +779,7 @@
                         V_fict = 0;
                         single_external_force = false, double_external_force=false, triple_external_force=false;
 
-//                         if (!cell->info().isInside) {
-			if (cell->info().fictious()!=0){
+                        if (!cell->info().isInside) {
                                 for (int i=0;i<4;i++) {
                                         if (cell->vertex(i)->info().isFictious) {
                                                 V_fict+=1;
@@ -585,11 +788,16 @@
                         }
 
                         switch (V_fict) {
-                        case(1) : single_external_force=true;break;
-                        case(2) : double_external_force=true;break;
-                        case(3) : triple_external_force=true;break;}
+                        case(1) : single_external_force=true;
+                                break;
+                        case(2) : double_external_force=true;
+                                break;
+                        case(3) : triple_external_force=true;
+                                break;
+                        }
 
-                        p1 = cell->info(); Cell_Force = nullVect, Vertex_force = nullVect;
+                        p1 = cell->info();
+                        Cell_Force = nullVect, Vertex_force = nullVect;
 
                         for (int j=0; j<4; j++) {
                                 neighbour_cell = cell->neighbor(j);
@@ -803,32 +1011,30 @@
                 if (!v->info().isFictious) {
 //                         if (DEBUG_OUT) cout << "id = " << v->info().id() << " force = " << v->info().forces << endl;
                         TotalForce = TotalForce + v->info().forces;
+			if (DEBUG_OUT) cout << "real_id = " << v->info().id() << " force = " << v->info().forces << endl;
                 } else {
                         if (boundary(v->info().id()).flowCondition==1) TotalForce = TotalForce + v->info().forces;
-                        if (DEBUG_OUT) cout << "fictious_id = " << v->info().id() << " force = " << v->info().forces << endl;
-                }
+                        if (DEBUG_OUT) cout << "fictious_id = " << v->info().id() << " force = " << v->info().forces << endl;}
         }
+	clock.top("tri/tess force calculation");
         cout << "TotalForce = "<< TotalForce << endl;
-        clock.top("tri/tess force calculation");
+
         //reset forces
         for (Finite_vertices_iterator v = Tri.finite_vertices_begin(); v != Tri.finite_vertices_end(); ++v) {
                 v->info().forces=nullVect;
         }
         ComputeTetrahedralForces();
-//  if (DEBUG_OUT) {
-        cout << "tetrahedral scheme" <<endl;
-        TotalForce = nullVect;
-        for (Finite_vertices_iterator v = Tri.finite_vertices_begin(); v != Tri.finite_vertices_end(); ++v) {
-                if (!v->info().isFictious) {
-//                         if (DEBUG_OUT) cout << "id = " << v->info().id() << " force = " << v->info().forces << endl;
-                        TotalForce = TotalForce + v->info().forces;
-                } else {
-                        if (boundary(v->info().id()).flowCondition==1) TotalForce = TotalForce + v->info().forces;
-                        if (DEBUG_OUT) cout << "fictious_id = " << v->info().id() << " force = " << v->info().forces << endl;
-                }
-        }
-        clock.top("facets force calculation");
-        cout << "TotalForce = "<< TotalForce << endl;
+        clock.top("tetrahedral force calculation");
+        ComputeFacetForces();
+	clock.top("facets force calculation");
+	cerr<<"FIXME : we are computing forces 20x"<<endl;
+	for (int l=0;l<20;l++){//here, cash is ignored
+		noCache=true;
+		ComputeFacetForcesWithCache();}
+	clock.top("facets force without cache (x20)");
+	for (int l=0;l<20;l++) ComputeFacetForcesWithCache();//here we use cached values from the previous loop
+	clock.top("facets force with cache (x20)");
+	
 }
 
 double FlowBoundingSphere::surface_external_triple_fictious(Cell_handle cell, Boundary b)
@@ -1191,7 +1397,7 @@
         int fictious_vertex=0, real_vertex=0; //counts total fictious/real vertices
 
         double Ssolid1=0, Ssolid1n=0, Ssolid2=0, Ssolid2n=0, Ssolid3=0, Ssolid3n=0, Ssolid=0;
-	//solid portions within a pore, for cell () and neighbour_cell (+n). Ssolid total solid surface
+        //solid portions within a pore, for cell () and neighbour_cell (+n). Ssolid total solid surface
 
         //bool fictious_solid = false;
 
@@ -1223,8 +1429,6 @@
                         real_vertex+=1;
                 }
         }
-
-
         if (fictious_vertex==2) {
                 double A [3], B[3], C[3];
 
@@ -1269,68 +1473,86 @@
                         cell->info().solidSurfaces[j][facetF2]=Ssolid3;
                 } else cell->info().solidSurfaces[j][facetF2]=0;
         }
-
-        else {
-                if (fictious_vertex==1) {
-                        SV1 = cell->vertex(F1);
-                        SV2 = cell->vertex(Re1);
-                        SV3 = cell->vertex(Re2);
-                        Vpore = volume_single_fictious_pore(SV1, SV2, SV3, p1,p2, cell->info().facetSurfaces[j]);
-                        Boundary &bi1 = boundary(SV1->info().id());
-                        if (bi1.flowCondition && !SLIP_ON_LATERALS) {
-                                Ssolid1 = abs(0.5*CGAL::cross_product(p1-p2, SV2->point()-SV3->point())[bi1.coordinate]);
-                                cell->info().solidSurfaces[j][facetF1]=Ssolid1;
-                        }
-                        Ssolid2 = fast_spherical_triangle_area(SV2->point(),SV1->point(),p1, p2);
-                        Ssolid2n = fast_spherical_triangle_area(SV2->point(),SV3->point(),p1, p2);
-                        cell->info().solidSurfaces[j][facetRe1]=Ssolid2+Ssolid2n;
-                        Ssolid3 = fast_spherical_triangle_area(SV3->point(),SV2->point(),p1, p2);
-                        Ssolid3n = fast_spherical_triangle_area(SV3->point(),SV1->point(),p1, p2);
-                        cell->info().solidSurfaces[j][facetRe2]=Ssolid3+Ssolid3n;
-                } else {
-                        SV1 = W[0];
-                        SV2 = W[1];
-                        SV3 = W[2];
-                        cell->info().facetSurfaces[j]=0.5*CGAL::cross_product(SV1->point()-SV3->point(),SV2->point()-SV3->point());
-                        if (cell->info().facetSurfaces[j]*(p2-p1) > 0) cell->info().facetSurfaces[j] = -1.0*cell->info().facetSurfaces[j];
-                        Vtot = abs(ONE_THIRD*cell->info().facetSurfaces[j]*(p1-p2));
-
-                        Vsolid1=0;
-                        Vsolid2=0;
-                        for (int i=0;i<3;i++) {
-                                Vsolid1 += spherical_triangle_volume(v[permut3[i][0]],v[permut3[i][1]],p1,p2);
-                                Vsolid2 += spherical_triangle_volume(v[permut3[i][0]],v[permut3[i][2]],p1,p2);
-                        }
-                        Vsolid = Vsolid1 + Vsolid2;
-                        Vsolid_tot += Vsolid;
-                        Vtotalissimo += Vtot;
-
-                        Vpore = Vtot - Vsolid;
-                        Vporale += Vpore;
-
-                        Ssolid1 = fast_spherical_triangle_area(SV1->point(), SV2->point(), p1, p2);
-                        Ssolid1n = fast_spherical_triangle_area(SV1->point(), SV3->point(), p1, p2);
-                        cell->info().solidSurfaces[j][0]=Ssolid1+Ssolid1n;
-                        Ssolid2 = fast_spherical_triangle_area(SV2->point(),SV1->point(),p1, p2);
-                        Ssolid2n = fast_spherical_triangle_area(SV2->point(),SV3->point(),p1, p2);
-                        cell->info().solidSurfaces[j][1]=Ssolid2+Ssolid2n;
-                        Ssolid3 = fast_spherical_triangle_area(SV3->point(),SV2->point(),p1, p2);
-                        Ssolid3n = fast_spherical_triangle_area(SV3->point(),SV1->point(),p1, p2);
-                        cell->info().solidSurfaces[j][2]=Ssolid3+Ssolid3n;
-                }
-        }
-        Ssolid = Ssolid1+Ssolid1n+Ssolid2+Ssolid2n+Ssolid3+Ssolid3n;
-        cell->info().solidSurfaces[j][3]=1.0/Ssolid;
-        Ssolid_tot += Ssolid;
-
-        //handle symmetry (tested ok)
-        if (/*SLIP_ON_LATERALS &&*/ fictious_vertex>0) {
-                //! Include a multiplier so that permeability will be K/2 or K/4 in symmetry conditions
-                Real mult= fictious_vertex==1 ? multSym1 : multSym2;
-                return Vpore/Ssolid*mult;
-        }
+        else if (fictious_vertex==1) {
+                SV1 = cell->vertex(F1);
+                SV2 = cell->vertex(Re1);
+                SV3 = cell->vertex(Re2);
+                Vpore = volume_single_fictious_pore(SV1, SV2, SV3, p1,p2, cell->info().facetSurfaces[j]);
+                Boundary &bi1 = boundary(SV1->info().id());
+                if (bi1.flowCondition && !SLIP_ON_LATERALS) {
+                        Ssolid1 = abs(0.5*CGAL::cross_product(p1-p2, SV2->point()-SV3->point())[bi1.coordinate]);
+                        cell->info().solidSurfaces[j][facetF1]=Ssolid1;
+                }
+                Ssolid2 = fast_spherical_triangle_area(SV2->point(),SV1->point(),p1, p2);
+                Ssolid2n = fast_spherical_triangle_area(SV2->point(),SV3->point(),p1, p2);
+                cell->info().solidSurfaces[j][facetRe1]=Ssolid2+Ssolid2n;
+                Ssolid3 = fast_spherical_triangle_area(SV3->point(),SV2->point(),p1, p2);
+                Ssolid3n = fast_spherical_triangle_area(SV3->point(),SV1->point(),p1, p2);
+                cell->info().solidSurfaces[j][facetRe2]=Ssolid3+Ssolid3n;
+        } else {//fictious_vertex==0
+                SV1 = W[0];
+                SV2 = W[1];
+                SV3 = W[2];
+                cell->info().facetSurfaces[j]=0.5*CGAL::cross_product(SV1->point()-SV3->point(),SV2->point()-SV3->point());
+                if (cell->info().facetSurfaces[j]*(p2-p1) > 0) cell->info().facetSurfaces[j] = -1.0*cell->info().facetSurfaces[j];
+                Vtot = abs(ONE_THIRD*cell->info().facetSurfaces[j]*(p1-p2));
+
+
+                Vsolid1=0;
+                Vsolid2=0;
+                for (int i=0;i<3;i++) {
+                        Vsolid1 += spherical_triangle_volume(v[permut3[i][0]],v[permut3[i][1]],p1,p2);
+                        Vsolid2 += spherical_triangle_volume(v[permut3[i][0]],v[permut3[i][2]],p1,p2);
+                }
+                Vsolid = Vsolid1 + Vsolid2;
+                Vsolid_tot += Vsolid;
+                Vtotalissimo += Vtot;
+
+                Vpore = Vtot - Vsolid;
+                Vporale += Vpore;
+
+                Ssolid1 = fast_spherical_triangle_area(SV1->point(), SV2->point(), p1, p2);
+                Ssolid1n = fast_spherical_triangle_area(SV1->point(), SV3->point(), p1, p2);
+                cell->info().solidSurfaces[j][0]=Ssolid1+Ssolid1n;
+                Ssolid2 = fast_spherical_triangle_area(SV2->point(),SV1->point(),p1, p2);
+                Ssolid2n = fast_spherical_triangle_area(SV2->point(),SV3->point(),p1, p2);
+                cell->info().solidSurfaces[j][1]=Ssolid2+Ssolid2n;
+                Ssolid3 = fast_spherical_triangle_area(SV3->point(),SV2->point(),p1, p2);
+                Ssolid3n = fast_spherical_triangle_area(SV3->point(),SV1->point(),p1, p2);
+                cell->info().solidSurfaces[j][2]=Ssolid3+Ssolid3n;
+        }
+
+        //Compute and store the area of sphere-facet intersections for later use
+#ifdef USE_FAST_MATH
+        //FIXME : code not compiling,, do the same as in "else"
+        assert((v[permut3[jj][1]]-v[permut3[jj][0]])*(v[permut3[jj][2]]-v[permut3[jj][0]])>=0 && (v[permut3[jj][1]]-v[permut3[jj][0]])*(v[permut3[jj][2]]-v[permut3[jj][0]])<=1);
+        for (int jj=0;jj<3;jj++)
+                cell->info().facetSphereCrossSections[j][jj]=0.5*v[jj].weight()*Wm3::FastInvCos1((v[permut3[jj][1]]-v[permut3[jj][0]])*(v[permut3[jj][2]]-v[permut3[jj][0]]));
+#else
+        cell->info().facetSphereCrossSections[j]=Vecteur(
+                                W[0]->info().isFictious ? 0 : 0.5*v[0].weight()*acos((v[1]-v[0])*(v[2]-v[0])/sqrt((v[1]-v[0]).squared_length()*(v[2]-v[0]).squared_length())),
+                                W[1]->info().isFictious ? 0 : 0.5*v[1].weight()*acos((v[0]-v[1])*(v[2]-v[1])/sqrt((v[1]-v[0]).squared_length()*(v[2]-v[1]).squared_length())),
+                                W[2]->info().isFictious ? 0 : 0.5*v[2].weight()*acos((v[0]-v[2])*(v[1]-v[2])/sqrt((v[1]-v[2]).squared_length()*(v[2]-v[0]).squared_length())));
+#endif
+#ifdef FACET_BASED_FORCES
+        //FIXME : cannot be done here because we are still comparing the different methods
+// 			if (FACET_BASED_FORCES) cell->info().facetSurfaces[j]=cell->info().facetSurfaces[j]*((facetSurfaces[j].length()-facetSphereCrossSections[j][0]-facetSphereCrossSections[j][1]-facetSphereCrossSections[j][2])/facetSurfaces[j].length());
+#endif
+//         if (DEBUG_OUT) std::cerr << "total facet surface "<< cell->info().facetSurfaces[j] << " with solid sectors : " << cell->info().facetSphereCrossSections[j][0] << " " << cell->info().facetSphereCrossSections[j][1] << " " << cell->info().facetSphereCrossSections[j][2] << " difference "<<sqrt(cell->info().facetSurfaces[j].squared_length())-cell->info().facetSphereCrossSections[j][0]-cell->info().facetSphereCrossSections[j][2]-cell->info().facetSphereCrossSections[j][1]<<endl;
+
+Ssolid = Ssolid1+Ssolid1n+Ssolid2+Ssolid2n+Ssolid3+Ssolid3n;
+cell->info().solidSurfaces[j][3]=1.0/Ssolid;
+Ssolid_tot += Ssolid;
+
+//handle symmetry (tested ok)
+if (/*SLIP_ON_LATERALS &&*/ fictious_vertex>0)
+{
+        //! Include a multiplier so that permeability will be K/2 or K/4 in symmetry conditions
+        Real mult= fictious_vertex==1 ? multSym1 : multSym2;
+        return Vpore/Ssolid*mult;
+}
 //  cout << "Vpore " << Vpore << ", Ssolid "<<Ssolid<<endl;
-        return Vpore/Ssolid;
+return Vpore/Ssolid;
 }
 
 double FlowBoundingSphere::dotProduct(Vecteur x, Vecteur y)
@@ -1604,41 +1826,67 @@
   double Q2=0, Q1=0;
   int cellQ1=0, cellQ2=0;
   double p_out_max=0, p_out_min=100000, p_in_max=0, p_in_min=100000,p_out_moy=0, p_in_moy=0;
-  bool first=false;
-  Finite_cells_iterator cell_end = Tri.finite_cells_end();
-  
-	for (int bound=0; bound<6;bound++) {
-                int& id = *boundsIds[bound];
-                Boundary& bi = boundary(id);
-                if (!bi.flowCondition) {
-                        Tesselation::Vector_Cell tmp_cells;
-                        tmp_cells.resize(1000);
-                        Tesselation::VCell_iterator cells_it = tmp_cells.begin();
-                        Tesselation::VCell_iterator cells_end = Tri.incident_cells(T[currentTes].vertexHandles[id],cells_it);
-                        for (Tesselation::VCell_iterator it = tmp_cells.begin(); it != cells_end; it++)
-			{
-			   Cell_handle& cell = *it;
-			   if(!first){for (int j2=0; j2<4; j2++) {if (!cell->neighbor(j2)->info().Pcondition){
-				Q1 = Q1 + (cell->neighbor(j2)->info().k_norm())[Tri.mirror_index(cell, j2)]* (cell->neighbor(j2)->info().p()-cell->info().p());
-				cellQ1+=1;
-				p_out_max = std::max(cell->neighbor(j2)->info().p(), p_out_max);
-				p_out_min = std::min(cell->neighbor(j2)->info().p(), p_out_min);
-				p_out_moy += cell->neighbor(j2)->info().p();}}}
-			   else {for (int j2=0; j2<4; j2++) {if (!cell->neighbor(j2)->info().Pcondition){
-				Q2 = Q2 + (cell->neighbor(j2)->info().k_norm())[Tri.mirror_index(cell, j2)]* (cell->info().p()-cell->neighbor(j2)->info().p());
-				cellQ2+=1;
-				p_in_max = std::max(cell->neighbor(j2)->info().p(), p_in_max);
-				p_in_min = std::min(cell->neighbor(j2)->info().p(), p_in_min);
-				p_in_moy += cell->neighbor(j2)->info().p();}}}
-
-			}first=true;}
-	}
-	cout << "the maximum superior pressure is = " << p_in_max << " the min is = " << p_in_min << endl;
-	cout << "the maximum inferior pressure is = " << p_out_max << " the min is = " << p_out_min << endl;
-	cout << "superior average pressure is " << p_in_moy/cellQ2 << endl;
-        cout << "inferior average pressure is " << p_out_moy/cellQ1 << endl;
-        cout << "celle comunicanti in basso = " << cellQ1 << endl;
-        cout << "celle comunicanti in alto = " << cellQ2 << endl;
+//   bool first=false;
+  
+  Tesselation::Vector_Cell tmp_cells;
+  tmp_cells.resize(1000);
+  Tesselation::VCell_iterator cells_it = tmp_cells.begin();
+  
+  Tesselation::VCell_iterator cell_up_end = Tri.incident_cells(T[currentTes].vertexHandles[y_max_id],cells_it);
+  for (Tesselation::VCell_iterator it = tmp_cells.begin(); it != cell_up_end; it++)
+  {
+    Cell_handle& cell = *it;{for (int j2=0; j2<4; j2++) {if (!cell->neighbor(j2)->info().Pcondition){
+    Q1 = Q1 + (cell->neighbor(j2)->info().k_norm())[Tri.mirror_index(cell, j2)]* (cell->neighbor(j2)->info().p()-cell->info().p());
+    cellQ1+=1;
+    p_out_max = std::max(cell->neighbor(j2)->info().p(), p_out_max);
+    p_out_min = std::min(cell->neighbor(j2)->info().p(), p_out_min);
+    p_out_moy += cell->neighbor(j2)->info().p();}
+  }}}
+  
+  Tesselation::VCell_iterator cell_down_end = Tri.incident_cells(T[currentTes].vertexHandles[y_min_id],cells_it);
+  for (Tesselation::VCell_iterator it = tmp_cells.begin(); it != cell_down_end; it++)
+  {
+    Cell_handle& cell = *it;{for (int j2=0; j2<4; j2++) {if (!cell->neighbor(j2)->info().Pcondition){
+    Q2 = Q2 + (cell->neighbor(j2)->info().k_norm())[Tri.mirror_index(cell, j2)]* (cell->info().p()-cell->neighbor(j2)->info().p());
+    cellQ2+=1;
+    p_in_max = std::max(cell->neighbor(j2)->info().p(), p_in_max);
+    p_in_min = std::min(cell->neighbor(j2)->info().p(), p_in_min);
+    p_in_moy += cell->neighbor(j2)->info().p();}
+  }}}
+  
+  
+// 	for (int bound=0; bound<6;bound++) {
+//                 int& id = *boundsIds[bound];
+//                 Boundary& bi = boundary(id);
+//                 if (!bi.flowCondition) {
+//                         Tesselation::Vector_Cell tmp_cells;
+//                         tmp_cells.resize(1000);
+//                         Tesselation::VCell_iterator cells_it = tmp_cells.begin();
+//                         Tesselation::VCell_iterator cells_end = Tri.incident_cells(T[currentTes].vertexHandles[id],cells_it);
+//                         for (Tesselation::VCell_iterator it = tmp_cells.begin(); it != cells_end; it++)
+// 			{
+// 			   Cell_handle& cell = *it;
+// 			   if(!first){for (int j2=0; j2<4; j2++) {if (!cell->neighbor(j2)->info().Pcondition){
+// 				Q1 = Q1 + (cell->neighbor(j2)->info().k_norm())[Tri.mirror_index(cell, j2)]* (cell->neighbor(j2)->info().p()-cell->info().p());
+// 				cellQ1+=1;
+// 				p_out_max = std::max(cell->neighbor(j2)->info().p(), p_out_max);
+// 				p_out_min = std::min(cell->neighbor(j2)->info().p(), p_out_min);
+// 				p_out_moy += cell->neighbor(j2)->info().p();}}}
+// 			   else {for (int j2=0; j2<4; j2++) {if (!cell->neighbor(j2)->info().Pcondition){
+// 				Q2 = Q2 + (cell->neighbor(j2)->info().k_norm())[Tri.mirror_index(cell, j2)]* (cell->info().p()-cell->neighbor(j2)->info().p());
+// 				cellQ2+=1;
+// 				p_in_max = std::max(cell->neighbor(j2)->info().p(), p_in_max);
+// 				p_in_min = std::min(cell->neighbor(j2)->info().p(), p_in_min);
+// 				p_in_moy += cell->neighbor(j2)->info().p();}}}
+// 
+// 			}first=true;}
+// 	}
+	cout << "the maximum superior pressure is = " << p_out_max << " the min is = " << p_in_min << endl;
+	cout << "the maximum inferior pressure is = " << p_in_max << " the min is = " << p_out_min << endl;
+	cout << "superior average pressure is " << p_out_moy/cellQ1 << endl;
+        cout << "inferior average pressure is " << p_in_moy/cellQ2 << endl;
+        cout << "celle comunicanti in basso = " << cellQ2 << endl;
+        cout << "celle comunicanti in alto = " << cellQ1 << endl;
 
         double density = 1;
         double viscosity = 1;
@@ -1697,7 +1945,7 @@
 	
         vtkfile.begin_cells();
         for (Finite_cells_iterator cell = T.finite_cells_begin(); cell != T.finite_cells_end(); ++cell) {
-		if (cell->info().fictious()==0){vtkfile.write_cell(cell->vertex(0)->info().id()-6, cell->vertex(1)->info().id()-6, cell->vertex(2)->info().id()-6, cell->vertex(3)->info().id()-6);}
+		if (cell->info().fictious()==0){vtkfile.write_cell(cell->vertex(0)->info().id()-id_offset, cell->vertex(1)->info().id()-id_offset, cell->vertex(2)->info().id()-id_offset, cell->vertex(3)->info().id()-id_offset);}
         }
         vtkfile.end_cells();
 	
@@ -1727,7 +1975,7 @@
 
         for (Finite_cells_iterator cell = Tri.finite_cells_begin(); cell != cell_end; cell++) {
 //   if ( !cell->info().isFictious )
-                if (cell->info().fictious()!=0) {
+                if (cell->info().fictious()==0) {
                         double p [3] = {0,0,0};
 
                         for (int j2=0; j2!=4; j2++) {
@@ -1738,8 +1986,8 @@
                         }
 
                         double pressure =  cell->info().p();
-                        double rad = 0.05;
-
+                        double rad = 0.00025;
+			
                         file << "  <body>" << endl;
                         file << "   <SPHER r=\""  <<  rad << "\">" << endl;
                         file << "    <position x=\""  <<  p[0] << "\" y=\"" << p[1] << "\" z=\"" << p[2] << "\"/>" << endl;

=== modified file 'lib/triangulation/FlowBoundingSphere.h'
--- lib/triangulation/FlowBoundingSphere.h	2010-06-17 12:30:19 +0000
+++ lib/triangulation/FlowBoundingSphere.h	2010-07-08 09:11:42 +0000
@@ -1,3 +1,10 @@
+/*************************************************************************
+*  Copyright (C) 2010 by Emanuele Catalano <catalano@xxxxxxxxxxxxxxx>    *
+*                                                                        *
+*  This program is free software; it is licensed under the terms of the  *
+*  GNU General Public License v2 or later. See file LICENSE for details. *
+*************************************************************************/
+
 #ifndef _FLOWBOUNDINGSPHERE_H
 #define _FLOWBOUNDINGSPHERE_H
 
@@ -41,6 +48,8 @@
 		double RELAX;
 		double ks; //Hydraulic Conductivity
 		bool meanK_LIMIT, meanK_STAT, distance_correction;
+		bool noCache;//flag for checking if cached values cell->unitForceVectors have been defined
+		bool computeAllCells;//exececute computeHydraulicRadius for all facets and all spheres (double cpu time but needed for now in order to define crossSections correctly)
 		double K_opt_factor;
 		int Iterations;
 		
@@ -88,7 +97,9 @@
 		void Initialize_pressures ( double P_zero );
 		/// Define forces using the same averaging volumes as for permeability
 		void ComputeTetrahedralForces();
+		/// Define forces spliting drag and buoyancy terms
 		void ComputeFacetForces();
+		void ComputeFacetForcesWithCache();
 		void save_vtk_file ( RTriangulation &T );
 		void MGPost ( RTriangulation& Tri );
 #ifdef XVIEW
@@ -141,6 +152,11 @@
 		double volume_double_fictious_pore ( Vertex_handle SV1, Vertex_handle SV2, Vertex_handle SV3, Point PV1 );
 		//Fast version, assign surface of facet for future forces calculations (pointing from PV2 to PV1)
 		double volume_double_fictious_pore (Vertex_handle SV1, Vertex_handle SV2, Vertex_handle SV3, Point& PV1, Point& PV2, Vecteur& facetSurface);
+		
+		int Average_Cell_Velocity(int id_sphere, RTriangulation& Tri);
+		void vtk_average_cell_velocity(RTriangulation &T, int id_sphere, int num_cells);
+		void ApplySinusoidalPressure(RTriangulation& Tri, double Pressure, double load_intervals);
+
 };
 
 } //namespace CGT

=== modified file 'lib/triangulation/def_types.h'
--- lib/triangulation/def_types.h	2010-06-25 10:15:51 +0000
+++ lib/triangulation/def_types.h	2010-07-08 09:11:42 +0000
@@ -14,7 +14,7 @@
 
 #include <boost/static_assert.hpp>
 
-#define FLOW_ENGINE
+//#define FLOW_ENGINE
 
 
 namespace CGT{
@@ -57,6 +57,8 @@
 	
 	// Surface vectors of facets, pointing from outside toward inside the cell
 	std::vector<Vecteur> facetSurfaces;
+	// Reflects the geometrical property of the cell, so that the force by cell fluid on grain "i" is pressure*unitForceVectors[i]
+	std::vector<Vecteur> unitForceVectors;
 	// Store the area of triangle-sphere intersections for each facet (used in forces definition)
 	std::vector<Vecteur> facetSphereCrossSections;
 	std::vector<Vecteur> cell_force;
@@ -73,6 +75,7 @@
 		cell_force.resize(4);
 		facetSurfaces.resize(4);
 		facetSphereCrossSections.resize(4);
+		unitForceVectors.resize(4);
 		for (int k=0; k<4;k++) for (int l=0; l<3;l++) solidSurfaces[k][l]=0;
 		RayHydr.resize(4, 0);
 		isInside = false;

=== modified file 'pkg/dem/Engine/PartialEngine/FlowEngine.cpp'
--- pkg/dem/Engine/PartialEngine/FlowEngine.cpp	2010-06-17 12:30:19 +0000
+++ pkg/dem/Engine/PartialEngine/FlowEngine.cpp	2010-07-08 09:11:42 +0000
@@ -51,8 +51,6 @@
 
 				timingDeltas->checkpoint("Triangulating");
 				
-				cout << "new iteration" << endl;
-				
 				UpdateVolumes ( );
 			
 				timingDeltas->checkpoint("Update_Volumes");
@@ -72,7 +70,7 @@
 				
 				if (save_vtk) flow->save_vtk_file(flow->T[flow->currentTes].Triangulation());
 			
-// 				flow->MGPost(flow->T[flow->currentTes].Triangulation());
+ 				flow->MGPost(flow->T[flow->currentTes].Triangulation());
 
 				flow->ComputeFacetForces();
 				
@@ -81,12 +79,21 @@
 			///End Compute flow and forces
 
 				CGT::Finite_vertices_iterator vertices_end = flow->T[flow->currentTes].Triangulation().finite_vertices_end ();
-				Vector3r f;int id;
+				Vector3r f; int id;
 				for ( CGT::Finite_vertices_iterator V_it = flow->T[flow->currentTes].Triangulation().finite_vertices_begin (); V_it !=  vertices_end; V_it++ )
 				{
 					id = V_it->info().id();
+					
+// 					scene->forces.sync();
+// 					const Vector3r& fbef = scene->forces.getForce(id);
+// 					if (id==id_sphere) cout << "force before = " << fbef << endl;
+// 					if (id==id_sphere) cout << "fluid force = " << V_it->info().forces << endl;
 					for ( int y=0;y<3;y++ ) f[y] = ( V_it->info().forces ) [y];
 					scene->forces.addForce ( id, f );
+					
+// 					scene->forces.sync();
+// 					const Vector3r& faft = scene->forces.getForce(id);
+// 					if (id==id_sphere) cout << "force after = " << faft << endl;
 				//scene->forces.addTorque(id,t);
 				}
 				
@@ -111,16 +118,18 @@
 				std::ofstream settle ("settle.txt", std::ios::app);
 				settle << j << " " << time << " " << currentStrain << endl;
 				
-				if ( Omega::instance().getCurrentIteration() % PermuteInterval == 0 )
+				first=false;
+				
+				if ( Omega::instance().getCurrentIteration()>1 && Omega::instance().getCurrentIteration() % PermuteInterval == 0 )
 				{ Update_Triangulation = true; }
 				
 				if ( Update_Triangulation ) { Build_Triangulation( );}
 				
 				timingDeltas->checkpoint("Storing Max Pressure");
-
-				first=false;
-				
-				cout << "end iteration" << endl;
+				
+// 				int numero = flow->Average_Cell_Velocity(id_sphere, flow->T[flow->currentTes].Triangulation());
+				
+// 				flow->vtk_average_cell_velocity(flow->T[flow->currentTes].Triangulation(), id_sphere, numero);
 		}
 	}
 }
@@ -142,20 +151,6 @@
 	flow->boundary ( flow->z_min_id ).value=Pressure_BACK_Boundary;
 }
 
-void FlowEngine::Oedometer_Boundary_Conditions()
-{
-	flow->boundary ( flow->y_min_id ).flowCondition=0;
-	flow->boundary ( flow->y_max_id ).flowCondition=0;
-	flow->boundary ( flow->y_min_id ).value=0;
-	flow->boundary ( flow->y_max_id ).value=0;
-	
-	triaxialCompressionEngine->wall_left_activated=0;
-	triaxialCompressionEngine->wall_right_activated=0;
-	triaxialCompressionEngine->wall_front_activated=0;
-	triaxialCompressionEngine->wall_back_activated=0;
-	triaxialCompressionEngine->wall_top_activated=1;
-	triaxialCompressionEngine->wall_bottom_activated=1;
-}
 
 void FlowEngine::Build_Triangulation ()
 {
@@ -180,11 +175,12 @@
 	flow->T[flow->currentTes].Clear();
 	flow->T[flow->currentTes].max_id=-1;
 	flow->x_min = 1000.0, flow->x_max = -10000.0, flow->y_min = 1000.0, flow->y_max = -10000.0, flow->z_min = 1000.0, flow->z_max = -10000.0;
-
-	AddBoundary ( );
+AddBoundary ( );
 	Triangulate ( );
 	
 	
+	
+	
 	cout << endl << "Tesselating------" << endl << endl;
 	flow->T[flow->currentTes].Compute();
 	
@@ -202,6 +198,8 @@
 		if (compute_K) {flow->TOLERANCE=1e-06; K = flow->Sample_Permeability ( flow->T[flow->currentTes].Triangulation(), flow->x_min, flow->x_max, flow->y_min, flow->y_max, flow->z_min, flow->z_max, flow->key );}
 		BoundaryConditions();
 		flow->Initialize_pressures( P_zero );
+// 		flow->ApplySinusoidalPressure(flow->T[flow->currentTes].Triangulation(), Sinus_Pressure, 5);
+		BoundaryConditions();
 		flow->TOLERANCE=Tolerance;
 		flow->RELAX=Relax;
 	}
@@ -220,6 +218,35 @@
 
 void FlowEngine::AddBoundary ()
 {
+  
+  shared_ptr<Sphere> sph ( new Sphere );
+
+	int Sph_Index = sph->getClassIndexStatic();
+	int contator = 0;
+	
+	FOREACH ( const shared_ptr<Body>& b, *scene->bodies )
+	{
+		if ( !b ) continue;
+		if ( b->shape->getClassIndex() ==  Sph_Index )
+		{
+		  Sphere* s=YADE_CAST<Sphere*> ( b->shape.get() );
+			const body_id_t& id = b->getId();
+			Real rad = s->radius;
+			Real x = b->state->pos[0];
+			Real y = b->state->pos[1];
+			Real z = b->state->pos[2];
+			
+			flow->x_min = min ( flow->x_min, x-rad);
+			flow->x_max = max ( flow->x_max, x+rad);
+			flow->y_min = min ( flow->y_min, y-rad);
+			flow->y_max = max ( flow->y_max, y+rad);
+			flow->z_min = min ( flow->z_min, z-rad);
+			flow->z_max = max ( flow->z_max, z+rad);
+			
+			contator+=1;
+		}
+	}
+	
 	cout << "Adding Boundary------" << endl;
 
 	shared_ptr<Box> bx ( new Box );
@@ -236,16 +263,18 @@
 			for ( int h=0;h<3;h++ ) {center[h] = b->state->pos[h]; Extent[h] = w->extents[h];}
 			wall_thickness = min(min(Extent[0],Extent[1]),Extent[2]);
 
-			flow->x_min = min ( flow->x_min, center[0]+wall_thickness);
-			flow->x_max = max ( flow->x_max, center[0]-wall_thickness);
-			flow->y_min = min ( flow->y_min, center[1]+wall_thickness);
-			flow->y_max = max ( flow->y_max, center[1]-wall_thickness);
-			flow->z_min = min ( flow->z_min, center[2]+wall_thickness);
-			flow->z_max = max ( flow->z_max, center[2]-wall_thickness);
+// 			flow->x_min = min ( flow->x_min, center[0]+wall_thickness);
+// 			flow->x_max = max ( flow->x_max, center[0]-wall_thickness);
+// 			flow->y_min = min ( flow->y_min, center[1]+wall_thickness);
+// 			flow->y_max = max ( flow->y_max, center[1]-wall_thickness);
+// 			flow->z_min = min ( flow->z_min, center[2]+wall_thickness);
+// 			flow->z_max = max ( flow->z_max, center[2]-wall_thickness);
 		}
 	}
 	
-	flow->id_offset = flow->T[flow->currentTes].max_id+1;
+	id_offset = flow->T[flow->currentTes].max_id+1;
+	
+	flow->id_offset = id_offset;
 
 	flow->y_min_id=triaxialCompressionEngine->wall_bottom_id;
 	flow->y_max_id=triaxialCompressionEngine->wall_top_id;
@@ -278,6 +307,13 @@
 			
 			flow->T[flow->currentTes].insert(x, y, z, rad, id);
 			
+// 			flow->x_min = min ( flow->x_min, x-rad);
+// 			flow->x_max = max ( flow->x_max, x+rad);
+// 			flow->y_min = min ( flow->y_min, y-rad);
+// 			flow->y_max = max ( flow->y_max, y+rad);
+// 			flow->z_min = min ( flow->z_min, z-rad);
+// 			flow->z_max = max ( flow->z_max, z+rad);
+			
 			contator+=1;
 		}
 	}

=== modified file 'pkg/dem/Engine/PartialEngine/FlowEngine.hpp'
--- pkg/dem/Engine/PartialEngine/FlowEngine.hpp	2010-06-17 12:30:19 +0000
+++ pkg/dem/Engine/PartialEngine/FlowEngine.hpp	2010-07-08 09:11:42 +0000
@@ -28,6 +28,7 @@
 		Real wall_thickness;
 		bool Update_Triangulation;
 		bool currentTes;
+		int id_offset;
 		
 		void Triangulate ();
 		void AddBoundary ();
@@ -79,6 +80,8 @@
 					((double, Pressure_BACK_Boundary,  0, "Pressure imposed on back boundary"))
 					((double, Pressure_LEFT_Boundary,  0, "Pressure imposed on left boundary"))
 					((double, Pressure_RIGHT_Boundary,  0, "Pressure imposed on right boundary"))
+					((double, Sinus_Pressure, 0, "Pressure value (amplitude) when sinusoidal pressure is applied"))
+					((int, id_sphere, 0, "Average velocity will be computed for all cells incident to that sphere"))
 					,timingDeltas=shared_ptr<TimingDeltas>(new TimingDeltas));
 		DECLARE_LOGGER;
 };


Follow ups