![]() |
ESPResSo 3.2.0-167-g2c9ead1-git
Extensible Simulation Package for Soft Matter Research
|
00001 /* 00002 Copyright (C) 2010,2012,2013 The ESPResSo project 00003 Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 00004 Max-Planck-Institute for Polymer Research, Theory Group 00005 00006 This file is part of ESPResSo. 00007 00008 ESPResSo is free software: you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation, either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 ESPResSo is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with this program. If not, see <http://www.gnu.org/licenses/>. 00020 */ 00021 /** \file thermostat.c 00022 Implementation of \ref thermostat.h "thermostat.h" 00023 */ 00024 #include <math.h> 00025 #include "utils.h" 00026 00027 #include "communication.h" 00028 #include "lattice.h" 00029 #include "npt.h" 00030 #include "ghmc.h" 00031 00032 #include "particle_data.h" 00033 #include "parser.h" 00034 #include "random.h" 00035 #include "global.h" 00036 #include "integrate.h" 00037 #include "cells.h" 00038 #include "lb.h" 00039 #include "dpd.h" 00040 #include "dpd_tcl.h" 00041 #include "virtual_sites.h" 00042 #include "thermostat_tcl.h" 00043 00044 00045 int tclcommand_thermostat_parse_off(Tcl_Interp *interp, int argc, char **argv) 00046 { 00047 /* set temperature to zero */ 00048 temperature = 0; 00049 mpi_bcast_parameter(FIELD_TEMPERATURE); 00050 /* langevin thermostat */ 00051 langevin_gamma = 0; 00052 mpi_bcast_parameter(FIELD_LANGEVIN_GAMMA); 00053 /* dpd thermostat */ 00054 #ifdef DPD 00055 dpd_switch_off(); 00056 #endif 00057 #ifdef INTER_DPD 00058 inter_dpd_switch_off(); 00059 #endif 00060 #ifdef NPT 00061 /* npt isotropic thermostat */ 00062 nptiso_gamma0 = 0; 00063 mpi_bcast_parameter(FIELD_NPTISO_G0); 00064 nptiso_gammav = 0; 00065 mpi_bcast_parameter(FIELD_NPTISO_GV); 00066 #endif 00067 #ifdef GHMC 00068 /* ghmc thermostat */ 00069 ghmc_nmd = 1; 00070 mpi_bcast_parameter(FIELD_GHMC_NMD); 00071 ghmc_phi = 1; 00072 mpi_bcast_parameter(FIELD_GHMC_PHI); 00073 ghmc_mflip = GHMC_MFLIP_OFF; 00074 mpi_bcast_parameter(FIELD_GHMC_FLIP); 00075 ghmc_tscale = GHMC_TSCALE_OFF; 00076 mpi_bcast_parameter(FIELD_GHMC_SCALE); 00077 #endif 00078 /* switch thermostat off */ 00079 thermo_switch = THERMO_OFF; 00080 mpi_bcast_parameter(FIELD_THERMO_SWITCH); 00081 return (TCL_OK); 00082 } 00083 00084 int tclcommand_thermostat_parse_langevin(Tcl_Interp *interp, int argc, char **argv) 00085 { 00086 double temp, gamma; 00087 00088 /* check number of arguments */ 00089 if (argc < 4) { 00090 Tcl_AppendResult(interp, "wrong # args: should be \n\"", 00091 argv[0]," ",argv[1]," <temp> <gamma>\"", (char *)NULL); 00092 return (TCL_ERROR); 00093 } 00094 00095 /* check argument types */ 00096 if ( !ARG_IS_D(2, temp) || !ARG_IS_D(3, gamma)) { 00097 Tcl_AppendResult(interp, argv[0]," ",argv[1]," needs two DOUBLES", (char *)NULL); 00098 return (TCL_ERROR); 00099 } 00100 00101 if (temp < 0 || gamma < 0) { 00102 Tcl_AppendResult(interp, "temperature and gamma must be positive", (char *)NULL); 00103 return (TCL_ERROR); 00104 } 00105 00106 /* broadcast parameters */ 00107 temperature = temp; 00108 langevin_gamma = gamma; 00109 thermo_switch = ( thermo_switch | THERMO_LANGEVIN ); 00110 mpi_bcast_parameter(FIELD_THERMO_SWITCH); 00111 mpi_bcast_parameter(FIELD_TEMPERATURE); 00112 mpi_bcast_parameter(FIELD_LANGEVIN_GAMMA); 00113 return (TCL_OK); 00114 } 00115 00116 #ifdef NPT 00117 int tclcommand_thermostat_parse_npt_isotropic(Tcl_Interp *interp, int argc, char **argv) 00118 { 00119 double temp, gamma0, gammav; 00120 /* check number of arguments */ 00121 if (argc < 5) { 00122 Tcl_AppendResult(interp, "wrong # args: should be \n\"", 00123 argv[0]," set ",argv[1]," <temp> <gamma0> <gammav>\"", (char *)NULL); 00124 return (TCL_ERROR); 00125 } 00126 /* check argument types */ 00127 if ( !ARG_IS_D(2, temp) || !ARG_IS_D(3, gamma0) || !ARG_IS_D(4, gammav) ) { 00128 Tcl_AppendResult(interp, argv[0]," ",argv[1]," needs four DOUBLES", (char *)NULL); 00129 return (TCL_ERROR); 00130 } 00131 /* broadcast parameters */ 00132 temperature = temp; 00133 nptiso_gamma0 = gamma0; 00134 nptiso_gammav = gammav; 00135 00136 thermo_switch = ( thermo_switch | THERMO_NPT_ISO ); 00137 mpi_bcast_parameter(FIELD_THERMO_SWITCH); 00138 mpi_bcast_parameter(FIELD_TEMPERATURE); 00139 mpi_bcast_parameter(FIELD_NPTISO_G0); 00140 mpi_bcast_parameter(FIELD_NPTISO_GV); 00141 return (TCL_OK); 00142 } 00143 #endif 00144 00145 #ifdef GHMC 00146 int tclcommand_thermostat_parse_ghmc(Tcl_Interp *interp, int argc, char **argv) 00147 { 00148 double temp, phi; 00149 int n_md_steps; 00150 00151 /* check number of arguments */ 00152 if (argc < 5) { 00153 Tcl_AppendResult(interp, "wrong # args: should be \n\"", 00154 argv[0]," ",argv[1]," <temp> <md_steps> <phi> {flip|no_flip|random_flip}\"", (char *)NULL); 00155 return (TCL_ERROR); 00156 } 00157 /* check argument types */ 00158 if ( !ARG_IS_D(2, temp) || !ARG_IS_I(3, n_md_steps) || !ARG_IS_D(4, phi) ) { 00159 Tcl_AppendResult(interp, argv[2]," ",argv[3]," needs two DOUBLES and one INTEGER", (char *)NULL); 00160 return (TCL_ERROR); 00161 } 00162 00163 if (temp < 0 || n_md_steps <= 0) { 00164 Tcl_AppendResult(interp, "temperature and number of MD steps must be positive", (char *)NULL); 00165 return (TCL_ERROR); 00166 } 00167 00168 if (phi < 0 || phi > 1) { 00169 Tcl_AppendResult(interp, "the parameter phi must be between zero and one", (char *)NULL); 00170 return (TCL_ERROR); 00171 } 00172 00173 if(argc > 5) { 00174 if (ARG_IS_S(5,"-flip")) { 00175 ghmc_mflip = GHMC_MFLIP_ON; 00176 00177 } 00178 else if (ARG_IS_S(5,"-no_flip")) { 00179 ghmc_mflip = GHMC_MFLIP_OFF; 00180 } 00181 else if (ARG_IS_S(5,"-random_flip")) { 00182 ghmc_mflip = GHMC_MFLIP_RAND; 00183 } 00184 } else { 00185 ghmc_mflip = GHMC_MFLIP_OFF; 00186 } 00187 00188 if(argc > 6) { 00189 if (ARG_IS_S(6,"-scale")) { 00190 ghmc_tscale = GHMC_TSCALE_ON; 00191 } 00192 else if (ARG_IS_S(6,"-no_scale")) { 00193 ghmc_tscale = GHMC_TSCALE_OFF; 00194 } 00195 } else { 00196 ghmc_tscale = GHMC_TSCALE_OFF; 00197 } 00198 00199 /* broadcast parameters */ 00200 temperature = temp; 00201 ghmc_nmd = n_md_steps; 00202 ghmc_phi = phi; 00203 00204 thermo_switch = ( thermo_switch | THERMO_GHMC ); 00205 mpi_bcast_parameter(FIELD_THERMO_SWITCH); 00206 mpi_bcast_parameter(FIELD_TEMPERATURE); 00207 mpi_bcast_parameter(FIELD_GHMC_NMD); 00208 mpi_bcast_parameter(FIELD_GHMC_PHI); 00209 mpi_bcast_parameter(FIELD_GHMC_FLIP); 00210 mpi_bcast_parameter(FIELD_GHMC_SCALE); 00211 return (TCL_OK); 00212 } 00213 #endif 00214 00215 int tclcommand_thermostat_print_all(Tcl_Interp *interp) 00216 { 00217 char buffer[TCL_DOUBLE_SPACE]; 00218 /* thermostat not initialized */ 00219 if(temperature == -1.0) { 00220 Tcl_AppendResult(interp,"{ not initialized } ", (char *)NULL); 00221 return (TCL_OK); 00222 } 00223 00224 /* no thermostat on */ 00225 if(thermo_switch == THERMO_OFF) { 00226 Tcl_AppendResult(interp,"{ off } ", (char *)NULL); 00227 return (TCL_OK); 00228 } 00229 00230 /* langevin */ 00231 if(thermo_switch & THERMO_LANGEVIN ) { 00232 Tcl_PrintDouble(interp, temperature, buffer); 00233 Tcl_AppendResult(interp,"{ langevin ",buffer, (char *)NULL); 00234 Tcl_PrintDouble(interp, langevin_gamma, buffer); 00235 Tcl_AppendResult(interp," ",buffer," } ", (char *)NULL); 00236 } 00237 00238 #ifdef DPD 00239 /* dpd */ 00240 if(thermo_switch & THERMO_DPD) { tclcommand_thermostat_parse_and_print_dpd(interp);} 00241 #endif 00242 00243 #ifdef NPT 00244 /* npt_isotropic */ 00245 if(thermo_switch & THERMO_NPT_ISO) { 00246 Tcl_PrintDouble(interp, temperature, buffer); 00247 Tcl_AppendResult(interp,"{ npt_isotropic ",buffer, (char *)NULL); 00248 Tcl_PrintDouble(interp, nptiso_gamma0, buffer); 00249 Tcl_AppendResult(interp," ",buffer, (char *)NULL); 00250 Tcl_PrintDouble(interp, nptiso_gammav, buffer); 00251 Tcl_AppendResult(interp," ",buffer, " } ", (char *)NULL); 00252 } 00253 #endif 00254 00255 #ifdef GHMC 00256 /* ghmc */ 00257 if(thermo_switch & THERMO_GHMC) { 00258 Tcl_PrintDouble(interp, temperature, buffer); 00259 Tcl_AppendResult(interp,"{ ghmc ",buffer, (char *)NULL); 00260 Tcl_PrintDouble(interp, ghmc_nmd, buffer); 00261 Tcl_AppendResult(interp," ",buffer, (char *)NULL); 00262 Tcl_PrintDouble(interp, ghmc_phi, buffer); 00263 Tcl_AppendResult(interp," ",buffer, " ", (char *)NULL); 00264 switch (ghmc_mflip) { 00265 case GHMC_MFLIP_OFF: 00266 Tcl_AppendResult(interp, "-no_flip ", (char *)NULL); 00267 break; 00268 case GHMC_MFLIP_ON: 00269 Tcl_AppendResult(interp, "-flip ", (char *)NULL); 00270 break; 00271 case GHMC_MFLIP_RAND: 00272 Tcl_AppendResult(interp, "-random_flip ", (char *)NULL); 00273 break; 00274 } 00275 if (ghmc_tscale == GHMC_TSCALE_ON) 00276 Tcl_AppendResult(interp, "-scale }", (char *)NULL); 00277 else 00278 Tcl_AppendResult(interp, "-no_scale }", (char *)NULL); 00279 } 00280 #endif 00281 00282 #if defined(LB) || defined(LB_GPU) 00283 /* lb */ 00284 if(thermo_switch & THERMO_LB) { 00285 Tcl_PrintDouble(interp, temperature, buffer); 00286 Tcl_AppendResult(interp,"{ lb ",buffer, " } ", (char *)NULL); 00287 } 00288 #endif 00289 00290 #ifdef INTER_DPD 00291 /* inter_dpd */ 00292 if(thermo_switch & THERMO_INTER_DPD) { 00293 Tcl_PrintDouble(interp, temperature, buffer); 00294 Tcl_AppendResult(interp,"{ inter_dpd ",buffer, " } ", (char *)NULL); 00295 } 00296 #endif 00297 return (TCL_OK); 00298 } 00299 00300 int tclcommand_thermostat_print_usage(Tcl_Interp *interp, int argc, char **argv) 00301 { 00302 Tcl_AppendResult(interp, "Usage of tcl-command thermostat:\n", (char *)NULL); 00303 Tcl_AppendResult(interp, "'", argv[0], "' for status return or \n ", (char *)NULL); 00304 Tcl_AppendResult(interp, "'", argv[0], " set off' to deactivate it (=> NVE-ensemble) \n ", (char *)NULL); 00305 Tcl_AppendResult(interp, "'", argv[0], " set langevin <temp> <gamma>' or \n ", (char *)NULL); 00306 #ifdef DPD 00307 tclcommand_thermostat_print_usage_dpd(interp,argc,argv); 00308 #endif 00309 #ifdef NPT 00310 Tcl_AppendResult(interp, "'", argv[0], " set npt_isotropic <temp> <gamma0> <gammav>' ", (char *)NULL); 00311 #endif 00312 #ifdef LB 00313 Tcl_AppendResult(interp, "'", argv[0], " set lb <temperature>" , (char *)NULL); 00314 #endif 00315 #ifdef LB_GPU 00316 Tcl_AppendResult(interp, "'", argv[0], " set lb_gpu <temperature>" , (char *)NULL); 00317 #endif 00318 return (TCL_ERROR); 00319 } 00320 00321 int tclcommand_thermostat(ClientData data, Tcl_Interp *interp, int argc, char **argv) 00322 { 00323 int err = TCL_OK; 00324 THERMO_TRACE(fprintf(stderr,"%d: thermostat:\n",this_node)); 00325 00326 /* print thermostat status */ 00327 if(argc == 1) return tclcommand_thermostat_print_all(interp); 00328 00329 if ( ARG1_IS_S("set") ) { 00330 argc--; 00331 argv++; 00332 00333 if (argc == 1) { 00334 Tcl_AppendResult(interp, "wrong # args: \n", (char *)NULL); 00335 return tclcommand_thermostat_print_usage(interp, argc, argv); 00336 } 00337 } 00338 if ( ARG1_IS_S("off") ) 00339 err = tclcommand_thermostat_parse_off(interp, argc, argv); 00340 else if ( ARG1_IS_S("langevin")) 00341 err = tclcommand_thermostat_parse_langevin(interp, argc, argv); 00342 #ifdef DPD 00343 else if ( ARG1_IS_S("dpd") ) 00344 err = tclcommand_thermostat_parse_dpd(interp, argc, argv); 00345 #endif 00346 #ifdef INTER_DPD 00347 else if ( ARG1_IS_S("inter_dpd") ) 00348 err = tclcommand_thermostat_parse_inter_dpd(interp, argc, argv); 00349 #endif 00350 #ifdef NPT 00351 else if ( ARG1_IS_S("npt_isotropic") ) 00352 err = tclcommand_thermostat_parse_npt_isotropic(interp, argc, argv); 00353 #endif 00354 #if defined(LB) || defined(LB_GPU) 00355 else if ( ARG1_IS_S("lb")) 00356 err = tclcommand_thermostat_parse_lb(interp, argc-1, argv+1); 00357 #endif 00358 #ifdef GHMC 00359 else if ( ARG1_IS_S("ghmc") ) 00360 err = tclcommand_thermostat_parse_ghmc(interp, argc, argv); 00361 #endif 00362 else { 00363 Tcl_AppendResult(interp, "Unknown thermostat ", argv[1], "\n", (char *)NULL); 00364 return tclcommand_thermostat_print_usage(interp, argc, argv); 00365 } 00366 return gather_runtime_errors(interp, err); 00367 } 00368 00369 int tclcommand_thermostat_parse_lb(Tcl_Interp *interp, int argc, char ** argv) 00370 { 00371 00372 #if defined(LB) || defined(LB_GPU) 00373 double temp; 00374 00375 /* get lb interaction type */ 00376 if (argc < 2) { 00377 Tcl_AppendResult(interp, "lattice-Boltzmann needs 1 parameter: " 00378 "<temperature>", 00379 (char *) NULL); 00380 return TCL_ERROR; 00381 } 00382 00383 /* copy lattice-boltzmann parameters */ 00384 if (! ARG_IS_D(1, temp)) { return TCL_ERROR; } 00385 00386 if ( temp < 0.0 ) { 00387 Tcl_AppendResult(interp, "temperature must be non-negative", (char *) NULL); 00388 return TCL_ERROR; 00389 } 00390 temperature = temp; 00391 thermo_switch = ( thermo_switch | THERMO_LB ); 00392 mpi_bcast_parameter(FIELD_THERMO_SWITCH); 00393 mpi_bcast_parameter(FIELD_TEMPERATURE); 00394 00395 #endif 00396 return TCL_OK; 00397 }
1.7.5.1