int tclcommand_inter_coulomb_parse_ewaldgpu(Tcl_Interp * interp, int argc, char ** argv) { double r_cut; int num_kx; int num_ky; int num_kz; double accuracy; double alpha=-1; IntList il; init_intlist(&il); if (argc < 1) { Tcl_AppendResult(interp, "expected: inter coulomb <bjerrum> ewaldgpu <r_cut> (<K_cut> | {<K_cut,x> <K_cut,y><K_cut,z>}) <alpha> \nexpected: inter coulomb <bjerrum> ewaldgpu tune <accuracy> [<precision>] \nexpected: inter coulomb <bjerrum> ewaldgpu tunealpha <r_cut> <K_cut> [<precision>]",(char *) NULL); return TCL_ERROR; } if (ARG0_IS_S("tune")) { int status = tclcommand_inter_coulomb_parse_ewaldgpu_tune(interp, argc-1, argv+1, 0); if(status==TCL_OK) return TCL_OK; if(status==TCL_ERROR) { Tcl_AppendResult(interp, "Accuracy could not been reached. Choose higher K_max or lower accuracy",(char *) NULL); return TCL_ERROR; } } if (ARG0_IS_S("tunealpha")) return tclcommand_inter_coulomb_parse_ewaldgpu_tunealpha(interp, argc-1, argv+1); if(! ARG0_IS_D(r_cut)) return TCL_ERROR; if(argc < 3 || argc > 5) { Tcl_AppendResult(interp, "expected: inter coulomb <bjerrum> ewaldgpu <r_cut> (<K_cut> | {<K_cut,x> <K_cut,y><K_cut,z>}) <alpha> \nexpected: inter coulomb <bjerrum> ewaldgpu tune <accuracy> [<precision>] \nexpected: inter coulomb <bjerrum> ewaldgpu tunealpha <r_cut> <K_cut> [<precision>]",(char *) NULL); return TCL_ERROR; } if(! ARG_IS_I(1, num_kx)) { if( ! ARG_IS_INTLIST(1, il) || !(il.n == 3) ) { Tcl_AppendResult(interp, "integer or interger list of length 3 expected", (char *) NULL); return TCL_ERROR; } else { num_kx = il.e[0]; num_ky = il.e[1]; num_kz = il.e[2]; } } else { num_kz = num_ky = num_kx; } if(argc > 2) { if(! ARG_IS_D(2, alpha)) return TCL_ERROR; } else { Tcl_AppendResult(interp, "Automatic ewaldgpu tuning not implemented.", (char *) NULL); return TCL_ERROR; } if(argc > 3) { if(! ARG_IS_D(3, accuracy)) { Tcl_AppendResult(interp, "accuracy double expected", (char *) NULL); return TCL_ERROR; } } // Create object EwaldgpuForce *A=new EwaldgpuForce(r_cut, num_kx, num_ky, num_kz, alpha); FI.addMethod(A); rebuild_verletlist = 1; ewaldgpu_params.ewaldgpu_is_running = true; ewaldgpu_params.isTuned = true; mpi_bcast_coulomb_params(); mpi_bcast_event(INVALIDATE_SYSTEM); return TCL_OK; }
int tclcommand_invalidate_system(ClientData data, Tcl_Interp *interp, int argc, char **argv) { mpi_bcast_event(INVALIDATE_SYSTEM); return TCL_OK; }
int tclcommand_inter_coulomb_parse_ewaldgpu_tunealpha(Tcl_Interp * interp, int argc, char ** argv) { double r_cut; double alpha; int num_kx; int num_ky; int num_kz; double precision=0.000001; IntList il; init_intlist(&il); if (argc < 3) { Tcl_AppendResult(interp, "wrong # arguments: <r_cut> <K_cut,x> <K_cut,y><K_cut,z> [<precision>] ", (char *) NULL); return TCL_ERROR; } /* PARSE EWALD COMMAND LINE */ /* epsilon */ if (! ARG_IS_D(0, r_cut)) { Tcl_AppendResult(interp, "<r_cut> should be a double",(char *) NULL); } /* k_cut */ if(! ARG_IS_I(1, num_kx)) { if( ! ARG_IS_INTLIST(1, il) || !(il.n == 3) ) { Tcl_AppendResult(interp, "integer or integer list of length 3 expected", (char *) NULL); return TCL_ERROR; } else { num_kx = il.e[0]; num_ky = il.e[1]; num_kz = il.e[2]; } } else { num_kz = num_ky = num_kx; } /* precision */ if (! ARG_IS_D(2, precision)) { Tcl_AppendResult(interp, "<precision> should be a double", (char *) NULL); return 0; } //Compute alpha double q_sqr = ewaldgpu_compute_q_sqare(); alpha = ewaldgpu_compute_optimal_alpha(r_cut, num_kx, num_ky, num_kz, q_sqr, box_l, precision); ewaldgpu_params.isTuned = true; mpi_bcast_coulomb_params(); mpi_bcast_event(INVALIDATE_SYSTEM); // Create object EwaldgpuForce *A=new EwaldgpuForce(r_cut, num_kx, num_ky, num_kz, alpha); FI.addMethod(A); rebuild_verletlist = 1; return TCL_OK; }
int tclcommand_inter_coulomb_parse_ewaldgpu_tune(Tcl_Interp * interp, int argc, char ** argv, int adaptive) { double r_cut; double alpha; int num_kx; int num_ky; int num_kz; int K_max = 30; int time_calc_steps = 0; double accuracy = 0.0001; double precision = 0.000001; while(argc > 0) { if(ARG0_IS_S("accuracy")) { if(! (argc > 1 && ARG1_IS_D(accuracy) && accuracy > 0)) { Tcl_AppendResult(interp, "accuracy expects a positive double ",(char *) NULL); return TCL_ERROR; } } else if(ARG0_IS_S("precision")) { if(! (argc > 1 && ARG1_IS_D(precision) && precision > 0)) { Tcl_AppendResult(interp, "precision expects a positive double ",(char *) NULL); return TCL_ERROR; } } else if(ARG0_IS_S("K_max")) { if(! (argc > 1 && ARG1_IS_I(K_max) && K_max > 0)) { Tcl_AppendResult(interp, "K_max expects a positive integer ",(char *) NULL); return TCL_ERROR; } } else if(ARG0_IS_S("time_calc_steps")) { if(! (argc > 1 && ARG1_IS_I(time_calc_steps) && time_calc_steps > 0)) { Tcl_AppendResult(interp, "time_calc_steps expects a positive integer ",(char *) NULL); return TCL_ERROR; } } /* unknown parameter. Probably one of the optionals */ else break; argc -= 2; argv += 2; } ewaldgpu_set_params_tune(accuracy, precision, K_max, time_calc_steps); /* Create object */ EwaldgpuForce *A=new EwaldgpuForce(r_cut, num_kx, num_ky, num_kz, alpha); FI.addMethod(A); rebuild_verletlist = 1; /* do the tuning */ char *log = NULL; if (ewaldgpu_adaptive_tune(&log) == ES_ERROR) { Tcl_AppendResult(interp, log, "\nfailed to tune ewaldgpu parameters to required accuracy ", (char *) NULL); if (log) free(log); return TCL_ERROR; } /* Tell the user about the tuning outcome */ Tcl_AppendResult(interp, log, (char *) NULL); if (log) free(log); rebuild_verletlist = 1; mpi_bcast_coulomb_params(); mpi_bcast_event(INVALIDATE_SYSTEM); return TCL_OK; }
int tclcommand_reaction(ClientData data, Tcl_Interp * interp, int argc, char ** argv){ #ifdef REACTIONS if (argc == 1 ) return tcl_command_reaction_print_usage(interp); if (argc == 2 ) { if (ARG1_IS_S("off")) { reaction.rate=0.0; mpi_bcast_event(REACTION); return TCL_OK; } if (ARG1_IS_S("print")) { return tcl_command_reaction_print(interp); } } if( argc!=11 && argc!=13) return tcl_command_reaction_print_usage(interp); if(reaction.rate != 0.0) { Tcl_AppendResult(interp, "Currently a simulation can only contain a single reaction!", (char *) NULL); return (TCL_ERROR); } if(time_step < 0.0) { Tcl_AppendResult(interp, "Time step needs to be set before setting up a reaction!", (char *) NULL); return (TCL_ERROR); } argc--; argv++; while (argc>0){ if (ARG_IS_S(0,"product_type")) { if (!ARG_IS_I(1,reaction.product_type)) return tcl_command_reaction_print_usage(interp); argc-=2; argv+=2; } else if (ARG_IS_S(0,"reactant_type")) { if (!ARG_IS_I(1,reaction.reactant_type)) return tcl_command_reaction_print_usage(interp); argc-=2; argv+=2; } else if (ARG_IS_S(0,"catalyzer_type")) { if (!ARG_IS_I(1,reaction.catalyzer_type)) return tcl_command_reaction_print_usage(interp); argc-=2; argv+=2; } else if (ARG_IS_S_EXACT(0,"range")) { if (!ARG_IS_D(1,reaction.range)) return tcl_command_reaction_print_usage(interp); argc-=2; argv+=2; } else if (ARG_IS_S_EXACT(0,"rate")) { if (!ARG_IS_D(1,reaction.rate)) return tcl_command_reaction_print_usage(interp); argc-=2; argv+=2; } else if (ARG_IS_S_EXACT(0,"back_rate")) { if (!ARG_IS_D(1,reaction.back_rate)) return tcl_command_reaction_print_usage(interp); argc-=2; argv+=2; } else { return tcl_command_reaction_print_usage(interp); } } mpi_bcast_event(REACTION); return TCL_OK; #else /* ifdef REACTIONS */ Tcl_AppendResult(interp, "REACTIONS not compiled in!" ,(char *) NULL); return (TCL_ERROR); #endif /* ifdef REACTIONS */ }
int tclcommand_sort_particles(ClientData data, Tcl_Interp *interp, int argc, char **argv) { mpi_bcast_event(SORT_PARTICLES); return TCL_OK; }
int scafacos_p3m_tuning(){ int mesh[3] = {0, 0, 0}, tmp_mesh_points; int tmp_mesh[3]; double r_cut_iL_min, r_cut_iL_max, r_cut_iL = -1, tmp_r_cut_iL=0.0; int cao; double alpha_L = -1, tmp_alpha_L=0.0; double accuracy = -1, tmp_accuracy=0.0; double time_best=1e20, tmp_time; char b[3*ES_INTEGER_SPACE + 3*ES_DOUBLE_SPACE + 128]; int buffer_cao, buffer_grid; double buffer_alpha_L, buffer_r_cut_iL, buffer_tolerance_field; if (skin == -1) { // *log = strcat_alloc(*log, "p3m cannot be tuned, since the skin is not yet set"); return ES_ERROR; } /* preparation */ mpi_bcast_event(FCS_P3M_COUNT_CHARGES); /* Print Status */ sprintf(b, "P3M tune parameters: Accuracy goal = %.5e\n", scafacos_p3m.params.tolerance_field); // *log = strcat_alloc(*log, b); sprintf(b, "System: box_l = %.5e # charged part = %d Sum[q_i^2] = %.5e\n", box_l[0], scafacos_p3m.sum_qpart, scafacos_p3m.sum_q2); // *log = strcat_alloc(*log, b); if (scafacos_p3m.sum_qpart == 0) { // *log = strcat_alloc(*log, "no charged particles in the system, cannot tune P3M"); return ES_ERROR; } double density, r_cut; density = n_total_particles /(box_l[0]* box_l[1]* box_l[2]); int number = 100; r_cut= pow(number/ density/3.14 *3 /4 , 1/3.0); if(scafacos_p3m.params.r_cut_iL == 0.0) { // WARNING: r_cut_iL_min should not be small ! r_cut_iL_min = dmin(min_local_box_l, min_box_l/2); r_cut_iL_min *= 0.18; r_cut_iL_min = r_cut *0.8; r_cut_iL_max = dmin(min_local_box_l, min_box_l/2); r_cut_iL_max *= 0.28; r_cut_iL_max = r_cut *1.5; if(r_cut_iL_max >= 4.5) r_cut_iL_max = 4.5; // r_cut_iL_max = dmin(min_local_box_l, min_box_l/2);// - skin; // r_cut_iL_min *= box_l_i[0]; // r_cut_iL_max *= box_l_i[0]; fprintf(stderr, "r_cut_iL_max: %f r_cut_iL_min: %f \n", r_cut_iL_max, r_cut_iL_min); fprintf(stderr, "box_l is: %f \n", box_l[0]); } else{ fprintf(stderr, "Scafacos_p3m tuning varies the cutoff radius; you have to leave cutoff unspecified"); return ES_ERROR; } // *log = strcat_alloc(*log, "mesh cao r_cut_iL alpha_L err rs_err ks_err time [ms]\n"); for(tmp_r_cut_iL = r_cut_iL_min; tmp_r_cut_iL <= r_cut_iL_max; tmp_r_cut_iL += 0.1){ scafacos_p3m.params.cutoff = tmp_r_cut_iL; tmp_time = time_force_calc(1); // *log = strcat_alloc(*log, " %f ms "); fprintf(stderr, "time: %f \n", tmp_time); // *log = strcat_alloc(*log, b); if ((tmp_time < time_best) && (tmp_time > 0)) { time_best = tmp_time; fcs_p3m_get_grid(fcs_handle, &buffer_grid); fcs_p3m_get_cao(fcs_handle, &buffer_cao); fcs_p3m_get_r_cut(fcs_handle, &buffer_r_cut_iL); fcs_p3m_get_alpha(fcs_handle, &buffer_alpha_L); fcs_p3m_get_tolerance_field(fcs_handle, &buffer_tolerance_field); // target accuracy remains the same } /* no hope of further optimisation */ //else if (tmp_time > time_best + P3M_TIME_GRAN) { // break; //} } if(time_best == 1e20) { fprintf(stderr, "failed to tune P3M parameters to required accuracy\n"); return ES_ERROR; } /* prepare tuned p3m parameters for broadcast*/ scafacos_p3m.params.cao = buffer_cao; scafacos_p3m.params.alpha_L = buffer_alpha_L; scafacos_p3m.params.grid = buffer_grid; scafacos_p3m.params.cutoff = buffer_r_cut_iL; scafacos_p3m.params.alpha_L = buffer_alpha_L; /* Tell the user about the outcome */ fprintf(stderr, "\nresulting parameters:\n%-4d %-3d %.5e %.5e %.5e %-8d\n", buffer_grid, buffer_cao, buffer_r_cut_iL, buffer_alpha_L, buffer_tolerance_field, (int)time_best); return ES_OK; }