int mdlc_tune(double error) { double de,n,gc,lz,lx,a,fa1,fa2,fa0,h; int kc,limitkc=200,flag; MDLC_TRACE(fprintf(stderr, "%d: mdlc_tune().\n", this_node)); n=(double) n_total_particles; lz=box_l[2]; a=box_l[0]*box_l[1]; mpi_bcast_max_mu(); /* we take the maximum dipole in the system, to be sure that the errors in the other case will be equal or less than for this one */ h=dlc_params.h; if (h < 0) return ES_ERROR; if(h > lz) { fprintf(stderr,"tune DLC dipolar: Slab is larger than the box size !!! \n"); exit(1); } if(fabs(box_l[0]-box_l[1])>0.001) { fprintf(stderr,"tune DLC dipolar: box size in x direction is different from y direction !!! \n"); fprintf(stderr,"The tuning formula requires both to be equal. \n"); exit(1); } lx=box_l[0]; flag=0; for(kc=1;kc<limitkc;kc++){ gc=kc*2.0*PI/lx; fa0=sqrt(9.0*exp(+2.*gc*h)*g1_DLC_dip(gc,lz-h)+22.0*g1_DLC_dip(gc,lz)+9.0*exp(-2.0*gc*h)*g1_DLC_dip(gc,lz+h) ); fa1=0.5*sqrt(PI/(2.0*a))*fa0; fa2=g2_DLC_dip(gc,lz); de=n*(mu_max*mu_max)/(4.0*(exp(gc*lz)-1.0)) *(fa1+fa2); if(de<error) {flag=1;break;} } if(flag==0) { fprintf(stderr,"tune DLC dipolar: Sorry, unable to find a proper cut-off for such system and accuracy.\n"); fprintf(stderr,"Try modifiying the variable limitkc in the c-code: dlc_correction.c ... \n"); return ES_ERROR; } dlc_params.far_cut=kc; MDLC_TRACE(fprintf(stderr, "%d: done mdlc_tune().\n", this_node)); return ES_OK; }
int tclcommand_inter_magnetic_parse_mdlc_params(Tcl_Interp * interp, int argc, char ** argv) { double pwerror; double gap_size; double far_cut = -1; MDLC_TRACE(fprintf(stderr, "%d: tclcommand_inter_magnetic_parse_mdlc_params().\n", this_node)); if (argc < 2) { Tcl_AppendResult(interp, "either nothing or mdlc <pwerror> <minimal layer distance> {<cutoff>} expected, not \"", argv[0], "\"", (char *)NULL); return TCL_ERROR; } if (!ARG0_IS_D(pwerror)) return TCL_ERROR; if (!ARG1_IS_D(gap_size)) return TCL_ERROR; argc -= 2; argv += 2; if (argc > 0) { // if there, parse away manual cutoff if(ARG0_IS_D(far_cut)) { argc--; argv++; } else Tcl_ResetResult(interp); if(argc > 0) { Tcl_AppendResult(interp, "either nothing or mdlc <pwerror> <minimal layer distance=size of the gap without particles> {<cutoff>} expected, not \"", argv[0], "\"", (char *)NULL); return TCL_ERROR; } } CHECK_VALUE(mdlc_set_params(pwerror,gap_size,far_cut),"choose a 3d electrostatics method prior to use mdlc"); coulomb.Dprefactor = (temperature > 0) ? temperature*coulomb.Dbjerrum : coulomb.Dbjerrum; }
int mdlc_set_params(double maxPWerror, double gap_size, double far_cut) { MDLC_TRACE(fprintf(stderr, "%d: mdlc_set_params().\n", this_node)); dlc_params.maxPWerror = maxPWerror; dlc_params.gap_size = gap_size; dlc_params.h = box_l[2] - gap_size; switch (coulomb.Dmethod) { #ifdef DP3M case DIPOLAR_MDLC_P3M: case DIPOLAR_P3M: coulomb.Dmethod =DIPOLAR_MDLC_P3M; break; #endif case DIPOLAR_MDLC_DS: case DIPOLAR_DS: coulomb.Dmethod =DIPOLAR_MDLC_DS; break; default: return ES_ERROR; } dlc_params.far_cut = far_cut; if (far_cut != -1) { dlc_params.far_calculated = 0; } else { dlc_params.far_calculated = 1; if (mdlc_tune(dlc_params.maxPWerror) == ES_ERROR) { char *errtxt = runtime_error(128); ERROR_SPRINTF(errtxt, "{009 mdlc tuning failed, gap size too small} "); } } mpi_bcast_coulomb_params(); return ES_OK; }
int mdlc_set_params(double maxPWerror, double gap_size, double far_cut) { MDLC_TRACE(fprintf(stderr, "%d: mdlc_set_params().\n", this_node)); dlc_params.maxPWerror = maxPWerror; dlc_params.gap_size = gap_size; dlc_params.h = box_l[2] - gap_size; switch (coulomb.Dmethod) { #ifdef DP3M case DIPOLAR_MDLC_P3M: case DIPOLAR_P3M: set_dipolar_method_local(DIPOLAR_MDLC_P3M); break; #endif case DIPOLAR_MDLC_DS: case DIPOLAR_DS: set_dipolar_method_local(DIPOLAR_MDLC_DS); break; default: return ES_ERROR; } dlc_params.far_cut = far_cut; if (far_cut != -1) { dlc_params.far_calculated = 0; } else { dlc_params.far_calculated = 1; if (mdlc_tune(dlc_params.maxPWerror) == ES_ERROR) { ostringstream msg; msg <<"mdlc tuning failed, gap size too small"; runtimeError(msg); } } mpi_bcast_coulomb_params(); return ES_OK; }