← Back to team overview

yade-dev team mailing list archive

[svn] r1616 - trunk/extra/SpherePadder

 

Author: richefeu
Date: 2009-01-08 16:58:45 +0100 (Thu, 08 Jan 2009)
New Revision: 1616

Modified:
   trunk/extra/SpherePadder/SpherePadder.cpp
   trunk/extra/SpherePadder/SpherePadder.hpp
   trunk/extra/SpherePadder/TetraMesh.hpp
Log:
SpherePadder (devel: 5 steps ok)




Modified: trunk/extra/SpherePadder/SpherePadder.cpp
===================================================================
--- trunk/extra/SpherePadder/SpherePadder.cpp	2009-01-08 11:26:43 UTC (rev 1615)
+++ trunk/extra/SpherePadder/SpherePadder.cpp	2009-01-08 15:58:45 UTC (rev 1616)
@@ -35,8 +35,8 @@
                 combination.push_back(lst);
         }
         
-   max_overlap_rate = 1e-2;   
-   n1 = n2 = n3 = n4 = n_densify = 0;  
+   max_overlap_rate = 1e-7;   
+   n1 = n2 = n3 = n4 = n5 = n_densify = 0;  
    
    //FIXME : 
    // si on utilise la class dans un autre programme c'est peu etre pas util
@@ -77,7 +77,9 @@
 	place_at_nodes();
 	place_at_segment_middle();
         cancel_overlap();
-	place_at_barycentre_3();
+        place_at_faces();
+        place_at_tetra_centers();
+        //place_at_tetra_vertexes ();
 
         cerr << "nb spheres = " << sphere.size() << endl;
 	
@@ -94,7 +96,8 @@
 	      << "  <newcolor name=\"at nodes\"/>" << endl
 	      << "  <newcolor name=\"at segments\"/>" << endl	
 	      << "  <newcolor name=\"at faces\"/>" << endl
-              << "  <newcolor name=\"at tetraCenters\"/>" << endl
+              << "  <newcolor name=\"at tetra centers\"/>" << endl
+              << "  <newcolor name=\"at tetra vertexes\"/>" << endl
 	      << "  <state id=\"" << 1 
 	      << "\" time=\"" << 0.0 << "\">" << endl;
 
@@ -209,7 +212,7 @@
 }
 
 
-void SpherePadder::place_at_barycentre_3 ()
+void SpherePadder::place_at_faces ()
 {
 	cerr << "place at barycentre 3... ";
  
@@ -228,10 +231,8 @@
 	Sphere S;
 	S.type = AT_FACE;
 
-	unsigned int ns0 = sphere.size();
-        unsigned int ns = ns0; 
+	unsigned int ns = sphere.size();
         const double div3 = 0.3333333333333;
-	double R1,R2,R3;
         Sphere S1,S2,S3;
 
 	for (unsigned int f = 0 ; f < mesh->face.size() ; ++f)
@@ -243,14 +244,9 @@
 
                 S.x = div3 * (S1.x + S2.x + S3.x); 
                 S.y = div3 * (S1.y + S2.y + S3.y); 
-                S.z = div3 * (S1.z + S2.z + S3.z); 
+                S.z = div3 * (S1.z + S2.z + S3.z);                 
+                S.R = rmin;
 		
-		R1 = distance_centre_spheres(S1,S) - S1.R;
-		R2 = distance_centre_spheres(S2,S) - S2.R;
-		R3 = distance_centre_spheres(S3,S) - S3.R;
-		S.R = (R1  > R2) ? R2 : R1;
-		S.R = (S.R > R3) ? R3 : S.R;
-		
 		S.tetraOwner = mesh->node[ mesh->face[f].nodeId[0] ].tetraOwner[0];
 		mesh->tetraedre[S.tetraOwner].sphereId.push_back(ns++);
                 sphere.push_back(S); ++(n3);
@@ -347,6 +343,8 @@
       {
         j = tetra_neighbor.sphereId[n];
 
+        if (sphere[j].R <= 0.0) continue;
+        
         added = false;
         for (unsigned int k = 0 ; k < j_ok.size() ; ++k) 
         {
@@ -370,8 +368,9 @@
   
   qsort(&(neighbor[0]),neighbor.size(),sizeof(neighbor_with_distance),compare_neighbor_with_distance); 
   S.R += neighbor[0].distance;
-  sphere[sphereId].R = S.R;
-  
+  if (S.R >= 0.0) sphere[sphereId].R = S.R;
+  else            sphere[sphereId].R = 0.0;
+
   vector<vector<unsigned int> > possible_combination;
   for (unsigned int c = 0 ; c < combination.size() ; ++c)
   {
@@ -392,6 +391,21 @@
     s4 = neighbor[ possible_combination[c][3] ].sphereId;
 
     failure = place_fifth_sphere(s1,s2,s3,s4,S);
+    
+    if (!failure)
+    {
+//       for (unsigned n = 0 ; n < sphere.size() ; ++n)
+//       {
+//         if (sphereId == n) continue;
+//         if ((distance_centre_spheres(S,sphere[n]) - (S.R + sphere[n].R)) < -max_overlap_rate * rmin) { failure = 128; break; }
+//       }
+      
+      for (unsigned n = 0 ; n < neighbor.size() ; ++n)
+      {
+        if ((distance_centre_spheres(S,sphere[neighbor[n].sphereId]) - (S.R + sphere[neighbor[n].sphereId].R)) < -max_overlap_rate * rmin) { failure = 128; break; }
+      }
+      
+    }  
 
     if (!failure)
     {
@@ -403,7 +417,7 @@
     }
 
   }
-
+  // sphere[sphereId].R = 0.0; //debug
   return 0;
 }
 
@@ -431,6 +445,7 @@
   unsigned int fail_overlap      =  8;
   unsigned int fail_gap          = 16;
   unsigned int fail_radius_range = 32;
+  unsigned int fail_NaN          = 64;
 
   // (x-x1)^2 + (y-y1)^2 + (z-z1)^2 = (r+r1)^2   (1)
   // (x-x2)^2 + (y-y2)^2 + (z-z2)^2 = (r+r2)^2   (2)
@@ -536,7 +551,7 @@
         || ( distance4 < half_distance_rate * (R + R4)) )
   { return fail_overlap; }
   
-  // The distance must not be too large
+  // The gap between spheres must not be too large
   double distance_max = max_overlap_rate * rmin; // FIXME should be imposed by the user? for example max_gap_rate
   if (     ( distance1 > distance_max) 
         || ( distance2 > distance_max)
@@ -545,7 +560,12 @@
   { return fail_gap; } 
   
   
-  // TODO check if there is no NaN or Inf
+  // Check if there is NaN 
+  if (     (centre[0] != centre[0])
+        || (centre[1] != centre[1])
+        || (centre[2] != centre[2])
+        || (R != R))
+  { return fail_NaN; }
   
   S.x = centre[0];
   S.y = centre[1];
@@ -555,16 +575,93 @@
   return 0;
 }
 
-void SpherePadder::place_at_barycentre_4 ()
+void SpherePadder::place_at_tetra_centers ()
 {
-// TODO 
+  cerr << "place at tetra centers... ";
+    
+  Sphere S;
+  S.type = AT_TETRA_CENTER;
+  Tetraedre T;
+  
+  unsigned int ns = sphere.size(); 
+  Node N1,N2,N3,N4;
+
+  for (unsigned int t = 0 ; t < mesh->tetraedre.size() ; ++t)
+  {
+    T = mesh->tetraedre[t];
+    N1 = mesh->node[T.nodeId[0]];
+    N2 = mesh->node[T.nodeId[1]];
+    N3 = mesh->node[T.nodeId[2]];
+    N4 = mesh->node[T.nodeId[3]];
+    
+    S.x = 0.25 * (N1.x + N2.x + N3.x + N4.x); 
+    S.y = 0.25 * (N1.y + N2.y + N3.y + N4.y); 
+    S.z = 0.25 * (N1.z + N2.z + N3.z + N4.z); 
+
+    S.R = rmin;
+                
+    S.tetraOwner = t;
+    mesh->tetraedre[t].sphereId.push_back(ns++);
+    sphere.push_back(S); ++(n4);
+  }
+        
+  for (unsigned int n = (n1+n2+n3) ; n < sphere.size() ; ++n)
+  {
+    place_sphere_4contacts(n);
+  }
+        
+  cerr << "Done" << endl;  
 }
+
+void SpherePadder::place_at_tetra_vertexes ()
+{
+  cerr << "place at tetra vertexes... ";
     
-void SpherePadder::place_at_tetra_centers ()
-{
-// TODO	
+  Sphere S;
+  S.type = AT_TETRA_VERTEX;
+  Tetraedre T;
+  
+  unsigned int ns = sphere.size(); 
+  Node N1,N2,N3,N4;
+  double centre[3];
+
+  for (unsigned int t = 0 ; t < mesh->tetraedre.size() ; ++t)
+  {
+    T = mesh->tetraedre[t];
+    N1 = mesh->node[T.nodeId[0]];
+    N2 = mesh->node[T.nodeId[1]];
+    N3 = mesh->node[T.nodeId[2]];
+    N4 = mesh->node[T.nodeId[3]];
+    
+    centre[0] = 0.25 * (N1.x + N2.x + N3.x + N4.x); 
+    centre[1] = 0.25 * (N1.y + N2.y + N3.y + N4.y); 
+    centre[2] = 0.25 * (N1.z + N2.z + N3.z + N4.z); 
+
+    S.R = rmin;
+                
+    double pondere = 1.0 / 3.0; // FIXME parametrable
+    for (unsigned int n = 0 ; n < 4 ; ++n)
+    {
+      S.x = pondere * mesh->node[ T.nodeId[n] ].x + (1.0-pondere) * centre[0];
+      S.y = pondere * mesh->node[ T.nodeId[n] ].y + (1.0-pondere) * centre[1];
+      S.z = pondere * mesh->node[ T.nodeId[n] ].z + (1.0-pondere) * centre[2];
+      
+      S.tetraOwner = t;
+      mesh->tetraedre[t].sphereId.push_back(ns++);
+      sphere.push_back(S); ++(n5);
+    }
+  }
+        
+  for (unsigned int n = (n1+n2+n3+n4) ; n < sphere.size() ; ++n)
+  {
+    place_sphere_4contacts(n);
+  }
+        
+  cerr << "Done" << endl; 
 }
+    
 
 
 
 
+

Modified: trunk/extra/SpherePadder/SpherePadder.hpp
===================================================================
--- trunk/extra/SpherePadder/SpherePadder.hpp	2009-01-08 11:26:43 UTC (rev 1615)
+++ trunk/extra/SpherePadder/SpherePadder.hpp	2009-01-08 15:58:45 UTC (rev 1616)
@@ -13,15 +13,13 @@
 
 #include "TetraMesh.hpp"
 
-enum SphereType {AT_NODE,AT_SEGMENT,AT_FACE,AT_TETRA_CENTER};
+enum SphereType {AT_NODE, AT_SEGMENT, AT_FACE, AT_TETRA_CENTER, AT_TETRA_VERTEX};
 
-
 struct Sphere
 {
-	double                x,y,z,R;
-	//unsigned int          type; // FIXME utiliser un enum ??
-        SphereType     type; 
-	unsigned int          tetraOwner;
+	double        x,y,z,R;
+        SphereType    type; 
+	unsigned int  tetraOwner;
 };
 
 struct Neighbor
@@ -46,9 +44,9 @@
         double       distance_vector3 (double V1[],double V2[]);
 	void         place_at_nodes ();
         void         place_at_segment_middle ();
-	void         place_at_barycentre_3 ();
+	void         place_at_faces ();
         void         place_at_tetra_centers ();
-        void         place_at_barycentre_4 ();
+        void         place_at_tetra_vertexes ();
 	void         cancel_overlap ();
         unsigned int place_fifth_sphere(unsigned int s1, unsigned int s2, unsigned int s3, unsigned int s4, Sphere& S);
         unsigned int place_sphere_4contacts (unsigned int sphereId);
@@ -56,7 +54,7 @@
 	double rmin,rmax,rmoy,dr;
 	double ratio;
 	double max_overlap_rate;
-        unsigned int n1,n2,n3,n4,n_densify;
+        unsigned int n1,n2,n3,n4,n5,n_densify;
 	
 	TetraMesh * mesh;
 	vector<Sphere> sphere;

Modified: trunk/extra/SpherePadder/TetraMesh.hpp
===================================================================
--- trunk/extra/SpherePadder/TetraMesh.hpp	2009-01-08 11:26:43 UTC (rev 1615)
+++ trunk/extra/SpherePadder/TetraMesh.hpp	2009-01-08 15:58:45 UTC (rev 1616)
@@ -52,22 +52,24 @@
 	
 class TetraMesh
 {
-
-	
+protected:
+    
+  double xtrans,ytrans,ztrans;
+  void organize (); 
+  	
 public:
-	vector<Node>       node;
-	vector<Segment>    segment;
-    vector<Face>       face;
-	vector<Tetraedre>  tetraedre;
+  
+  vector<Node>       node;
+  vector<Segment>    segment;
+  vector<Face>       face;
+  vector<Tetraedre>  tetraedre;
+  
+  double mean_segment_length;
+  double min_segment_length;
+  double max_segment_length;
+  
+  void read_data (const char* name);
 
-	double xtrans,ytrans,ztrans;
-	double mean_segment_length;
-	double min_segment_length;
-	double max_segment_length;
-		
-	//void read_data (string filename);
-	void read_data (const char* name);
-	void organize (); // FIXME protected ?
 };
 
 #endif // TETRA_MESH_HPP