16 #if !__EMSCRIPTEN__ && __GNUC__ < 8
17 #include <experimental/filesystem>
18 namespace fs = std::experimental::filesystem ;
21 namespace fs = std::filesystem ;
34 #include <boost/random.hpp>
37 #define STR_PROTECT(s) static_cast<const char*>(s "\0")
39 #define STR_PROTECT(s) s
46 enum class ExportData {
NONE=0,
POSITION=0x1,
VELOCITY=0x2,
OMEGA=0x4,
OMEGAMAG=0x8,
ORIENTATION=0x10,
COORDINATION=0x20,
RADIUS=0x40,
IDS=0x80,
FN=0x100,
FT=0x200,
TORQUE=0x400,
GHOSTMASK=0x800,
GHOSTDIR=0x1000,
BRANCHVECTOR=0x2000,
FN_EL=0x4000,
FN_VISC=0x8000,
FT_EL=0x10000,
FT_VISC=0x20000,
FT_FRIC=0x40000,
FT_FRICTYPE=0x80000,
CONTACTPOSITION=0x100000,
MASS=0x200000} ;
66 auto res = s.find(
':') ;
double val ;
67 if (res==std::string::npos)
69 val=stod(s) ;
first=
static_cast<T
>(val) ;
70 isconst=true ; delta=0 ;
76 val=stod(s) ;
first=
static_cast<T
>(val) ;
77 s=s.substr(res+1) ; res = s.find(
':') ;
78 if (res==std::string::npos)
80 val=stod(s) ;
last=
static_cast<T
>(val) ;
85 val=stod(s) ; delta=
static_cast<T
>(val) ;
87 val=stod(s) ;
last=
static_cast<T
>(val) ;
100 if (iter>0 && !allow)
return {} ;
109 T res =
first+delta*iter ;
110 if (res>
last && !allow)
118 bool isconst = true ;
121 template <
typename T>
145 forceinsphere(false),
150 Directory (
"Output"),
151 orientationtracking(true),
152 wallforcecompute(false),
153 wallforcerequested(false),
154 wallforcecomputed(false),
163 N=NN ; r.resize(
N,0.5) ;
167 Frozen.resize(
N,
false) ;
189 vector <std::pair<ExportType,ExportData>>
dumps ;
191 bool xmlstarted=false ;
208 unsigned long int seed = 5489UL ;
209 double gravityrotateangle = 0.0;
213 std::string restart_filename=
"" ;
218 template <
class Archive>
223 ar(
N, tdump, tinfo, T, dt, rho, Kn, Kt, Gamman, Gammat, Mu, Mu_wall, damping, forceinsphere, cellsize, ContactModel, contact_strategy,
224 dumps, xmlstarted, xml_location, r, m, I, g, Frozen,
Boundaries, Directory, orientationtracking, wallforcecompute, wallforcerequested, wallforcecomputed,
225 graddesc_gamma, graddesc_tol, contactforcedump, seed, gravityrotateangle, RigidBodies, Meshes, events,
226 n_restart, restart_filename, restart_flag
232 template <
class Archive>
234 ar(
N, tdump, tinfo, T, dt, rho, Kn, Kt, Gamman, Gammat, Mu, Mu_wall, damping, forceinsphere, cellsize, ContactModel, contact_strategy,
235 dumps, xmlstarted, xml_location, r, m, I, g, Frozen,
Boundaries, Directory, orientationtracking, wallforcecompute, wallforcerequested, wallforcecomputed,
236 graddesc_gamma, graddesc_tol, contactforcedump, seed, gravityrotateangle, RigidBodies, Meshes, events,
237 n_restart, restart_filename, restart_flag
250 int set_boundaries() ;
253 void perform_PBCLE_move() ;
255 bool perform_forceinsphere(
v1d & X) ;
257 void perform_MOVINGWALL() ;
262 double grav_intensity = 10, grav_omega=1 ;
int grav_rotdim[2]={0,1} ;
263 void do_gravityrotate (
double deltatime) {gravityrotateangle += deltatime*grav_omega; g[grav_rotdim[0]]=grav_intensity*
cos(gravityrotateangle); g[grav_rotdim[1]]=grav_intensity*
sin(gravityrotateangle);
return;}
266 void load_datafile (
char path[],
v2d & X,
v2d & V,
v2d & Omega) ;
267 void check_events(
float time,
v2d & X,
v2d & V,
v2d & Omega) ;
268 void interpret_command (istream & in,
v2d & X,
v2d & V,
v2d & Omega) ;
269 void interpret_command (
string & in,
v2d & X,
v2d & V,
v2d & Omega) ;
271 void remove_particle (
int idx,
v2d & X,
v2d & V,
v2d & A,
v2d & Omega,
v2d & F,
v2d & FOld,
v2d & Torque,
v2d & TorqueOld) ;
272 void add_particle () ;
273 void init_locations (
char *line,
v2d & X,
char *extras) ;
274 void init_radii (
char line[],
v1d & r) ;
276 void display_info(
int tint,
v2d& V,
v2d& Omega,
v2d& F,
v2d& Torque,
int,
int) ;
277 void quit_cleanly() ;
280 int dumphandling (
int ti,
double t,
v2d &X,
v2d &V,
v1d &Vmag,
v2d &A,
v2d &Omega,
v1d &OmegaMag, vector<uint32_t> &PBCFlags,
v1d & Z,
Multiproc<d> & MP) ;
296 char c; std::string word ;
297 if (!in.good())
return std::numeric_limits<double>::quiet_NaN();
298 while (isspace(c = in.peek())) in.get();
299 if ( !isdigit(c) && c!=
'-' && c!=
'.') { in >> word ;
return std::numeric_limits<double>::quiet_NaN(); }
310 for (
int i=0 ; i<
d ; i++)
386 { printf(
"ERR: forceinsphere expect the sphere to be the first wall.") ;
return false ; }
389 for (
int dd=0 ; dd<
d ; dd++) dst += (X[dd]-
Boundaries[0].center[dd])*(X[dd]-
Boundaries[0].center[dd]) ;
392 printf(
"%g ", dst) ; fflush(stdout) ;
393 boost::random::mt19937
rng(++seed);
394 boost::random::uniform_01<boost::mt19937> rand(
rng) ;
397 for(
int dd=0 ; dd <
d ; dd++)
404 printf(
"[INFO] Bringing back in sphere forcibly. \n"); fflush(stdout) ;
430 for (
int i=0 ; i<
N ; i++)
438 for (
int i=0; i<
N ; i++)
451 if (!in.is_open()) { printf(
"[Input] file cannot be open\n"); return ;}
455 interpret_command(in, X, V, Omega) ;
461 fs::path pcp (Directory+
"/in") ;
462 copy_file(p,pcp, fs::copy_options::overwrite_existing);
468 while (events.size()>0 && events.begin()->first < time)
470 stringstream command ; command.str(events.begin()->second) ;
471 printf(
"\nThe following event is implemented now: %s\n", events.begin()->second.c_str()) ;
472 interpret_command(command, X,V,Omega) ;
473 events.erase(events.begin()) ;
478 std::istream&
operator>>(std::istream& in, std::variant<int*,double*,bool*> v)
480 printf(
"SETTING variable %ld\n", v.index());
483 case 0: in >> *(std::get<int*>(v)) ; break ;
484 case 1: in >> *(std::get<double*>(v)); break ;
485 case 2: in >> *(std::get<bool*>(v)); break ;
493 return (interpret_command(B, X, V, Omega)) ;
498 map <string, std::variant<int*,double*,bool*>> SetValueMap = {
505 {
"Mu_wall",&Mu_wall},
506 {
"damping",&damping},
509 {
"orientationtracking",&orientationtracking},
513 {
"gradientdescent_gamma", &graddesc_gamma},
514 {
"gradientdescent_tol", &graddesc_tol},
515 {
"cell_size", &cellsize},
516 {
"forceinsphere", &forceinsphere}
520 auto discard_line = [&](){
char line [5000] ; in.getline(line, 5000) ; } ;
521 auto read_event = [&](){
float time ;
char line [5000] ; in >> time ; in.getline (line, 5000) ; events.insert(make_pair(time,line)) ; printf(
"[INFO] Registering an event: %g -> %s\n", time, line) ;} ;
522 auto doauto = [&]() {
char line [5000] ; in>>line ;
523 if (!strcmp(line,
"mass")) init_mass() ;
524 else if (!strcmp(line,
"rho"))
527 printf(
"[INFO] Using first particle mass to set rho: %g [M].[L]^-%d\n", rho,
d) ;
529 else if (!strcmp(line,
"inertia")) init_inertia() ;
530 else if (!strcmp(line,
"location"))
533 char extras[5000]; in.getline(extras, 5000) ;
534 init_locations(line, X, extras) ;
535 printf(
"[INFO] Set all particle locations\n") ;
537 else if (!strcmp(line,
"radius"))
539 in.getline(line, 5000) ;
540 init_radii(line, r) ;
541 printf(
"[INFO] Set all particle radii\n") ;
543 else printf(
"[WARN] Unknown auto command in input script\n") ;
544 printf(
"[INFO] Doing an auto \n") ;
546 auto setvalue = [&]() {
char line[5000] ; in >> line ;
548 in >> SetValueMap.at(line) ;
550 catch (
const std::out_of_range & e) {
551 if (!strcmp(line,
"dumps"))
563 else if (word==
"WALLFORCE") {wallforcecompute = true ;
goto LABEL_leave ;}
564 else {printf(
"Unknown dump type\n") ; }
568 if (word !=
"with") printf(
"ERR: expecting keyword 'with'\n") ;
572 for (
int i=0 ; i<nbparam ; i++)
579 else if (word ==
"Orientation")
581 orientationtracking=true ;
602 else printf(
"Unknown asked data %s\n", word.c_str()) ;
615 dumps.push_back(make_pair(dumpkind,dumplist)) ;
620 printf(
"[ERROR] Unknown parameter to set\n") ;
625 map<string,
function<void()>> Lvl0 ;
626 Lvl0[
"event"] = read_event ;
627 Lvl0[
"CG"] = discard_line ;
628 Lvl0[
"set"] = setvalue ;
629 Lvl0[
"auto"] = doauto ;
631 Lvl0[
"directory"] = [&](){in>>Directory ;
if (! fs::exists(Directory)) fs::create_directory(Directory); };
632 Lvl0[
"dimensions"] = [&](){
int nn;
int dd ; in>>dd>>nn ;
if (
N!=nn ||
d!=dd) {printf(
"[ERROR] Dimension of number of particles not matching the input file requirements d=%d N=%d\n",
d,
N) ; std::exit(2) ; }} ;
633 Lvl0[
"location"] = [&]()
636 in >> ids ;
for (
int i=0 ; i<d ; i++) in >> locs[i] ;
639 while (
id.has_value())
641 for (
int i=0 ;
id.has_value() && i<
d ; i++)
648 printf(
"[INFO] Changing particle location.\n") ;
651 Lvl0[
"velocity"] = [&](){
int id ; in>>id ;
for (
int i=0 ; i<
d ; i++) {in >> V[id][i] ;} printf(
"[INFO] Changing particle velocity.\n") ; } ;
652 Lvl0[
"omega"] = [&](){
int id ; in>>id ;
for (
int i=0 ; i<
d*(
d-1)/2 ; i++) {in >> Omega[id][i] ;} printf(
"[INFO] Changing particle angular velocity.\n") ; } ;
653 Lvl0[
"freeze"] = [&](){
int id ; in>>id ; Frozen[id]=true ; printf(
"[INFO] Freezing particle.\n") ;} ;
654 Lvl0[
"radius"] = [&](){
int id ;
double radius ; in>>
id>>
radius ;
if(
id==-1) r =
v1d(
N,
radius) ;
else r[id]=
radius ; printf(
"[INFO] Set radius of particle.\n") ;} ;
655 Lvl0[
"mass"] = [&](){
int id ;
double mass ; in>>
id>>
mass ;
if(
id==-1) m =
v1d(
N,
mass ) ;
else r[id]=
mass ; printf(
"[INFO] Set mass of particle.\n") ;} ;
656 Lvl0[
"gravity"] = [&](){
for (
int i=0 ; i<
d ; i++) {in >> g[i] ;} printf(
"[INFO] Changing gravity.\n") ; } ;
658 Lvl0[
"ContactStrategy"] = [&](){ std::string s ; in >> s ;
if (s==
"naive") {contact_strategy =
ContactStrategies::NAIVE ; }
661 else {printf(
"[WARN] Unknown contact strategy\n") ; }} ;
662 Lvl0[
"gravityangle"] = [&](){
double intensity, angle ; in >> intensity >> angle ;
664 g[0] = -intensity *
cos(angle / 180. * M_PI) ;
665 g[1] = intensity *
sin(angle / 180. * M_PI) ;
666 printf(
"[INFO] Changing gravity angle in degree between x0 and x1.\n") ;
668 Lvl0[
"gravityrotate"] = [&] () {
671 in >> grav_intensity >> grav_omega >> grav_rotdim[0] >> grav_rotdim[1] ;
672 printf(
"[INFO] Setting up a rotating gravity\n") ;
674 Lvl0[
"boundary"] = [&](){
size_t id ; in>>id ;
676 char line [5000] ; in>>line ;
677 if (!strcmp(line,
"PBC"))
679 else if (!strcmp(line,
"WALL"))
681 else if (!strcmp(line,
"MOVINGWALL"))
683 else if (!strcmp(line,
"SPHERE"))
685 else if (!strcmp(line,
"HEMISPHERE"))
687 else if (!strcmp(line,
"AXIALCYLINDER"))
689 else if (!strcmp(line,
"ROTATINGSPHERE"))
691 else if (!strcmp(line,
"PBCLE"))
696 else if (!strcmp(line,
"ELLIPSE"))
698 else if (!strcmp(line,
"REMOVE"))
700 else printf(
"[WARN] Unknown boundary condition, unchanged.\n") ;
704 printf(
"[INFO] Changing BC.\n") ;
706 Lvl0[
"rigid"] = [&] ()
708 size_t id, npart ; in >> id ;
709 if (RigidBodies.
RB.size()<
id+1) RigidBodies.
RB.resize(
id+1) ;
715 std::vector<int> ids ;
int tmp ;
716 for (
size_t i=0 ; i<npart ; i++)
721 RigidBodies.
RB[id].setparticles(ids, X, m) ;
723 else if (s==
"gravity")
726 if (s==
"on") RigidBodies.
RB[id].cancelgravity = false ;
727 else if (s==
"off") RigidBodies.
RB[id].cancelgravity = true ;
729 else if (s==
"addforce")
731 for (
int dd=0 ; dd<
d ; dd++)
732 in >> RigidBodies.
RB[
id].addforce[dd] ;
734 else if (s==
"velocity")
736 for (
int dd=0 ; dd<
d ; dd++)
738 printf(
"%g %g\n", RigidBodies.
RB[0].setvel[0], RigidBodies.
RB[0].setvel[1]) ;
741 printf(
"[INFO] Defining a rigid body.\n") ;
743 Lvl0[
"mesh"] = [&] ()
747 if (s==
"file" || s==
"string")
752 std::ifstream i(s.c_str());
753 if (i.is_open()==
false) {printf(
"Cannot find the json file provided as argument\n") ; return ; }
758 std::getline(in, s) ;
763 if (j[
"dimension"].get<int>()!=
d) {printf(
"Incorrect dimension in the json Mesh file: %d, expecting %d.\n", j[
"dimension"].get<int>(),
d) ; return ;}
764 for (
auto & v: j[
"objects"])
766 Meshes.push_back({v[
STR_PROTECT(
"dimensionality")].get<
int>(), v[
"vertices"].
get<std::vector<std::vector<double>>>()}) ;
768 printf(
"[INFO] Mesh object added.\n") ;
772 else if (s==
"translate")
774 std::vector<double> t(
d,0) ;
775 for (
int i=0 ; i<d ; i++) in>>t[i] ;
776 for (
auto &v: Meshes) v.translate(t) ;
778 else if (s==
"rotate")
780 std::vector<double> r(
d*
d, 0) ;
781 for (
int i=0 ; i<d*d ; i++) in >> r[i] ;
782 for (
auto &v: Meshes) v.rotate(r) ;
784 else if (s==
"remove")
788 Meshes.erase(Meshes.begin()+
id) ;
790 else if (s==
"export")
793 FILE * out = fopen(s.c_str(),
"w") ;
794 if (out==NULL) printf(
"[WARN] Cannot open file to export mesh") ;
797 fprintf(out,
"{\n \"dimension\": %d, \n \"objects\":[\n",
d) ;
798 for (
size_t i=0 ; i<Meshes.size() ; i++)
800 auto res = Meshes[i].export_json() ;
801 fprintf(out,
"%s", res.c_str()) ;
802 if (i<Meshes.size()-1) fprintf(out,
",\n") ;
804 fprintf(out,
"\n]}") ;
810 printf(
"[WARN] Unknown mesh subcommand\n") ;
813 Lvl0[
"restart"] = [&] () {
815 std::string s ; in >> s ;
817 restart_flag |= (1<<1) ;
819 restart_flag |= (2<<1) ;
826 in >> restart_filename ;
833 if (line[0]==
'#') {discard_line() ; return ;}
834 try {Lvl0.at(line)() ; }
835 catch (
const std::out_of_range & e) { printf(
"LVL0 command unknown: %s\n", line.c_str()) ; discard_line() ; }
844 printf(
"WARN: it is probably a bad idea to use remove particle which hasn't been tested ... \n") ;
845 X.erase (X.begin()+idx) ; V.erase (V.begin()+idx) ;
846 A.erase (A.begin()+idx) ; Omega.erase (Omega.begin()+idx) ;
847 F.erase (F.begin()+idx) ; FOld.erase (FOld.begin()+idx) ;
848 Torque.erase (Torque.begin()+idx) ; TorqueOld.erase (TorqueOld.begin()+idx) ;
849 I.erase(I.begin()+idx) ; m.erase(m.begin()+idx) ; r.erase(r.begin()+idx) ;
850 Frozen.erase(Frozen.begin()+idx) ;
857 printf(
"add_particle NOT IMPLEMENTED YET\n") ;
863 boost::random::mt19937
rng(seed);
864 boost::random::uniform_01<boost::mt19937> rand(
rng) ;
865 if (!strcmp(line,
"square"))
867 auto m = *(std::max_element(r.begin(), r.end())) ;
870 for (dd=0 ; dd<
d ; dd++) X[0][dd]=
Boundaries[dd].xmin+m ;
871 for (
int i=1 ; i<
N ; i++)
874 for (dd=0 ; dd<
d ; dd++)
882 if (dd==
d) {printf(
"WARN: cannot affect all particles on the square lattice, not enough space in the simulation box\n") ; break ; }
885 else if (!strcmp(line,
"randomsquare"))
887 auto m = *(std::max_element(r.begin(), r.end())) ;
890 for (dd=0 ; dd<
d ; dd++) X[0][dd]=
Boundaries[dd].xmin+m ;
891 for (
int i=1 ; i<
N ; i++)
894 for (dd=0 ; dd<
d ; dd++)
898 X[i][dd] =
Boundaries[dd].xmin+m + 0.1*m*(rand()-0.5) ;
902 if (dd==
d) {printf(
"WARN: cannot affect all particles on the square lattice, not enough space in the simulation box\n") ; break ; }
905 else if (!strcmp(line,
"randomdrop"))
908 for (
int i=0 ; i<
N ; i++)
910 for(
int dd=0 ; dd <
d ; dd++)
919 else if (!strcmp(line,
"insphere"))
922 auto w = std::find_if(
Boundaries.begin(),
Boundaries.end(), [](
auto u){return (u.Type==WallType::SPHERE || u.Type==WallType::ROTATINGSPHERE) ; }) ;
923 if ( w ==
Boundaries.end()) {printf(
"ERR: the spherical wall cannot be found\n") ; fflush(stdout) ; }
926 for (
int i=0 ; i<
N ; i++)
929 printf(
".") ; fflush(stdout);
932 for(
int dd=0 ; dd <
d ; dd++)
940 else if (!strcmp(line,
"incylinder"))
943 auto w = std::find_if(
Boundaries.begin(),
Boundaries.end(), [](
auto u){return (u.Type==WallType::AXIALCYLINDER) ; }) ;
944 if ( w==
Boundaries.end()) {printf(
"ERR: the cylinder wall cannot be found\n") ; fflush(stdout) ; }
947 for (
int i=0 ; i<
N ; i++)
950 printf(
".") ; fflush(stdout);
953 for(
int dd=0 ; dd <
d ; dd++)
962 dst += X[i][dd]*X[i][dd] ;
968 else if (!strcmp(line,
"roughinclineplane"))
970 printf(
"Location::roughinclineplane assumes a plane of normal [1,0,0...] at location 0 along the 1st dimension.") ; fflush(stdout) ;
971 auto m = *(std::max_element(r.begin(), r.end())) ;
973 for (
int dd=0 ; dd<
d ; dd++) X[0][dd]=
Boundaries[dd].xmin+m+delta ;
975 for (
int i=1 ; i<
N ; i++)
978 for (
int dd=
d-1 ; dd>=0 ; dd--)
980 X[i][dd] += 2*m+2*delta ;
986 if (X[i][0]==
Boundaries[0].xmin+m+delta) Frozen[i]=true ;
988 for (
int dd=0 ; dd<
d ; dd++)
989 X[i-1][dd] += (rand()-0.5)*2*delta ;
992 else if (!strcmp(line,
"smallroughinclineplane"))
994 printf(
"Location::smallroughinclineplane assumes a plane of normal [1,0,0...] at location 0 along the 1st dimension. The frozen particles are forced to be the smallest particle radius\n") ; fflush(stdout) ;
995 auto r_max = *(std::max_element(r.begin(), r.end())) ;
998 double delta=0.1*r_max ;
999 int i_bottom_layer = 1;
1000 for (
int dd=1 ; dd<
d ; dd++)
1002 printf(
"BOTTOM LAYER NUMBER: %d\n", i_bottom_layer);
1006 for (
int i=1 ; i<
N ; i++)
1009 if (i < i_bottom_layer ) {
1018 for (
int dd=
d-1 ; dd>=0 ; dd--)
1020 X[i][dd] += 2*m+2*delta ;
1022 if (i < i_bottom_layer ) {
1031 for (
int dd=0 ; dd<
d ; dd++) {
1032 if (i >= i_bottom_layer) {
1033 X[i][dd] += (rand()-0.5)*2*delta ;
1038 for (
int i=1 ; i<i_bottom_layer ; i++)
1040 X[i][0] += rand()*2*delta;
1043 else if (!strcmp(line,
"roughinclineplane2"))
1045 printf(
"Location::roughinclineplane assumes a plane of normal [1,0,0...] at location 0 along the 1st dimension.") ; fflush(stdout) ;
1046 auto m = *(std::max_element(r.begin(), r.end())) ;
1047 double delta=0.1*m ;
int ddd ;
1048 for (
int dd=0 ; dd<
d ; dd++) X[0][dd]=
Boundaries[dd].xmin+m ;
1049 Frozen[0]=true ;
bool bottomlayer=true ;
1050 for (
int i=1 ; i<
N ; i++)
1053 for (ddd=
d-1 ; ddd>=0 ; ddd--)
1065 X[i][ddd] += 2*m+2*delta ;
1072 if (ddd==0) bottomlayer=false ;
1076 X[i-1][0] += rand()*delta ;
1080 for (
int dd=0 ; dd<
d ; dd++)
1081 X[i-1][dd] += (rand()-0.5)*2*delta ;
1085 else if (!strcmp(line,
"quasicrystal"))
1087 auto m = *(std::max_element(r.begin(), r.end())) ;
1091 for (dd=0 ; dd<
d ; dd++) { X[0][dd]=
Boundaries[dd].xmin+m ; }
1092 for (
int i=1 ; i<
N ; i++)
1095 for (dd=0 ; dd<
d ; dd++)
1103 if (dd==
d) {printf(
"WARN: cannot affect all particles on the square lattice, not enough space in the simulation box\n") ; break ; }
1106 else if (!strcmp(line,
"fromfile"))
1108 while (*extras ==
' ') extras++ ;
1109 std::ifstream in(extras);
1111 if (!in) { std::cerr <<
"Failed to open the file." << std::endl;
return;}
1116 for (
int dd=0 ; dd<
d ; dd++)
1122 printf(
"ERR: undefined initial location function.\n") ;
1128 std::istringstream s(line) ;
1130 double minr, maxr, fraction, fuzz ;
1131 boost::random::mt19937
rng(seed);
1132 boost::random::uniform_01<boost::mt19937> rand(
rng) ;
1135 printf(
"[%s]\n", word.c_str()) ;
1136 if (word ==
"uniform")
1138 s >> minr ; s >> maxr ;
1139 for (
auto & v : r) v = rand()*(maxr-minr)+minr ;
1141 else if (word ==
"bidisperse")
1143 s >> minr ; s >> maxr ;
1148 double f = fraction*Vs/((1-fraction)*Vl+fraction*Vs) ;
1150 for (
auto & v : r) v = (rand()<f?maxr:minr) ;
1153 else if (word ==
"bidisperse_fuzzy")
1155 s >> minr ; s >> maxr ;
1161 double f = fraction*Vs/((1-fraction)*Vl+fraction*Vs) ;
1165 v = (rand()<f?maxr:minr) ;
1166 v = v + (rand()*2-1)*(fuzz*v) ;
1170 printf(
"WARN: unknown radius distribution automatic creation. Nothing done ...\n") ;
1178 static bool first=true ;
1179 static double Rmax, mmax ;
1182 Rmax=*max_element(r.begin(), r.end()) ;
1183 mmax=*max_element(m.begin(), m.end()) ;
1193 if (!
first) printf(
"\e[8A") ;
1195 printf(
"\n\e[80G NContacts: %d | Nghosts: %d \n", nct, ngst) ;
1197 double Vmax=
Tools<d>::norm(*max_element(V.begin(), V.end(), [](
cv1d &
a,
cv1d &b) {return (Tools<d>::normsq(a)<Tools<d>::normsq(b)) ;})) ;
1198 double Omegamax=
Tools<d>::skewnorm(*max_element(Omega.begin(), Omega.end(), [](
cv1d &
a,
cv1d &b) {return (Tools<d>::skewnormsq(a)<Tools<d>::skewnormsq(b)) ;})) ;
1199 double Torquemax=
Tools<d>::skewnorm(*max_element(Torque.begin(), Torque.end(), [](
cv1d &
a,
cv1d &b) {return (Tools<d>::skewnormsq(a)<Tools<d>::skewnormsq(b)) ;})) ;
1200 double Fmax=
Tools<d>::norm(*max_element(F.begin(), F.end(), [](
cv1d &
a,
cv1d &b) {return (Tools<d>::normsq(a)<Tools<d>::normsq(b)) ;})) ;
1203 printf(
"\e[80G Max V: %15g | V dt / R = %15g \n", Vmax, Vmax*dt/Rmax) ;
1204 printf(
"\e[80G Max O: %15g | Omega dt = %15g \n", Omegamax, Omegamax*dt) ;
1205 printf(
"\e[80G Max F: %15g | F dt dt / m r = %15g \n", Fmax, Fmax*dt*dt/(mmax*Rmax)) ;
1206 printf(
"\e[80G Max M: %15g | M dt / m R R = %15g \n", Torquemax, Torquemax*dt/(mmax*Rmax*Rmax)) ;
1207 printf(
"\e[80G | g dt dt / R = %15g \n",
Tools<d>::norm(g)*dt*dt/Rmax) ;
1228 for (
auto v: r)
xmlout->
fic << v <<
" " ;
1236 for (
auto v : dumps)
1243 for (
auto v : dumps)
1251 int Parameters<d>::dumphandling (
int ti,
double t,
v2d &X,
v2d &V,
v1d &Vmag,
v2d &A,
v2d &Omega,
v1d &OmegaMag, vector<uint32_t> &PBCFlags,
v1d & Z,
Multiproc<d> & MP)
1253 for (
auto v : dumps)
1257 char path[500] ; sprintf(path,
"%s/dump-%05d.csv", Directory.c_str(), ti) ;
1269 char path[500] ; sprintf(path,
"%s/dumpA-%05d.csv", Directory.c_str(), ti) ;
1277 char path[500] ; sprintf(path,
"%s/dumpcontactforce-%05d.csv", Directory.c_str(), ti) ;
1278 FILE * out = fopen(path,
"w") ;
1279 if (out == NULL) {printf(
"[ERR] Cannot open file for contact force writing.\n") ; fflush(stdout) ;
return 1 ; }
1280 savecsvcontact(out, v.second, MP, X) ;
1287 char path[500] ; sprintf(path,
"%s/dump-%05d.vtk", Directory.c_str(), ti) ;
1292 vector<std::pair<ExportData, int>> mapping ;
1293 vector<vector<double>> contactdata ;
1296 std::tie(mapping, contactdata) = MP.
contacts2array(v.second, X, *
this) ;
1297 if (mapping[0].
first !=
ExportData::IDS) printf(
"ERR: something went wrong in writing contact data in the vtk file %X\n",
static_cast<unsigned int>(mapping[0].
first)) ;
1304 vector <TensorInfos> val;
1313 vector<double> tmpid (
N, 0) ;
1314 for (
int i=0 ; i<
N ; i++)
1319 if (mapping.size()>1)
1323 for (
auto & v:mapping)
1348 printf(
"WARN: netcdf writing hasn't been tested and therefore is not plugged in\n") ;
1352 if (xmlstarted==
false)
1354 char path[500] ; sprintf(path,
"%s/dump.xml", Directory.c_str()) ;
1364 printf(
"Omega Mag not implemented yet\n");
1371 for (
auto & v:mapping)
1403 if (xmlstarted==
false)
1405 char path[500] ; sprintf(path,
"%s/dump.xml", Directory.c_str()) ;
1415 printf(
"Omega Mag not implemented yet\n");
1432 for (
int dd = 0 ; dd<
d ; dd++)
1433 fprintf(out,
"x%d_i, ", dd) ;
1434 for (
int dd = 0 ; dd<
d ; dd++)
1435 fprintf(out,
"x%d_j, ", dd) ;
1438 for (
int dd = 0 ; dd<
d ; dd++)
1439 fprintf(out,
"Fn%d_i, ", dd) ;
1441 for (
int dd = 0 ; dd<
d ; dd++)
1442 fprintf(out,
"Ft%d_i, ", dd) ;
1445 for (
int dd = 0 ; dd<
d*(
d-1)/2 ; dd++)
1448 fprintf(out,
"Torque%d:%d_i, ", val.first, val.second) ;
1450 for (
int dd = 0 ; dd<
d*(
d-1)/2 ; dd++)
1453 fprintf(out,
"Torque%d:%d_j, ", val.first, val.second) ;
1457 fprintf(out,
"GhostMask, ") ;
1459 fprintf(out,
"GhostDir, ") ;
1462 for (
int dd = 0 ; dd<
d ; dd++)
1463 fprintf(out,
"lij%d, ", dd) ;
1467 fprintf(out,
"\n") ;
1469 for (
auto & CLp : MP.
CLp)
1471 for (
auto & contact: CLp.v)
1474 fprintf(out,
"%d %d ", contact.i, contact.j) ;
1477 for (
auto dd : X[contact.i])
1478 fprintf(out,
"%g ", dd) ;
1479 for (
auto dd : X[contact.j])
1480 fprintf(out,
"%g ", dd) ;
1483 for (
auto dd : contact.infos->Fn)
1484 fprintf(out,
"%g ", dd) ;
1486 for (
auto dd : contact.infos->Ft)
1487 fprintf(out,
"%g ", dd) ;
1491 for (
auto dd : contact.infos->Torquei)
1492 fprintf(out,
"%g ", dd) ;
1493 for (
auto dd : contact.infos->Torquej)
1494 fprintf(out,
"%g ", dd) ;
1498 fprintf(out,
"%d ", contact.ghost) ;
1500 fprintf(out,
"%d ", contact.ghostdir) ;
1504 auto [loc,branch] = contact.compute_branchvector(X, *
this) ;
1506 for (
int dd = 0 ; dd<
d ; dd++) fprintf(out,
"%g ", branch[dd]) ;
1508 fprintf(out,
"\n") ;
EIGEN_DEVICE_FUNC const FloorReturnType floor() const
Definition: ArrayCwiseUnaryOps.h:481
EIGEN_DEVICE_FUNC const SqrtReturnType sqrt() const
Definition: ArrayCwiseUnaryOps.h:187
EIGEN_DEVICE_FUNC const CosReturnType cos() const
Definition: ArrayCwiseUnaryOps.h:237
EIGEN_DEVICE_FUNC const SinReturnType sin() const
Definition: ArrayCwiseUnaryOps.h:255
double nan_or_double(istream &in)
Definition: Parameters.h:294
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.hpp:25318
internal::enable_if< internal::valid_indexed_view_overload< RowIndices, ColIndices >::value &&internal::traits< typename EIGEN_INDEXED_VIEW_METHOD_TYPE< RowIndices, ColIndices >::type >::ReturnAsIndexedView, typename EIGEN_INDEXED_VIEW_METHOD_TYPE< RowIndices, ColIndices >::type >::type operator()(const RowIndices &rowIndices, const ColIndices &colIndices) EIGEN_INDEXED_VIEW_METHOD_CONST
Definition: IndexedViewMethods.h:73
boost::random::mt19937 rng(static_cast< unsigned int >(std::time(nullptr)))
Manual multiprocessor handling for OpenMP, for max efficiency & avoiding bugs & race conditions,...
Definition: Multiproc.h:60
vector< ContactList< d > > CLp
ContactList particle-particle for each processor.
Definition: Multiproc.h:271
Generic class to handle the simulation set up.
Definition: Parameters.h:128
vector< double > g
Gravity vector.
Definition: Parameters.h:197
void do_nothing(double time __attribute__((unused)))
Definition: Parameters.h:261
bool contactforcedump
Extract the forces between grains as well?
Definition: Parameters.h:207
bool orientationtracking
Track orientation?
Definition: Parameters.h:201
void load_datafile(char path[], v2d &X, v2d &V, v2d &Omega)
Load and parse input script.
Definition: Parameters.h:446
void remove_particle(int idx, v2d &X, v2d &V, v2d &A, v2d &Omega, v2d &F, v2d &FOld, v2d &Torque, v2d &TorqueOld)
Not tested.
Definition: Parameters.h:842
bool perform_forceinsphere(v1d &X)
Definition: Parameters.h:382
void perform_PBCLE_move()
Definition: Parameters.h:358
void do_gravityrotate(double deltatime)
Definition: Parameters.h:263
double T
Run until this time (note it is a floating point).
Definition: Parameters.h:175
void quit_cleanly()
Close opened dump files in the event of an emergency quit (usually a SIGINT signal to the process)
Definition: Parameters.h:1234
void init_radii(char line[], v1d &r)
Set particle radii.
Definition: Parameters.h:1126
bool forceinsphere
Definition: Parameters.h:185
void xml_header()
Write the Xml header (should go into a file dedicated to the writing though ...)
Definition: Parameters.h:1218
bool wallforcecompute
Compute for on the wall?
Definition: Parameters.h:202
void save(Archive &ar) const
Definition: Parameters.h:219
vector< double > r
Particle radii.
Definition: Parameters.h:194
int N
Number of particles.
Definition: Parameters.h:172
void display_info(int tint, v2d &V, v2d &Omega, v2d &F, v2d &Torque, int, int)
On screen information display.
Definition: Parameters.h:1176
RigidBodies_< d > RigidBodies
Handle all the rigid bodies.
Definition: Parameters.h:210
void perform_PBCLE(v1d &X, v1d &V, uint32_t &PBCFlag)
Definition: Parameters.h:335
size_t xml_location
Temporary stores the already written locations in the xml, so that upon restart we can resume at the ...
Definition: Parameters.h:192
int tinfo
Show detail information on scren every this many timesteps.
Definition: Parameters.h:174
double Kt
Tangential spring constant.
Definition: Parameters.h:179
double Gamman
Normal dissipation.
Definition: Parameters.h:180
bool wallforcerequested
Compute for on the wall?
Definition: Parameters.h:203
double graddesc_gamma
Decay rate parameters for the gradient descent algorithm.
Definition: Parameters.h:205
void finalise()
Close opened dump files.
Definition: Parameters.h:1241
Parameters()
Definition: Parameters.h:130
string Directory
Saving directory.
Definition: Parameters.h:200
int savecsvcontact(FILE *out, ExportData outflags, Multiproc< d > &MP, cv2d &X)
Definition: Parameters.h:1427
double Kn
Normal spring constant.
Definition: Parameters.h:178
void load(Archive &ar)
Definition: Parameters.h:233
int dumphandling(int ti, double t, v2d &X, v2d &V, v1d &Vmag, v2d &A, v2d &Omega, v1d &OmegaMag, vector< uint32_t > &PBCFlags, v1d &Z, Multiproc< d > &MP)
Dump writing functions.
Definition: Parameters.h:1251
int set_boundaries()
Set default boundaries.
Definition: Parameters.h:308
double damping
Definition: Parameters.h:184
vector< bool > Frozen
Frozen atom if true.
Definition: Parameters.h:198
double dt
timestep
Definition: Parameters.h:176
void perform_PBC(v1d &X, uint32_t &PBCFlags)
Bring particle back in the simulation box if the grains cross the boundaries.
Definition: Parameters.h:322
vector< Mesh< d > > Meshes
Handle all meshes.
Definition: Parameters.h:211
multimap< float, string > events
For storing events. first is the time at which the event triggers, second is the event command string...
Definition: Parameters.h:216
Parameters(int NN)
Set the default values for all parameters. Calls to setup parameter function should be provided after...
Definition: Parameters.h:131
vector< double > m
Particle mass.
Definition: Parameters.h:195
double cellsize
Size of cells for contact detection.
Definition: Parameters.h:186
void reset_ND(int NN)
reset the full simulation.
Definition: Parameters.h:161
vector< Boundary< d > > Boundaries
List of boundaries. Second dimension is {min, max, length, type}.
Definition: Parameters.h:199
double Mu
Fricton.
Definition: Parameters.h:182
int init_inertia()
Initialise particle moment of inertia.
Definition: Parameters.h:436
void check_events(float time, v2d &X, v2d &V, v2d &Omega)
Verify if an event triggers at the current time time.
Definition: Parameters.h:466
double rho
density
Definition: Parameters.h:177
void add_particle()
Not implemented.
Definition: Parameters.h:855
bool wallforcecomputed
Compute for on the wall?
Definition: Parameters.h:204
void interpret_command(istream &in, v2d &X, v2d &V, v2d &Omega)
Parse input script commands.
Definition: Parameters.h:496
double graddesc_tol
Tolerance for the gradient descent algorithm.
Definition: Parameters.h:206
int init_mass()
Initialise particle mass.
Definition: Parameters.h:428
vector< double > I
Particule moment of inertia.
Definition: Parameters.h:196
vector< std::pair< ExportType, ExportData > > dumps
Vector linking dump file and data dumped.
Definition: Parameters.h:189
void init_locations(char *line, v2d &X, char *extras)
Set particle locations.
Definition: Parameters.h:861
void perform_MOVINGWALL()
Move the boundary wall if moving.
Definition: Parameters.h:369
int tdump
Write dump file every this many timesteps.
Definition: Parameters.h:173
double Gammat
Tangential dissipation.
Definition: Parameters.h:181
double Mu_wall
Definition: Parameters.h:183
unsigned char restart_flag
Definition: Parameters.h:214
Definition: RigidBody.h:48
std::vector< RigidBody< d > > RB
Definition: RigidBody.h:51
void emergencyclose()
Definition: Xml.cpp:183
void header(int dimension, string input)
Definition: Xml.cpp:38
void startTS(double ts)
Definition: Xml.cpp:56
streamoff get_file_location()
Definition: Xml.h:52
void writeArray(string name, vector< vector< double >> *x, int beg, int length, ArrayType t, EncodingType te=EncodingType::ascii)
Definition: Xml.cpp:68
void stopTS()
Definition: Xml.cpp:62
bool closebranch()
Definition: Xml.cpp:15
void save(Archive &ar) const
Definition: Xml.h:63
void openbranch(string name, vector< pair< string, string >> attributes)
Definition: Xml.cpp:4
void load(Archive &ar)
Definition: Xml.h:67
void close()
Definition: Xml.cpp:165
ofstream fic
Definition: Xml.h:60
namespace for Niels Lohmann
Definition: json.hpp:20203
Small class to handle number generator (ie. first:step:last syntax)
Definition: Parameters.h:62
int niter()
Definition: Parameters.h:94
void reset()
Definition: Parameters.h:93
void parse(std::string s)
Definition: Parameters.h:64
T cur()
Definition: Parameters.h:95
@ NONE
Definition: Coarsing.h:58
vector< vector< double > > v2d
Definition: Typedefs.h:10
static void savecsv(char path[], cv2d &X, cv1d &r, const vector< uint32_t > &PBCFlags, cv1d &Vmag, cv1d &OmegaMag, [[maybe_unused]] cv1d &Z)
Save the location and a few more informations in a CSV file.
Definition: Tools.h:380
ExportData & operator>>=(ExportData &w, int u)
Definition: Parameters.h:52
ExportData operator|(ExportData a, ExportData b)
Definition: Parameters.h:49
static void setzero(v2d &a)
Set a matrix to zero in-place.
Definition: Tools.h:117
ExportType & operator|=(ExportType &a, const ExportType b)
Definition: Parameters.h:47
ContactStrategies
Definition: Typedefs.h:22
ExportData operator~(ExportData a)
Definition: Parameters.h:50
static double skewnorm(cv1d &a)
Norm of a skew-symetric matrix.
Definition: Tools.h:125
ExportData
Definition: Parameters.h:46
static double InertiaMomentum(double R, double rho)
Compute the hypersphere moment of inertia.
Definition: Tools.h:865
@ radius
Definition: Typedefs.h:19
@ mass
Definition: Typedefs.h:19
ExportType
Definition: Parameters.h:45
#define STR_PROTECT(s)
Definition: Parameters.h:39
ContactModels
Definition: Typedefs.h:21
bool operator&(ExportType &a, ExportType b)
Definition: Parameters.h:54
auto contacts2array(ExportData exp, cv2d &X, Parameters< d > &P)
pack the contact data in a 2d array
Definition: Multiproc.h:568
const vector< double > cv1d
Definition: Typedefs.h:13
const vector< vector< double > > cv2d
Definition: Typedefs.h:14
ExportData & operator<<=(ExportData &w, int u)
Definition: Parameters.h:53
XMLWriter * xmlout
Definition: DEMND.cpp:22
ExportData & operator&=(ExportData &a, const ExportData b)
Definition: Parameters.h:51
vector< double > v1d
Definition: Typedefs.h:9
static double norm(const vector< double > &a)
Norm of a vector.
Definition: Tools.h:119
static double Volume(double R)
Compute the hypersphere volume.
Definition: Tools.h:853
std::istream & operator>>(std::istream &in, number_gen< T > &n)
Definition: Parameters.h:122
@ CELLS
Definition: Typedefs.h:22
@ OCTREE
Definition: Typedefs.h:22
@ NAIVE
Definition: Typedefs.h:22
@ HERTZ
Definition: Typedefs.h:21
@ HOOKE
Definition: Typedefs.h:21
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16() max(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:576
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool() isnan(const bfloat16 &a)
Definition: BFloat16.h:480
EIGEN_CONSTEXPR Index first(const T &x) EIGEN_NOEXCEPT
Definition: IndexedViewHelper.h:81
svint32_t PacketXi __attribute__((arm_sve_vector_bits(EIGEN_ARM64_SVE_VL)))
Definition: PacketMath.h:33
static const symbolic::SymbolExpr< internal::symbolic_last_tag > last
Definition: IndexedViewHelper.h:38
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())
Definition: json.hpp:5657
struct JsonValue json
Definition: json_parser.h:15
Definition: json.hpp:5678
int write_data(FILE *out, TensorInfos v, int d)
Definition: Vtk.h:73
FILE * open(char path[], int d)
Definition: Vtk.h:4
int write_points(FILE *out, cv2d &X, int d)
Definition: Vtk.h:16
int write_contactlines(FILE *out, cv2d &ids)
Definition: Vtk.h:25
int write_celldata(FILE *out, std::string name, cv2d &v, TensorType order, int idx, int N, int d)
Definition: Vtk.h:103
int write_dimension_data(FILE *out, cv2d &X, cv1d &r, int d, vector< Boundary< dd > > boundaries)
Definition: Vtk.h:47
void close(FILE *out)
Definition: Vtk.h:123
int start_celldata(FILE *out, int N, int Ncf)
Definition: Vtk.h:40
int start_pointdata(FILE *out, cv2d &X)
Definition: Vtk.h:34
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1282
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1181
PUGI_IMPL_FN I min_element(I begin, I end, const Pred &pred)
Definition: pugixml.cpp:7604
Type
Type of JSON value.
Definition: rapidjson.h:644
unsigned int uint32_t
Definition: stdint.h:126
#define SEEK_CUR
Definition: zconf.h:512