yade-dev team mailing list archive
-
yade-dev team
-
Mailing list archive
-
Message #01168
[svn] r1731 - trunk/extra/SpherePadder
Author: richefeu
Date: 2009-03-26 10:14:05 +0100 (Thu, 26 Mar 2009)
New Revision: 1731
Modified:
trunk/extra/SpherePadder/CellPartition.cpp
trunk/extra/SpherePadder/CellPartition.hpp
trunk/extra/SpherePadder/SpherePadder.cpp
trunk/extra/SpherePadder/SpherePadder.hpp
trunk/extra/SpherePadder/TetraMesh.cpp
trunk/extra/SpherePadder/main.cpp
Log:
Bug corrections (min and max radii)
Modified: trunk/extra/SpherePadder/CellPartition.cpp
===================================================================
--- trunk/extra/SpherePadder/CellPartition.cpp 2009-03-25 21:30:06 UTC (rev 1730)
+++ trunk/extra/SpherePadder/CellPartition.cpp 2009-03-26 09:14:05 UTC (rev 1731)
@@ -12,7 +12,7 @@
CellPartition::CellPartition()
{
- cell_is_found = false;
+
}
void CellPartition::init(TetraMesh & mesh, double security_factor)
@@ -36,23 +36,17 @@
zmax = (zmax < mesh.node[i].z) ? mesh.node[i].z : zmax;
}
- isize = (unsigned int)((xmax - xmin) / mesh.mean_segment_length);
+ isize = (unsigned int)((xmax - xmin) / (security_factor * mesh.mean_segment_length));
if (isize < 1) isize = 1;
- jsize = (unsigned int)((ymax - ymin) / mesh.mean_segment_length);
+ jsize = (unsigned int)((ymax - ymin) / (security_factor * mesh.mean_segment_length));
if (jsize < 1) jsize = 1;
- ksize = (unsigned int)((zmax - zmin) / mesh.mean_segment_length);
+ ksize = (unsigned int)((zmax - zmin) / (security_factor * mesh.mean_segment_length));
if (ksize < 1) ksize = 1;
-// isize *= security_factor;
-// jsize *= security_factor;
-// ksize *= security_factor;
+ //cerr << "nb cells: " << isize << ", " << jsize << ", " << ksize << endl;
- //isize = jsize = ksize = 1; // pour test
-
- cerr << "nb cells: " << isize << ", " << jsize << ", " << ksize << endl;
-
vector<unsigned int> kvec;
for (unsigned int k = 0 ; k < ksize ; ++k) kvec.push_back(0);
vector<vector<unsigned int> > jvec;
@@ -76,14 +70,10 @@
x_adjuster = (double)isize / (xmax - xmin);
y_adjuster = (double)jsize / (ymax - ymin);
z_adjuster = (double)ksize / (zmax - zmin);
-
- cell_is_found = false;
}
void CellPartition::add(unsigned int n, double x, double y, double z)
-{
- cell_is_found = false;
-
+{
int i,j,k;
i = (int)(floor((x - xmin) * x_adjuster));
j = (int)(floor((y - ymin) * y_adjuster));
@@ -102,15 +92,11 @@
else current_k = (unsigned int)k;
cell[ cellId[current_i][current_j][current_k] ].sphereId.push_back(n);
-
- cell_is_found = true;
}
void CellPartition::locateCellOf(double x, double y, double z)
{
- cell_is_found = false;
-
int i,j,k;
i = (int)(floor((x - xmin) * x_adjuster));
@@ -128,8 +114,6 @@
if (k >= (int)ksize) current_k = ksize - 1;
else if (k < 0) current_k = 0;
else current_k = (unsigned int)k;
-
- cell_is_found = true;
}
Modified: trunk/extra/SpherePadder/CellPartition.hpp
===================================================================
--- trunk/extra/SpherePadder/CellPartition.hpp 2009-03-25 21:30:06 UTC (rev 1730)
+++ trunk/extra/SpherePadder/CellPartition.hpp 2009-03-26 09:14:05 UTC (rev 1731)
@@ -35,7 +35,6 @@
unsigned int isize,jsize,ksize;
unsigned int current_i,current_j,current_k;
- bool cell_is_found; // TODO enlever
CellPartition();
void init(TetraMesh & mesh, double security_factor = 1.0);
@@ -52,8 +51,7 @@
unsigned int j_up () { return ( (current_j < jsize - 1) ? (current_j + 1) : jsize - 1); }
unsigned int k_down() { return ( (current_k > 0) ? (current_k - 1) : 0 ); }
- unsigned int k_up () { return ( (current_k < ksize - 1) ? (current_k + 1) : ksize - 1); }
-
+ unsigned int k_up () { return ( (current_k < ksize - 1) ? (current_k + 1) : ksize - 1); }
};
#endif // CELL_PARTITION_HPP
Modified: trunk/extra/SpherePadder/SpherePadder.cpp
===================================================================
--- trunk/extra/SpherePadder/SpherePadder.cpp 2009-03-25 21:30:06 UTC (rev 1730)
+++ trunk/extra/SpherePadder/SpherePadder.cpp 2009-03-26 09:14:05 UTC (rev 1731)
@@ -52,8 +52,8 @@
trace_functions = true;
meshIsPlugged = false;
probeIsDefined = false;
- ratio = 2.0; rmoy = 0.0;
- virtual_radius_factor = 10.0;
+ ratio = 4.0; rmoy = 0.0;
+ virtual_radius_factor = 5.0;
/* FIXME
pour le moment, l'utilisateur ne peut entre qu'un ratio.
@@ -159,119 +159,111 @@
time_t start_time = clock();
place_at_nodes();
- //save_granulo("nodes_granulo.dat");
place_at_segment_middle();
- //save_granulo("segments_granulo.dat");
cancel_overlaps();
- //save_granulo("cancel_overlaps_granulo.dat");
place_at_faces();
- //save_granulo("faces_granulo.dat");
place_at_tetra_centers();
- //save_granulo("tetra_centers_granulo.dat");
place_at_tetra_vertexes ();
- //save_granulo("tetra_vertexes_granulo.dat");
- //detect_overlap();
- //place_virtual_spheres();
-
+
time_t stop_time = clock();
+
+ unsigned int nzero = 0;
+ for (unsigned int i = 0 ; i < sphere.size() ; ++i)
+ {
+ if (sphere[i].R <= 0.0) ++nzero;
+ }
cerr << "Total number of spheres = " << sphere.size() << endl;
cerr << "Number at nodes = " << n1 << endl;
cerr << "Number at segments = " << n2 << endl;
cerr << "Number near faces = " << n3 << endl;
cerr << "Number near tetra centers = " << n4 << endl;
- cerr << "Number near tetra vextexes = " << n5 << endl;
+ cerr << "Number near tetra vextexes = " << n5 << endl;
+ cerr << "Number cancelled = " << nzero << endl;
+
float time_used = (float)(stop_time - start_time) / 1000000.0;
- cerr << "Time used = " << time_used << " s" << endl;
+ cerr << "Time used = " << time_used << " s" << endl;
+
}
-void SpherePadder::densify()
+void SpherePadder::densify() // TODO FIXME loop until target solid fraction is reached
{
- //BEGIN_FUNCTION ("Densify");
+ BEGIN_FUNCTION ("Densify");
+ tetra_porosity P;
+ Sphere S,S1,S2,S3,S4;
+ bool can_be_added;
+ S.type = INSERTED_BY_USER;//FROM_TRIANGULATION;
+ unsigned int ns = sphere.size();
+
//place_virtual_spheres();
+
+ // TODO clear triangulation
for (unsigned int i = 0 ; i < sphere.size() ; i++)
{
+ if (sphere[i].R <= 0.0) continue;
triangulation.insert_node(sphere[i].x, sphere[i].y, sphere[i].z, i, false);
}
- tetra_porosity P;
if (!tetra_porosities.empty()) tetra_porosities.clear();
- // if triangulation is empty ...
+ // FIXME if triangulation is empty ...
triangulation.init_current_tetrahedron();
do
{
triangulation.current_tetrahedron_get_nodes(P.id1,P.id2,P.id3,P.id4);
+ if (P.id1>=ns || P.id2>=ns || P.id3>=ns || P.id4>=ns) continue;
P.volume = triangulation.current_tetrahedron_get_volume();
P.void_volume = P.volume - solid_volume_of_tetrahedron(sphere[P.id1], sphere[P.id2], sphere[P.id3], sphere[P.id4]);
- tetra_porosities.push_back(P);
+ if (P.void_volume>0.0)
+ {
+ tetra_porosities.push_back(P);
+ }
} while (triangulation.next_tetrahedron());
+
+ // sort tetrahdrons from big to small void volumes
qsort(&(tetra_porosities[0]),tetra_porosities.size(),sizeof(tetra_porosity),compare_tetra_porosity);
+
+ // TODO FIXME exclude tetra that involve virtual spheres
for (unsigned int i = 0 ; i < tetra_porosities.size() ; i++)
{
- cout << tetra_porosities[i].volume << "\t" << tetra_porosities[i].void_volume << endl;
- }
+ //cout << tetra_porosities[i].volume << "\t" << tetra_porosities[i].void_volume << endl;
+ //if (tetra_porosities[i].void_volume > 0.0)
- //END_FUNCTION;
-}
+ S1 = sphere[tetra_porosities[i].id1];
+ S2 = sphere[tetra_porosities[i].id2];
+ S3 = sphere[tetra_porosities[i].id3];
+ S4 = sphere[tetra_porosities[i].id4];
-void SpherePadder::tetra_pad() // EN TRAVAUX !!!!!!!!!!!!!!!!!!!!!!!!!
-{
- place_at_nodes();
- place_at_segment_middle();
- cancel_overlaps();
- place_at_faces();
- detect_overlap();
-
- for (unsigned int i = 0 ; i < sphere.size() ; i++)
- {
- //cout << sphere[i].x << "\t" << sphere[i].y << "\t" << sphere[i].z << "\t" << sphere[i].R << "\t" << i << endl;
- triangulation.insert_node(sphere[i].x, sphere[i].y, sphere[i].z, i, false);
+ can_be_added = (S1.type != VIRTUAL);
+ can_be_added &= (S2.type != VIRTUAL);
+ can_be_added &= (S3.type != VIRTUAL);
+ can_be_added &= (S4.type != VIRTUAL);
+
+ if (can_be_added)
+ {
+// TODO write a function 'try_to_place_into(id1,id2,id3,id4)'
+
+ if( place_fifth_sphere(tetra_porosities[i].id1,tetra_porosities[i].id2,tetra_porosities[i].id3,tetra_porosities[i].id4,S) )
+ {
+ sphere.push_back(S);
+ }
+
+ /*
+ S.x = 0.25 * (S1.x + S2.x + S3.x + S4.x);
+ S.y = 0.25 * (S1.y + S2.y + S3.y + S4.y);
+ S.z = 0.25 * (S1.z + S2.z + S3.z + S4.z);
+ S.R = rmin;
+
+ sphere.push_back(S);
+ place_sphere_4contacts(ns,4);
+ ++ns;
+ */
+ }
}
-
- //unsigned int id1=0,id2=0,id3=0,id4=0;
- tetra_porosity P;
- if (!tetra_porosities.empty()) tetra_porosities.clear();
- // if triangulatio empty ...
- triangulation.init_current_tetrahedron();
- do
- {
- triangulation.current_tetrahedron_get_nodes(P.id1,P.id2,P.id3,P.id4);
- P.volume = triangulation.current_tetrahedron_get_volume();
- P.void_volume = P.volume - solid_volume_of_tetrahedron(sphere[P.id1], sphere[P.id2], sphere[P.id3], sphere[P.id4]);
- tetra_porosities.push_back(P);
- } while (triangulation.next_tetrahedron());
- qsort(&(tetra_porosities[0]),tetra_porosities.size(),sizeof(tetra_porosity),compare_tetra_porosity);
-
- for (unsigned int i = 0 ; i < tetra_porosities.size() ; i++)
- {
- cout << tetra_porosities[i].volume << "\t" << tetra_porosities[i].void_volume << endl;
- }
-/*
- Sphere S;
- S.type = AT_TETRA_CENTER;
- triangulation.init_current_tetrahedron();
- do
- {
- unsigned int id1,id2,id3,id4;
- triangulation.current_tetrahedron_get_nodes(id1,id2,id3,id4);
- // place_fifth_sphere(id1,id2,id3,id4,S);
-
- S.x = 0.25 * (sphere[id1].x + sphere[id2].x +sphere[id3].x + sphere[id4].x);
- S.y = 0.25 * (sphere[id1].y + sphere[id2].y +sphere[id3].y + sphere[id4].y);
- S.z = 0.25 * (sphere[id1].z + sphere[id2].z +sphere[id3].z + sphere[id4].z);
- S.R = rmin; // rand...
-
- sphere.push_back(S);
-
- //cerr << "add\n";
- } while (triangulation.next_tetrahedron());
-
-*/
-
-
+
+ END_FUNCTION;
}
@@ -292,20 +284,24 @@
<< " <newcolor name=\"at faces\"/>" << endl
<< " <newcolor name=\"at tetra centers\"/>" << endl
<< " <newcolor name=\"at tetra vertexes\"/>" << endl
+ << " <newcolor name=\"insered by user\"/>" << endl
+ //<< " <newcolor name=\"from triangulation\"/>" << endl
<< " <state id=\"" << 1
<< "\" time=\"" << 0.0 << "\">" << endl;
for (unsigned int i = 0 ; i < sphere.size() ; ++i)
{
- //if (sphere[i].R < rmin) continue;
-
+ if (sphere[i].R <= 0.0 && sphere[i].type != AT_NODE) continue;
+ if (sphere[i].type == VIRTUAL) continue;
+
+
fmgpost << " <body>" << endl;
fmgpost << " <SPHER id=\"" << i+1 << "\" col=\"" << sphere[i].type << "\" r=\"" << sphere[i].R << "\">" << endl
<< " <position x=\"" << sphere[i].x + xtrans << "\" y=\""
<< sphere[i].y + ytrans << "\" z=\"" << sphere[i].z + ztrans << "\"/>" << endl
<< " </SPHER>" << endl << flush;
- // tmp (bricolage)
+ // This is not the contact network but rather the tetrahedrons
if (i < mesh->node.size())
{
for (unsigned int s = 0 ; s < mesh->segment.size() ; ++s)
@@ -339,6 +335,7 @@
for (unsigned int i = 0 ; i < sphere.size() ; ++i)
{
+ if (sphere[i].R <= 0.0) continue;
file << sphere[i].R << " " << sphere[i].x + xtrans << " " << sphere[i].y + ytrans << " " << sphere[i].z + ztrans << endl;
}
@@ -385,6 +382,8 @@
S.R = (S.R < mesh->segment[segId].length) ? S.R : mesh->segment[segId].length;
}
S.R /= 4.0;
+ if (S.R > rmax) S.R = rmax;
+ if (S.R < rmin) S.R = rmin;
sphere.push_back(S); ++(n1);
//check_inProbe(n);compacity_in_probe(n);
@@ -422,7 +421,7 @@
S.z = 0.5 * (z1 + z2);
S.R = 0.125 * mesh->segment[s].length;
if (S.R < rmin) S.R = rmin;
- else if (S.R > rmax) S.R = rmoy + dr * (double)rand()/(double)RAND_MAX;
+ if (S.R > rmax) S.R = rmoy + dr * (double)rand()/(double)RAND_MAX;
sphere.push_back(S); ++(n2);
//check_inProbe(ns);compacity_in_probe(ns);
@@ -535,7 +534,7 @@
S.type = AT_TETRA_VERTEX;
Tetraedre T;
- //unsigned int ns = sphere.size();
+ unsigned int ns = sphere.size();
Node N1,N2,N3,N4;
double centre[3];
@@ -556,22 +555,24 @@
double pondere = 0.333333333; // 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.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);
+ place_sphere_4contacts(ns);
+ ++ns;
}
}
- for (unsigned int n = (n1+n2+n3+n4) ; n < sphere.size() ; ++n)
- {
- place_sphere_4contacts(n);
- check_inProbe(n);compacity_in_probe(n);
- }
-
+// for (unsigned int n = (n1+n2+n3+n4) ; n < sphere.size() ; ++n)
+// {
+// place_sphere_4contacts(n);
+// check_inProbe(n);compacity_in_probe(n);
+// }
+//
END_FUNCTION;
}
@@ -600,62 +601,16 @@
{
Sphere S = sphere[sphereId];
Sphere Sbackup;
-// unsigned int current_tetra_id = S.tetraOwner;
-// Tetraedre current_tetra = mesh->tetraedre[current_tetra_id];
-// unsigned int j;
-// unsigned int tetra_neighbor_id;
-// Tetraedre tetra_neighbor;
vector<neighbor_with_distance> neighbor;
- //vector<unsigned int> j_ok;
neighbor_with_distance N;
- /*
- j_ok.push_back(sphereId);
- bool added;
- for (unsigned int t = 0 ; t < current_tetra.tetraNeighbor.size() ; ++t)
- {
- tetra_neighbor_id = current_tetra.tetraNeighbor[t];
- tetra_neighbor = mesh->tetraedre[tetra_neighbor_id];
- for (unsigned int n = 0 ; n < tetra_neighbor.sphereId.size() ; ++n)
- {
- j = tetra_neighbor.sphereId[n];
-
- if (sphere[j].R <= 0.0) continue;
-
- added = false;
- for (unsigned int k = 0 ; k < j_ok.size() ; ++k)
- {
- if (j == j_ok[k])
- {
- added = true;
- break;
- }
- }
-
- if (!added)
- {
- N.sphereId = j;
- N.distance = distance_spheres(sphereId,j);
- // if (N.distance < rmax)
- neighbor.push_back(N);
- j_ok.push_back(j);
- }
- }
- }
- */
unsigned int id;
- //Cell& current_cell = partition.get_cell(0,0,0);
Cell current_cell;
partition.locateCellOf(S.x,S.y,S.z);
- if (!partition.cell_is_found)
- {
- cerr << "cell not found\n";
- sphere[sphereId].R = 0.0;
- return 0;
- }
-
+
+ // Build the list of neighbors
for (unsigned int i = partition.i_down() ; i <= partition.i_up() ; ++i)
{
for (unsigned int j = partition.j_down() ; j <= partition.j_up() ; ++j)
@@ -711,99 +666,29 @@
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; }
-// }
-
-// double distance_max = -max_overlap_rate * rmin;
-// for (unsigned n = 0 ; n < neighbor.size() ; ++n)
-// {
-// if ((distance_centre_spheres(S,sphere[neighbor[n].sphereId]) - (S.R + sphere[neighbor[n].sphereId].R)) < distance_max)
-// { failure = 128; break; }
-// }
-
+ {
partition.locateCellOf(S.x,S.y,S.z);
- if (!partition.cell_is_found)
- {
- //cerr << "Cell not found !!!!?" << endl;
-// failure = 128;
-
- 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 int i = 0 ; i < partition.isize ; i += partition.isize - 1)
-// {
-// for (unsigned int j = 0 ; j < partition.jsize ; j += partition.jsize - 1)
-// {
-// for (unsigned int k = 0 ; k < partition.ksize ; k += partition.ksize - 1)
-// {
-//
-// current_cell = partition.get_cell(i,j,k);
-// for (unsigned int s = 0 ; s < current_cell.sphereId.size() ; ++s)
-// {
-// id = current_cell.sphereId[s];
-// if (id != sphereId)
-// {
-// if ((distance_centre_spheres(S,sphere[id]) - (S.R + sphere[id].R)) < -max_overlap_rate * rmin) { failure = 128; break; }
-// }
-// }
-//
-// }
-// }
-// }
-
- }
- else
- {
-
-// 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; }
-// }
-
-// cerr << "sphere.size() = " << sphere.size() << endl;
-// cerr << "current ijk = " << partition.current_i << ", "<< partition.current_j << ", "<< partition.current_k << endl ;
- unsigned int nb = 0;
- for (unsigned int i = partition.i_down() ; i <= partition.i_up() ; ++i)
- {
- for (unsigned int j = partition.j_down() ; j <= partition.j_up() ; ++j)
- {
- for (unsigned int k = partition.k_down() ; k <= partition.k_up() ; ++k)
- {
-
- current_cell = partition.get_cell(i,j,k);
-// cerr << "current_cell.sphereId.size() = " << current_cell.sphereId.size() << endl;
-// cerr << "ijk = " << i << ", " << j << ", " << k << endl;
- nb += current_cell.sphereId.size();
-
- for (unsigned int s = 0 ; s < current_cell.sphereId.size() ; ++s)
- {
- id = current_cell.sphereId[s];
- if (id != sphereId && sphere[id].R > 0.0)
- {
- if ((distance_centre_spheres(S,sphere[id]) - (S.R + sphere[id].R)) < -max_overlap_rate * rmin) { failure = 128; break; }
-
- }
- }
-
- }
- }
- }
-
-// cerr << "Total = " << nb << endl << endl;
-
- }
-
-
-
+ unsigned int nb = 0;
+ for (unsigned int i = partition.i_down() ; i <= partition.i_up() ; ++i)
+ {
+ for (unsigned int j = partition.j_down() ; j <= partition.j_up() ; ++j)
+ {
+ for (unsigned int k = partition.k_down() ; k <= partition.k_up() ; ++k)
+ {
+ current_cell = partition.get_cell(i,j,k);
+ nb += current_cell.sphereId.size(); // FIXME why ??
+ for (unsigned int s = 0 ; s < current_cell.sphereId.size() ; ++s)
+ {
+ id = current_cell.sphereId[s];
+ if (id != sphereId && sphere[id].R > 0.0)
+ {
+ if ((distance_centre_spheres(S,sphere[id]) - (S.R + sphere[id].R)) < -max_overlap_rate * rmin) { failure = 128; break; }
+ }
+ }
+ }
+ }
+ }
+
}
if (!failure)
@@ -1013,13 +898,11 @@
n2 = current_tetra.nodeId[1];
n3 = current_tetra.nodeId[2];
n4 = current_tetra.nodeId[3];
-
s1 = mesh->face[f].nodeId[0];
s2 = mesh->face[f].nodeId[1];
s3 = mesh->face[f].nodeId[2];
-
if ((n1 != s1) && (n1 != s2) && (n1 != s3))
{
s4 = n1;
@@ -1042,9 +925,9 @@
S3 = sphere[ s3 ];
S4 = sphere[ s4 ];
- const double inv_distance_sphere_1_2 = 1 / distance_centre_spheres( S1, S2);
- const double inv_distance_sphere_1_3 = 1 / distance_centre_spheres( S1, S3);
- const double inv_distance_sphere_1_4 = 1 / distance_centre_spheres( S1, S4);
+ const double inv_distance_sphere_1_2 = 1.0 / distance_centre_spheres( S1, S2);
+ const double inv_distance_sphere_1_3 = 1.0 / distance_centre_spheres( S1, S3);
+ const double inv_distance_sphere_1_4 = 1.0 / distance_centre_spheres( S1, S4);
vect1 [0] = (S1.x - S2.x) * inv_distance_sphere_1_2;
vect1 [1] = (S1.y - S2.y) * inv_distance_sphere_1_2;
@@ -1074,10 +957,10 @@
if ( k < 0) k = -k;
if ( scalar_product < 0) k = -k;
- // TODO : il suffit de prendre tester la valeur de mesh->face[f].normal_swap
+ // TODO : il suffit de tester la valeur de mesh->face[f].normal_swap
- // First virtual sphere
+ // First virtual sphere
/////////////////////////////////////////////
S.x = S1.x + k * perpendicular_vector [0];
S.y = S1.y + k * perpendicular_vector [1];
@@ -1103,7 +986,7 @@
partition.add(sphereId++,S.x,S.y,S.z);
}
- // Second virtual sphere
+ // Second virtual sphere
/////////////////////////////////////////////
S.x = S2.x + k * perpendicular_vector [0];
@@ -1130,7 +1013,7 @@
partition.add(sphereId++,S.x,S.y,S.z);
}
- // Third virtual sphere
+ // Third virtual sphere
///////////////////////////////////////////////
S.x = S3.x + k * perpendicular_vector [0];
S.y = S3.y + k * perpendicular_vector [1];
@@ -1176,16 +1059,13 @@
unsigned int id;
Cell current_cell;
-// cout << "la porosite dans ce tetraedre est de = " << calculated_porosity(Sphere& S1, Sphere& S2, Sphere& S3, Sphere& S4)
-//Les spheres en interpenetrations avec les spheres virtuelles vont être mises au zéro (A Optimiser)
double distance_max = -max_overlap_rate * rmin;
for ( unsigned int n = 0 ; n < j_ok.size() ; ++n) //spheres virtuelles
{
S = sphere[j_ok[n]];
partition.locateCellOf(S.x,S.y,S.z);
-// cerr << "sphere.size() = " << sphere.size() << endl;
-// cerr << "current ijk = " << partition.current_i << ", "<< partition.current_j << ", "<< partition.current_k << endl ;
+
for (unsigned int i = partition.i_down() ; i <= partition.i_up() ; ++i)
{
for (unsigned int j = partition.j_down() ; j <= partition.j_up() ; ++j)
@@ -1193,15 +1073,12 @@
for (unsigned int k = partition.k_down() ; k <= partition.k_up() ; ++k)
{
current_cell = partition.get_cell(i,j,k);
-// cerr << "current_cell.sphereId.size() = " << current_cell.sphereId.size() << endl;
-// cerr << "ijk = " << i << ", " << j << ", " << k << endl;
for (unsigned int s = 0 ; s < current_cell.sphereId.size() ; ++s)
{
id = current_cell.sphereId[s];
if (sphere[id].type != VIRTUAL && sphere[id].R > 0.0)
{
- if ((distance_centre_spheres(S,sphere[id]) - (S.R + sphere[id].R)) < distance_max) sphere[id].R = 0;
-
+ if ((distance_centre_spheres(S,sphere[id]) - (S.R + sphere[id].R)) < distance_max) sphere[id].R = 0.0;
}
}
@@ -1211,52 +1088,67 @@
}
- END_FUNCTION;
+ END_FUNCTION;
}
+void SpherePadder::insert_sphere(double x, double y, double z, double R)
+{
+ Sphere S;
+ S.x = x;
+ S.y = y;
+ S.z = z;
+ S.R = R;
+ S.type = INSERTED_BY_USER;
+ sphere.push_back(S);
+ unsigned int inseredId = sphere.size()-1;
+
+ partition.locateCellOf(x-R, y-R, z-R);
+ unsigned int iCellMin = partition.i_down();
+ unsigned int jCellMin = partition.j_down();
+ unsigned int kCellMin = partition.k_down();
+
+ partition.locateCellOf(x+R, y+R, z+R);
+ unsigned int iCellMax = partition.i_up();
+ unsigned int jCellMax = partition.j_up();
+ unsigned int kCellMax = partition.k_up();
+
+ double distance_max = -max_overlap_rate * rmin;
+ unsigned int id;
+ Cell current_cell;
+
+ for (unsigned int i = iCellMin ; i <= iCellMax ; ++i)
+ {
+ for (unsigned int j = jCellMin ; j <= jCellMax ; ++j)
+ {
+ for (unsigned int k = kCellMin ; k <= kCellMax ; ++k)
+ {
+ current_cell = partition.get_cell(i,j,k);
+ for (unsigned int s = 0 ; s < current_cell.sphereId.size() ; ++s)
+ {
+ id = current_cell.sphereId[s];
+ if (sphere[id].type != INSERTED_BY_USER && sphere[id].R > 0.0)
+ {
+ if (distance_spheres(inseredId,id) < distance_max )
+ {
+ sphere[id].R = 0.0;
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+}
+
void SpherePadder::cancel_overlaps()
{
-
BEGIN_FUNCTION("Cancel_overlaps");
- //unsigned int current_tetra_id,tetra_neighbor_id,j;
- //Tetraedre current_tetra, tetra_neighbor;
- double distance;
- //double k;
- double distance_max = -max_overlap_rate * rmin;
-
- /*
- for(unsigned int i = 0 ; i < sphere.size(); ++i)
- {
- if (sphere[i].R <= 0.0) continue;
-
- current_tetra_id = sphere[i].tetraOwner;
- current_tetra = mesh->tetraedre[current_tetra_id];
-
- for (unsigned int t = 0 ; t < current_tetra.tetraNeighbor.size() ; ++t)
- {
- tetra_neighbor_id = current_tetra.tetraNeighbor[t];
- tetra_neighbor = mesh->tetraedre[tetra_neighbor_id];
- for (unsigned int n = 0 ; n < tetra_neighbor.sphereId.size() ; ++n)
- {
- j = tetra_neighbor.sphereId[n];
- if (sphere[j].R <= 0.0) continue;
- //if (i < j)
- if (i != j)
- {
- while ( (distance = distance_spheres(i,j)) < distance_max )
- {
- k = 1.0 + distance / (sphere[i].R + sphere[j].R);
- sphere[i].R *= k;
- sphere[j].R *= k;
- }
- }
- }
- }
- }
-*/
+ double distance;
+ double distance_max = -max_overlap_rate * rmin;
unsigned int id;
Cell current_cell;
double kfact;
@@ -1265,12 +1157,6 @@
{
partition.locateCellOf(sphere[sphereId].x,sphere[sphereId].y,sphere[sphereId].z);
- if (!partition.cell_is_found) continue;
-
-// cerr << "ijk = " << partition.current_i << ", " << partition.current_j << ", " << partition.current_k << endl;
-// cerr << "i down up = " << partition.i_down() << ", " << partition.i_up() << endl;
-// cerr << "j down up = " << partition.j_down() << ", " << partition.j_up() << endl;
-// cerr << "k down up = " << partition.k_down() << ", " << partition.k_up() << endl << endl;
for (unsigned int i = partition.i_down() ; i <= partition.i_up() ; ++i)
{
@@ -1290,6 +1176,8 @@
sphere[sphereId].R *= kfact;
sphere[id].R *= kfact;
}
+ if (sphere[id].R < rmin) sphere[id].R = 0.0;
+ if (sphere[sphereId].R < rmin) sphere[sphereId].R = 0.0;
}
}
}
@@ -1298,32 +1186,10 @@
}
-
-/*
- for(unsigned int i = 0 ; i < sphere.size() -1 ; ++i)
- {
-
- for (unsigned int j = i+1 ; j < sphere.size() ; ++j)
- {
-
- if (sphere[j].R <= 0.0) continue;
-
- while ( (distance = distance_spheres(i,j)) < distance_max )
- {
- k = 1.0 + distance / (sphere[i].R + sphere[j].R);
- sphere[i].R *= k;
- sphere[j].R *= k;
- }
-
- }
- }
-*/
-
END_FUNCTION;
}
-
// FIXME attention aux interpenetrations avec rayons nuls
void SpherePadder::detect_overlap ()
{
@@ -1332,8 +1198,6 @@
Sphere S1,S2;
unsigned int nb_overlap = 0;
double d;
-
- //ofstream file("overlap.dat");
for (unsigned int n = 0 ; n < sphere.size()-1 ; ++n)
{
@@ -1346,7 +1210,6 @@
if ( S2.type != VIRTUAL && S2.R > rmin)
{
d = distance_spheres(n, t);
- //if (d <= 0.0) file << d/sphere[n].R << ' ' << d/sphere[t].R << endl;
if (d < -max_overlap_rate * rmin)
{
@@ -1363,7 +1226,6 @@
cerr << " rmin = " << rmin << endl;
sphere[n].type = sphere[t].type = AT_TETRA_VERTEX;
sphere[n].R = sphere[t].R = 0.0;
- //place_sphere_4contacts( (n > t) ? n : t );
++(nb_overlap);
}
}
@@ -1411,35 +1273,7 @@
volume_portion2 = spherical_triangle(point2, point1, point3, point4);
volume_portion3 = spherical_triangle(point3, point1, point2, point4);
volume_portion4 = spherical_triangle(point4, point1, point2, point3);
-/*
- double segment_12[3];
- double segment_23[3];
- double segment_34[3];
-
- segment_12[0] = point1[0] - point2[0];
- segment_12[1] = point1[1] - point2[1];
- segment_12[2] = point1[2] - point2[2];
-
- segment_23[0] = point2[0] - point3[0];
- segment_23[1] = point2[1] - point3[1];
- segment_23[2] = point2[2] - point3[2];
-
- segment_34[0] = point3[0] - point4[0];
- segment_34[1] = point3[1] - point4[1];
- segment_34[2] = point3[2] - point4[2];
-
- double determinant_matrix[3];
-
- determinant_matrix[0] = segment_12[0] * ( segment_23[1]*segment_34[2] - segment_23[2]*segment_34[1]);
- determinant_matrix[1] = -segment_23[0] * ( segment_12[1]*segment_34[2] - segment_12[2]*segment_34[1]);
- determinant_matrix[2] = segment_34[0] * ( segment_12[1]*segment_23[2] - segment_12[2]*segment_23[1]);
-
- const double div6 = 0.16666666666666667;
- double volume_tetrahedron = div6 * sqrt(determinant_matrix[0]*determinant_matrix[0]
- + determinant_matrix[1]*determinant_matrix[1] + determinant_matrix[2]*determinant_matrix[2]);
-
- return (volume_tetrahedron - volume_portion1 - volume_portion2 - volume_portion3 - volume_portion4 );
- */
+
return (volume_portion1 + volume_portion2 + volume_portion3 + volume_portion4);
}
@@ -1468,10 +1302,6 @@
double norme12 = sqrt( (vect12[0]*vect12[0]) + (vect12[1]*vect12[1]) + (vect12[2]*vect12[2]) );
double norme13 = sqrt( (vect13[0]*vect13[0]) + (vect13[1]*vect13[1]) + (vect13[2]*vect13[2]) );
double norme14 = sqrt( (vect14[0]*vect14[0]) + (vect14[1]*vect14[1]) + (vect14[2]*vect14[2]) );
-
-// if (norme12 == 0.0) cout << "sin(A) == 0.0" << endl;
-// if (norme13 == 0.0) cout << "sin(B) == 0.0" << endl;
-// if (norme14 == 0.0) cout << "sin(C) == 0.0" << endl;
double A = acos( (vect12[0]*vect13[0] + vect12[1]*vect13[1] + vect12[2]*vect13[2]) / (norme13 * norme12));
double B = acos( (vect12[0]*vect14[0] + vect12[1]*vect14[1] + vect12[2]*vect14[2]) / (norme14 * norme12));
@@ -1480,10 +1310,6 @@
double a = acos( (cos(A) - cos(B) * cos(C)) / (sin(B) * sin(C)) );
double b = acos( (cos(B) - cos(C) * cos(A)) / (sin(C) * sin(A)) );
double c = acos( (cos(C) - cos(A) * cos(B)) / (sin(A) * sin(B)) );
-
-// if (sin(A) == 0.0) cout << "sin(A) == 0.0" << endl;
-// if (sin(B) == 0.0) cout << "sin(B) == 0.0" << endl;
-// if (sin(C) == 0.0) cout << "sin(C) == 0.0" << endl;
double aire_triangle_spherique = rayon * rayon * (a + b + c - M_PI);
@@ -1496,3 +1322,6 @@
+
+
+
Modified: trunk/extra/SpherePadder/SpherePadder.hpp
===================================================================
--- trunk/extra/SpherePadder/SpherePadder.hpp 2009-03-25 21:30:06 UTC (rev 1730)
+++ trunk/extra/SpherePadder/SpherePadder.hpp 2009-03-26 09:14:05 UTC (rev 1731)
@@ -19,7 +19,7 @@
# define BEGIN_FUNCTION(arg) if (trace_functions) cerr << (arg) << "... " << flush
# define END_FUNCTION if (trace_functions) cerr << "Done\n" << flush
-enum SphereType {AT_NODE, AT_SEGMENT, AT_FACE, AT_TETRA_CENTER, AT_TETRA_VERTEX, VIRTUAL, INSERED_BY_USER, FROM_TRIANGULATION};
+enum SphereType {AT_NODE, AT_SEGMENT, AT_FACE, AT_TETRA_CENTER, AT_TETRA_VERTEX, INSERTED_BY_USER, FROM_TRIANGULATION, VIRTUAL};
struct Sphere
{
@@ -30,18 +30,18 @@
struct Neighbor
{
- unsigned int i,j;
+ unsigned int i,j; // FIXME long ?
};
struct neighbor_with_distance
{
- unsigned int sphereId;
+ unsigned int sphereId;// FIXME long ?
double distance;
};
struct tetra_porosity
{
- unsigned int id1,id2,id3,id4;
+ unsigned int id1,id2,id3,id4;// FIXME long ?
double volume;
double void_volume;
};
@@ -61,11 +61,11 @@
{
protected:
- vector<vector<unsigned int> > combination;
- SpherePackingTriangulation triangulation;
+ vector<vector<unsigned int> > combination;// FIXME long ?
+ SpherePackingTriangulation triangulation;// TODO use Delaunay Triangulation to avoid flat tetrahedra
vector<tetra_porosity> tetra_porosities;
- double distance_spheres (unsigned int i, unsigned int j);
+ double distance_spheres (unsigned int i, unsigned int j);// FIXME long ?
double distance_centre_spheres(Sphere& S1, Sphere& S2);
double distance_vector3 (double V1[],double V2[]);
double spherical_triangle (double point1[],double point2[],double point3[],double point4[]);
@@ -76,11 +76,11 @@
void place_at_tetra_centers ();
void place_at_tetra_vertexes ();
void cancel_overlaps ();
- void place_virtual_spheres ();
+
//
- 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, unsigned int nb_combi_max = 30);
+ unsigned int place_fifth_sphere(unsigned int s1, unsigned int s2, unsigned int s3, unsigned int s4, Sphere& S);// FIXME long ?
+ unsigned int place_sphere_4contacts (unsigned int sphereId, unsigned int nb_combi_max = 30);// FIXME long ?
// Check functions
void detect_overlap ();
@@ -96,9 +96,9 @@
CellPartition partition;
// FOR ANALYSIS
- set<Neighbor,CompareNeighborId> neighbor; // non utilise pour le moment
+ set<Neighbor,CompareNeighborId> neighbor; // pas utilise pour le moment
bool probeIsDefined;
- vector<unsigned int> sphereInProbe;
+ vector<unsigned int> sphereInProbe;// FIXME long ?
double xProbe,yProbe,zProbe,RProbe;
ofstream compacity_file;
@@ -120,13 +120,19 @@
SpherePadder();
- // High level pading functions
+ // Pading functions
+
+ //! \brief 5-step padding (for details see Jerier et al.)
void pad_5 ();
- void tetra_pad();
+
+ //! \brief Place virtual spheres at boudaries.
+ void place_virtual_spheres ();
+
+ // en cours de debuggage
void densify();
- // void insert_sphere(double x, double y, double z, double R);
- // void densify ();
+ //! \brief Insert a sphere (x,y,z,R) within the packing. Overlapping spheres are cancelled.
+ void insert_sphere(double x, double y, double z, double R);
// FOR ANALYSIS
void add_spherical_probe(double Rfact = 1.0);
Modified: trunk/extra/SpherePadder/TetraMesh.cpp
===================================================================
--- trunk/extra/SpherePadder/TetraMesh.cpp 2009-03-25 21:30:06 UTC (rev 1730)
+++ trunk/extra/SpherePadder/TetraMesh.cpp 2009-03-26 09:14:05 UTC (rev 1731)
@@ -15,7 +15,7 @@
isOrganized = false;
}
-
+// FIXME Some problem should occur with gmsh because nodes are sometimes duplicated.
void TetraMesh::read_gmsh (const char* name)
{
ifstream meshFile(name);
@@ -57,7 +57,7 @@
for (unsigned int e = 0 ; e < nbElements ; ++e)
{
meshFile >> num_element >> element_type;
- // 4-node tetrahedron
+ // 4-node tetrahedron
if (element_type != 4)
{
meshFile.getline(not_read,150);
@@ -72,7 +72,7 @@
meshFile >> T.nodeId[0] >> T.nodeId[1] >> T.nodeId[2] >> T.nodeId[3];
- // numbers begin at 0 instead of 1
+ // nodeId has 0-offset
// (0 in C/C++ corresponds to 1 in the file)
T.nodeId[0] -= 1;
T.nodeId[1] -= 1;
@@ -457,11 +457,11 @@
}
mean_segment_length /= (double)(segment.size());
- cerr << "mean_segment_length = " << mean_segment_length << endl;
- cerr << "min_segment_length = " << min_segment_length << endl;
- cerr << "max_segment_length = " << max_segment_length << endl;
+// cerr << "mean_segment_length = " << mean_segment_length << endl;
+// cerr << "min_segment_length = " << min_segment_length << endl;
+// cerr << "max_segment_length = " << max_segment_length << endl;
- // Define tetraedre neighbors
+ // Define tetraedre neighbors FIXME still usefull??
bool stop = false;
for (unsigned int t1 = 0 ; t1 < tetraedre.size() ; ++t1)
{
Modified: trunk/extra/SpherePadder/main.cpp
===================================================================
--- trunk/extra/SpherePadder/main.cpp 2009-03-25 21:30:06 UTC (rev 1730)
+++ trunk/extra/SpherePadder/main.cpp 2009-03-26 09:14:05 UTC (rev 1731)
@@ -21,7 +21,6 @@
int main()
{
#ifdef DEBUG
-
TetraMesh * mesh = new TetraMesh();
//mesh->read_gmsh("meshes/cube1194.msh");
@@ -33,10 +32,12 @@
//padder->add_spherical_probe(0.7);
padder->pad_5();
+ padder->insert_sphere(0.5,0.5,0.5,0.2);
+ padder->place_virtual_spheres();
padder->densify();
padder->save_mgpost("mgp.out.001");
- // padder->save_Rxyz("spheres.Rxyz");
+ padder->save_Rxyz("spheres.Rxyz");
return 0;
#else