int tclcommand_integrate(ClientData data, Tcl_Interp *interp, int argc, char **argv) { int n_steps; INTEG_TRACE(fprintf(stderr,"%d: integrate:\n",this_node)); if (argc < 1) { Tcl_AppendResult(interp, "wrong # args: \n\"", (char *) NULL); return tclcommand_integrate_print_usage(interp); } else if (argc < 2) { return tclcommand_integrate_print_status(interp); } if (ARG1_IS_S("set")) { if (argc < 3) return tclcommand_integrate_print_status(interp); if (ARG_IS_S(2,"nvt")) return tclcommand_integrate_set_nvt(interp, argc, argv); #ifdef NPT else if (ARG_IS_S(2,"npt_isotropic")) return tclcommand_integrate_set_npt_isotropic(interp, argc, argv); #endif else { Tcl_AppendResult(interp, "unknown integrator method:\n", (char *)NULL); return tclcommand_integrate_print_usage(interp); } } else if ( !ARG_IS_I(1,n_steps) ) return tclcommand_integrate_print_usage(interp); /* go on with integrate <n_steps> */ if(n_steps < 0) { Tcl_AppendResult(interp, "illegal number of steps (must be >0) \n", (char *) NULL); return tclcommand_integrate_print_usage(interp);; } /* perform integration */ if (mpi_integrate(n_steps)) return mpi_gather_runtime_errors(interp, TCL_OK); return TCL_OK; }
/** Parse integrate npt_isotropic command */ int tclcommand_integrate_set_npt_isotropic(Tcl_Interp *interp, int argc, char **argv) { int xdir, ydir, zdir; xdir = ydir = zdir = nptiso.cubic_box = 0; if (argc < 4) { Tcl_AppendResult(interp, "wrong # args: \n", (char *)NULL); return tclcommand_integrate_print_usage(interp); } /* set parameters p_ext and piston */ if ( !ARG_IS_D(3, nptiso.p_ext) ) return tclcommand_integrate_print_usage(interp); tclcallback_p_ext(interp, &nptiso.p_ext); if ( argc > 4 ) { if(!ARG_IS_D(4, nptiso.piston) ) return tclcommand_integrate_print_usage(interp); tclcallback_npt_piston(interp, &nptiso.piston); } else if ( nptiso.piston <= 0.0 ) { Tcl_AppendResult(interp, "You must set <piston> as well before you can use this integrator! \n", (char *)NULL); return tclcommand_integrate_print_usage(interp); } if ( argc > 5 ) { if (!ARG_IS_I(5,xdir) || !ARG_IS_I(6,ydir) || !ARG_IS_I(7,zdir) ) { return tclcommand_integrate_print_usage(interp);} else { /* set the geometry to include rescaling specified directions only*/ nptiso.geometry = 0; nptiso.dimension = 0; nptiso.non_const_dim = -1; if ( xdir ) { nptiso.geometry = ( nptiso.geometry | NPTGEOM_XDIR ); nptiso.dimension += 1; nptiso.non_const_dim = 0; } if ( ydir ) { nptiso.geometry = ( nptiso.geometry | NPTGEOM_YDIR ); nptiso.dimension += 1; nptiso.non_const_dim = 1; } if ( zdir ) { nptiso.geometry = ( nptiso.geometry | NPTGEOM_ZDIR ); nptiso.dimension += 1; nptiso.non_const_dim = 2; } } } else { /* set the geometry to include rescaling in all directions; the default*/ nptiso.geometry = 0; nptiso.geometry = ( nptiso.geometry | NPTGEOM_XDIR ); nptiso.geometry = ( nptiso.geometry | NPTGEOM_YDIR ); nptiso.geometry = ( nptiso.geometry | NPTGEOM_ZDIR ); nptiso.dimension = 3; nptiso.non_const_dim = 2; } if ( argc > 8 ) { /* enable if the volume fluctuations should also apply to dimensions which are switched off by the above flags and which do not contribute to the pressure (3D) / tension (2D, 1D) */ if (!ARG_IS_S(8,"-cubic_box")) { return tclcommand_integrate_print_usage(interp); } else { nptiso.cubic_box = 1; } } /* Sanity Checks */ #ifdef ELECTROSTATICS if ( nptiso.dimension < 3 && !nptiso.cubic_box && coulomb.bjerrum > 0 ){ fprintf(stderr,"WARNING: If electrostatics is being used you must use the -cubic_box option!\n"); fprintf(stderr,"Automatically reverting to a cubic box for npt integration.\n"); fprintf(stderr,"Be aware though that all of the coulombic pressure is added to the x-direction only!\n"); nptiso.cubic_box = 1; } #endif #ifdef DIPOLES if ( nptiso.dimension < 3 && !nptiso.cubic_box && coulomb.Dbjerrum > 0 ){ fprintf(stderr,"WARNING: If magnetostatics is being used you must use the -cubic_box option!\n"); fprintf(stderr,"Automatically reverting to a cubic box for npt integration.\n"); fprintf(stderr,"Be aware though that all of the magnetostatic pressure is added to the x-direction only!\n"); nptiso.cubic_box = 1; } #endif if( nptiso.dimension == 0 || nptiso.non_const_dim == -1) { Tcl_AppendResult(interp, "You must enable at least one of the x y z components as fluctuating dimension(s) for box length motion!", (char *)NULL); Tcl_AppendResult(interp, "Cannot proceed with npt_isotropic, reverting to nvt integration... \n", (char *)NULL); integ_switch = INTEG_METHOD_NVT; mpi_bcast_parameter(FIELD_INTEG_SWITCH); return (TCL_ERROR); } /* set integrator switch */ integ_switch = INTEG_METHOD_NPT_ISO; mpi_bcast_parameter(FIELD_INTEG_SWITCH); /* broadcast npt geometry information to all nodes */ mpi_bcast_nptiso_geom(); return (TCL_OK); }
int tclcommand_integrate(ClientData data, Tcl_Interp *interp, int argc, char **argv) { int n_steps, reuse_forces = 0; INTEG_TRACE(fprintf(stderr, "%d: integrate:\n", this_node)); if (argc < 1) { Tcl_AppendResult(interp, "wrong # args: \n\"", (char *)NULL); return tclcommand_integrate_print_usage(interp); } else if (argc < 2) { return tclcommand_integrate_print_status(interp); } if (ARG1_IS_S("set")) { if (argc < 3) return tclcommand_integrate_print_status(interp); if (ARG_IS_S(2, "nvt")) return tclcommand_integrate_set_nvt(interp, argc, argv); #ifdef NPT else if (ARG_IS_S(2, "npt_isotropic")) return tclcommand_integrate_set_npt_isotropic(interp, argc, argv); #endif else { Tcl_AppendResult(interp, "unknown integrator method:\n", (char *)NULL); return tclcommand_integrate_print_usage(interp); } } else { if (!ARG_IS_I(1, n_steps)) return tclcommand_integrate_print_usage(interp); // actual integration if ((argc == 3) && ARG_IS_S(2, "reuse_forces")) { reuse_forces = 1; } else if ((argc == 3) && ARG_IS_S(2, "recalc_forces")) { reuse_forces = -1; } else if (argc != 2) return tclcommand_integrate_print_usage(interp); } /* go on with integrate <n_steps> */ if (n_steps < 0) { Tcl_AppendResult(interp, "illegal number of steps (must be >0) \n", (char *)NULL); return tclcommand_integrate_print_usage(interp); ; } /* if skin wasn't set, do an educated guess now */ if (!skin_set) { if (max_cut == 0.0) { Tcl_AppendResult(interp, "cannot automatically determine skin, please " "set it manually via \"setmd skin\"\n", (char *)NULL); return TCL_ERROR; } skin = 0.4 * max_cut; mpi_bcast_parameter(FIELD_SKIN); } /* perform integration */ if (!correlations_autoupdate && !observables_autoupdate) { if (mpi_integrate(n_steps, reuse_forces)) return gather_runtime_errors(interp, TCL_OK); } else { for (int i = 0; i < n_steps; i++) { if (mpi_integrate(1, reuse_forces)) return gather_runtime_errors(interp, TCL_OK); reuse_forces = 1; autoupdate_observables(); autoupdate_correlations(); } if (n_steps == 0) { if (mpi_integrate(0, reuse_forces)) return gather_runtime_errors(interp, TCL_OK); } } return TCL_OK; }