yade-dev team mailing list archive
-
yade-dev team
-
Mailing list archive
-
Message #01200
[svn] r1756 - trunk/extra/SpherePadder
Author: richefeu
Date: 2009-04-17 17:11:23 +0200 (Fri, 17 Apr 2009)
New Revision: 1756
Modified:
trunk/extra/SpherePadder/SpherePadder.cpp
trunk/extra/SpherePadder/SpherePadder.hpp
trunk/extra/SpherePadder/TetraMesh.cpp
trunk/extra/SpherePadder/main.cpp
Log:
We can now make the packing denser with a stop criterion based on the solid fraction or total number of spheres.
Modified: trunk/extra/SpherePadder/SpherePadder.cpp
===================================================================
--- trunk/extra/SpherePadder/SpherePadder.cpp 2009-04-15 08:19:44 UTC (rev 1755)
+++ trunk/extra/SpherePadder/SpherePadder.cpp 2009-04-17 15:11:23 UTC (rev 1756)
@@ -13,10 +13,15 @@
int compare_neighbor_with_distance (const void * a, const void * b)
{
double d1 = (*(neighbor_with_distance *)a).distance;
- double d2 = (*(neighbor_with_distance *)b).distance;
+ double d2 = (*(neighbor_with_distance *)b).distance;
+ bool p1 = (*(neighbor_with_distance *)a).priority;
+ bool p2 = (*(neighbor_with_distance *)a).priority;
+ if (p1 && !p2) return -1;
+ if (p2 && !p1) return 1;
return (d1 > d2) ? 1 :-1;
}
+
int compare_tetra_porosity (const void * a, const void * b)
{
double d1 = (*(tetra_porosity *)a).void_volume;
@@ -24,14 +29,16 @@
return ((d1) < (d2)) ? 1 :-1;
}
+
int compareDouble (const void * a, const void * b)
{
return ( *(double*)a > *(double*)b ) ? 1 :-1;
}
+
SpherePadder::SpherePadder()
{
- vector <unsigned int> lst;
+ vector <id_type> lst;
unsigned int nb = 5;
for (unsigned int i = 0 ; i <= nb ; ++i)
@@ -43,10 +50,10 @@
for (unsigned int l = k+1 ; l <= nb+3 ; ++l)
{
lst.clear();
- lst.push_back(i);
- lst.push_back(j);
- lst.push_back(k);
- lst.push_back(l);
+ lst.push_back((id_type)i);
+ lst.push_back((id_type)j);
+ lst.push_back((id_type)k);
+ lst.push_back((id_type)l);
combination.push_back(lst);
}
}
@@ -54,15 +61,22 @@
}
n1 = n2 = n3 = n4 = n5 = n_densify = 0;
- trace_functions = true;
+
+ // Default values
+ verbose = true;
meshIsPlugged = false;
- probeIsDefined = false;
RadiusDataIsOK = RadiusIsSet = false;
-
max_overlap_rate = 1e-4;
virtual_radius_factor = 100.0;
+ criterion.nb_spheres = false;
+ criterion.solid_fraction = false;
+ max_iter_densify = 20;
+ Must_Stop = false;
+ zmin = 1;
+ gap_max = 0.0;
}
+
void SpherePadder::setRadiusRatio(double r)
{
r = fabs(r);
@@ -74,10 +88,16 @@
rmoy = 0.125 * mesh->mean_segment_length; // 1/8 = 0.125
rmin = (2.0 * rmoy) / (ratio + 1.0);
rmax = 2.0 * rmoy - rmin;
- dr = rmax - rmoy;
+ dr = rmax - rmoy; // FIXME a enlever
+ gap_max = rmin;
RadiusDataIsOK = true;
- cout << "rmin = " << rmin << endl;
- cout << "rmax = " << rmax << endl;
+ if (verbose)
+ {
+ cout << "rmin = " << rmin << endl;
+ cout << "rmax = " << rmax << endl;
+ cout << "rmoy = " << rmoy << endl;
+ cout << "ratio = " << ratio << endl;
+ }
}
else
{
@@ -88,6 +108,7 @@
RadiusIsSet = true;
}
+
void SpherePadder::setRadiusRange(double min, double max)
{
if (min > max)
@@ -102,26 +123,57 @@
}
ratio = rmax/rmin;
rmoy = 0.5*(rmin+rmax);
+ gap_max = rmin;
RadiusDataIsOK = true;
RadiusIsSet = true;
+
+ if (verbose)
+ {
+ cout << "rmin = " << rmin << endl;
+ cout << "rmax = " << rmax << endl;
+ cout << "rmoy = " << rmoy << endl;
+ cout << "ratio = " << ratio << endl;
+ }
}
+void SpherePadder::setMaxNumberOfSpheres(id_type max)
+{
+ criterion.nb_spheres_max = max;
+ criterion.nb_spheres = true;
+}
+
+
+void SpherePadder::setMaxSolidFractioninProbe(double max, double x, double y,double z, double R)
+{
+ max = fabs(max);
+ if (max >= 1.0) cout << "TargetSolidFraction > 1.0 (!)" << endl;
+ criterion.solid_fraction_max = max;
+ criterion.solid_fraction = true;
+ criterion.x = x; // FIXME + xtrans ?
+ criterion.y = y;
+ criterion.z = z;
+ criterion.R = R;
+}
+
+
void SpherePadder::plugTetraMesh (TetraMesh * pluggedMesh)
{
mesh = pluggedMesh;
partition.init(*mesh);
meshIsPlugged = true;
- cout << "mesh->mean_segment_length = " << mesh->mean_segment_length << endl;
- cout << "mesh->min_segment_length = " << mesh->min_segment_length << endl;
- cout << "mesh->max_segment_length = " << mesh->max_segment_length << endl;
+ if (verbose)
+ {
+ cout << "mesh->mean_segment_length = " << mesh->mean_segment_length << endl;
+ cout << "mesh->min_segment_length = " << mesh->min_segment_length << endl;
+ cout << "mesh->max_segment_length = " << mesh->max_segment_length << endl;
+ }
- if (!RadiusDataIsOK && RadiusIsSet && ratio != 0.0) setRadiusRatio(ratio);
- else cerr << "@SpherePadder::plugTetraMesh, no radius range defined!" << endl;
-
+ if (!RadiusDataIsOK && RadiusIsSet && ratio != 0.0) setRadiusRatio(ratio);
}
+
void SpherePadder::pad_5 ()
{
if (mesh == 0)
@@ -147,65 +199,90 @@
time_t stop_time = clock();
- unsigned int nzero = 0;
- for (unsigned int i = 0 ; i < sphere.size() ; ++i)
+ nzero = 0;
+ for (id_type 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 cancelled = " << nzero << endl;
+ if (verbose)
+ {
+ cout << "Summary:" << endl;
+ cout << " Total number of spheres = " << sphere.size() << endl;
+ cout << " Number at nodes = " << n1 << endl;
+ cout << " Number at segments = " << n2 << endl;
+ cout << " Number near faces = " << n3 << endl;
+ cout << " Number near tetra centers = " << n4 << endl;
+ cout << " Number near tetra vextexes = " << n5 << endl;
+ cout << " Number cancelled = " << nzero << endl;
+ }
float time_used = (float)(stop_time - start_time) / 1000000.0;
- cerr << "Time used = " << time_used << " s" << endl;
+ if (verbose) cout << "Time used (pad5) = " << time_used << " s" << endl;
}
-void SpherePadder::densify()
+
+void SpherePadder::densify() // makeDenser
{
BEGIN_FUNCTION ("Densify");
- unsigned int added = 0, back_added = 0;
+ unsigned int added = 0;
unsigned int nbfail = 0;
- unsigned int max_iter_densify = 40;
unsigned int i;
-
+
repack_null_radii();
for (i = 0 ; i < max_iter_densify ; ++i)
{
-
- // CRITERE BIDON !!!!! WARNING
- if ((added = iter_densify()) == back_added)
- {
- if (++nbfail == 3) { cout << "@densify, cannot add more spheres with this ratio" << endl; break; }
+ //repack_null_radii();
+ if ( (added = iter_densify(ceil(0.005*sphere.size()))) == 0 )
+ {
+ if (++nbfail == 2) { cout << "@densify, cannot add more spheres with this ratio" << endl; break; }
+ }
+ else nbfail = 0;
+
+ cout << "iter " << i << ", Total number = " << sphere.size() - nzero << ", Added in this iteration = " << added << endl;
+ if (Must_Stop) break;
}
- else nbfail = 0;
- cout << "iter " << i << ", nb spheres = " << sphere.size() /*- nzero*/ << ", added = " << added << endl;
- back_added = added;
- }
-
if (i == max_iter_densify) cout << "@densify, maximum number of iteration reached" << endl;
+
+ if (criterion.solid_fraction)
+ cout << "Final solid fraction = " << getMeanSolidFraction(criterion.x,criterion.y,criterion.z,criterion.R) << endl;
END_FUNCTION;
}
-void SpherePadder::repack_null_radii() // TODO FIXME loop until target solid fraction is reached
-{
+
+void SpherePadder::repack_null_radii() // repack_boundaries
+{
+ Sphere S_stored;
for (unsigned int i = 0 ; i < sphere.size() ; i++)
{
if (sphere[i].R > 0.0) continue;
- place_sphere_4contacts(i);
+ S_stored = sphere[i];
+ if (!place_sphere_4contacts(i)) sphere[i] = S_stored;
}
+
+//Sphere S;
+//vector<neighbor_with_distance> neighbor;
+//unsigned int ns = sphere.size();
+//if (bounds.empty()) return;
+//Sphere S;
+//cout << "bounds.size() = " << bounds.size() << endl;
+//list<unsigned int>::iterator it;
+//for (it = bounds.begin() ; it != bounds.end(); ++it)
+//{
+ //S = sphere[*it]; // save
+
+ //if (sphere[*it].R == 0.0)
+ //if (!place_sphere_4contacts(*it)) sphere[*it] = S;
+ //else bounds.erase(it);
+//}
}
-unsigned int SpherePadder::iter_densify(unsigned int nb_check)
+
+unsigned int SpherePadder::iter_densify(unsigned int nb_check) // iter_MakeDenser
{
unsigned int nb_added = 0, total_added = 0;
tetra_porosity P;
@@ -214,12 +291,13 @@
unsigned int ns = sphere.size();
unsigned int failure;
unsigned int nbVirtual;
- //double Volume_min = 1.333333333*M_PI*rmin*rmin*rmin;
-
- // TODO add bool VirtualSpheresOK
+ double Volume_min = 0.05*1.333333333*M_PI*rmin*rmin*rmin;
+ static bool finalyze = false;
+ if (finalyze) nb_check = 1;
+
triangulation.clear();
- for (unsigned int i = 0 ; i < sphere.size() ; i++)
+ for (id_type 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, (sphere[i].type == VIRTUAL));
@@ -231,7 +309,6 @@
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; // FIXME why ?
nbVirtual = 0;
if (sphere[P.id1].type == VIRTUAL) ++nbVirtual;
@@ -240,18 +317,9 @@
if (sphere[P.id4].type == VIRTUAL) ++nbVirtual;
if (nbVirtual == 4) continue;
-/*
- if (squared_distance_centre_spheres(P.id1, P.id2) > 0.01) continue;
- if (squared_distance_centre_spheres(P.id1, P.id3) > 0.01) continue;
- if (squared_distance_centre_spheres(P.id1, P.id4) > 0.01) continue;
- if (squared_distance_centre_spheres(P.id2, P.id3) > 0.01) continue;
- if (squared_distance_centre_spheres(P.id2, P.id4) > 0.01) continue;
- if (squared_distance_centre_spheres(P.id3, P.id4) > 0.01) 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]);
- if (P.void_volume > /*Volume_min*/ 0.0 || nbVirtual > 0)
+ if (P.void_volume > Volume_min || nbVirtual > 0)
{
tetra_porosities.push_back(P);
}
@@ -260,63 +328,21 @@
// sort tetrahdrons from bigger to smaller void volumes
qsort(&(tetra_porosities[0]),tetra_porosities.size(),sizeof(tetra_porosity),compare_tetra_porosity);
- for (unsigned int i = 0 ; i < tetra_porosities.size() ; i++)
+ for (id_type i = 0 ; i < tetra_porosities.size() ; i++)
{
- failure = place_fifth_sphere(tetra_porosities[i].id1,tetra_porosities[i].id2,tetra_porosities[i].id3,tetra_porosities[i].id4,S);
-
- if (!failure)
- {
- failure = check_overlaps(S,ns+1); // ns+1 i.e. on exclut aucune sphere
- }
- else // failure
- {
-// Sphere & S1 = sphere[tetra_porosities[i].id1];
-// Sphere & S2 = sphere[tetra_porosities[i].id2];
-// Sphere & S3 = sphere[tetra_porosities[i].id3];
-// Sphere & S4 = sphere[tetra_porosities[i].id4];
-
- /*
- CGAL::weighted_circumcenterC3 (
- S1.x, S1.y, S1.z, S1.R * S1.R,
- S2.x, S2.y, S2.z, S2.R * S2.R,
- S3.x, S3.y, S3.z, S3.R * S3.R,
- S4.x, S4.y, S4.z, S4.R * S4.R,
- S.x, S.y, S.z
- );
- */
-
-
-
-// double distance_min = distance_centre_spheres(S,S1) - S1.R;
-// double distance;
-// distance_min = (distance_min < (distance = distance_centre_spheres(S,S2) - S2.R)) ? distance_min : distance;
-// distance_min = (distance_min < (distance = distance_centre_spheres(S,S3) - S3.R)) ? distance_min : distance;
-// distance_min = (distance_min < (distance = distance_centre_spheres(S,S4) - S4.R)) ? distance_min : distance;
-// S.R = distance_min;
-// if (S.R > rmax) S.R = rmax;
- // TODO mettre en contact
-
- S.R = rmin; // test
-
- //if (S.R >= rmin)
- {
-//failure = 0;
- failure = check_overlaps(S,ns+10);
- }
- }
-
+ failure = place_fifth_sphere(tetra_porosities[i].id1, tetra_porosities[i].id2, tetra_porosities[i].id3, tetra_porosities[i].id4, S);
+ if (failure) S.R = rmin;
+ failure = check_overlaps(S,ns+1); // ns+1 (means that no sphere is excluded)
if(!failure)
{
vector<neighbor_with_distance> neighbor;
- build_sorted_list_of_neighbors(S, neighbor);
-
+ build_sorted_list_of_neighbors(S, neighbor);
S.R += neighbor[0].distance;
if (S.R >= rmin && S.R <= rmax)
{
sphere.push_back(S);++(n_densify);
partition.add(ns,S.x,S.y,S.z);
- triangulation.insert_node(S.x,S.y,S.z,ns,false); // necessary to compute mean solid fraction
++ns; ++nb_added; ++total_added;
}
}
@@ -324,20 +350,115 @@
// check if we must stop
if (nb_added >= nb_check)
{
- //cout << "check, total_added = " << total_added << endl;
nb_added = 0;
- // getMeanSolidFraction();
+
+ if (criterion.nb_spheres)
+ {
+ cout << " Nb Spheres = " << sphere.size() << endl;
+ if (sphere.size() >= criterion.nb_spheres_max)
+ {
+ cout << "------------------------------------" << endl;
+ cout << ">> Maximum number of spheres reached" << endl;
+ cout << " * Nb Spheres = " << sphere.size() << endl;
+ cout << " * Target = " << criterion.nb_spheres_max << endl;
+ cout << "------------------------------------" << endl;
+ Must_Stop = true;
+ return total_added;
+ }
+ }
+
+ if (criterion.solid_fraction)
+ {
+ double SF = getMeanSolidFraction(criterion.x,criterion.y,criterion.z,criterion.R);
+ cout << "Solid fraction = " << SF << endl;
+ if (SF >= 0.995*criterion.solid_fraction_max) { finalyze = true; nb_check = 1; }
+ if (SF >= criterion.solid_fraction_max)
+ {
+ cout << "------------------------------------" << endl;
+ cout << ">> Maximum solid fraction reached" << endl;
+ cout << " * Solid fraction = " << SF << endl;
+ cout << " * Target = " << criterion.solid_fraction_max << endl;
+ cout << "------------------------------------" << endl;
+ Must_Stop = true;
+ return total_added;
+ }
+ }
+
}
}
return total_added;
}
+
+double SpherePadder::getMeanSolidFraction(double x, double y, double z, double R)
+{
+ 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();
+
+ id_type id;
+ Cell current_cell;
+ double dx,dy,dz,Rs,dist2,dist,d1,d2;
+ const double _4div3 = 1.3333333333333;
+ double Vs=0.0, Vp=_4div3*M_PI*R*R*R;
+ if (Vp <= 0.0) return 0.0;
+
+ 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 != VIRTUAL && sphere[id].R > 0.0)
+ {
+ dx = sphere[id].x - x;
+ dy = sphere[id].y - y;
+ dz = sphere[id].z - z;
+ Rs = sphere[id].R;
+ dist2 = dx*dx + dy*dy + dz*dz;
+ if (dist2 <= (R+Rs)*(R+Rs)) // At least a portion of the sphere intersects the probe
+ {
+
+ if (dist2 <= (R-Rs)*(R-Rs)) // Entier sphere into the probe
+ {
+ Vs += _4div3*M_PI*Rs*Rs*Rs;
+ }
+ else // Intersecting sphere
+ {
+ dist = sqrt(dist2);
+ d1 = (R+Rs-dist)*(R+Rs-dist);
+ d2 = dist2 + 2.0*dist*Rs - 3.0*Rs*Rs + 2.0*dist*R + 6.0*Rs*R - 3.0*R*R;
+ Vs += (M_PI*d1*d2)/(12.0*dist);
+ }
+
+ }
+
+ }
+ }
+ }
+ }
+ }
+
+ return (Vs/Vp);
+}
+
+
void SpherePadder::save_tri_mgpost (const char* name)
{
// triangulation
triangulation.clear();
- for (unsigned int i = 0 ; i < sphere.size() ; i++)
+ for (id_type 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, (sphere[i].type == VIRTUAL));
@@ -358,9 +479,9 @@
triangulation.current_tetrahedron_get_nodes(id1,id2,id3,id4);
//if(sphere[id1].type == VIRTUAL && sphere[id2].type == VIRTUAL && sphere[id3].type == VIRTUAL && sphere[id4].type == VIRTUAL) continue;
- xp = 0.25*(sphere[id1].x+sphere[id2].x+sphere[id3].x+sphere[id4].x);
- yp = 0.25*(sphere[id1].y+sphere[id2].y+sphere[id3].y+sphere[id4].y);
- zp = 0.25*(sphere[id1].z+sphere[id2].z+sphere[id3].z+sphere[id4].z);
+ xp = 0.25 * (sphere[id1].x+sphere[id2].x+sphere[id3].x+sphere[id4].x);
+ yp = 0.25 * (sphere[id1].y+sphere[id2].y+sphere[id3].y+sphere[id4].y);
+ zp = 0.25 * (sphere[id1].z+sphere[id2].z+sphere[id3].z+sphere[id4].z);
rad = (sphere[id1].R>sphere[id2].R)?sphere[id1].R:sphere[id2].R;
rad = (rad>sphere[id3].R)?rad:sphere[id3].R;
rad = (rad>sphere[id4].R)?rad:sphere[id4].R;
@@ -390,6 +511,7 @@
}
+
void SpherePadder::save_mgpost (const char* name)
{
BEGIN_FUNCTION ("Save mgp");
@@ -399,6 +521,7 @@
double xtrans = mesh->xtrans;
double ytrans = mesh->ytrans;
double ztrans = mesh->ztrans;
+ unsigned int n = 1;
fmgpost << "<?xml version=\"1.0\"?>" << endl
<< " <mgpost mode=\"3D\">" << endl
@@ -410,44 +533,55 @@
<< " <newcolor name=\"at tetra vertexes\"/>" << endl
<< " <newcolor name=\"insered by user\"/>" << endl
<< " <newcolor name=\"from triangulation\"/>" << endl
+ << " <newcolor name=\"virtual\"/>" << endl
<< " <state id=\"" << 1
<< "\" time=\"" << 0.0 << "\">" << endl;
- for (unsigned int i = 0 ; i < sphere.size() ; ++i)
- {
- // the sphere with R=0 that are placed at nodes are saved because mgpost needs them
- // for the display of tetrahdrons.
- 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;
-
- // 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)
+ for (unsigned int i = 0 ; i < mesh->node.size() ; ++i)
{
- if (mesh->segment[s].nodeId[0] == i)
+ fmgpost << " <body>" << endl;
+ fmgpost << " <SPHER id=\"" << n << "\" col=\"" << 9 << "\" r=\"" << 0.0 << "\">" << endl
+ << " <position x=\"" << mesh->node[i].x + xtrans << "\" y=\""
+ << mesh->node[i].y + ytrans << "\" z=\"" << mesh->node[i].z + ztrans << "\"/>" << endl
+ << " </SPHER>" << endl << flush;
+ n++;
+ // This is not the contact network but rather the tetrahedrons
+ if (i < mesh->node.size())
{
- if (mesh->segment[s].nodeId[1] < mesh->node.size())
- fmgpost << " <SPSPx antac=\"" << mesh->segment[s].nodeId[1] + 1 << "\"/>" << endl;
+ for (unsigned int s = 0 ; s < mesh->segment.size() ; ++s)
+ {
+ if (mesh->segment[s].nodeId[0] == i)
+ {
+ if (mesh->segment[s].nodeId[1] < mesh->node.size())
+ fmgpost << " <SPSPx antac=\"" << mesh->segment[s].nodeId[1] + 1 << "\"/>" << endl;
+ }
+ }
}
+
+ fmgpost << " </body>" << endl;
}
- }
+
+ for (id_type i = 0 ; i < sphere.size() ; ++i)
+ {
+ if (sphere[i].R <= 0.0 /*&& sphere[i].type != AT_NODE*/) continue;
+ if (sphere[i].type == VIRTUAL) continue;
- fmgpost << " </body>" << endl;
- }
+ fmgpost << " <body>" << endl;
+ fmgpost << " <SPHER id=\"" << n << "\" 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;
+ fmgpost << " </body>" << endl;
+ n++;
+ }
+
fmgpost << " </state>" << endl
<< " </mgpost>" << endl;
END_FUNCTION;
}
+
void SpherePadder::save_Rxyz (const char* name)
{
@@ -468,24 +602,7 @@
END_FUNCTION;
}
-void SpherePadder::save_granulo(const char* name)
-{
- vector<double> D;
- for (unsigned int i = 0 ; i < sphere.size() ; ++i)
- {
- if (sphere[i].R <= 0.0) continue;
- D.push_back(2.0 * sphere[i].R);
- }
- qsort (&(D[0]), D.size(), sizeof(double), compareDouble);
-
- ofstream file(name);
- double inv_N = 1.0 / (double)D.size();
- for (unsigned int i = 0 ; i < D.size() ; ++i)
- {
- file << D[i] << ' ' << (double)i * inv_N << endl;
- }
-}
-
+
void SpherePadder::place_at_nodes ()
{
BEGIN_FUNCTION("Place at nodes");
@@ -507,18 +624,23 @@
segId = mesh->node[n].segmentOwner[i];
S.R = (S.R < mesh->segment[segId].length) ? S.R : mesh->segment[segId].length;
}
- S.R /= 4.0;
+ S.R *= 0.25;
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);
partition.add(n,S.x,S.y,S.z);
}
-
+
+ if (verbose)
+ {
+ cout << " Added = " << n1 << endl;
+ }
+
END_FUNCTION;
}
+
void SpherePadder::place_at_segment_middle ()
{
BEGIN_FUNCTION("Place at segment middle");
@@ -554,8 +676,13 @@
mesh->segment[s].sphereId = ns;
++ns;
-
- }
+ }
+
+ if (verbose)
+ {
+ cout << " Added = " << n2 << endl;
+ }
+
END_FUNCTION;
}
@@ -564,7 +691,6 @@
{
BEGIN_FUNCTION("Place at faces");
- // FIXME move the following loops in TetraMesh or at the end of place_at_segment_middle ??
unsigned int sphereId,faceId;
for (unsigned int s = 0 ; s < mesh->segment.size() ; ++s)
{
@@ -579,7 +705,6 @@
Sphere S;
S.type = AT_FACE;
- unsigned int ns = sphere.size();
const double div3 = 0.3333333333333;
Sphere S1,S2,S3;
@@ -593,12 +718,15 @@
S.y = div3 * (S1.y + S2.y + S3.y);
S.z = div3 * (S1.z + S2.z + S3.z);
S.R = rmin;
-
- sphere.push_back(S); ++(n3);
- place_sphere_4contacts(ns);
- ++ns;
+
+ n3 += place_sphere_4contacts(S);
}
-
+
+ if (verbose)
+ {
+ cout << " Added = " << n3 << endl;
+ }
+
END_FUNCTION;
}
@@ -611,7 +739,6 @@
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)
@@ -627,12 +754,14 @@
S.z = 0.25 * (N1.z + N2.z + N3.z + N4.z);
S.R = rmin;
-
- sphere.push_back(S); ++(n4);
- place_sphere_4contacts(ns);
- ++ns;
+ n4 += place_sphere_4contacts(S);
}
-
+
+ if (verbose)
+ {
+ cout << " Added = " << n4 << endl;
+ }
+
END_FUNCTION;
}
@@ -644,7 +773,6 @@
S.type = AT_TETRA_VERTEX;
Tetraedre T;
- unsigned int ns = sphere.size();
Node N1,N2,N3,N4;
double centre[3];
@@ -662,23 +790,27 @@
S.R = rmin;
- double pondere = 0.333333333; // FIXME parametrable ?
+ double pondere = 0.33333333333;
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];
-
- sphere.push_back(S); ++(n5);
- place_sphere_4contacts(ns);
- ++ns;
+
+ n5 += place_sphere_4contacts(S);
}
}
-
+
+ if (verbose)
+ {
+ cout << " Added = " << n5 << endl;
+ }
+
END_FUNCTION;
}
-double SpherePadder::squared_distance_centre_spheres(unsigned int i, unsigned int j)
+
+double SpherePadder::squared_distance_centre_spheres(id_type i, id_type j)
{
double lx,ly,lz;
lx = sphere[j].x - sphere[i].x;
@@ -687,8 +819,8 @@
return ((lx*lx + ly*ly + lz*lz));
}
-// deprecated
-double SpherePadder::distance_spheres(unsigned int i, unsigned int j)
+
+double SpherePadder::distance_spheres(id_type i, id_type j)
{
double lx,ly,lz;
lx = sphere[j].x - sphere[i].x;
@@ -697,6 +829,7 @@
return (sqrt(lx*lx + ly*ly + lz*lz) - sphere[i].R - sphere[j].R);
}
+
double SpherePadder::distance_spheres(Sphere & S1, Sphere & S2)
{
double lx,ly,lz;
@@ -706,6 +839,7 @@
return (sqrt(lx*lx + ly*ly + lz*lz) - S1.R - S2.R);
}
+
double SpherePadder::distance_centre_spheres(Sphere& S1, Sphere& S2)
{
double lx,ly,lz;
@@ -715,9 +849,11 @@
return (sqrt(lx*lx + ly*ly + lz*lz));
}
+
void SpherePadder::build_sorted_list_of_neighbors(Sphere & S, vector<neighbor_with_distance> & neighbor)
{
neighbor_with_distance N;
+ if (!neighbor.empty()) neighbor.clear();
unsigned int id;
Cell current_cell;
@@ -736,10 +872,12 @@
for (unsigned int s = 0 ; s < current_cell.sphereId.size() ; ++s)
{
id = current_cell.sphereId[s];
- //if (id != sphereId)
+ //if (id != excluded)
+ if (sphere[id].R > 0.0)
{
N.sphereId = id;
N.distance = distance_spheres(S,sphere[id]);
+ N.priority = (sphere[id].type == VIRTUAL); // or INSERTED_BY_USER ? FIXME
neighbor.push_back(N);
}
}
@@ -749,17 +887,25 @@
}
qsort(&(neighbor[0]),neighbor.size(),sizeof(neighbor_with_distance),compare_neighbor_with_distance);
+// cout << "->" ;
+// for (unsigned int a = 0;a<5;++a)
+// {
+// cout << "dist " << neighbor[a].distance;
+// if (sphere[ neighbor[a].sphereId ].type == VIRTUAL) cout << " (VIRTUAL)" << endl;
+// else cout << endl;
+// }
}
-void SpherePadder::build_sorted_list_of_neighbors(unsigned int sphereId, vector<neighbor_with_distance> & neighbor)
+
+void SpherePadder::build_sorted_list_of_neighbors(id_type sphereId, vector<neighbor_with_distance> & neighbor)
{
neighbor_with_distance N;
-
+
unsigned int id;
Cell current_cell;
-
+
partition.locateCellOf(sphere[sphereId].x,sphere[sphereId].y,sphere[sphereId].z);
-
+
// Build the local list of neighbors
for (unsigned int i = partition.i_down() ; i <= partition.i_up() ; ++i)
{
@@ -767,34 +913,94 @@
{
for (unsigned int k = partition.k_down() ; k <= partition.k_up() ; ++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 (id != sphereId)
+ if (id != sphereId && sphere[id].R > 0.0)
{
N.sphereId = id;
N.distance = distance_spheres(sphereId,id);
+ N.priority = (sphere[id].type == VIRTUAL);
neighbor.push_back(N);
}
}
-
+
}
}
}
-
+
qsort(&(neighbor[0]),neighbor.size(),sizeof(neighbor_with_distance),compare_neighbor_with_distance);
}
-unsigned int SpherePadder::place_sphere_4contacts (unsigned int sphereId, unsigned int nb_combi_max)
-{
+
+unsigned int SpherePadder::place_sphere_4contacts (Sphere& S, unsigned int nb_combi_max)
+{
+ unsigned int ns = sphere.size();
+ Sphere Sbackup;
+
+ vector<neighbor_with_distance> neighbor;
+ build_sorted_list_of_neighbors(S, neighbor);
+
+ S.R += neighbor[0].distance;
+ if (S.R > rmax) S.R = rmax;
+ else if (S.R < rmin) S.R = 0.0;
+
+ vector<vector<unsigned int> > possible_combination;
+ for (unsigned int c = 0 ; c < combination.size() ; ++c)
+ {
+ if (combination[c][0] >= neighbor.size()) continue;
+ if (combination[c][1] >= neighbor.size()) continue;
+ if (combination[c][2] >= neighbor.size()) continue;
+ if (combination[c][3] >= neighbor.size()) continue;
+ possible_combination.push_back(combination[c]);
+ }
+
+ unsigned int s1,s2,s3,s4;
+ unsigned int failure;
+ unsigned int nb_combi;
+ nb_combi = (nb_combi_max < possible_combination.size()) ? nb_combi_max : possible_combination.size();
+ Sbackup = S;
+ for (unsigned int c = 0 ; c < nb_combi ; ++c)
+ {
+ s1 = neighbor[ possible_combination[c][0] ].sphereId;
+ s2 = neighbor[ possible_combination[c][1] ].sphereId;
+ s3 = neighbor[ possible_combination[c][2] ].sphereId;
+ s4 = neighbor[ possible_combination[c][3] ].sphereId;
+
+ if (sphere[s1].R <= 0.0) continue;
+ if (sphere[s2].R <= 0.0) continue;
+ if (sphere[s3].R <= 0.0) continue;
+ if (sphere[s4].R <= 0.0) continue;
+
+ S = Sbackup;
+ failure = place_fifth_sphere(s1,s2,s3,s4,S);
+
+ if (!failure)
+ failure = check_overlaps(S,ns+1);
+ else continue;
+
+ if (!failure && S.R >= rmin && S.R <= rmax)
+ {
+ sphere.push_back(S);
+ partition.add(ns,S.x,S.y,S.z);//++ns;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+
+unsigned int SpherePadder::place_sphere_4contacts (id_type sphereId, id_type nb_combi_max)
+{
Sphere S = sphere[sphereId];
Sphere Sbackup;
vector<neighbor_with_distance> neighbor;
- build_sorted_list_of_neighbors(sphereId, neighbor);
-
+ build_sorted_list_of_neighbors(sphere[sphereId], neighbor);
+
S.R += neighbor[0].distance;
if (S.R >= rmin && S.R <= rmax) sphere[sphereId].R = S.R;
else if (S.R > rmax) sphere[sphereId].R = rmax;
@@ -809,19 +1015,24 @@
if (combination[c][3] >= neighbor.size()) continue;
possible_combination.push_back(combination[c]);
}
-
- unsigned int s1,s2,s3,s4;
+
+ id_type s1,s2,s3,s4;
unsigned int failure;
unsigned int nb_combi;
nb_combi = (nb_combi_max < possible_combination.size()) ? nb_combi_max : possible_combination.size();
Sbackup = S;
for (unsigned int c = 0 ; c < nb_combi ; ++c)
- {
+ {
s1 = neighbor[ possible_combination[c][0] ].sphereId;
s2 = neighbor[ possible_combination[c][1] ].sphereId;
s3 = neighbor[ possible_combination[c][2] ].sphereId;
s4 = neighbor[ possible_combination[c][3] ].sphereId;
-
+
+ if (sphere[s1].R <= 0.0) continue;
+ if (sphere[s2].R <= 0.0) continue;
+ if (sphere[s3].R <= 0.0) continue;
+ if (sphere[s4].R <= 0.0) continue;
+
S = Sbackup;
failure = place_fifth_sphere(s1,s2,s3,s4,S);
@@ -838,7 +1049,6 @@
partition.add(sphereId,S.x,S.y,S.z);
return 1;
}
-
}
if (sphere[sphereId].R > 0.0) partition.add(sphereId,S.x,S.y,S.z);
@@ -847,7 +1057,7 @@
unsigned int SpherePadder::check_overlaps(Sphere & S, unsigned int excludedId)
{
- unsigned int id;
+ id_type id;
Cell current_cell;
partition.locateCellOf(S.x,S.y,S.z);
@@ -863,7 +1073,7 @@
id = current_cell.sphereId[s];
if (id != excludedId && sphere[id].R > 0.0)
{
- if (distance_spheres(S,sphere[id]) < (-max_overlap_rate * rmin)) { return 128; }
+ if (distance_spheres(S,sphere[id]) < (-max_overlap_rate * rmin)) { return FAIL_OVERLAP; }
}
}
}
@@ -881,7 +1091,8 @@
return ( sqrt(D[0]*D[0] + D[1]*D[1] + D[2]*D[2]) );
}
-unsigned int SpherePadder::place_fifth_sphere(unsigned int s1, unsigned int s2, unsigned int s3, unsigned int s4, Sphere& S)
+// FIXME review notations
+unsigned int SpherePadder::place_fifth_sphere(id_type s1, id_type s2, id_type s3, id_type s4, Sphere& S)
{
double C1[3],C2[3],C3[3],C4[3];
double R1,R2,R3,R4;
@@ -890,17 +1101,6 @@
C3[0] = sphere[s3].x ; C3[1] = sphere[s3].y ; C3[2] = sphere[s3].z ; R3 = sphere[s3].R;
C4[0] = sphere[s4].x ; C4[1] = sphere[s4].y ; C4[2] = sphere[s4].z ; R4 = sphere[s4].R;
- // rougth estimate of the position
- // TODO
-
- unsigned int fail_det = 0x01;
- unsigned int fail_delta = 0x02;
- unsigned int fail_radius = 0x04;
- unsigned int fail_overlap = 0x08;
- unsigned int fail_gap = 0x10;
- unsigned int fail_radius_range = 0x20;
- unsigned int fail_NaN = 0x40;
-
// (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)
// (x-x3)^2 + (y-y3)^2 + (z-z3)^2 = (r+r3)^2 (3)
@@ -963,7 +1163,6 @@
double zb = (a31*e + a32*ee + a33*eee);
// Replace x, y and z in Equation (1) and solve the second order equation A*r^2 + B*r + C = 0
-
double A = xa*xa + ya*ya + za*za - 1.0;
double B = 2.0*(xa*(xb-C1[0])) + 2.0*(ya*(yb-C1[1])) + 2.0*(za*(zb-C1[2])) - 2.0*R1;
double C = (xb-C1[0])*(xb-C1[0]) + (yb-C1[1])*(yb-C1[1]) + (zb-C1[2])*(zb-C1[2]) - R1*R1;
@@ -978,19 +1177,19 @@
RR1 = (-B + sqrt_DELTA) * inv_2A;
RR2 = (-B - sqrt_DELTA) * inv_2A;
}
- else return fail_delta;
+ else return FAIL_DELTA;
if (RR1 > 0.0) R = RR1;
else if (RR2 > 0.0) R = RR2;
- else if (RR1 <= 0.0 && RR2 <= 0.0) return fail_radius;
+ else if (RR1 <= 0.0 && RR2 <= 0.0) return FAIL_RADIUS;
- if (R < rmin || R > rmax) return fail_radius_range;
+ if (R < rmin || R > rmax) return FAIL_RADIUS_RANGE;
centre[0] = xa * R + xb;
centre[1] = ya * R + yb;
centre[2] = za * R + zb;
}
- else return fail_det;
+ else return FAIL_DET;
S.x = centre[0];
S.y = centre[1];
@@ -1011,32 +1210,35 @@
// || ( distance2 < half_distance_rate * (R + R2))
// || ( distance3 < half_distance_rate * (R + R3))
// || ( distance4 < half_distance_rate * (R + R4)) )
-// { return fail_overlap; }
+// { return FAIL_OVERLAP; }
double max_overlap = -max_overlap_rate * rmin;
if ( ( distance1 < max_overlap)
|| ( distance2 < max_overlap)
|| ( distance3 < max_overlap)
|| ( distance4 < max_overlap) )
- { return fail_overlap; }
+ { return FAIL_OVERLAP; }
+
+ unsigned int nc = 0;
+ if (distance1 <= 0.0) ++nc;
+ if (distance2 <= 0.0) ++nc;
+ if (distance3 <= 0.0) ++nc;
+ if (distance4 <= 0.0) ++nc;
+ if (nc < zmin) return FAIL_GAP;
+
+ if ( ( distance1 > gap_max)
+ && ( distance2 > gap_max)
+ && ( distance3 > gap_max)
+ && ( distance4 > gap_max) )
+ { return FAIL_GAP; }
- // The gap between spheres must not be too large
- double distance_max = max_overlap_rate * rmin;
- if ( ( distance1 > distance_max)
- || ( distance2 > distance_max)
- || ( distance3 > distance_max)
- || ( distance4 > distance_max) )
- { return fail_gap; }
-
// Check if there is NaN
if ( (centre[0] != centre[0])
|| (centre[1] != centre[1])
|| (centre[2] != centre[2])
|| (R != R))
- { return fail_NaN; }
+ { return FAIL_NaN; }
-
- //S.R = R;
return 0;
}
@@ -1044,11 +1246,12 @@
void SpherePadder::place_virtual_spheres() // WARNING there is a bug in this function (TODO include modifications of Philippe Marin)
{
- BEGIN_FUNCTION("Place virtual spheres...");
+ BEGIN_FUNCTION("Place virtual spheres");
Tetraedre current_tetra, tetra_neighbor;
- unsigned int sphereId, current_tetra_id, n1, n2, n3, n4, s1, s2, s3, s4;
+ id_type sphereId, n1, n2, n3, n4, s1, s2, s3, s4;
+ unsigned int current_tetra_id;
const double div3 = 0.3333333333333;
Sphere S1,S2,S3,S4,S;
double sphere_virtual_radius, k;
@@ -1056,7 +1259,7 @@
double vect1 [3], vect2 [3], vect3 [3], perpendicular_vector [3];
bool added;
- vector<unsigned int> j_ok;
+ vector<id_type> j_ok;
sphere_virtual_radius = (mesh->mean_segment_length) * virtual_radius_factor;
k = sphere_virtual_radius;
@@ -1131,8 +1334,8 @@
scalar_product = ( (perpendicular_vector [0] * vect3 [0]) + (perpendicular_vector [1] * vect3 [1]) + (perpendicular_vector [2] * vect3 [2]) ) ;
- if ( k < 0) k = -k;
- if ( scalar_product < 0) k = -k;
+ if (k < 0) k = -k;
+ if (scalar_product < 0) k = -k;
// TODO : il suffit de tester la valeur de mesh->face[f].normal_swap
// mais pour le moment cette routine n'est pas critique (suffisemment rapide)
@@ -1143,8 +1346,7 @@
S.y = S1.y + k * perpendicular_vector [1];
S.z = S1.z + k * perpendicular_vector [2];
S.R = sphere_virtual_radius;
- S.type = VIRTUAL;
- S.tetraOwner = current_tetra_id;
+ S.type = VIRTUAL;
added = false;
for (unsigned int n = 0 ; n < j_ok.size() ; ++n)
@@ -1170,8 +1372,7 @@
S.y = S2.y + k * perpendicular_vector [1];
S.z = S2.z + k * perpendicular_vector [2];
S.R = sphere_virtual_radius;
- S.type = VIRTUAL;
- S.tetraOwner = current_tetra_id;
+ S.type = VIRTUAL;
added = false;
for (unsigned int n = 0 ; n < j_ok.size() ; ++n)
@@ -1196,8 +1397,7 @@
S.y = S3.y + k * perpendicular_vector [1];
S.z = S3.z + k * perpendicular_vector [2];
S.R = sphere_virtual_radius;
- S.type = VIRTUAL;
- S.tetraOwner = current_tetra_id;
+ S.type = VIRTUAL;
added = false;
for (unsigned int n = 0 ; n < j_ok.size() ; ++n)
@@ -1225,7 +1425,6 @@
S.R = sphere_virtual_radius;
S.type = VIRTUAL;
- S.tetraOwner = current_tetra_id;
sphere.push_back(S);
partition.add(sphereId++,S.x,S.y,S.z);
@@ -1234,10 +1433,11 @@
}
- unsigned int id;
+ id_type id;
Cell current_cell;
double distance_max = -max_overlap_rate * rmin;
-
+ double dist,nx,ny,nz,invnorm;
+
for ( unsigned int n = 0 ; n < j_ok.size() ; ++n) //spheres virtuelles
{
S = sphere[j_ok[n]];
@@ -1253,22 +1453,76 @@
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 (sphere[id].type != VIRTUAL && sphere[id].type != INSERTED_BY_USER && sphere[id].R > 0.0)
{
- if ((distance_centre_spheres(S,sphere[id]) - (S.R + sphere[id].R)) < distance_max) sphere[id].R = 0.0;
+ if ( (dist = distance_spheres(S,sphere[id])) < distance_max )
+ {
+ // Ingoing normal
+ invnorm = 1.0 / (dist + S.R + sphere[id].R);
+ nx = (sphere[id].x - S.x) * invnorm;
+ ny = (sphere[id].y - S.y) * invnorm;
+ nz = (sphere[id].z - S.z) * invnorm;
+ sphere[id].x -= (0.5 * dist)*nx;
+ sphere[id].y -= (0.5 * dist)*ny;
+ sphere[id].z -= (0.5 * dist)*nz;
+ sphere[id].R += 0.5 * dist;
+
+ //Sphere S = sphere[id]; // save
+ //if (!place_sphere_4contacts(id)) sphere[id] = S;
+ vector<neighbor_with_distance> neighbor;
+ build_sorted_list_of_neighbors(id, neighbor);
+ double radius_max = fabs(neighbor[1].distance+sphere[id].R);
+ double inc = 0.5*max_overlap_rate*rmin;
+ while (sphere[id].R < radius_max)
+ {
+ sphere[id].x += inc*nx;
+ sphere[id].y += inc*ny;
+ sphere[id].z += inc*nz;
+ sphere[id].R += inc;
+ }
+
+
+ // recherche plus proches voisins
+// vector<neighbor_with_distance> neighbor;
+// build_sorted_list_of_neighbors(id, neighbor);
+// if ( (sphere[id].R + 0.5*neighbor[1].distance) < rmax)
+// {
+// sphere[id].R += 0.5*neighbor[1].distance;
+// sphere[id].x += (0.5 * neighbor[1].distance)*nx;
+// sphere[id].y += (0.5 * neighbor[1].distance)*ny;
+// sphere[id].z += (0.5 * neighbor[1].distance)*nz;
+// }
+// else
+// {
+// double d = rmax-sphere[id].R;
+// sphere[id].R = rmax;
+// sphere[id].x += (0.5 * d)*nx;
+// sphere[id].y += (0.5 * d)*ny;
+// sphere[id].z += (0.5 * d)*nz;
+// }
+
+ if (sphere[id].R < rmin)
+ {
+ sphere[id].R = 0.0;
+ bounds.push_back(id);
+ }
+
+ }
}
}
-
}
}
}
+ }
- }
-
+ cout << "bounds.size() = " << bounds.size() << endl;
+ bounds.unique(); // FIXME marche pas !!!
+ cout << "bounds.size() = " << bounds.size() << endl;
+
END_FUNCTION;
-
}
+
void SpherePadder::insert_sphere(double x, double y, double z, double R)
{
Sphere S;
@@ -1292,17 +1546,16 @@
unsigned int kCellMax = partition.k_up();
double distance_max = -max_overlap_rate * rmin;
- unsigned int id;
+ id_type id;
Cell current_cell;
- for (unsigned int i = iCellMin ; i <= iCellMax ; ++i /*unsigned int i = 0 ; i <= partition.isize-1 ; ++i*/)
+ for (unsigned int i = iCellMin ; i <= iCellMax ; ++i)
{
- for (unsigned int j = jCellMin ; j <= jCellMax ; ++j /*unsigned int j = 0 ; j <= partition.jsize-1 ; ++j*/)
+ for (unsigned int j = jCellMin ; j <= jCellMax ; ++j)
{
- for (unsigned int k = kCellMin ; k <= kCellMax ; ++k /*unsigned int k = 0 ; k <= partition.ksize-1 ; ++k*/)
+ for (unsigned int k = kCellMin ; k <= kCellMax ; ++k)
{
current_cell = partition.get_cell(i,j,k);
- partition.add_in_cell(inseredId,i,j,k); // FIXME could be set only in iCellMin+1 to iCellMax-1 ...
for (unsigned int s = 0 ; s < current_cell.sphereId.size() ; ++s)
{
id = current_cell.sphereId[s];
@@ -1317,32 +1570,29 @@
}
}
}
+
+ if (++iCellMin > partition.isize - 1) iCellMin = partition.isize - 1;
+ if (++jCellMin > partition.jsize - 1) jCellMin = partition.jsize - 1;
+ if (++kCellMin > partition.ksize - 1) kCellMin = partition.ksize - 1;
+ if (--iCellMax < 0) iCellMax = 0;
+ if (--jCellMax < 0) jCellMax = 0;
+ if (--kCellMax < 0) kCellMax = 0;
+
+ for (unsigned int i = iCellMin ; i <= iCellMax ; ++i)
+ {
+ for (unsigned int j = jCellMin ; j <= jCellMax ; ++j)
+ {
+ for (unsigned int k = kCellMin ; k <= kCellMax ; ++k)
+ {
+ partition.add_in_cell(inseredId,i,j,k);
+ }
+ }
+ }
+}
-// for (/*unsigned int i = iCellMin ; i <= iCellMax ; ++i*/unsigned int i = 0 ; i <= partition.isize-1 ; ++i)
-// {
-// for (/*unsigned int j = jCellMin ; j <= jCellMax ; ++j*/unsigned int j = 0 ; j <= partition.jsize-1 ; ++j)
-// {
-// for (/*unsigned int k = kCellMin ; k <= kCellMax ; ++k*/unsigned int k = 0 ; k <= partition.ksize-1 ; ++k)
-// {
-//
-// current_cell = partition.get_cell(i,j,k);
-// for (unsigned int s = 0 ; s < current_cell.sphereId.size() ; ++s)
-// {
-//
-// if (current_cell.sphereId[s] == inseredId)
-// cout << "Cell " << i << ", " << j << ", " << k << " OK -> " << current_cell.sphereId[s] << endl;
-//
-// }
-// }
-// }
-// }
-
-
-
-}
-
+// FIXME Do not change radius of virtual and user spheres
void SpherePadder::cancel_overlaps()
{
BEGIN_FUNCTION("Cancel_overlaps");
@@ -1431,28 +1681,20 @@
cerr << " pos S1 = " << S1.x << ", " << S1.y << ", " << S1.z << endl;
cerr << " pos S2 = " << S2.x << ", " << S2.y << ", " << S2.z << endl;
cerr << " Distance / rmin = " << d/rmin << endl;
- //cerr << " rmin = " << rmin << endl;
- //sphere[n].type = sphere[t].type = AT_TETRA_VERTEX;
- //sphere[n].R = sphere[t].R = 0.0;
++(nb_overlap);
}
}
}
}
}
- cerr << "NB Overlap = " << nb_overlap << endl;
+ cerr << "NB Overlaps = " << nb_overlap << endl;
END_FUNCTION;
}
double SpherePadder::solid_volume_of_tetrahedron(Sphere& S1, Sphere& S2, Sphere& S3, Sphere& S4)
-{
- double volume_portion1;
- double volume_portion2;
- double volume_portion3;
- double volume_portion4;
-
+{
double point1[4];
point1[0] = S1.x;
point1[1] = S1.y;
@@ -1477,10 +1719,10 @@
point4[2] = S4.z;
point4[3] = S4.R;
- volume_portion1 = spherical_triangle(point1, point2, point3, point4);
- 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 volume_portion1 = spherical_triangle(point1, point2, point3, point4);
+ double volume_portion2 = spherical_triangle(point2, point1, point3, point4);
+ double volume_portion3 = spherical_triangle(point3, point1, point2, point4);
+ double volume_portion4 = spherical_triangle(point4, point1, point2, point3);
return (volume_portion1 + volume_portion2 + volume_portion3 + volume_portion4);
}
@@ -1489,8 +1731,8 @@
double SpherePadder::spherical_triangle (double point1[],double point2[],double point3[],double point4[])
{
- double rayon = point1[3];
- if (rayon == 0.0) return 0.0;
+ double R = point1[3];
+ if (R == 0.0) return 0.0;
double vect12[3], vect13[3], vect14[3];
@@ -1514,84 +1756,159 @@
double B = acos( (vect12[0]*vect14[0] + vect12[1]*vect14[1] + vect12[2]*vect14[2]) / (norme14 * norme12));
double C = acos( (vect14[0]*vect13[0] + vect14[1]*vect13[1] + vect14[2]*vect13[2]) / (norme13 * norme14));
- 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)) );
+ double cosA = cos(A);
+ double cosB = cos(B);
+ double cosC = cos(C);
+ double sinA = sin(A);
+ double sinB = sin(B);
+ double sinC = sin(C);
- double aire_triangle_spherique = rayon * rayon * (a + b + c - M_PI);
+ double a = acos( (cosA - cosB * cosC) / (sinB * sinC) );
+ double b = acos( (cosB - cosC * cosA) / (sinC * sinA) );
+ double c = acos( (cosC - cosA * cosB) / (sinA * sinB) );
+
+ double S = R * R * (a + b + c - M_PI);
- double aire_sphere = 4.0 * M_PI * rayon * rayon;
+ double Stot = 4.0 * M_PI * R * R;
- return ( (4.0 * 0.3333333 * M_PI * rayon * rayon * rayon) * (aire_triangle_spherique / aire_sphere) ) ;
-
+ return ( (4.0 * 0.3333333 * M_PI * R * R * R) * (S/Stot) ) ;
}
// ============================
// ANALISYS
// ============================
-void SpherePadder::check_inProbe(unsigned int i)
+
+void SpherePadder::save_granulo(const char* name)
{
- if (!probeIsDefined) return;
- if (sphere[i].R <= 0.0) return;
-
- double dx = sphere[i].x - xProbe;
- double dy = sphere[i].y - yProbe;
- double dz = sphere[i].z - zProbe;
- double squared_distance = dx*dx + dy*dy + dz*dz;
- if (squared_distance + sphere[i].R*sphere[i].R < RProbe * RProbe) sphereInProbe.push_back(i);
+ vector<double> D;
+ for (id_type i = 0 ; i < sphere.size() ; ++i)
+ {
+ if (sphere[i].R <= 0.0 || sphere[i].type == VIRTUAL) continue;
+ D.push_back(2.0 * sphere[i].R);
+ }
+ qsort (&(D[0]), D.size(), sizeof(double), compareDouble);
+
+ ofstream file(name);
+ double inv_N = 1.0 / (double)D.size();
+ for (id_type i = 0 ; i < D.size() ; ++i)
+ {
+ file << D[i] << " " << (double)i * inv_N << endl;
+ }
}
-void SpherePadder::add_spherical_probe(double Rfact)
+
+// pair correlation function or radial distribution function (RDF)
+void SpherePadder::rdf (unsigned int Npoint, unsigned int Nrmean)
{
- double xmin,xmax;
- double ymin,ymax;
- double zmin,zmax;
- double R;
+ double rmean = 0.0;
+ unsigned int nspheres = 0;
+ double xmin,xmax,ymin,ymax,zmin,zmax;
- xmin=xmax=mesh->node[0].x;
- ymin=ymax=mesh->node[0].y;
- zmin=zmax=mesh->node[0].z;
- for (unsigned int i = 1 ; i < mesh->node.size() ; ++i)
+ xmin = xmax = sphere[0].x;
+ ymin = ymax = sphere[0].y;
+ zmin = zmax = sphere[0].z;
+
+ for (unsigned int i = 0; i<sphere.size();++i)
{
- xmin = (xmin > mesh->node[i].x) ? mesh->node[i].x : xmin;
- xmax = (xmax < mesh->node[i].x) ? mesh->node[i].x : xmax;
- ymin = (ymin > mesh->node[i].y) ? mesh->node[i].y : ymin;
- ymax = (ymax < mesh->node[i].y) ? mesh->node[i].y : ymax;
- zmin = (zmin > mesh->node[i].z) ? mesh->node[i].z : zmin;
- zmax = (zmax < mesh->node[i].z) ? mesh->node[i].z : zmax;
+ if (sphere[i].R <= 0.0 || sphere[i].type == VIRTUAL || sphere[i].type == INSERTED_BY_USER) continue;
+ rmean += sphere[i].R;
+ ++nspheres;
+ xmin = (xmin < sphere[i].x) ? xmin : sphere[i].x;
+ xmax = (xmax > sphere[i].x) ? xmax : sphere[i].x;
+ ymin = (ymin < sphere[i].y) ? ymin : sphere[i].y;
+ ymax = (xmax > sphere[i].y) ? ymax : sphere[i].y;
+ zmin = (zmin < sphere[i].z) ? zmin : sphere[i].z;
+ zmax = (zmax > sphere[i].z) ? zmax : sphere[i].z;
}
- xProbe = 0.5 * (xmin + xmax);
- yProbe = 0.5 * (ymin + ymax);
- zProbe = 0.5 * (zmin + zmax);
- RProbe = (xmax - xmin);
- RProbe = (RProbe < (R = ymax - ymin)) ? RProbe : R;
- RProbe = (RProbe < (R = zmax - zmin)) ? RProbe : R;
- RProbe *= 0.5 * Rfact;
- probeIsDefined = true;
- compacity_file.open("compacity.dat");
-}
+ cout << "x : " << xmin << ", " << xmax << endl;
+ cout << "y : " << ymin << ", " << ymax << endl;
+ cout << "z : " << zmin << ", " << zmax << endl;
+ rmean /= (double)nspheres;
+ cout << "rmean = " << rmean << endl;
+ xmin += Nrmean*rmean;
+ xmax -= Nrmean*rmean;
+ ymin += Nrmean*rmean;
+ ymax -= Nrmean*rmean;
+ zmin += Nrmean*rmean;
+ zmax -= Nrmean*rmean;
+ cout << "x : " << xmin << ", " << xmax << endl;
+ cout << "y : " << ymin << ", " << ymax << endl;
+ cout << "z : " << zmin << ", " << zmax << endl;
+
+ vector<unsigned int> lst;
+ for (unsigned int i = 0 ; i < sphere.size() ; ++i)
+ {
+ if (sphere[i].R <= 0.0) continue;
+ if (sphere[i].x < xmin) continue;
+ if (sphere[i].x > xmax) continue;
+ if (sphere[i].y < ymin) continue;
+ if (sphere[i].y > ymax) continue;
+ if (sphere[i].z < zmin) continue;
+ if (sphere[i].z > zmax) continue;
+ lst.push_back(i);
+ }
+ unsigned int Nbod = lst.size();
+ cout << "Nbody = " << Nbod << endl;
-double SpherePadder::compacity_in_probe(unsigned int ninsered)
-{
- if (!probeIsDefined) return -1.0;
+ double dx,dy,dz,d;
+ unsigned int rang;
+
+ double dmax = Nrmean*rmean;
+ double amp = dmax/(double) Npoint;
+ cout << "dmax = " << dmax << endl;
+ cout << "amp = " << amp << endl;
- double dr = 0.0;
- double Vs = 0.0;
- double fact = 1.333333333 * M_PI;
- for (unsigned int i = 1 ; i < sphereInProbe.size() ; ++i)
+ vector<unsigned int > N(Npoint,0);
+
+ for (unsigned int i = 0 ; i < lst.size() ; ++i)
{
- Vs += fact * sphere[i].R * sphere[i].R * sphere[i].R;
+ unsigned int idi = lst[i];
+ double xi = sphere[idi].x;
+ double yi = sphere[idi].y;
+ double zi = sphere[idi].z;
+
+ for( unsigned int j = 0 ; j < sphere.size() ; ++j)
+ {
+ if (idi == j) continue;
+
+ dx = xi - sphere[j].x;
+ dy = yi - sphere[j].y;
+ dz = zi - sphere[j].z;
+ d = sqrt(dx*dx + dy*dy + dz*dz);
+ if (d>dmax) continue;
+
+ //rang = (unsigned int) floor( d/amp );
+ rang = (unsigned int)(floor((d/dmax) * (double)Npoint));
+
+ if (rang > Npoint) continue;
+ else N[rang] += 1;
+
+ }
}
- // TODO ameliorer cette fonction en prennant en compte les spheres coupees...
+ double meandensity = (double) (Nbod)/((xmax-xmin)*(ymax-ymin)*(zmax-zmin));
+ cout << "mean number density = " << meandensity << endl;
+ vector<double> density(Npoint);
+ double r;
+ density[0] = N[0]/(double)(Nbod)/( 4.0*M_PI*amp*amp);
+ for (unsigned int i = 1 ; i < Npoint ; ++i)
+ {
+ r = (i+1.0) * amp;
+ density[i] = (double) (N[i]) /(double)(Nbod);
+ density[i] /= 4.0*M_PI*r*r*amp;
+ }
- dr = Vs / (fact*RProbe*RProbe*RProbe);
- compacity_file << ninsered << ' ' << dr << endl;
- return (dr);
+ ofstream rfd("rdf.dat",ios::out);
+ for (unsigned int i = 0 ; i < Npoint ; ++i)
+ {
+ r = (i+1) * amp;
+ rfd << 0.5*r / rmean << " " << density[i]/meandensity << endl;
+ }
}
+
Modified: trunk/extra/SpherePadder/SpherePadder.hpp
===================================================================
--- trunk/extra/SpherePadder/SpherePadder.hpp 2009-04-15 08:19:44 UTC (rev 1755)
+++ trunk/extra/SpherePadder/SpherePadder.hpp 2009-04-17 15:11:23 UTC (rev 1756)
@@ -15,37 +15,67 @@
#include "SpherePackingTriangulation/SpherePackingTriangulation.hpp"
#include <time.h>
#include <set>
+#include <list>
-# define BEGIN_FUNCTION(arg) if (trace_functions) cerr << (arg) << "..." << endl << flush
-# define END_FUNCTION if (trace_functions) cerr << "Done\n" << flush
+# define BEGIN_FUNCTION(arg) if (verbose) cerr << "+--> " << (arg) << endl << flush
+# define END_FUNCTION if (verbose) cerr << "+-- Done <--+\n\n" << flush
-enum SphereType {AT_NODE, AT_SEGMENT, AT_FACE, AT_TETRA_CENTER, AT_TETRA_VERTEX, INSERTED_BY_USER, FROM_TRIANGULATION, VIRTUAL};
+#define FAIL_DET 0x01
+#define FAIL_DELTA 0x02
+#define FAIL_RADIUS 0x04
+#define FAIL_OVERLAP 0x08
+#define FAIL_GAP 0x10
+#define FAIL_RADIUS_RANGE 0x20
+#define FAIL_NaN 0x40
+typedef unsigned int id_type; // [0 -> 4,294,967,295] if 32 bits
+enum SphereType
+{
+ AT_NODE,
+ AT_SEGMENT,
+ AT_FACE,
+ AT_TETRA_CENTER,
+ AT_TETRA_VERTEX,
+ INSERTED_BY_USER,
+ FROM_TRIANGULATION,
+ VIRTUAL
+};
+
+struct Criterion
+{
+ bool nb_spheres;
+ bool solid_fraction;
+ id_type nb_spheres_max;
+ double solid_fraction_max;
+ double x,y,z,R;
+};
+
struct Sphere
{
- double x,y,z,R;
- SphereType type;
- unsigned int tetraOwner; // FIXME can be removed ??
+ double x,y,z,R;
+ SphereType type;
};
struct Neighbor
{
- unsigned int i,j; // FIXME long ?
+ id_type i,j;
};
struct neighbor_with_distance
{
- unsigned int sphereId;// FIXME long ?
- double distance;
+ id_type sphereId;
+ double distance;
+ bool priority;
};
struct tetra_porosity
{
- unsigned int id1,id2,id3,id4;// FIXME long ?
- double volume;
- double void_volume;
+ id_type id1,id2,id3,id4;
+ double volume;
+ double void_volume;
};
+// not used
class CompareNeighborId
{
public:
@@ -61,16 +91,17 @@
{
protected:
- vector<vector<unsigned int> > combination;// FIXME long ?
- SpherePackingTriangulation triangulation;
- vector<tetra_porosity> tetra_porosities;
+ vector<vector<id_type> > combination;
+ SpherePackingTriangulation triangulation;
+ vector<tetra_porosity> tetra_porosities;
+ Criterion criterion;
- double distance_spheres (unsigned int i, unsigned int j);// FIXME long ?
+ double distance_spheres (id_type i, id_type j); // deprecated
double distance_spheres (Sphere& S1,Sphere& S2);
- double squared_distance_centre_spheres(unsigned int i, unsigned int j);
+ double squared_distance_centre_spheres(id_type i, id_type j); // deprecated
double distance_centre_spheres(Sphere& S1, Sphere& S2);
double distance_vector3 (double V1[],double V2[]);
- void build_sorted_list_of_neighbors(unsigned int sphereId, vector<neighbor_with_distance> & neighbor);
+ void build_sorted_list_of_neighbors(id_type sphereId, vector<neighbor_with_distance> & neighbor);
void build_sorted_list_of_neighbors(Sphere & S, vector<neighbor_with_distance> & neighbor);
double spherical_triangle (double point1[],double point2[],double point3[],double point4[]);
double solid_volume_of_tetrahedron(Sphere& S1, Sphere& S2, Sphere& S3, Sphere& S4);
@@ -80,77 +111,86 @@
void place_at_tetra_centers ();
void place_at_tetra_vertexes ();
void cancel_overlaps ();
- unsigned int iter_densify(unsigned int nb_check = 100);
+ unsigned int iter_densify(unsigned int nb_check = 20);
void repack_null_radii();
// some key functions
- 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 = 15);// FIXME long ?
- unsigned int check_overlaps(Sphere & S, unsigned int excludedId);
+ unsigned int place_fifth_sphere(id_type s1, id_type s2, id_type s3, id_type s4, Sphere& S);
+ unsigned int place_sphere_4contacts (id_type sphereId, unsigned int nb_combi_max = 15);// (deprecated)
+ unsigned int place_sphere_4contacts (Sphere& S, unsigned int nb_combi_max = 15);
+ unsigned int check_overlaps(Sphere & S, id_type excludedId);
double rmin,rmax,rmoy,dr;
double ratio; // rmax/rmin
double max_overlap_rate;
- unsigned int n1,n2,n3,n4,n5,n_densify;
- unsigned int nb_iter_max;
+ id_type n1,n2,n3,n4,n5,n_densify,nzero;
+ unsigned int max_iter_densify;
+ double virtual_radius_factor;
bool RadiusDataIsOK,RadiusIsSet;
+ unsigned int zmin;
+ double gap_max;
TetraMesh * mesh;
vector <Sphere> sphere;
CellPartition partition;
-
- // FOR ANALYSIS
- set<Neighbor,CompareNeighborId> neighbor; // pas utilise pour le moment
- bool probeIsDefined;
- vector<unsigned int> sphereInProbe;// FIXME long ?
- double xProbe,yProbe,zProbe,RProbe;
- ofstream compacity_file;
+ list <id_type> bounds;
- double compacity_in_probe(unsigned int ninsered);
- void check_inProbe(unsigned int i);
-
- bool trace_functions;
- void save_granulo(const char* name);
-
+ bool verbose;
+ bool Must_Stop;
+
public:
bool meshIsPlugged;
+ void ShutUp() { verbose = false; }
+ void Speak() { verbose = true; }
+
void setRadiusRatio(double r);
void setRadiusRange(double min, double max);
void setMaxOverlapRate(double r) { max_overlap_rate = fabs(r); }
void setVirtualRadiusFactor(double f) {virtual_radius_factor = fabs(f);}
- void setTargetSolidFraction(double sf)
+ void setMaxNumberOfSpheres(id_type max);
+ void setMaxSolidFractioninProbe(double max, double x, double y,double z, double R);
+
+
+ id_type getNumberOfSpheres()
{
- // TODO
+ id_type nb = 0;
+ for (id_type i = 0 ; i < sphere.size() ; ++i)
+ {
+ if (sphere[i].type == VIRTUAL || sphere[i].type == INSERTED_BY_USER || sphere[i].R <= 0.0) continue;
+ ++nb;
+ }
+ return nb;
+ //return (n1+n2+n3+n4+n5);
}
+ double getMeanSolidFraction(double x, double y, double z, double R);
void plugTetraMesh (TetraMesh * mesh);
void save_mgpost (const char* name);
void save_tri_mgpost (const char* name);
void save_Rxyz (const char* name);
-
- double virtual_radius_factor;
SpherePadder();
- // Check functions (to debug)
+ // Check functions only for debug (very slow!!)
void detect_overlap ();
//! \brief 5-step padding (for details see Jerier et al.)
void pad_5 ();
- //! \brief Place virtual spheres at boudaries.
+ //! \brief Place virtual spheres at mesh boudaries and modify the position and radius of overlapping spheres in such a way that theu are in contact with the boundary plans.
void place_virtual_spheres ();
- // en cours de debuggage
+ //! \brief Make the packing denser by filling void spaces detected by building a Delaunay triangulation (with CGAL)
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);
+ void insert_sphere(double x, double y, double z, double R);
// FOR ANALYSIS
- void add_spherical_probe(double Rfact = 1.0);
+ void save_granulo(const char* name);
+ void rdf (unsigned int Npoint, unsigned int Nrmean);
};
Modified: trunk/extra/SpherePadder/TetraMesh.cpp
===================================================================
--- trunk/extra/SpherePadder/TetraMesh.cpp 2009-04-15 08:19:44 UTC (rev 1755)
+++ trunk/extra/SpherePadder/TetraMesh.cpp 2009-04-17 15:11:23 UTC (rev 1756)
@@ -238,6 +238,10 @@
void TetraMesh::organize ()
{
+ // Display informations
+ cout << "nb Nodes = " << node.size() << endl;
+ cout << "nb Tetra = " << tetraedre.size() << endl;
+
// Translate all nodes in such a manner that all coordinates are > 0
xtrans = node[0].x;
ytrans = node[0].y;
Modified: trunk/extra/SpherePadder/main.cpp
===================================================================
--- trunk/extra/SpherePadder/main.cpp 2009-04-15 08:19:44 UTC (rev 1755)
+++ trunk/extra/SpherePadder/main.cpp 2009-04-17 15:11:23 UTC (rev 1756)
@@ -9,6 +9,7 @@
*************************************************************************/
#include "SpherePadder.hpp"
+#include <limits.h>
unsigned int mesh_format;
vector <unsigned int> output_format;
@@ -16,37 +17,77 @@
char output_file_name[100];
void resume();
-int main()
-{
+int main(int argc, char ** argv)
+{
+# if 0
+ cout << "\n Int Types" << endl;
+ cout << "Size of int types is " <<
+ sizeof(int) << " bytes" << endl;
+ cout << "Signed int min: " << INT_MIN
+ << " max: " << INT_MAX << endl;
+ cout << "Unsigned int min: 0 max: " <<
+ UINT_MAX << endl;
+
+ cout << "\n Long Int Types" <<
+ endl;
+ cout << "Size of long int types is " <<
+ sizeof(long) << " bytes" << endl;
+ cout << "Signed long min: " << LONG_MIN
+ << " max: " << LONG_MAX << endl;
+ cout << "Unsigned long min: 0 max: " <<
+ ULONG_MAX << endl;
+
+ return 0;
+#endif
+
#if 1
TetraMesh * mesh = new TetraMesh();
//mesh->read_gmsh("meshes/cube1194.msh");
- mesh->read("meshes/test.tetra");
+ //mesh->read("meshes/test.tetra");
+ mesh->read_gmsh("etude_t_vs_ntetra/vincent_1000.msh");
+
//mesh->write_surface_MGP ("cube.mgp");
SpherePadder * padder = new SpherePadder();
+ //padder->ShutUp();
padder->plugTetraMesh(mesh);
- padder->setRadiusRatio(4.0);
+ padder->setRadiusRatio(3.0/*atof(argv[2])*/);
padder->setMaxOverlapRate(1.0e-4);
- padder->setVirtualRadiusFactor(100.0);
+ padder->setVirtualRadiusFactor(100.0);
+
+ // ---------
+ time_t start_time = clock();
padder->pad_5();
padder->place_virtual_spheres();
- padder->insert_sphere(0.5,0.5,0.5,0.4);
+ //padder->insert_sphere(0.5,0.5,0.5,0.2);
+
+ //unsigned int nmax = padder->getNumberOfSpheres() * 1.2;
+ //padder->setMaxNumberOfSpheres(nmax);
+ padder->setMaxSolidFractioninProbe(0.6 /*atof(argv[1])*/, 0.5, 0.5,0.5, 0.45);
+
padder->densify();
- padder->detect_overlap ();
+ time_t stop_time = clock();
+ float time_used = (float)(stop_time - start_time) / 1000000.0;
+ cout << "Total time used = " << fabs(time_used) << " s" << endl;
+ cout << "nspheres = " << padder->getNumberOfSpheres() << endl;
+ // ---------
+
+ //padder->detect_overlap ();
//padder->save_tri_mgpost("triangulation.mgp");
- padder->save_mgpost("mgp.out.001");
- padder->save_Rxyz("spheres.Rxyz");
+ //padder->save_mgpost("mgp.out.001");
+ //padder->save_Rxyz("spheres.Rxyz");
+ //padder->rdf(80,8);
+ //padder->save_granulo("granulo.dat");
return 0;
#else
char name_with_ext[100];
-
+
bool mesh_format_is_defined = false;
bool mesh_file_name_is_defined = false;
bool output_file_name_is_defined = false;