SimParameters.C

Go to the documentation of this file.
00001 
00007 /*****************************************************************************
00008  * $Source: /home/cvs/namd/cvsroot/namd2/src/SimParameters.C,v $
00009  * $Author: jim $
00010  * $Date: 2017/03/30 20:06:17 $
00011  * $Revision: 1.1478 $
00012  *****************************************************************************/
00013 
00020 #include "InfoStream.h"
00021 #include "ComputeNonbondedUtil.h"
00022 #include "LJTable.h"
00023 #include "ComputePme.h"
00024 #include "ConfigList.h"
00025 #include "SimParameters.h"
00026 #include "ParseOptions.h"
00027 #include "structures.h"
00028 #include "Communicate.h"
00029 #include "MStream.h"
00030 #include "Output.h"
00031 #include <stdio.h>
00032 #include <time.h>
00033 #ifdef NAMD_FFTW
00034 #ifdef NAMD_FFTW_3
00035 #include <fftw3.h>
00036 #else
00037 // fftw2 doesn't have these defined
00038 #define fftwf_malloc fftw_malloc
00039 #define fftwf_free fftw_free
00040 #ifdef NAMD_FFTW_NO_TYPE_PREFIX
00041 #include <fftw.h>
00042 #include <rfftw.h>
00043 #else
00044 #include <sfftw.h>
00045 #include <srfftw.h>
00046 #endif
00047 #endif
00048 #endif
00049 #if defined(WIN32) && !defined(__CYGWIN__)
00050 #include <direct.h>
00051 #define CHDIR _chdir
00052 #define MKDIR(X) mkdir(X)
00053 #define PATHSEP '\\'
00054 #define PATHSEPSTR "\\"
00055 #else
00056 #include <unistd.h>
00057 #define CHDIR chdir
00058 #define MKDIR(X) mkdir(X,0777)
00059 #define PATHSEP '/'
00060 #define PATHSEPSTR "/"
00061 #endif
00062 #include <fcntl.h>
00063 #include <sys/stat.h>
00064 #ifdef WIN32
00065 #include <io.h>
00066 #define access(PATH,MODE) _access(PATH,00)
00067 #endif
00068 #include <fstream>
00069 using namespace std;
00070 
00071 #ifdef WIN32
00072 extern "C" {
00073   double erfc(double);
00074 }
00075 #endif
00076 
00077 #include "strlib.h"    //  For strcasecmp and strncasecmp
00078 
00079 #include "ComputeNonbondedMICKernel.h"
00080 
00081 //#ifdef NAMD_CUDA
00082 //bool one_cuda_device_per_node();
00083 //#endif
00084 #include "DeviceCUDA.h"
00085 #ifdef NAMD_CUDA
00086 #ifdef WIN32
00087 #define __thread __declspec(thread)
00088 #endif
00089 extern __thread DeviceCUDA *deviceCUDA;
00090 #endif
00091 
00092 //#define DEBUGM
00093 #include "Debug.h"
00094 
00095 #define XXXBIGREAL 1.0e32
00096 
00097 
00098 char* SimParameters::getfromparseopts(const char* name, char *outbuf) {
00099   if ( parseopts ) return parseopts->getfromptr(name,outbuf);
00100   else return 0;
00101 }
00102 
00103 int SimParameters::istrueinparseopts(const char* name) {
00104   if ( parseopts ) return parseopts->istruefromptr(name);
00105   else return -1;
00106 }
00107 
00108 int SimParameters::issetinparseopts(const char* name) {
00109   if ( parseopts ) return parseopts->issetfromptr(name);
00110   else return -1;
00111 }
00112 
00113 
00114 /************************************************************************/
00115 /*                  */
00116 /*      FUNCTION initialize_config_data      */
00117 /*                  */
00118 /*  This function is used by the master process to populate the     */
00119 /*   simulation parameters from a ConfigList object that is passed to   */
00120 /*   it.  Each parameter is checked to make sure that it has a value    */
00121 /*   that makes sense, and that it doesn't conflict with any other      */
00122 /*   values that have been given.          */
00123 /*                  */
00124 /************************************************************************/
00125 
00126 void SimParameters::initialize_config_data(ConfigList *config, char *&cwd)
00127 
00128 {
00129 
00130    parseopts = new ParseOptions;   //  Object to check consistency of config file
00131    ParseOptions &opts = *parseopts;
00132 
00133    config_parser(opts);
00134 
00136    if (!opts.check_consistency()) 
00137    {
00138       NAMD_die("Internal error in configuration file parser");
00139    }
00140 
00141    // Now, feed the object with the actual configuration options through the
00142    // ParseOptions file and make sure everything is OK
00143    if (!opts.set(*config)) 
00144    {
00145       NAMD_die("ERROR(S) IN THE CONFIGURATION FILE");
00146    }
00147 
00149 
00150    check_config(opts,config,cwd);
00151 
00152    print_config(opts,config,cwd);
00153 
00154 }
00155 
00156 /************************************************************************/
00157 /*                                                                      */
00158 /*      FUNCTION scriptSet                                              */
00159 /*                                                                      */
00160 /************************************************************************/
00161 
00162 int atobool(const char *s) {
00163   return ( (! strncasecmp(s,"yes",8)) ||
00164            (! strncasecmp(s,"on",8)) || 
00165            (! strncasecmp(s,"true",8)) );
00166 };
00167                          
00168 void SimParameters::scriptSet(const char *param, const char *value) {
00169 
00170   if ( CkMyRank() ) return;
00171 
00172 #define MAX_SCRIPT_PARAM_SIZE 128
00173 #define SCRIPT_PARSE_BOOL(NAME,VAR) { if ( ! strncasecmp(param,(NAME),MAX_SCRIPT_PARAM_SIZE) ) { (VAR) = atobool(value); return; } }
00174 #define SCRIPT_PARSE_INT(NAME,VAR) { if ( ! strncasecmp(param,(NAME),MAX_SCRIPT_PARAM_SIZE) ) { (VAR) = atoi(value); return; } }
00175 #define SCRIPT_PARSE_FLOAT(NAME,VAR) { if ( ! strncasecmp(param,(NAME),MAX_SCRIPT_PARAM_SIZE) ) { (VAR) = atof(value); return; } }
00176 #define SCRIPT_PARSE_MOD_FLOAT(NAME,VAR,MOD) { if ( ! strncasecmp(param,(NAME),MAX_SCRIPT_PARAM_SIZE) ) { (VAR) = atof(value) MOD; return; } }
00177 #define SCRIPT_PARSE_VECTOR(NAME,VAR) { if ( ! strncasecmp(param,(NAME),MAX_SCRIPT_PARAM_SIZE) ) { (VAR).set(value); return; } }
00178 #define SCRIPT_PARSE_STRING(NAME,VAR) { if ( ! strncasecmp(param,(NAME),MAX_SCRIPT_PARAM_SIZE) ) { strcpy(VAR,value); return; } }
00179 
00180   SCRIPT_PARSE_FLOAT("scriptArg1",scriptArg1)
00181   SCRIPT_PARSE_FLOAT("scriptArg2",scriptArg2)
00182   SCRIPT_PARSE_FLOAT("scriptArg3",scriptArg3)
00183   SCRIPT_PARSE_FLOAT("scriptArg4",scriptArg4)
00184   SCRIPT_PARSE_FLOAT("scriptArg5",scriptArg5)
00185   SCRIPT_PARSE_INT("scriptIntArg1",scriptIntArg1)
00186   SCRIPT_PARSE_INT("scriptIntArg2",scriptIntArg2)
00187   SCRIPT_PARSE_STRING("scriptStringArg1",scriptStringArg1)
00188   SCRIPT_PARSE_STRING("scriptStringArg2",scriptStringArg2)
00189   SCRIPT_PARSE_INT("numsteps",N)
00190   if ( ! strncasecmp(param,"firsttimestep",MAX_SCRIPT_PARAM_SIZE) ) {
00191     N = firstTimestep = atoi(value); return;
00192   }
00193   SCRIPT_PARSE_FLOAT("reassignTemp",reassignTemp)
00194   SCRIPT_PARSE_FLOAT("rescaleTemp",rescaleTemp)
00195   SCRIPT_PARSE_BOOL("velocityQuenching",minimizeOn)
00196   SCRIPT_PARSE_BOOL("maximumMove",maximumMove)
00197   // SCRIPT_PARSE_BOOL("Langevin",langevinOn)
00198   if ( ! strncasecmp(param,"Langevin",MAX_SCRIPT_PARAM_SIZE) ) {
00199     langevinOn = atobool(value);
00200     if ( langevinOn && ! langevinOnAtStartup ) {
00201       NAMD_die("Langevin must be enabled at startup to disable and re-enable in script.");
00202     }
00203     return;
00204   }
00205   SCRIPT_PARSE_FLOAT("langevinTemp",langevinTemp)
00206   SCRIPT_PARSE_BOOL("langevinBAOAB",langevin_useBAOAB) // [!!] Use the BAOAB integrator or not
00207   SCRIPT_PARSE_FLOAT("loweAndersenTemp",loweAndersenTemp) // BEGIN LA, END LA
00208   SCRIPT_PARSE_BOOL("stochRescale",stochRescaleOn)
00209   SCRIPT_PARSE_FLOAT("stochRescaleTemp",stochRescaleTemp)
00210   SCRIPT_PARSE_FLOAT("initialTemp",initialTemp)
00211   SCRIPT_PARSE_BOOL("useGroupPressure",useGroupPressure)
00212   SCRIPT_PARSE_BOOL("useFlexibleCell",useFlexibleCell)
00213   SCRIPT_PARSE_BOOL("useConstantArea",useConstantArea)
00214   SCRIPT_PARSE_BOOL("fixCellDims",fixCellDims)
00215   SCRIPT_PARSE_BOOL("fixCellDimX",fixCellDimX)
00216   SCRIPT_PARSE_BOOL("fixCellDimY",fixCellDimY)
00217   SCRIPT_PARSE_BOOL("fixCellDimZ",fixCellDimZ)
00218   SCRIPT_PARSE_BOOL("useConstantRatio",useConstantRatio)
00219   SCRIPT_PARSE_BOOL("LangevinPiston",langevinPistonOn)
00220   SCRIPT_PARSE_MOD_FLOAT("LangevinPistonTarget",
00221                         langevinPistonTarget,/PRESSUREFACTOR)
00222   SCRIPT_PARSE_FLOAT("LangevinPistonPeriod",langevinPistonPeriod)
00223   SCRIPT_PARSE_FLOAT("LangevinPistonDecay",langevinPistonDecay)
00224   SCRIPT_PARSE_FLOAT("LangevinPistonTemp",langevinPistonTemp)
00225   SCRIPT_PARSE_MOD_FLOAT("SurfaceTensionTarget",
00226                         surfaceTensionTarget,*(100.0/PRESSUREFACTOR))
00227   SCRIPT_PARSE_BOOL("BerendsenPressure",berendsenPressureOn)
00228   SCRIPT_PARSE_MOD_FLOAT("BerendsenPressureTarget",
00229                         berendsenPressureTarget,/PRESSUREFACTOR)
00230   SCRIPT_PARSE_MOD_FLOAT("BerendsenPressureCompressibility",
00231                         berendsenPressureCompressibility,*PRESSUREFACTOR)
00232   SCRIPT_PARSE_FLOAT("BerendsenPressureRelaxationTime",
00233                                 berendsenPressureRelaxationTime)
00234   SCRIPT_PARSE_FLOAT("constraintScaling",constraintScaling)
00235   SCRIPT_PARSE_FLOAT("consForceScaling",consForceScaling)
00236   SCRIPT_PARSE_BOOL("drudeHardWall",drudeHardWallOn)
00237   SCRIPT_PARSE_FLOAT("drudeBondConst",drudeBondConst)
00238   SCRIPT_PARSE_FLOAT("drudeBondLen",drudeBondLen)
00239   SCRIPT_PARSE_STRING("outputname",outputFilename)
00240   SCRIPT_PARSE_INT("outputEnergies",outputEnergies)
00241   SCRIPT_PARSE_STRING("restartname",restartFilename)
00242   SCRIPT_PARSE_INT("DCDfreq",dcdFrequency)
00243   if ( ! strncasecmp(param,"DCDfile",MAX_SCRIPT_PARAM_SIZE) ) { 
00244     close_dcdfile();  // *** implemented in Output.C ***
00245     strcpy(dcdFilename,value);
00246     return;
00247   }
00248   if ( ! strncasecmp(param,"velDCDfile",MAX_SCRIPT_PARAM_SIZE) ) { 
00249     close_veldcdfile();  // *** implemented in Output.C ***
00250     strcpy(velDcdFilename,value);
00251     return;
00252   }
00253   SCRIPT_PARSE_STRING("tclBCArgs",tclBCArgs)
00254   SCRIPT_PARSE_VECTOR("eField",eField)
00255   SCRIPT_PARSE_FLOAT("eFieldFreq",eFieldFreq)
00256   SCRIPT_PARSE_FLOAT("eFieldPhase",eFieldPhase) 
00257   SCRIPT_PARSE_FLOAT("accelMDE",accelMDE) 
00258   SCRIPT_PARSE_FLOAT("accelMDalpha",accelMDalpha) 
00259   SCRIPT_PARSE_FLOAT("accelMDTE",accelMDTE) 
00260   SCRIPT_PARSE_FLOAT("accelMDTalpha",accelMDTalpha) 
00261   SCRIPT_PARSE_FLOAT("accelMDGSigma0P",accelMDGSigma0P) 
00262   SCRIPT_PARSE_FLOAT("accelMDGSigma0D",accelMDGSigma0D) 
00263   SCRIPT_PARSE_STRING("accelMDGRestartFile",accelMDGRestartFile)
00264   SCRIPT_PARSE_VECTOR("stirAxis",stirAxis)
00265   SCRIPT_PARSE_VECTOR("stirPivot",stirPivot)
00266   if ( ! strncasecmp(param,"mgridforcescale",MAX_SCRIPT_PARAM_SIZE) ) {
00267     NAMD_die("Can't yet modify mgridforcescale in a script");
00268     return;
00269   }
00270   if ( ! strncasecmp(param,"mgridforcevoff",MAX_SCRIPT_PARAM_SIZE) ) {
00271     NAMD_die("Can't yet modify mgridforcevoff in a script");
00272     return;
00273   }
00274    
00275   if ( ! strncasecmp(param,"fixedatoms",MAX_SCRIPT_PARAM_SIZE) ) {
00276     if ( ! fixedAtomsOn )
00277       NAMD_die("FixedAtoms may not be enabled in a script.");
00278     if ( ! fixedAtomsForces )
00279       NAMD_die("To use fixedAtoms in script first use fixedAtomsForces yes.");
00280     fixedAtomsOn = atobool(value);
00281     return;
00282   }
00283 
00284 //fepb
00285   if ( ! strncasecmp(param,"alch",MAX_SCRIPT_PARAM_SIZE) ) {
00286     alchOn = atobool(value);
00287     if ( alchOn && ! alchOnAtStartup ) {
00288        NAMD_die("Alchemy must be enabled at startup to disable and re-enable in script.");
00289     }
00290     alchFepOn = alchOn && alchFepOnAtStartup;
00291     alchThermIntOn = alchOn && alchThermIntOnAtStartup;
00292     ComputeNonbondedUtil::select();
00293     if ( PMEOn ) ComputePmeUtil::select();
00294     return;
00295   }
00296   SCRIPT_PARSE_INT("alchEquilSteps",alchEquilSteps)
00297 
00298   if ( ! strncasecmp(param,"alchRepLambda",MAX_SCRIPT_PARAM_SIZE) ) {
00299     alchRepLambda = atof(value);
00300     alchFepWCARepuOn = true;
00301     alchFepWCADispOn = false;
00302     alchFepElecOn    = false;
00303     ComputeNonbondedUtil::select();
00304     return;
00305   }
00306 
00307   if ( ! strncasecmp(param,"alchDispLambda",MAX_SCRIPT_PARAM_SIZE) ) {
00308     alchDispLambda = atof(value);
00309     alchFepWCARepuOn = false;
00310     alchFepWCADispOn = true;
00311     alchFepElecOn    = false;
00312     ComputeNonbondedUtil::select();
00313     return;
00314   }
00315 
00316   if ( ! strncasecmp(param,"alchElecLambda",MAX_SCRIPT_PARAM_SIZE) ) {
00317     alchElecLambda = atof(value);
00318     alchFepWCARepuOn = false;
00319     alchFepWCADispOn = false;
00320     alchFepElecOn    = true;
00321     ComputeNonbondedUtil::select();
00322     return;
00323   }
00324 
00325 
00326   if ( ! strncasecmp(param,"alchFepWCArcut1",MAX_SCRIPT_PARAM_SIZE) ) {
00327     alchFepWCArcut1 = atof(value);
00328     ComputeNonbondedUtil::select();
00329     return;
00330   }
00331 
00332   if ( ! strncasecmp(param,"alchFepWCArcut2",MAX_SCRIPT_PARAM_SIZE) ) {
00333     alchFepWCArcut2 = atof(value);
00334     ComputeNonbondedUtil::select();
00335     return;
00336   }
00337 
00338   if ( ! strncasecmp(param,"alchFepWCArcut3",MAX_SCRIPT_PARAM_SIZE) ) {
00339     alchFepWCArcut3 = atof(value);
00340     ComputeNonbondedUtil::select();
00341     return;
00342   }
00343 
00344   if ( ! strncasecmp(param,"alchLambda",MAX_SCRIPT_PARAM_SIZE) ) {
00345     alchLambda = atof(value);
00346     if ( alchLambda < 0.0 || 1.0 < alchLambda ) {
00347       NAMD_die("Alchemical lambda values should be in the range [0.0, 1.0]\n");
00348     }
00349     ComputeNonbondedUtil::select();
00350     return;
00351   }
00352 
00353   if ( ! strncasecmp(param,"alchLambda2",MAX_SCRIPT_PARAM_SIZE) ) {
00354     alchLambda2 = atof(value);
00355     if ( alchLambda2 < 0.0 || 1.0 < alchLambda2 ) {
00356       NAMD_die("Alchemical lambda values should be in the range [0.0, 1.0]\n");
00357     }
00358     ComputeNonbondedUtil::select();
00359     return;
00360   }
00361 
00362   if ( ! strncasecmp(param,"alchLambdaIDWS",MAX_SCRIPT_PARAM_SIZE) ) {
00363     alchLambdaIDWS = atof(value);
00364     if ( alchLambdaIDWS > 1. ) {
00365       NAMD_die("alchLambdaIDWS should be either in the range [0.0, 1.0], or negative (disabled).\n");
00366     }
00367     // Switch lambda2 every other cycle of fullElectFrequency steps
00368     // or every other nonbondedFrequency steps if undefined
00369     // or every alchOutFreq steps if larger (no need to switch faster that we output)
00370     alchIDWSfreq = fullElectFrequency > 0 ? fullElectFrequency : nonbondedFrequency;
00371     if ( alchOutFreq > alchIDWSfreq )
00372       alchIDWSfreq = alchOutFreq;
00373     ComputeNonbondedUtil::select();
00374     return;
00375   }
00376 
00377   if ( ! strncasecmp(param,"alchLambdaFreq",MAX_SCRIPT_PARAM_SIZE) ) {
00378     alchLambdaFreq = atoi(value);
00379     if ( alchLambdaIDWS >= 0 ) {
00380       NAMD_die("alchLambdaIDWS and alchLambdaFreq are not compatible.\n");
00381     }
00382     ComputeNonbondedUtil::select();
00383     return;
00384   }
00385 //fepe
00386 
00387   if ( ! strncasecmp(param,"nonbondedScaling",MAX_SCRIPT_PARAM_SIZE) ) {
00388     nonbondedScaling = atof(value);
00389     ComputeNonbondedUtil::select();
00390     return;
00391   }
00392 
00393   if ( ! strncasecmp(param,"commOnly",MAX_SCRIPT_PARAM_SIZE) ) {
00394     commOnly = atobool(value);
00395     ComputeNonbondedUtil::select();
00396     return;
00397   }
00398 
00399   // REST2 - We don't have to make any changes to ComputeNonbondedUtil
00400   // other than recalculating the LJTable.  Skip doing the other stuff.
00401   if ( ! strncasecmp(param,"soluteScalingFactor",MAX_SCRIPT_PARAM_SIZE)) {
00402     soluteScalingFactor = atof(value);
00403     if (soluteScalingFactor < 0.0) {
00404       NAMD_die("Solute scaling factor should be non-negative\n");
00405     }
00406     soluteScalingFactorCharge = soluteScalingFactor;
00407     soluteScalingFactorVdw = soluteScalingFactor;
00408     if ( ComputeNonbondedUtil::ljTable ) delete ComputeNonbondedUtil::ljTable;
00409     ComputeNonbondedUtil::ljTable = new LJTable;
00410     return;
00411   }
00412   if ( ! strncasecmp(param,"soluteScalingFactorVdw",MAX_SCRIPT_PARAM_SIZE)) {
00413     soluteScalingFactorVdw = atof(value);
00414     if (soluteScalingFactorVdw < 0.0) {
00415       NAMD_die("Solute scaling factor for van der Waals "
00416           "should be non-negative\n");
00417     }
00418     if ( ComputeNonbondedUtil::ljTable ) delete ComputeNonbondedUtil::ljTable;
00419     ComputeNonbondedUtil::ljTable = new LJTable;
00420     return;
00421   }
00422   if ( ! strncasecmp(param,"soluteScalingFactorCharge",MAX_SCRIPT_PARAM_SIZE)) {
00423     soluteScalingFactorCharge = atof(value);
00424     if (soluteScalingFactorCharge < 0.0) {
00425       NAMD_die("Solute scaling factor for electrostatics "
00426           "should be non-negative\n");
00427     }
00428     return;
00429   }
00430 
00431   char *error = new char[2 * MAX_SCRIPT_PARAM_SIZE + 100];
00432   sprintf(error,"Setting parameter %s from script failed!\n",param);
00433   NAMD_die(error);
00434 
00435 }
00436 
00437 void SimParameters::nonbonded_select() {
00438     ComputeNonbondedUtil::select();
00439 }
00440 
00441 void SimParameters::pme_select() {
00442   ComputePmeUtil::select();
00443 }
00444 
00445 /************************************************************************/
00446 /*                                                                      */
00447 /*      FUNCTION config_parser                                          */
00448 /*                                                                      */
00449 /************************************************************************/
00450                          
00451 void SimParameters::config_parser(ParseOptions &opts) {
00452 
00453    //  Set all variable to fallback default values.  This is not really
00454    //  necessary, as we give default values when we set up the ParseOptions
00455    //  object, but it helps the debuggers figure out we've initialized the
00456    //  variables.
00457    HydrogenBonds = FALSE;
00458    useAntecedent = TRUE;
00459    aaAngleExp = 2;
00460    haAngleExp = 4;
00461    distAttExp = 4;
00462    distRepExp = 6;
00463    dhaCutoffAngle = 100.0;
00464    dhaOnAngle = 60.0;
00465    dhaOffAngle = 80.0;
00466    daCutoffDist = 7.5;
00467    daOnDist = 5.5;
00468    daOffDist = 6.5;
00469 
00470    config_parser_basic(opts);
00471    config_parser_fileio(opts);
00472    config_parser_fullelect(opts);
00473    config_parser_methods(opts);
00474    config_parser_constraints(opts);
00475    #ifdef OPENATOM_VERSION
00476    config_parser_openatom(opts);
00477    #endif // OPENATOM_VERSION
00478 
00479    config_parser_gridforce(opts);
00480    config_parser_mgridforce(opts);
00481    config_parser_movdrag(opts);
00482    config_parser_rotdrag(opts);
00483    config_parser_constorque(opts);
00484    config_parser_boundary(opts);
00485    config_parser_misc(opts);
00486 
00487 }
00488 
00489 void SimParameters::config_parser_basic(ParseOptions &opts) {
00490    
00491    //  So first we set up the ParseOptions objects so that it will check
00492    //  all of the logical rules that the configuration file must follow.
00493 
00494    opts.optional("main", "obsolete", "used to flag obsolete options",
00495     PARSE_STRING);
00496 
00498    opts.require("main", "timestep", "size of the timestep, in fs",
00499     &dt, 1.0);
00500    opts.range("timestep", NOT_NEGATIVE);
00501    opts.units("timestep", N_FSEC);
00502 
00503    opts.optional("main", "numsteps", "number of timesteps to perform",
00504     &N,0);
00505    opts.range("numsteps", NOT_NEGATIVE);
00506 
00507    opts.optional("main", "stepspercycle",
00508       "Number of steps between atom migrations", 
00509       &stepsPerCycle, 20);
00510    opts.range("stepspercycle", POSITIVE);
00511 
00512    opts.require("main", "cutoff", "local electrostatic and Vdw distance", 
00513       &cutoff);
00514    opts.range("cutoff", POSITIVE);
00515    opts.units("cutoff", N_ANGSTROM);
00516    
00517    opts.optional("main", "nonbondedScaling", "nonbonded scaling factor",
00518      &nonbondedScaling, 1.0);
00519    opts.range("nonbondedScaling", NOT_NEGATIVE);
00520 
00521    opts.optional("main", "limitDist", "limit nonbonded below this distance",
00522      &limitDist, 0.0);
00523    opts.range("limitDist", NOT_NEGATIVE);
00524 
00525    opts.require("main", "exclude", "Electrostatic and VDW exclusion policy",
00526     PARSE_STRING);
00527 
00528    opts.optional("exclude", "1-4scaling", "1-4 electrostatic scaling factor",
00529      &scale14, 1.0);
00530    opts.range("1-4scaling", POSITIVE);
00531 
00532    opts.optionalB("main", "switching",
00533      "Should a smoothing function be used?", &switchingActive, TRUE);
00534    
00535    opts.optionalB("switching", "vdwForceSwitching",
00536      "Use force switching for vdw?", &vdwForceSwitching, FALSE);
00537    
00538    opts.optional("switching", "switchdist",
00539      "Distance for switching function activation",
00540      &switchingDist);
00541    opts.range("switchdist", POSITIVE);
00542    opts.units("switchdist", N_ANGSTROM);
00543    
00544    opts.optionalB("main", "martiniSwitching",
00545      "Use Martini residue-based coarse-grain switching?", &martiniSwitching, FALSE);
00546    opts.optionalB("main", "martiniDielAllow",
00547      "Allow use of dielectric != 15.0 when using Martini", &martiniDielAllow, FALSE);
00548 
00549    opts.optional("main", "pairlistdist",  "Pairlist inclusion distance",
00550      &pairlistDist);
00551    opts.range("pairlistdist", POSITIVE);
00552    opts.units("pairlistdist", N_ANGSTROM);
00553 
00554    opts.optional("main", "pairlistMinProcs",  "Min procs for pairlists",
00555      &pairlistMinProcs,1);
00556    opts.range("pairlistMinProcs", POSITIVE);
00557 
00558    opts.optional("main", "pairlistsPerCycle",  "regenerate x times per cycle",
00559      &pairlistsPerCycle,2);
00560    opts.range("pairlistsPerCycle", POSITIVE);
00561 
00562    opts.optional("main", "outputPairlists", "how often to print warnings",
00563      &outputPairlists, 0);
00564    opts.range("outputPairlists", NOT_NEGATIVE);
00565 
00566    opts.optional("main", "pairlistShrink",  "tol *= (1 - x) on regeneration",
00567      &pairlistShrink,0.01);
00568    opts.range("pairlistShrink", NOT_NEGATIVE);
00569 
00570    opts.optional("main", "pairlistGrow",  "tol *= (1 + x) on trigger",
00571      &pairlistGrow, 0.01);
00572    opts.range("pairlistGrow", NOT_NEGATIVE);
00573 
00574    opts.optional("main", "pairlistTrigger",  "trigger is atom > (1 - x) * tol",
00575      &pairlistTrigger, 0.3);
00576    opts.range("pairlistTrigger", NOT_NEGATIVE);
00577 
00578    opts.optional("main", "temperature", "initial temperature",
00579      &initialTemp);
00580    opts.range("temperature", NOT_NEGATIVE);
00581    opts.units("temperature", N_KELVIN);
00582 
00583    opts.optionalB("main", "COMmotion", "allow initial center of mass movement",
00584       &comMove, FALSE);
00585 
00586    opts.optionalB("main", "zeroMomentum", "constrain center of mass",
00587       &zeroMomentum, FALSE);
00588    opts.optionalB("zeroMomentum", "zeroMomentumAlt", "constrain center of mass",
00589       &zeroMomentumAlt, FALSE);
00590 
00591    opts.optionalB("main", "wrapWater", "wrap waters around periodic boundaries on output",
00592       &wrapWater, FALSE);
00593    opts.optionalB("main", "wrapAll", "wrap all clusters around periodic boundaries on output",
00594       &wrapAll, FALSE);
00595    opts.optionalB("main", "wrapNearest", "wrap to nearest image to cell origin",
00596       &wrapNearest, FALSE);
00597 
00598    opts.optional("main", "dielectric", "dielectric constant",
00599      &dielectric, 1.0);
00600    opts.range("dielectric", POSITIVE); // Hmmm, dielectric < 1 ...
00601 
00602    opts.optional("main", "margin", "Patch width margin", &margin, XXXBIGREAL);
00603    opts.range("margin", NOT_NEGATIVE);
00604    opts.units("margin", N_ANGSTROM);
00605 
00606    opts.optional("main", "seed", "Initial random number seed", &randomSeed);
00607    opts.range("seed", POSITIVE);
00608 
00609    opts.optional("main", "outputEnergies", "How often to print energies in timesteps",
00610      &outputEnergies, 1);
00611    opts.range("outputEnergies", POSITIVE);
00612      
00613    opts.optional("main", "outputMomenta", "How often to print linear and angular momenta in timesteps",
00614      &outputMomenta, 0);
00615    opts.range("outputMomenta", NOT_NEGATIVE);
00616      
00617    opts.optional("main", "outputTiming", "How often to print timing data in timesteps",
00618      &outputTiming);
00619    opts.range("outputTiming", NOT_NEGATIVE);
00620      
00621    opts.optional("main", "outputCudaTiming", "How often to print CUDA timing data in timesteps",
00622      &outputCudaTiming, 0);
00623    opts.range("outputCudaTiming", NOT_NEGATIVE);
00624      
00625    opts.optional("main", "outputPressure", "How often to print pressure data in timesteps",
00626      &outputPressure, 0);
00627    opts.range("outputPressure", NOT_NEGATIVE);
00628      
00629    opts.optionalB("main", "mergeCrossterms", "merge crossterm energy with dihedral when printing?",
00630       &mergeCrossterms, TRUE);
00631 
00632    opts.optional("main", "MTSAlgorithm", "Multiple timestep algorithm",
00633     PARSE_STRING);
00634 
00635    opts.optional("main", "longSplitting", "Long range force splitting option",
00636     PARSE_STRING);
00637 
00638    opts.optionalB("main", "ignoreMass", "Do not use masses to find hydrogen atoms",
00639     &ignoreMass, FALSE);
00640 
00641    opts.optional("main", "splitPatch", "Atom into patch splitting option",
00642     PARSE_STRING);
00643    opts.optional("main", "hgroupCutoff", "Hydrogen margin", &hgroupCutoff, 2.5);
00644 
00645    opts.optional("main", "extendedSystem",
00646     "Initial configuration of extended system variables and periodic cell",
00647     PARSE_STRING);
00648 
00649    opts.optional("main", "cellBasisVector1", "Basis vector for periodic cell",
00650     &cellBasisVector1);
00651    opts.optional("main", "cellBasisVector2", "Basis vector for periodic cell",
00652     &cellBasisVector2);
00653    opts.optional("main", "cellBasisVector3", "Basis vector for periodic cell",
00654     &cellBasisVector3);
00655    opts.optional("main", "cellOrigin", "Fixed center of periodic cell",
00656     &cellOrigin);
00657 
00658    opts.optionalB("main", "molly", "Rigid bonds to hydrogen",&mollyOn,FALSE);
00659    opts.optional("main", "mollyTolerance", "Error tolerance for MOLLY",
00660                  &mollyTol, 0.00001);
00661    opts.optional("main", "mollyIterations", 
00662                  "Max number of iterations for MOLLY", &mollyIter, 100);
00663 
00664    opts.optional("main", "rigidBonds", "Rigid bonds to hydrogen",PARSE_STRING);
00665    opts.optional("main", "rigidTolerance", 
00666                  "Error tolerance for rigid bonds to hydrogen",
00667                  &rigidTol, 1.0e-8);
00668    opts.optional("main", "rigidIterations", 
00669                  "Max number of SHAKE iterations for rigid bonds to hydrogen",
00670                  &rigidIter, 100);
00671    opts.optionalB("main", "rigidDieOnError", 
00672                  "Die if rigidTolerance is not achieved after rigidIterations",
00673                  &rigidDie, TRUE);
00674    opts.optionalB("main", "useSettle",
00675                   "Use the SETTLE algorithm for rigid waters",
00676                  &useSettle, TRUE);
00677 
00678    opts.optional("main", "nonbondedFreq", "Nonbonded evaluation frequency",
00679     &nonbondedFrequency, 1);
00680    opts.range("nonbondedFreq", POSITIVE);
00681 
00682    opts.optionalB("main", "outputPatchDetails", "print number of atoms in each patch",
00683       &outputPatchDetails, FALSE);
00684    opts.optionalB("main", "staticAtomAssignment", "never migrate atoms",
00685       &staticAtomAssignment, FALSE);
00686    opts.optionalB("main", "replicaUniformPatchGrids", "same patch grid size on all replicas",
00687       &replicaUniformPatchGrids, FALSE);
00688 #ifndef MEM_OPT_VERSION
00689    // in standard (non-mem-opt) version, enable lone pairs by default
00690    // for compatibility with recent force fields
00691    opts.optionalB("main", "lonePairs", "Enable lone pairs", &lonepairs, TRUE);
00692 #else
00693    // in mem-opt version, disable lone pairs by default
00694    // because they are not supported
00695    opts.optionalB("main", "lonePairs", "Enable lone pairs", &lonepairs, FALSE);
00696 #endif
00697    opts.optional("main", "waterModel", "Water model to use", PARSE_STRING);
00698    opts.optionalB("main", "LJcorrection", "Apply analytical tail corrections for energy and virial", &LJcorrection, FALSE);
00699 }
00700 
00701 void SimParameters::config_parser_fileio(ParseOptions &opts) {
00702    
00704 
00705    opts.optional("main", "cwd", "current working directory", PARSE_STRING);
00706 
00707 // In order to include AMBER options, "coordinates", "structure"
00708 // and "parameters" are now optional, not required. The presence
00709 // of them will be checked later in check_config()
00710 
00711 //   opts.require("main", "coordinates", "initial PDB coordinate file",
00712 //    PARSE_STRING);
00713    opts.optional("main", "coordinates", "initial PDB coordinate file",
00714     PARSE_STRING);
00715 
00716    opts.optional("main", "velocities",
00717      "initial velocities, given as a PDB file", PARSE_STRING);
00718    opts.optional("main", "binvelocities",
00719      "initial velocities, given as a binary restart", PARSE_STRING);
00720    opts.optional("main", "bincoordinates",
00721      "initial coordinates in a binary restart file", PARSE_STRING);
00722 #ifdef MEM_OPT_VERSION
00723    opts.optional("main", "binrefcoords",
00724      "reference coordinates in a binary restart file", PARSE_STRING);
00725 #endif
00726 
00727 //   opts.require("main", "structure", "initial PSF structure file",
00728 //    PARSE_STRING);
00729    opts.optional("main", "structure", "initial PSF structure file",
00730     PARSE_STRING);   
00731 
00732 //   opts.require("main", "parameters",
00733 //"CHARMm 19 or CHARMm 22 compatable force field file (multiple "
00734 //"inputs allowed)", PARSE_MULTIPLES);
00735    opts.optional("main", "parameters",
00736 "CHARMm 19 or CHARMm 22 compatable force field file (multiple "
00737 "inputs allowed)", PARSE_MULTIPLES);
00738 
00739 
00740    //****** BEGIN CHARMM/XPLOR type changes
00742    opts.optionalB("parameters", "paraTypeXplor", "Parameter file in Xplor format?", &paraTypeXplorOn, FALSE);
00743    opts.optionalB("parameters", "paraTypeCharmm", "Parameter file in Charmm format?", &paraTypeCharmmOn, FALSE); 
00744    //****** END CHARMM/XPLOR type changes
00745 
00746    // Ported by JLai -- JE - Go parameters
00747    opts.optionalB("main", "GromacsPair", "Separately calculate pair interactions", &goGroPair, FALSE);
00748    opts.optionalB("main", "GoForcesOn", "Go forces will be calculated", &goForcesOn, FALSE);
00749    opts.require("GoForcesOn", "GoParameters", "Go parameter file", goParameters);
00750    opts.require("GoForcesOn", "GoCoordinates", "target coordinates for Go forces", goCoordinates);
00751    // Added by JLai -- Go-method parameter -- switches between using the matrix and sparse matrix representations [6.3.11] 
00752    //   opts.optional("GoForcesOn", "GoMethod", "Which type of matrix should be used to store Go contacts?", &goMethod);
00753    // Added by JLai -- Go-method parameter [8.2.11]
00754    //opts.optional("GoForcesOn", "GoMethod", "Which type of matrix should be used to store Go contacts?", PARSE_STRING); 
00755    opts.require("GoForcesOn", "GoMethod", "Which type of matrix should be used to store Go contacts?", PARSE_STRING); 
00756   // End of Port -- JL
00757    
00758    opts.require("main", "outputname",
00759     "prefix for the final PDB position and velocity filenames", 
00760     outputFilename);
00761 
00762    opts.optional("main", "auxFile", "Filename for data stream output",
00763      auxFilename);
00764 
00765    opts.optional("main", "numinputprocs", "Number of pes to use for parallel input", 
00766                  &numinputprocs, 0);
00767    opts.range("numinputprocs", NOT_NEGATIVE);
00768 
00769    opts.optional("main", "numoutputprocs", "Number of pes to use for parallel output", 
00770                  &numoutputprocs, 0);
00771    opts.range("numoutputprocs", NOT_NEGATIVE);
00772    opts.optional("main", "numoutputwriters", "Number of output processors that simultaneously write to an output file", 
00773                  &numoutputwrts, 1);
00774    opts.range("numoutputwriters", NOT_NEGATIVE);
00775 
00776    opts.optional("main", "DCDfreq", "Frequency of DCD trajectory output, in "
00777     "timesteps", &dcdFrequency, 0);
00778    opts.range("DCDfreq", NOT_NEGATIVE);
00779    opts.optional("DCDfreq", "DCDfile", "DCD trajectory output file name",
00780      dcdFilename);
00781    opts.optionalB("DCDfreq", "DCDunitcell", "Store unit cell in dcd timesteps?",
00782        &dcdUnitCell);
00783 
00784    opts.optional("main", "velDCDfreq", "Frequency of velocity "
00785     "DCD output, in timesteps", &velDcdFrequency, 0);
00786    opts.range("velDCDfreq", NOT_NEGATIVE);
00787    opts.optional("velDCDfreq", "velDCDfile", "velocity DCD output file name",
00788      velDcdFilename);
00789    
00790    opts.optional("main", "forceDCDfreq", "Frequency of force"
00791     "DCD output, in timesteps", &forceDcdFrequency, 0);
00792    opts.range("forceDCDfreq", NOT_NEGATIVE);
00793    opts.optional("forceDCDfreq", "forceDCDfile", "force DCD output file name",
00794      forceDcdFilename);
00795    
00796    opts.optional("main", "XSTfreq", "Frequency of XST trajectory output, in "
00797     "timesteps", &xstFrequency, 0);
00798    opts.range("XSTfreq", NOT_NEGATIVE);
00799    opts.optional("XSTfreq", "XSTfile", "Extended sytem trajectory output "
00800     "file name", xstFilename);
00801 
00802    opts.optional("main", "restartfreq", "Frequency of restart file "
00803     "generation", &restartFrequency, 0);
00804    opts.range("restartfreq", NOT_NEGATIVE);
00805    opts.optional("restartfreq", "restartname", "Prefix for the position and "
00806      "velocity PDB files used for restarting", restartFilename);
00807    opts.optionalB("restartfreq", "restartsave", "Save restart files with "
00808      "unique filenames rather than overwriting", &restartSave, FALSE);
00809    opts.optionalB("restartfreq", "restartsavedcd", "Save DCD files with "
00810      "unique filenames at each restart", &restartSaveDcd, FALSE);
00811 
00812    opts.optionalB("restartfreq", "binaryrestart", "Specify use of binary restart files ", 
00813        &binaryRestart, TRUE);
00814 
00815    opts.optionalB("outputname", "binaryoutput", "Specify use of binary output files ", 
00816        &binaryOutput, TRUE);
00817 
00818    opts.optionalB("main", "amber", "Is it AMBER force field?",
00819        &amberOn, FALSE);
00820    opts.optionalB("amber", "readexclusions", "Read exclusions from parm file?",
00821        &readExclusions, TRUE);
00822    opts.require("amber", "scnb", "1-4 VDW interactions are divided by scnb",
00823        &vdwscale14, 2.0);
00824    opts.require("amber", "parmfile", "AMBER parm file", PARSE_STRING);
00825    opts.optional("amber", "ambercoor", "AMBER coordinate file", PARSE_STRING);
00826 
00827    /* GROMACS options */
00828    opts.optionalB("main", "gromacs", "Use GROMACS-like force field?",
00829        &gromacsOn, FALSE);
00830    opts.require("gromacs", "grotopfile", "GROMACS topology file",
00831                 PARSE_STRING);
00832    opts.optional("gromacs", "grocoorfile","GROMACS coordinate file",
00833                  PARSE_STRING);
00834 
00835   // OPLS options
00836    opts.optionalB("main", "vdwGeometricSigma",
00837        "Use geometric mean to combine L-J sigmas, as for OPLS",
00838        &vdwGeometricSigma, FALSE);
00839 
00840    // load/store computeMap
00841    opts.optional("main", "computeMapFile", "Filename for computeMap",
00842      computeMapFilename);
00843    opts.optionalB("main", "storeComputeMap", "store computeMap?",
00844        &storeComputeMap, FALSE);
00845    opts.optionalB("main", "loadComputeMap", "load computeMap?",
00846        &loadComputeMap, FALSE);
00847 }
00848 
00849 
00850 void SimParameters::config_parser_fullelect(ParseOptions &opts) {
00851    
00853 #ifdef DPMTA
00854    DebugM(1,"DPMTA setup start\n");
00855    //  PMTA is included, so really get these values
00856    opts.optionalB("main", "FMA", "Should FMA be used?", &FMAOn, FALSE);
00857    opts.optional("FMA", "FMALevels", "Tree levels to use in FMA", &FMALevels,
00858      5);
00859    opts.range("FMALevels", POSITIVE);
00860    opts.optional("FMA", "FMAMp", "Number of FMA multipoles", &FMAMp, 8);
00861    opts.range("FMAMp", POSITIVE);
00862    opts.optionalB("FMA", "FMAFFT", "Use FFT enhancement in FMA?", &FMAFFTOn, TRUE);
00863    opts.optional("FMAFFT", "FMAFFTBlock", "FFT blocking factor",
00864     &FMAFFTBlock, 4);
00865    opts.range("FMAFFTBlock", POSITIVE);
00866    DebugM(1,"DPMTA setup end\n");
00867 #else
00868    //  PMTA is NOT included.  So just set all the values to 0.
00869    FMAOn = FALSE;
00870    FMALevels = 0;
00871    FMAMp = 0;
00872    FMAFFTOn = FALSE;
00873    FMAFFTBlock = 0;
00874 #endif
00875 
00876    opts.optional("main", "fullElectFrequency",
00877       "Number of steps between full electrostatic executions", 
00878       &fullElectFrequency);
00879    opts.range("fullElectFrequency", POSITIVE);
00880 
00881    //  USE OF THIS PARAMETER DISCOURAGED
00882    opts.optional("main", "fmaFrequency",
00883       "Number of steps between full electrostatic executions", 
00884       &fmaFrequency);
00885    opts.range("fmaFrequency", POSITIVE);
00886 
00887    opts.optional("main", "fmaTheta",
00888       "FMA theta parameter value", 
00889       &fmaTheta,0.715);
00890    opts.range("fmaTheta", POSITIVE);
00891 
00892    opts.optionalB("main", "FullDirect", "Should direct calculations of full electrostatics be performed?",
00893       &fullDirectOn, FALSE);
00894 
00895 
00897 
00898    opts.optionalB("main", "MSM",
00899        "Use multilevel summation method for electrostatics?",
00900        &MSMOn, FALSE);
00901    opts.optional("MSM", "MSMQuality", "MSM quality",
00902        &MSMQuality, 0);
00903    opts.optional("MSM", "MSMApprox", "MSM approximation",
00904        &MSMApprox, 0);
00905    opts.optional("MSM", "MSMSplit", "MSM splitting",
00906        &MSMSplit, 0);
00907    opts.optional("MSM", "MSMLevels", "MSM maximum number of levels",
00908        &MSMLevels, 0);  // set to 0 adapts to as many as needed
00909    opts.optional("MSM", "MSMGridSpacing", "MSM grid spacing (Angstroms)",
00910        &MSMGridSpacing, 2.5);
00911    opts.optional("MSM", "MSMPadding", "MSM padding (Angstroms)",
00912        &MSMPadding, 2.5);
00913    opts.optional("MSM", "MSMxmin", "MSM x minimum (Angstroms)", &MSMxmin, 0);
00914    opts.optional("MSM", "MSMxmax", "MSM x maximum (Angstroms)", &MSMxmax, 0);
00915    opts.optional("MSM", "MSMymin", "MSM y minimum (Angstroms)", &MSMymin, 0);
00916    opts.optional("MSM", "MSMymax", "MSM y maximum (Angstroms)", &MSMymax, 0);
00917    opts.optional("MSM", "MSMzmin", "MSM z minimum (Angstroms)", &MSMzmin, 0);
00918    opts.optional("MSM", "MSMzmax", "MSM z maximum (Angstroms)", &MSMzmax, 0);
00919    opts.optional("MSM", "MSMBlockSizeX",
00920        "MSM grid block size along X direction (for decomposing parallel work)",
00921        &MSMBlockSizeX, 8);
00922    opts.optional("MSM", "MSMBlockSizeY",
00923        "MSM grid block size along Y direction (for decomposing parallel work)",
00924        &MSMBlockSizeY, 8);
00925    opts.optional("MSM", "MSMBlockSizeZ",
00926        "MSM grid block size along Z direction (for decomposing parallel work)",
00927        &MSMBlockSizeZ, 8);
00928 
00929    opts.optionalB("MSM", "MsmSerial",
00930        "Use MSM serial version for long-range calculation?",
00931        &MsmSerialOn, FALSE);
00932 
00933 
00935 
00936    opts.optionalB("main", "FMM",
00937        "Use fast multipole method for electrostatics?",
00938        &FMMOn, FALSE);
00939    opts.optional("FMM", "FMMLevels", "FMM number of levels",
00940        &FMMLevels, 0);
00941    opts.optional("FMM", "FMMPadding", "FMM padding margin (Angstroms)",
00942        &FMMPadding, 0);
00943 
00944    opts.optionalB("main", "useCUDA2", "Use new CUDA code", &useCUDA2, TRUE);
00945 
00947 
00948    opts.optionalB("main", "PME", "Use particle mesh Ewald for electrostatics?",
00949         &PMEOn, FALSE);
00950    opts.optional("PME", "PMETolerance", "PME direct space tolerance",
00951         &PMETolerance, 1.e-6);
00952    opts.optional("PME", "PMEInterpOrder", "PME interpolation order",
00953         &PMEInterpOrder, 4);  // cubic interpolation is default
00954    opts.optional("PME", "PMEGridSizeX", "PME grid in x dimension",
00955         &PMEGridSizeX, 0);
00956    opts.optional("PME", "PMEGridSizeY", "PME grid in y dimension",
00957         &PMEGridSizeY, 0);
00958    opts.optional("PME", "PMEGridSizeZ", "PME grid in z dimension",
00959         &PMEGridSizeZ, 0);
00960    opts.optional("PME", "PMEGridSpacing", "Maximum PME grid spacing (Angstroms)",
00961         &PMEGridSpacing, 0.);
00962    opts.range("PMEGridSpacing", NOT_NEGATIVE);
00963    opts.optional("PME", "PMEProcessors",
00964         "PME FFT and reciprocal sum processor count", &PMEProcessors, 0);
00965    opts.optional("PME", "PMEMinSlices",
00966         "minimum thickness of PME reciprocal sum slab", &PMEMinSlices, 2);
00967    opts.range("PMEMinSlices", NOT_NEGATIVE);
00968    opts.optional("PME", "PMEPencils",
00969         "PME FFT and reciprocal sum pencil grid size", &PMEPencils, -1);
00970    opts.optional("PME", "PMEPencilsX",
00971         "PME FFT and reciprocal sum pencil grid size X", &PMEPencilsX, 0);
00972    opts.optional("PME", "PMEPencilsY",
00973         "PME FFT and reciprocal sum pencil grid size Y", &PMEPencilsY, 0);
00974    opts.optional("PME", "PMEPencilsZ",
00975         "PME FFT and reciprocal sum pencil grid size Z", &PMEPencilsZ, 0);
00976    opts.range("PMEPencilsX", NOT_NEGATIVE);
00977    opts.range("PMEPencilsY", NOT_NEGATIVE);
00978    opts.range("PMEPencilsZ", NOT_NEGATIVE);
00979    opts.optional("PME", "PMEPencilsYLayout",
00980         "PME FFT and reciprocal sum Y pencil layout strategy", &PMEPencilsYLayout, 0);
00981    opts.optional("PME", "PMEPencilsXLayout",
00982         "PME FFT and reciprocal sum X pencil layout strategy", &PMEPencilsXLayout, 1);
00983    opts.range("PMEPencilsYLayout", NOT_NEGATIVE);
00984    opts.range("PMEPencilsXLayout", NOT_NEGATIVE);
00985    opts.optional("PME", "PMESendOrder",
00986         "PME message ordering control", &PMESendOrder, 0);
00987    opts.range("PMESendOrder", NOT_NEGATIVE);
00988    opts.optional("PME", "PMEMinPoints",
00989         "minimum points per PME reciprocal sum pencil", &PMEMinPoints, 10000);
00990    opts.range("PMEMinPoints", NOT_NEGATIVE);
00991    opts.optionalB("main", "PMEBarrier", "Use barrier in PME?",
00992         &PMEBarrier, FALSE);
00993    opts.optionalB("main", "PMEOffload", "Offload PME to accelerator?",
00994         &PMEOffload);
00995 
00996    opts.optionalB("PME", "usePMECUDA", "Use the PME CUDA version", &usePMECUDA, CmiNumPhysicalNodes() < 5);
00997    opts.optionalB("PME", "useOptPME", "Use the new scalable PME optimization", &useOptPME, FALSE);
00998    opts.optionalB("PME", "useManyToMany", "Use the many-to-many PME optimization", &useManyToMany, FALSE);
00999    if (PMEOn && !useOptPME)
01000      useManyToMany = false;
01001 
01002 #ifdef DPME
01003    opts.optionalB("PME", "useDPME", "Use old DPME code?", &useDPME, FALSE);
01004 #else
01005    useDPME = 0;
01006 #endif
01007    opts.optionalB("main", "FFTWPatient", "Use intensive plan creation to optimize FFTW?",
01008 #ifdef WIN32
01009         &FFTWPatient, TRUE);
01010 #else
01011         &FFTWPatient, FALSE);
01012 #endif
01013 
01014    opts.optionalB("main", "FFTWEstimate", "Use estimates to optimize FFTW?",
01015 #ifdef WIN32
01016         &FFTWEstimate, TRUE);
01017 #else
01018         &FFTWEstimate, FALSE);
01019 #endif
01020    opts.optionalB("main", "FFTWUseWisdom", "Read/save wisdom file for FFTW?",
01021 #ifdef WIN32
01022         &FFTWUseWisdom, FALSE);
01023 #else
01024         &FFTWUseWisdom, TRUE);
01025 #endif
01026    opts.optional("FFTWUseWisdom", "FFTWWisdomFile", "File for FFTW wisdom",
01027         FFTWWisdomFile);
01028 
01029 }
01030 
01031 void SimParameters::config_parser_methods(ParseOptions &opts) {
01032    
01034    opts.optionalB("main", "minimization", "Should minimization be performed?",
01035       &minimizeCGOn, FALSE);
01036    opts.optionalB("main", "minVerbose", "Print extra minimization diagnostics?",
01037       &minVerbose, FALSE);
01038    opts.optional("main", "minTinyStep", "very first minimization steps",
01039       &minTinyStep, 1.0e-6);
01040    opts.range("minTinyStep", POSITIVE);
01041    opts.optional("main", "minBabyStep", "initial minimization steps",
01042       &minBabyStep, 1.0e-2);
01043    opts.range("minBabyStep", POSITIVE);
01044    opts.optional("main", "minLineGoal", "line minimization gradient reduction",
01045       &minLineGoal, 1.0e-3);
01046    opts.range("minLineGoal", POSITIVE);
01047 
01048    opts.optionalB("main", "velocityQuenching",
01049       "Should old-style minimization be performed?", &minimizeOn, FALSE);
01050 
01051    opts.optional("main", "maximumMove", "Maximum atom movement per step", &maximumMove, 0.0);
01052    opts.range("maximumMove", NOT_NEGATIVE);
01053    opts.units("maximumMove", N_ANGSTROM);
01054 
01055    opts.optionalB("main", "Langevin", "Should Langevin dynamics be performed?",
01056       &langevinOn, FALSE);
01057    opts.require("Langevin", "langevinTemp", "Temperature for heat bath in Langevin "
01058      "dynamics", &langevinTemp);
01059    opts.range("langevinTemp", NOT_NEGATIVE);
01060    opts.units("langevinTemp", N_KELVIN);
01061    opts.optional("Langevin", "langevinDamping", "Damping coefficient (1/ps)",
01062       &langevinDamping);
01063    opts.range("langevinDamping", POSITIVE);
01064    opts.optionalB("Langevin", "langevinHydrogen", "Should Langevin dynamics be applied to hydrogen atoms?",
01065       &langevinHydrogen);
01066    opts.optional("Langevin", "langevinFile", "PDB file with temperature "
01067      "coupling terms (B(i)) (default is the PDB input file)",
01068      PARSE_STRING);
01069    opts.optional("Langevin", "langevinCol", "Column in the langevinFile "
01070      "containing the temperature coupling term B(i);\n"
01071      "default is 'O'", PARSE_STRING);
01072 
01073    // use BAOAB integration instead of BBK
01074    opts.optionalB("Langevin", "langevinBAOAB",
01075        "Should Langevin dynamics be performed using BAOAB integration?",
01076        &langevin_useBAOAB, FALSE);
01077 
01078 // BEGIN LA
01079    opts.optionalB("main", "LoweAndersen", "Should Lowe-Andersen dynamics be performed?",
01080                   &loweAndersenOn, FALSE);
01081    opts.require("LoweAndersen", "loweAndersenTemp", "Temperature for heat bath in Lowe-Andersen "
01082                 "dynamics", &loweAndersenTemp);
01083    opts.range("loweAndersenTemp", NOT_NEGATIVE);
01084    opts.units("loweAndersenTemp", N_KELVIN);
01085    opts.optional("LoweAndersen", "loweAndersenRate", "Collision rate (1/ps)",
01086                  &loweAndersenRate, 50);
01087    opts.range("loweAndersenRate", POSITIVE);
01088    opts.optional("LoweAndersen", "loweAndersenCutoff", "Cutoff radius",
01089                  &loweAndersenCutoff, 2.7);
01090    opts.range("loweAndersenCutoff", POSITIVE);
01091    opts.units("loweAndersenCutoff", N_ANGSTROM);
01092 // END LA
01093 
01094 //fepb
01095    opts.optionalB("main", "alch", "Is achemical simulation being performed?",
01096      &alchOn, FALSE);
01097    opts.require("alch", "alchLambda", "Alchemical coupling parameter value",
01098      &alchLambda);
01099    opts.range("alchLambda", NOT_NEGATIVE);
01100 
01101    opts.optional("alch", "alchFile", "PDB file with perturbation flags "
01102      "default is the input PDB file", PARSE_STRING);
01103    opts.optional("alch", "alchCol", "Column in the alchFile with the "
01104      "perturbation flag", PARSE_STRING);
01105 
01106    opts.optional("alch", "alchOutFreq", "Frequency of alchemical energy"
01107      "output in timesteps", &alchOutFreq, 5);
01108    opts.range("alchoutfreq", NOT_NEGATIVE);
01109    opts.optional("alch", "alchOutFile", "Alchemical energy output filename",
01110      alchOutFile);
01111 
01112    // soft-core parameters
01113    opts.optional("alch", "alchVdwShiftCoeff", "Coeff used for generating"
01114      "the altered alchemical vDW interactions", &alchVdwShiftCoeff, 5.);
01115    opts.range("alchVdwShiftCoeff", NOT_NEGATIVE);
01116 
01117    // scheduling options for different interaction types
01118    opts.optional("alch", "alchElecLambdaStart", "Lambda at which electrostatic"
01119       "scaling of exnihilated particles begins", &alchElecLambdaStart, 0.5);
01120    opts.range("alchElecLambdaStart", NOT_NEGATIVE);
01121 
01122    opts.optional("alch", "alchVdwLambdaEnd", "Lambda at which vdW"
01123       "scaling of exnihilated particles begins", &alchVdwLambdaEnd, 1.0);
01124    opts.range("alchVdwLambdaEnd", NOT_NEGATIVE);
01125 
01126    opts.optional("alch", "alchBondLambdaEnd", "Lambda at which bonded"
01127       "scaling of exnihilated particles begins", &alchBondLambdaEnd, 0.0);
01128    opts.range("alchBondLambdaEnd", NOT_NEGATIVE);
01129    
01130    opts.optionalB("alch", "alchDecouple", "Enable alchemical decoupling?",
01131      &alchDecouple, FALSE);
01132    opts.optionalB("alch", "alchBondDecouple", "Enable decoupling of purely "
01133      "alchemical bonds?", &alchBondDecouple, FALSE);
01134 
01135    // parameters for alchemical analysis options
01136    opts.optional("alch", "alchType", "Which alchemical method to use?",
01137      PARSE_STRING);
01138    opts.optional("alch", "alchLambda2", "Alchemical coupling comparison value",
01139      &alchLambda2, -1);
01140    opts.optional("alch", "alchLambdaIDWS", "Alchemical coupling comparison value for interleaved double-wide sampling",
01141      &alchLambdaIDWS, -1);
01142    opts.optional("alch", "alchLambdaFreq",
01143      "Frequency of increasing coupling parameter value", &alchLambdaFreq, 0);
01144    opts.range("alchLambdaFreq", NOT_NEGATIVE);
01145    opts.optional("alch", "alchSwitchType", "Switching type flag",
01146      PARSE_STRING);
01147    opts.optional("alch", "alchEquilSteps", "Equilibration steps, before "
01148      "data collection in the alchemical window", &alchEquilSteps, 0);
01149    opts.range("alchEquilSteps", NOT_NEGATIVE);
01150 
01151    // WCA decomposition options
01152    opts.optionalB("alch", "alchFepWCARepuOn",
01153      "WCA decomposition repu interaction in use?", &alchFepWCARepuOn, FALSE);
01154    opts.optionalB("alch", "alchFepWCADispOn",
01155      "WCA decomposition disp interaction in use?", &alchFepWCADispOn, FALSE);
01156    opts.optionalB("alch", "alchEnsembleAvg", "Ensemble Average in use?",
01157      &alchEnsembleAvg, TRUE);
01158    opts.optionalB("alch", "alchFepWhamOn",
01159      "Energy output for Wham postprocessing in use?", &alchFepWhamOn, FALSE);
01160    opts.optional("alch", "alchFepWCArcut1",
01161      "WCA repulsion Coeff1 used for generating the altered alchemical vDW "
01162      "interactions", &alchFepWCArcut1, 0.0);
01163    opts.range("alchFepWCArcut1", NOT_NEGATIVE);
01164    opts.optional("alch", "alchFepWCArcut2", "WCA repulsion Coeff2 used for "
01165      "generating the altered alchemical vDW interactions", &alchFepWCArcut2,
01166      1.0);
01167    opts.range("alchFepWCArcut2", NOT_NEGATIVE);
01168    opts.optional("alch", "alchFepWCArcut3",
01169      "WCA repulsion Coeff3 used for generating the altered alchemical vDW "
01170      "interactions", &alchFepWCArcut3, 1.0);
01171    opts.range("alchFepWCArcut3", NOT_NEGATIVE);
01172    // These default to invalid lambda values.
01173    opts.optional("alch", "alchRepLambda", "Lambda of WCA repulsion"
01174      "Coupling parameter value for WCA repulsion", &alchRepLambda, -1.0);
01175    opts.optional("alch", "alchDispLambda", "Lambda of WCA dispersion"
01176      "Coupling parameter value for WCA dispersion", &alchDispLambda, -1.0);
01177    opts.optional("alch", "alchElecLambda", "Lambda of electrostatic "
01178      "perturbation Coupling parameter value for electrostatic perturbation",
01179      &alchElecLambda, -1.0);
01180 //fepe
01181 
01182    opts.optionalB("main", "les", "Is locally enhanced sampling enabled?",
01183      &lesOn, FALSE);
01184    opts.require("les", "lesFactor", "Local enhancement factor", &lesFactor);
01185    opts.optional("les", "lesFile", "PDB file with enhancement flags "
01186      "default is the input PDB file", PARSE_STRING); 
01187    opts.optional("les", "lesCol", "Column in the lesFile with the "
01188      "enhancement flag", PARSE_STRING);
01189    opts.optionalB("les", "lesReduceTemp", "Reduce enhanced atom temperature?",
01190      &lesReduceTemp, FALSE);
01191    opts.optionalB("les", "lesReduceMass", "Reduce enhanced atom mass?",
01192      &lesReduceMass, FALSE);
01193 
01194    // REST2 (replica exchange solute tempering) parameters
01195    opts.optionalB("main", "soluteScaling",
01196        "Is replica exchange solute tempering enabled?",
01197        &soluteScalingOn, FALSE);
01198    opts.require("soluteScaling", "soluteScalingFactor",
01199        "Solute scaling factor",
01200        &soluteScalingFactor);
01201    opts.range("soluteScalingFactor", NOT_NEGATIVE);
01202    opts.optional("soluteScaling", "soluteScalingFactorCharge",
01203        "Solute scaling factor for electrostatic interactions",
01204        &soluteScalingFactorCharge);
01205    opts.range("soluteScalingFactorCharge", NOT_NEGATIVE);
01206    opts.optional("soluteScaling", "soluteScalingFactorVdw",
01207        "Solute scaling factor for van der Waals interactions",
01208        &soluteScalingFactorVdw);
01209    opts.range("soluteScalingFactorVdw", NOT_NEGATIVE);
01210    opts.optional("soluteScaling", "ssFile",
01211        "PDB file with scaling flags; if undefined, defaults to main PDB file",
01212        PARSE_STRING);
01213    opts.optional("soluteScaling", "ssCol",
01214        "Column in the ssFile providing the scaling flag",
01215        PARSE_STRING);
01216    opts.optionalB("main", "soluteScalingAll",
01217        "Apply scaling also to bond and angle interactions?",
01218        &soluteScalingAll, TRUE);
01219 
01220    // Drude oscillators
01221    opts.optionalB("main", "drude", "Perform integration of Drude oscillators?",
01222        &drudeOn, FALSE);
01223    opts.require("drude", "drudeTemp", "Temperature for freezing "
01224        "Drude oscillators", &drudeTemp);
01225    opts.range("drudeTemp", NOT_NEGATIVE);
01226    opts.units("drudeTemp", N_KELVIN);
01227    opts.optional("drude", "drudeDamping", "Damping coefficient (1/ps) for "
01228        "Drude oscillators", &drudeDamping);
01229    opts.range("drudeDamping", POSITIVE);
01230    opts.optional("drude", "drudeBondLen", "Drude oscillator bond length "
01231        "beyond which to apply restraint", &drudeBondLen);
01232    opts.range("drudeBondLen", POSITIVE);
01233    opts.optional("drude", "drudeBondConst", "Drude oscillator restraining "
01234        "force constant", &drudeBondConst);
01235    opts.range("drudeBondConst", POSITIVE);
01236    opts.optional("drude", "drudeNbtholeCut", "Nonbonded Thole interactions "
01237        "interaction radius", &drudeNbtholeCut);
01238    opts.range("drudeNbtholeCut", POSITIVE);
01239    opts.optionalB("drude", "drudeHardWall", "Apply maximum Drude bond length "
01240        "restriction?", &drudeHardWallOn, FALSE);
01241 
01242    // Pair interaction calculations
01243     opts.optionalB("main", "pairInteraction", 
01244         "Are pair interactions calculated?", &pairInteractionOn, FALSE);
01245     opts.optional("pairInteraction", "pairInteractionFile", 
01246         "PDB files with interaction flags " "default is the input PDB file", 
01247         PARSE_STRING);
01248     opts.optional("pairInteraction", "pairInteractionCol", 
01249         "Column in the pairInteractionFile with the interaction flags",
01250         PARSE_STRING);
01251     opts.require("pairInteraction", "pairInteractionGroup1",
01252         "Flag for interaction group 1", &pairInteractionGroup1);
01253     opts.optional("pairInteraction", "pairInteractionGroup2",
01254         "Flag for interaction group 2", &pairInteractionGroup2, -1);
01255     opts.optionalB("pairInteraction", "pairInteractionSelf",
01256         "Compute only within-group interactions?", &pairInteractionSelf, 
01257         FALSE);
01258    // Options for CG simulations
01259    opts.optionalB("main", "cosAngles", "Are some angles cosine-based?", &cosAngles, FALSE);
01260 
01261 
01262    //  Dihedral angle dynamics
01263    opts.optionalB("main", "globalTest", "Should global integration (for development) be used?",
01264     &globalOn, FALSE);
01265    opts.optionalB("main", "dihedral", "Should dihedral angle dynamics be performed?",
01266     &dihedralOn, FALSE);
01267    COLDOn = FALSE;
01268    opts.optionalB("dihedral", "COLD", "Should overdamped Langevin dynamics be performed?",
01269     &COLDOn, FALSE);
01270    opts.require("COLD", "COLDTemp", "Temperature for heat bath in COLD",
01271     &COLDTemp);
01272    opts.range("COLDTemp", NOT_NEGATIVE);
01273    opts.units("COLDTemp", N_KELVIN);
01274    opts.require("COLD", "COLDRate", "Damping rate for COLD",
01275     &COLDRate, 3000.0);
01276    opts.range("COLDRate", NOT_NEGATIVE);
01277 
01278    //  Get the parameters for temperature coupling
01279    opts.optionalB("main", "tcouple", 
01280       "Should temperature coupling be performed?",
01281       &tCoupleOn, FALSE);
01282    opts.require("tcouple", "tCoupleTemp", 
01283     "Temperature for temperature coupling", &tCoupleTemp);
01284    opts.range("tCoupleTemp", NOT_NEGATIVE);
01285    opts.units("tCoupleTemp", N_KELVIN);
01286    opts.optional("tCouple", "tCoupleFile", "PDB file with temperature "
01287      "coupling terms (B(i)) (default is the PDB input file)",
01288      PARSE_STRING);
01289    opts.optional("tCouple", "tCoupleCol", "Column in the tCoupleFile "
01290      "containing the temperature coupling term B(i);\n"
01291      "default is 'O'", PARSE_STRING);
01292 
01293    opts.optionalB("main", "stochRescale",
01294       "Should stochastic velocity rescaling be performed?",
01295       &stochRescaleOn, FALSE);
01296    opts.require("stochRescale", "stochRescaleTemp",
01297       "Temperature for stochastic velocity rescaling",
01298        &stochRescaleTemp);
01299    opts.range("stochRescaleTemp", NOT_NEGATIVE);
01300    opts.units("stochRescaleTemp", N_KELVIN);
01301    opts.require("stochRescale", "stochRescalePeriod",
01302       "Time scale for stochastic velocity rescaling (ps)",
01303        &stochRescalePeriod);
01304    opts.range("stochRescalePeriod", POSITIVE);
01305    opts.optional("stochRescale", "stochRescaleFreq",
01306        "Number of steps between stochastic rescalings",
01307         &stochRescaleFreq);
01308    opts.range("stochRescaleFreq", POSITIVE);
01309 
01310    opts.optional("main", "rescaleFreq", "Number of steps between "
01311     "velocity rescaling", &rescaleFreq);
01312    opts.range("rescaleFreq", POSITIVE);
01313    opts.optional("main", "rescaleTemp", "Target temperature for velocity rescaling",
01314     &rescaleTemp);
01315    opts.range("rescaleTemp", NOT_NEGATIVE);
01316    opts.units("rescaleTemp", N_KELVIN);
01317 
01318    opts.optional("main", "reassignFreq", "Number of steps between "
01319     "velocity reassignment", &reassignFreq);
01320    opts.range("reassignFreq", POSITIVE);
01321    opts.optional("main", "reassignTemp", "Target temperature for velocity reassignment",
01322     &reassignTemp);
01323    opts.range("reassignTemp", NOT_NEGATIVE);
01324    opts.units("reassignTemp", N_KELVIN);
01325    opts.optional("main", "reassignIncr", "Temperature increment for velocity reassignment",
01326     &reassignIncr);
01327    opts.units("reassignIncr", N_KELVIN);
01328    opts.optional("main", "reassignHold", "Final holding temperature for velocity reassignment",
01329     &reassignHold);
01330    opts.range("reassignHold", NOT_NEGATIVE);
01331    opts.units("reassignHold", N_KELVIN);
01332 
01334    opts.optionalB("main", "useGroupPressure", 
01335       "Use group rather than atomic quantities for pressure control?",
01336       &useGroupPressure, FALSE);
01337 
01339    opts.optionalB("main", "useFlexibleCell",
01340       "Use anisotropic cell fluctuation for pressure control?",
01341       &useFlexibleCell, FALSE);
01342 
01343    // Fix specific cell dimensions
01344    opts.optionalB("main", "fixCellDims",
01345       "Fix some cell dimensions?",
01346       &fixCellDims, FALSE);
01347 
01348    opts.optionalB("fixCellDims", "fixCellDimX",
01349       "Fix the X dimension?",
01350       &fixCellDimX, FALSE);
01351    opts.optionalB("fixCellDims", "fixCellDimY",
01352       "Fix the Y dimension?",
01353       &fixCellDimY, FALSE);
01354    opts.optionalB("fixCellDims", "fixCellDimZ",
01355       "Fix the Z dimension?",
01356       &fixCellDimZ, FALSE);
01357 
01359    opts.optionalB("main", "useConstantRatio",
01360       "Use constant X-Y ratio for pressure control?",
01361       &useConstantRatio, FALSE);
01362 
01364    opts.optionalB("main", "useConstantArea",
01365       "Use constant area for pressure control?",
01366       &useConstantArea, FALSE);
01367 
01369    opts.optionalB("main", "excludeFromPressure",
01370         "Should some atoms be excluded from pressure rescaling?",
01371         &excludeFromPressure, FALSE);
01372    opts.optional("excludeFromPressure", "excludeFromPressureFile",
01373         "PDB file for atoms to be excluded from pressure",
01374         PARSE_STRING);
01375    opts.optional("excludeFromPressure", "excludeFromPressureCol", 
01376         "Column in the excludeFromPressureFile"
01377         "containing the flags (nonzero means excluded);\n"
01378         "default is 'O'", PARSE_STRING);
01379 
01381    opts.optionalB("main", "BerendsenPressure", 
01382       "Should Berendsen pressure bath coupling be performed?",
01383       &berendsenPressureOn, FALSE);
01384    opts.require("BerendsenPressure", "BerendsenPressureTarget",
01385     "Target pressure for pressure coupling",
01386     &berendsenPressureTarget);
01387    // opts.units("BerendsenPressureTarget",);
01388    opts.require("BerendsenPressure", "BerendsenPressureCompressibility",
01389     "Isothermal compressibility for pressure coupling",
01390     &berendsenPressureCompressibility);
01391    // opts.units("BerendsenPressureCompressibility",);
01392    opts.require("BerendsenPressure", "BerendsenPressureRelaxationTime",
01393     "Relaxation time for pressure coupling",
01394     &berendsenPressureRelaxationTime);
01395    opts.range("BerendsenPressureRelaxationTime", POSITIVE);
01396    opts.units("BerendsenPressureRelaxationTime", N_FSEC);
01397    opts.optional("BerendsenPressure", "BerendsenPressureFreq",
01398     "Number of steps between volume rescaling",
01399     &berendsenPressureFreq, 1);
01400    opts.range("BerendsenPressureFreq", POSITIVE);
01401 
01403    opts.optionalB("main", "LangevinPiston",
01404       "Should Langevin piston pressure control be used?",
01405       &langevinPistonOn, FALSE);
01406    opts.optionalB("LangevinPiston", "LangevinPistonBarrier",
01407       "Should Langevin piston barrier be used?",
01408       &langevinPistonBarrier, TRUE);
01409    opts.require("LangevinPiston", "LangevinPistonTarget",
01410       "Target pressure for pressure control",
01411       &langevinPistonTarget);
01412    opts.require("LangevinPiston", "LangevinPistonPeriod",
01413       "Oscillation period for pressure control",
01414       &langevinPistonPeriod);
01415    opts.range("LangevinPistonPeriod", POSITIVE);
01416    opts.units("LangevinPistonPeriod", N_FSEC);
01417    opts.require("LangevinPiston", "LangevinPistonDecay",
01418       "Decay time for pressure control",
01419       &langevinPistonDecay);
01420    opts.range("LangevinPistonDecay", POSITIVE);
01421    opts.units("LangevinPistonDecay", N_FSEC);
01422    opts.require("LangevinPiston", "LangevinPistonTemp",
01423       "Temperature for pressure control piston",
01424       &langevinPistonTemp);
01425    opts.range("LangevinPistonTemp", POSITIVE);
01426    opts.units("LangevinPistonTemp", N_KELVIN);
01427    opts.optional("LangevinPiston", "StrainRate",
01428       "Initial strain rate for pressure control (x y z)",
01429       &strainRate);
01430 
01431    // Multigrator temperature and/or pressure control
01432    opts.optionalB("main", "Multigrator", 
01433       "Should multigrator temperature and/or pressure control be used?",
01434       &multigratorOn, FALSE);
01435    opts.require("Multigrator", "MultigratorPressureTarget",
01436     "Target pressure for pressure coupling",
01437     &multigratorPressureTarget);
01438    opts.require("Multigrator", "MultigratorTemperatureTarget",
01439     "Target temperature for temperature coupling",
01440     &multigratorTemperatureTarget);
01441    opts.require("Multigrator", "MultigratorPressureFreq",
01442     "Number of steps between pressure control moves",
01443     &multigratorPressureFreq);
01444    opts.range("MultigratorPressureFreq", POSITIVE);
01445    opts.optional("Multigrator", "MultigratorPressureRelaxationTime",
01446     "Relaxation time for pressure coupling is fs",
01447     &multigratorPressureRelaxationTime, 30000);
01448    opts.range("MultigratorPressureRelaxationTime", POSITIVE);
01449    opts.units("MultigratorPressureRelaxationTime", N_FSEC);
01450    opts.optional("Multigrator", "MultigratorTemperatureRelaxationTime",
01451     "Relaxation time for temperature coupling is fs",
01452     &multigratorTemperatureRelaxationTime, 1000);
01453    opts.range("MultigratorTemperatureRelaxationTime", POSITIVE);
01454    opts.units("MultigratorTemperatureRelaxationTime", N_FSEC);
01455    opts.require("Multigrator", "MultigratorTemperatureFreq",
01456     "Number of steps between temperature control moves",
01457     &multigratorTemperatureFreq);
01458    opts.range("MultigratorTemperatureFreq", POSITIVE);
01459    opts.optional("Multigrator", "MultigratorNoseHooverChainLength",
01460     "Nose-Hoover chain length",
01461     &multigratorNoseHooverChainLength, 4);
01462    opts.range("MultigratorNoseHooverChainLength", POSITIVE);
01463 
01465    opts.optional("main", "SurfaceTensionTarget",
01466       "Surface tension in the x-y plane",
01467       &surfaceTensionTarget, 0);
01468 
01470    opts.optionalB("main", "pressureprofile", "Compute pressure profile?",
01471      &pressureProfileOn, FALSE);
01472    opts.require("pressureprofile", "pressureprofileslabs", 
01473      "Number of pressure profile slabs", &pressureProfileSlabs, 10);
01474    opts.optional("pressureprofile", "pressureprofilefreq",
01475      "How often to store profile data", &pressureProfileFreq, 1);
01476    opts.optional("pressureprofile", "pressureProfileAtomTypes", 
01477      "Number of pressure profile atom types", &pressureProfileAtomTypes, 1);
01478    opts.range("pressureProfileAtomTypes", POSITIVE);
01479    opts.optional("pressureProfile", "pressureProfileAtomTypesFile", 
01480         "PDB files with pressure profile atom types" "default is the input PDB file", 
01481         PARSE_STRING);
01482    opts.optional("pressureProfile", "pressureProfileAtomTypesCol", 
01483         "Column in the pressureProfileAtomTypesFile with the atom types ",
01484         PARSE_STRING);
01485    opts.optionalB("pressureProfile", "pressureProfileEwald", 
01486        "Compute Ewald contribution to pressure profile",
01487        &pressureProfileEwaldOn, FALSE);
01488    opts.optional("pressureProfile", "pressureProfileEwaldX",
01489        "Ewald grid size X", &pressureProfileEwaldX, 10);
01490    opts.range("pressureProfileEwaldX", POSITIVE);
01491    opts.optional("pressureProfile", "pressureProfileEwaldY",
01492        "Ewald grid size Y", &pressureProfileEwaldY, 10);
01493    opts.range("pressureProfileEwaldY", POSITIVE);
01494    opts.optional("pressureProfile", "pressureProfileEwaldZ",
01495        "Ewald grid size Z", &pressureProfileEwaldZ, 10);
01496    opts.range("pressureProfileEwaldZ", POSITIVE);
01497 
01499    opts.optionalB("main", "accelMD", "Perform acclerated MD?", &accelMDOn, FALSE);
01500    opts.optional("accelMD", "accelMDFirstStep", "First accelMD step", &accelMDFirstStep, 0);
01501    opts.range("accelMDFirstStep", NOT_NEGATIVE);
01502    opts.optional("accelMD", "accelMDLastStep", "Last accelMD step", &accelMDLastStep, 0);
01503    opts.range("accelMDLastStep", NOT_NEGATIVE);
01504    opts.optional("accelMD", "accelMDOutFreq", "Frequency of accelMD output", &accelMDOutFreq, 1);
01505    opts.range("accelMDOutFreq", POSITIVE);
01506    opts.optionalB("accelMD", "accelMDdihe", "Apply boost to dihedral potential", &accelMDdihe, TRUE);
01507    opts.optionalB("accelMD", "accelMDDebugOn", "Debugging accelMD", &accelMDDebugOn, FALSE);
01508    opts.optional("accelMD", "accelMDE","E for AMD", &accelMDE);
01509    opts.units("accelMDE", N_KCAL);
01510    opts.optional("accelMD", "accelMDalpha","alpha for AMD", &accelMDalpha);
01511    opts.units("accelMDalpha", N_KCAL);
01512    opts.range("accelMDalpha", POSITIVE);
01513    opts.optionalB("accelMD", "accelMDdual", "Apply dual boost", &accelMDdual, FALSE);
01514    opts.optional("accelMDdual", "accelMDTE","E for total potential under accelMDdual mode", &accelMDTE);
01515    opts.units("accelMDTE", N_KCAL);
01516    opts.optional("accelMDdual", "accelMDTalpha","alpha for total potential under accelMDdual mode", &accelMDTalpha);
01517    opts.units("accelMDTalpha", N_KCAL);
01518    opts.range("accelMDTalpha", POSITIVE);
01519    // GaMD parameters
01520    opts.optionalB("accelMD", "accelMDG", "Perform Gaussian accelMD calculation?", &accelMDG, FALSE);
01521    opts.optional("accelMDG", "accelMDGiE", "Flag to set the mode iE in Gaussian accelMD", &accelMDGiE, 1);
01522    opts.optional("accelMDG", "accelMDGcMDSteps", "No. of cMD steps", &accelMDGcMDSteps, 1000000);
01523    opts.range("accelMDGcMDSteps", NOT_NEGATIVE);
01524    opts.optional("accelMDG", "accelMDGEquiSteps", "No. of equilibration steps after adding boost potential", &accelMDGEquiSteps, 1000000);
01525    opts.range("accelMDGEquiSteps", NOT_NEGATIVE);
01526    opts.require("accelMDG", "accelMDGcMDPrepSteps", "No. of preparation cMD steps", &accelMDGcMDPrepSteps, 200000);
01527    opts.range("accelMDGcMDPrepSteps", NOT_NEGATIVE);
01528    opts.require("accelMDG", "accelMDGEquiPrepSteps", "No. of preparation equilibration steps", &accelMDGEquiPrepSteps, 200000);
01529    opts.range("accelMDGEquiPrepSteps", NOT_NEGATIVE);
01530    opts.optional("accelMDG", "accelMDGSigma0P", "Upper limit of std of total potential", &accelMDGSigma0P, 6.0);
01531    opts.units("accelMDGSigma0P", N_KCAL);
01532    opts.range("accelMDGSigma0P", NOT_NEGATIVE);
01533    opts.optional("accelMDG", "accelMDGSigma0D", "Upper limit of std of dihedral potential", &accelMDGSigma0D, 6.0);
01534    opts.units("accelMDGSigma0D", N_KCAL);
01535    opts.range("accelMDGSigma0D", NOT_NEGATIVE);
01536    opts.optionalB("accelMDG", "accelMDGRestart", "Flag to set use restart file in Gaussian accelMD", &accelMDGRestart, FALSE);
01537    opts.require("accelMDGRestart", "accelMDGRestartFile", "Restart file name for Gaussian accelMD", accelMDGRestartFile);
01538    opts.optionalB("accelMDG", "accelMDGresetVaftercmd", "Flag to reset potential after accelMDGcMDSteps steps", 
01539            &accelMDGresetVaftercmd, FALSE);
01540 
01541    // Adaptive Temperature Sampling (adaptTemp) parameters
01542    opts.optionalB("main", "adaptTempMD", "Perform adaptive temperature sampling", &adaptTempOn, FALSE);
01543    opts.optional("adaptTempMD", "adaptTempFirstStep", "First adaptTemp step", &adaptTempFirstStep, 0);
01544    opts.range("adaptTempFirstStep", NOT_NEGATIVE);
01545    opts.optional("adaptTempMD", "adaptTempLastStep", "Last adaptTemp step", &adaptTempLastStep, 0);
01546    opts.range("adaptTempLastStep", NOT_NEGATIVE);
01547    opts.optional("adaptTempMD", "adaptTempOutFreq", "Frequency of adaptTemp output", &adaptTempOutFreq, 10);
01548    opts.range("adaptTempOutFreq", POSITIVE);
01549    opts.optional("adaptTempMD", "adaptTempFreq", "Frequency of writing average energies to adaptTempOutFile", &adaptTempFreq, 10);
01550    opts.range("adaptTempFreq", POSITIVE);
01551    opts.optionalB("adaptTempMD", "adaptTempDebug", "Print debug output for adaptTemp", &adaptTempDebug, FALSE);
01552    opts.optional("adaptTempMD", "adaptTempTmin","Minimun temperature for adaptTemp", &adaptTempTmin);
01553    opts.units("adaptTempTmin", N_KELVIN);
01554    opts.range("adaptTempTmin", POSITIVE);
01555    opts.optional("adaptTempMD", "adaptTempTmax","Maximum temperature for adaptTemp", &adaptTempTmax);
01556    opts.units("adaptTempTmax", N_KELVIN);
01557    opts.range("adaptTempTmax", POSITIVE);
01558    opts.optional("adaptTempMD", "adaptTempBins","Number of bins to store average energies", &adaptTempBins,0);
01559    opts.range("adaptTempBins", NOT_NEGATIVE);
01560    opts.optional("adaptTempMD", "adaptTempDt", "Integration timestep for Temp. updates", &adaptTempDt, 0.0001);
01561    opts.units("adaptTempDt", N_FSEC);
01562    opts.range("adaptTempDt", NOT_NEGATIVE);
01563    opts.optional("adaptTempMD", "adaptTempAutoDt", "Average temperature update in percent of temperature range", &adaptTempAutoDt, 0.0);
01564    opts.range("adaptTempAutoDt", NOT_NEGATIVE);
01565    opts.optional("adaptTempMD", "adaptTempCgamma", "Adaptive bin averaging constant", &adaptTempCgamma, 0.1);
01566    opts.range("adaptTempCgamma", NOT_NEGATIVE);
01567    opts.optionalB("adaptTempMD","adaptTempLangevin","Send adaptTemp temperature to langevin thermostat",&adaptTempLangevin,TRUE);
01568    opts.optionalB("adaptTempMD","adaptTempRescaling","Send adaptTemp temperature to velocity rescaling thermostat", &adaptTempRescale,TRUE);
01569    opts.optional("adaptTempMD", "adaptTempInFile", "File containing restart information for adaptTemp", adaptTempInFile);
01570    opts.optional("adaptTempMD", "adaptTempRestartFile", "File for writing adaptTemp restart information", adaptTempRestartFile);
01571    opts.require("adaptTempRestartFile","adaptTempRestartFreq", "Frequency of writing restart file", &adaptTempRestartFreq,0);
01572    opts.range("adaptTempRestartFreq",NOT_NEGATIVE);
01573    opts.optionalB("adaptTempMD", "adaptTempRandom", "Randomly assign a temperature if we step out of range", &adaptTempRandom, FALSE);
01574 }
01575 
01576 void SimParameters::config_parser_constraints(ParseOptions &opts) {
01577    
01579    opts.optionalB("main", "fixedatoms", "Are there fixed atoms?",
01580     &fixedAtomsOn, FALSE);
01581    opts.optionalB("fixedatoms", "fixedAtomsForces",
01582      "Calculate forces between fixed atoms?  (Required to unfix during run.)",
01583      &fixedAtomsForces, FALSE);
01584    opts.optional("fixedatoms", "fixedAtomsFile", "PDB file with flags for "
01585      "fixed atoms (default is the PDB input file)",
01586      PARSE_STRING);
01587    opts.optional("fixedatoms", "fixedAtomsCol", "Column in the fixedAtomsFile "
01588      "containing the flags (nonzero means fixed);\n"
01589      "default is 'O'", PARSE_STRING);
01590    opts.optional("fixedatoms", "fixedAtomListFile", "the text input file for fixed atoms "
01591                  "used for parallel input IO", PARSE_STRING);
01592    opts.optionalB("fixedatoms", "fixedAtomsForceOutput",
01593      "Do we write out forces acting on fixed atoms?",
01594      &fixedAtomsForceOutput, FALSE);
01595 
01597    opts.optionalB("main", "constraints", "Are harmonic constraints active?",
01598      &constraintsOn, FALSE);
01599    opts.require("constraints", "consexp", "Exponent for harmonic potential",
01600     &constraintExp, 2);
01601    opts.range("consexp", POSITIVE);
01602 #ifndef MEM_OPT_VERSION
01603    opts.require("constraints", "consref", "PDB file containing reference "
01604     "positions",
01605     PARSE_STRING);
01606    opts.require("constraints", "conskfile", "PDB file containing force "
01607     "constaints in one of the columns", PARSE_STRING);
01608    opts.require("constraints", "conskcol", "Column of conskfile to use "
01609     "for the force constants", PARSE_STRING);
01610 #else
01611    opts.require("constraints", "consAtomListFile", "the text input file for constrained atoms "
01612                  "used for parallel input IO", PARSE_STRING);
01613 #endif
01614    opts.require("constraints", "constraintScaling", "constraint scaling factor",
01615      &constraintScaling, 1.0);
01616    opts.range("constraintScaling", NOT_NEGATIVE);
01617 
01618 
01619 
01620    //****** BEGIN selective restraints (X,Y,Z) changes
01621 
01623    opts.optionalB("constraints", "selectConstraints", 
01624    "Restrain only selected Cartesian components of the coordinates?",
01625      &selectConstraintsOn, FALSE);
01626    opts.optionalB("selectConstraints", "selectConstrX",  
01627    "Restrain X components of coordinates ", &constrXOn, FALSE);
01628    opts.optionalB("selectConstraints", "selectConstrY",  
01629    "Restrain Y components of coordinates ", &constrYOn, FALSE);
01630    opts.optionalB("selectConstraints", "selectConstrZ",  
01631    "Restrain Z components of coordinates ", &constrZOn, FALSE);
01632    //****** END selective restraints (X,Y,Z) changes
01633 
01634    // spherical constraints
01635    opts.optionalB("constraints", "sphericalConstraints", 
01636    "Restrain only radial spherical component of the coordinates?",
01637      &sphericalConstraintsOn, FALSE);
01638    opts.optional("sphericalConstraints", "sphericalConstrCenter",
01639    "Center of spherical constraints", &sphericalConstrCenter);
01640  
01641    //****** BEGIN moving constraints changes 
01642 
01644    opts.optionalB("constraints", "movingConstraints",
01645       "Are some of the constraints moving?", 
01646       &movingConstraintsOn, FALSE);
01647    opts.require("movingConstraints", "movingConsVel",
01648     "Velocity of the movement, A/timestep", &movingConsVel);
01649    //****** END moving constraints changes 
01650 
01651    // BEGIN rotating constraints changes
01652    opts.optionalB("constraints", "rotConstraints",
01653       "Are the constraints rotating?", 
01654       &rotConstraintsOn, FALSE);
01655    opts.require("rotConstraints", "rotConsAxis",
01656     "Axis of rotation", &rotConsAxis);
01657    opts.require("rotConstraints", "rotConsPivot",
01658     "Pivot point of rotation", 
01659     &rotConsPivot);
01660    opts.require("rotConstraints", "rotConsVel",
01661     "Velocity of rotation, deg/timestep", &rotConsVel);
01662 
01663    // END rotating constraints changes
01664 
01665    // external command forces
01666    opts.optionalB("main", "extForces", "External command forces?",
01667       &extForcesOn, FALSE);
01668    opts.require("extForces", "extForcesCommand",
01669       "External forces command", extForcesCommand);
01670    opts.require("extForces", "extCoordFilename",
01671       "External forces coordinate filename", extCoordFilename);
01672    opts.require("extForces", "extForceFilename",
01673       "External forces force filename", extForceFilename);
01674 
01675    
01676   // QM/MM forces
01677    opts.optionalB("main", "QMForces", "Apply QM forces?",
01678       &qmForcesOn, FALSE);
01679    opts.require("QMForces", "QMSoftware",
01680       "software whose format will be used for input/output", qmSoftware);
01681    opts.require("QMForces", "QMExecPath",
01682       "path to executable", qmExecPath);
01683    opts.optional("QMForces", "QMChargeMode",
01684       "type of QM atom charges gathered from the QM software", qmChrgModeS);
01685    opts.require("QMForces", "QMColumn",
01686       "column defining QM and MM regions", qmColumn);
01687    opts.require("QMForces", "QMBaseDir",
01688       "base path and name for QM input and output (preferably in memory)", qmBaseDir);
01689    opts.optional("QMForces", "QMConfigLine",
01690       "Configuration line for QM (multiple inputs allowed)", PARSE_MULTIPLES);
01691    opts.optional("QMForces", "QMParamPDB",
01692       "PDB with QM parameters", qmParamPDB);
01693    opts.optional("QMForces", "QMPrepProc",
01694       "initial preparation executable", qmPrepProc);
01695    opts.optional("QMForces", "QMSecProc",
01696       "secondary executable", qmSecProc);
01697    opts.optional("QMForces", "QMCharge",
01698       "charge of the QM group", PARSE_MULTIPLES);
01699    opts.optionalB("QMForces", "QMChargeFromPSF",
01700       "gets charge of the QM group form PSF values", &qmChrgFromPSF, FALSE);
01701    opts.optional("QMForces", "QMMult",
01702       "multiplicity of the QM group", PARSE_MULTIPLES);
01703    opts.optional("QMForces", "QMLinkElement",
01704       "element of link atom", PARSE_MULTIPLES);
01705    opts.optionalB("QMForces", "QMReplaceAll",
01706       "replace all NAMD forces with QM forces", &qmReplaceAll, FALSE);
01707    opts.optional("QMForces", "QMPCStride",
01708       "frequency of selection of point charges", &qmPCSelFreq, 1);
01709    opts.range("QMPCStride", POSITIVE);
01710    opts.optionalB("QMForces", "QMNoPntChrg",
01711       "no point charges will be passed to the QM system(s)", &qmNoPC, FALSE);
01712    opts.optionalB("QMForces", "QMElecEmbed",
01713       "activates electrostatic embedding", &qmElecEmbed, TRUE);
01714    opts.optionalB("QMForces", "QMVdWParams",
01715       "use special VdW parameters for QM atoms", &qmVDW, FALSE);
01716    opts.optional("QMForces", "QMBondColumn",
01717       "column defining QM-MM bomnds", qmBondColumn);
01718    opts.optionalB("QMForces", "QMBondDist",
01719       "values in QMBondColumn defines the distance of new link atom", &qmBondDist, FALSE);
01720    opts.optional("QMForces", "QMBondValueType",
01721       "type of value in bond column: len or ratio", qmBondValueTypeS);
01722    opts.optional("QMForces", "QMBondScheme",
01723       "type of treatment given to QM-MM bonds.", qmBondSchemeS);
01724    opts.optional("QMForces", "QMenergyStride",
01725       "frequency of QM specific energy output (every x steps)", &qmEnergyOutFreq, 1);
01726    opts.optional("QMForces", "QMOutStride",
01727       "frequency of QM specific charge output (every x steps)", &qmOutFreq, 0);
01728    opts.range("QMOutStride", NOT_NEGATIVE);
01729    opts.optional("QMForces", "QMPositionOutStride",
01730       "frequency of QM specific position output (every x steps)", &qmPosOutFreq, 0);
01731    opts.range("QMPositionOutStride", NOT_NEGATIVE);
01732    opts.optional("QMForces", "QMSimsPerNode",
01733       "QM executions per node", &qmSimsPerNode, 1);
01734    opts.range("QMSimsPerNode", POSITIVE);
01735    opts.optionalB("QMForces", "QMSwitching",
01736       "apply switching to point charges.", &qmPCSwitchOn, FALSE);
01737    opts.optional("QMForces", "QMSwitchingType",
01738       "How are charges scaled down to be presented to QM groups.", qmPCSwitchTypeS);
01739    opts.optional("QMForces", "QMPointChargeScheme",
01740       "type of treatment given to the total sum of point charges.", qmPCSchemeS);
01741    opts.optionalB("QMForces", "QMCustomPCSelection",
01742       "custom and fixed selection of point charges per QM group.", &qmCustomPCSel, FALSE);
01743    opts.optional("QMForces", "QMCustomPCFile",
01744       "file with a selection of point charges for a single QM group", PARSE_MULTIPLES);
01745    opts.optionalB("QMForces", "QMLiveSolventSel",
01746       "Continuously update the selection of solvent molecules in QM groups", &qmLSSOn, FALSE);
01747    opts.optional("QMForces", "QMLSSFreq",
01748       "frequency of QM water selection update", &qmLSSFreq, 100);
01749    opts.range("QMLSSFreq", POSITIVE);
01750    opts.optional("QMForces", "QMLSSResname",
01751       "residue name for the solvent molecules (TIP3).", qmLSSResname);
01752    opts.optional("QMForces", "QMLSSMode",
01753       "mode of selection of point solvent molecules", qmLSSModeS);
01754    opts.optional("QMForces", "QMLSSRef",
01755       "for COM mode, defines reference for COM distance calculation", PARSE_MULTIPLES);
01756    opts.optionalB("QMForces", "QMCSMD",
01757       "Do we use Conditional SMD option?", &qmCSMD, FALSE);
01758    opts.optional("QMForces", "QMCSMDFile",
01759                 "File for Conditional SMD information",qmCSMDFile);
01760    
01761    //print which bad contacts are being moved downhill
01762    opts.optionalB("main", "printBadContacts", "Print atoms with huge forces?",
01763       &printBadContacts, FALSE);
01764 
01765    /* GBIS generalized born implicit solvent*/
01766 
01767    opts.optionalB("main", "GBIS", "Use GB implicit solvent?",
01768       &GBISOn, FALSE);
01769    opts.optionalB("main", "GBISSer", "Use GB implicit solvent?",
01770       &GBISserOn, FALSE);
01771 
01772    opts.optional("GBIS", "solventDielectric",
01773       "Solvent Dielectric", &solvent_dielectric, 78.5);
01774    opts.optional("GBIS", "intrinsicRadiusOffset",
01775       "Coulomb Radius Offset", &coulomb_radius_offset, 0.09);
01776    opts.optional("GBIS", "ionConcentration",
01777       "Ion Concentration", &ion_concentration, 0.2); //0.2 mol/L
01778    opts.optional("GBIS", "GBISDelta",
01779       "delta from GBOBC", &gbis_delta, 1.0); //0.8 or 1.0
01780    opts.optional("GBIS", "GBISBeta",
01781       "beta from GBOBC", &gbis_beta, 0.8);   //0.0 or 0.8
01782    opts.optional("GBIS", "GBISGamma",
01783       "gamma from GBOBC", &gbis_gamma, 4.85);//2.290912 or 4.85
01784    opts.optional("GBIS", "alphaCutoff",
01785       "cutoff for calculating effective born radius", &alpha_cutoff, 15);
01786    opts.optional("GBIS", "alphaMax",
01787       "maximum allowable born radius", &alpha_max, 30);
01788    opts.optional("GBIS", "fsMax",
01789       "maximum screened intrinsic radius", &fsMax, 1.728);
01790 
01791    opts.optionalB("main", "SASA", "Use Linear Combination of Pairwise Overlaps (LCPO) for calculating SASA",
01792       &LCPOOn, FALSE);
01793    opts.optional("SASA", "surfaceTension",
01794       "Surfce Tension for SASA (kcal/mol/Ang^2)", &surface_tension, 0.005);
01795 
01796    //****** BEGIN SMD constraints changes 
01797 
01798    // SMD constraints
01799    opts.optionalB("main", "SMD",
01800       "Do we use SMD option?", 
01801       &SMDOn, FALSE);
01802    opts.require("SMD", "SMDVel",
01803                 "Velocity of the movement, A/timestep", &SMDVel);
01804    opts.range("SMDVel", NOT_NEGATIVE);
01805    opts.require("SMD", "SMDDir",
01806                 "Direction of movement", &SMDDir);
01807    opts.require("SMD", "SMDk",
01808                 "Elastic constant for SMD", &SMDk);
01809    opts.optional("SMD", "SMDk2",
01810                 "Transverse elastic constant for SMD", &SMDk2, 0);
01811    opts.range("SMDk", NOT_NEGATIVE);
01812    opts.range("SMDk2", NOT_NEGATIVE);
01813    opts.require("SMD", "SMDFile",
01814                 "File for SMD information",
01815                  SMDFile);
01816    opts.optional("SMD", "SMDOutputFreq",
01817                  "Frequency of output",
01818                  &SMDOutputFreq, 1);
01819    opts.range("SMDOutputFreq", POSITIVE);
01820    
01821    //****** END SMD constraints changes 
01822 
01823    //****** BEGIN tabulated energies section
01824    opts.optionalB("main", "tabulatedEnergies", "Do we get energies from a table?", &tabulatedEnergies, FALSE);
01825 //   opts.require("tabulatedEnergies", "tableNumTypes","Number of types for energy tabulation", &tableNumTypes);
01826    opts.require("tabulatedEnergies", "tabulatedEnergiesFile", "File containing energy table", tabulatedEnergiesFile);
01827    opts.require("tabulatedEnergies", "tableInterpType", "Cubic or linear interpolation", tableInterpType);
01828 
01829    // TMD parameters
01830    opts.optionalB("main", "TMD", "Perform Targeted MD?", &TMDOn, FALSE);
01831    opts.optional("TMD", "TMDk", "Elastic constant for TMD", &TMDk, 0); 
01832    opts.range("TMDk", NOT_NEGATIVE);
01833    opts.require("TMD", "TMDFile", "File for TMD information", TMDFile);
01834    opts.optionalB("TMD", "TMDDiffRMSD", "Restrain Difference between the RMSD from two structures", &TMDDiffRMSD, FALSE);
01835    opts.require("TMDDiffRMSD", "TMDFile2",  "Second file for TMD information", TMDFile2); 
01836     
01837    opts.optional("TMD", "TMDOutputFreq", "Frequency of TMD output", 
01838        &TMDOutputFreq, 1);
01839    opts.range("TMDOutputFreq", POSITIVE);
01840    opts.require("TMD", "TMDLastStep", "Last TMD timestep", &TMDLastStep);
01841    opts.range("TMDLastStep", POSITIVE);
01842    opts.optional("TMD", "TMDFirstStep", "First TMD step (default 0)", &TMDFirstStep, 0);
01843    opts.optional("TMD", "TMDInitialRMSD", "Target RMSD at first TMD step (default -1 to use initial coordinates)", &TMDInitialRMSD);
01844    TMDInitialRMSD = -1;
01845    opts.optional("TMD", "TMDFinalRMSD", "Target RMSD at last TMD step (default 0 )", &TMDFinalRMSD, 0);
01846    opts.range("TMDInitialRMSD", NOT_NEGATIVE);
01847    // End of TMD parameters
01848 
01849    // Symmetry restraint parameters
01850    opts.optionalB("main", "symmetryRestraints", "Enable symmetry restraints?", &symmetryOn, FALSE); 
01851    opts.optional("symmetryRestraints", "symmetryk", "Elastic constant for symmetry restraints", &symmetryk, 0);
01852    opts.range("symmetryk", NOT_NEGATIVE);
01853    opts.optional("symmetryRestraints", "symmetrykfile", "PDB file specifying force contants on a per-atom basis", PARSE_MULTIPLES);
01854    opts.optionalB("symmetryRestraints", "symmetryScaleForces", "Scale applied forces over time?", &symmetryScaleForces, FALSE);
01855    opts.require("symmetryRestraints", "symmetryFile", "File for symmetry information", PARSE_MULTIPLES);
01856    opts.optional("symmetryRestraints", "symmetryMatrixFile", "File(s) for transfromation matrices", PARSE_MULTIPLES);
01857    opts.optional("symmetryRestraints", "symmetryLastStep", "Last symmetry timestep", &symmetryLastStep, -1);
01858    opts.optional("symmetryRestraints", "symmetryFirstStep", "First symmetry step (default 0)", &symmetryFirstStep, 0);
01859    opts.optional("symmetryRestraints", "symmetryLastFullStep", "Last full force symmetry timestep (default symmetryLastStep)", &symmetryLastFullStep, symmetryLastStep);
01860    opts.optional("symmetryRestraints", "symmetryFirstFullStep", "First full force symmetry step (default symmetryFirstStep)", &symmetryFirstFullStep, symmetryFirstStep);
01861   //End of symmetry restraint parameters.
01862 
01864    opts.optionalB("main", "tclForces", "Are Tcl global forces active?",
01865      &tclForcesOn, FALSE);
01866    opts.require("tclForces", "tclForcesScript",
01867      "Tcl script for global forces", PARSE_MULTIPLES);
01868 
01870    opts.optionalB("main", "tclBC", "Are Tcl boundary forces active?",
01871      &tclBCOn, FALSE);
01872    opts.require("tclBC", "tclBCScript",
01873      "Tcl script defining calcforces for boundary forces", PARSE_STRING);
01874    tclBCScript = 0;
01875    opts.optional("tclBC", "tclBCArgs", "Extra args for calcforces command",
01876      tclBCArgs);
01877    tclBCArgs[0] = 0;
01878 
01880    opts.optionalB("main", "miscForces", "Are misc global forces active?",
01881      &miscForcesOn, FALSE);
01882    opts.optional("miscForces", "miscForcesScript",
01883      "script for misc forces", PARSE_MULTIPLES);
01884 
01886    opts.optionalB("main", "freeEnergy", "Perform free energy perturbation?",
01887      &freeEnergyOn, FALSE);
01888    opts.require("freeEnergy", "freeEnergyConfig",
01889      "Configuration file for free energy perturbation", PARSE_MULTIPLES);
01890 
01892    opts.optionalB("main", "constantforce", "Apply constant force?",
01893      &consForceOn, FALSE);
01894    opts.optional("constantforce", "consForceFile",
01895        "Configuration file for constant forces", PARSE_STRING);
01896    opts.require("constantforce", "consForceScaling",
01897        "Scaling factor for constant forces", &consForceScaling, 1.0);
01898  
01900     opts.optionalB("main", "colvars", "Is the colvars module enabled?",
01901       &colvarsOn, FALSE);
01902     opts.optional("colvars", "colvarsConfig",
01903       "configuration for the collective variables", PARSE_STRING);
01904     opts.optional("colvars", "colvarsInput",
01905       "input restart file for the collective variables", PARSE_STRING);
01906 
01907 }
01908 
01909 #ifdef OPENATOM_VERSION
01910 void SimParameters::config_parser_openatom(ParseOptions &opts) {
01911   opts.optionalB("main", "openatom", "OpenAtom active?", &openatomOn, FALSE);
01912   opts.require("openatom", "openatomDriverFile", "What config file specifies openatom input parameters", PARSE_STRING);
01913   opts.require("openatom", "openatomPhysicsFile", "What structure file specifies openatom input system", PARSE_STRING);
01914   opts.require("openatom", "openatomPdbFile", "NAMD input file defining QM and MM regions", PARSE_STRING);
01915    opts.optional("openatom", "openatomCol", "Column in the openatomPdb with the QM/MM flag", PARSE_STRING);
01916 }
01917 #endif // OPENATOM_VERSION
01918 
01919 /* BEGIN gf */
01920 void SimParameters::config_parser_mgridforce(ParseOptions &opts) {
01922     opts.optionalB("main", "mgridforce", "Is Multiple gridforce active?", 
01923                    &mgridforceOn, FALSE);
01924     opts.optional("mgridforce", "mgridforcevolts", "Is Gridforce using Volts/eV as units?",
01925                   PARSE_MULTIPLES);
01926     opts.require("mgridforce", "mgridforcescale", "Scale factor by which to multiply "
01927                  "grid forces", PARSE_MULTIPLES);
01928     opts.require("mgridforce", "mgridforcefile", "PDB file containing force "
01929                  "multipliers in one of the columns", PARSE_MULTIPLES);
01930     opts.require("mgridforce", "mgridforcecol", "Column of gridforcefile to "
01931                  "use for force multiplier", PARSE_MULTIPLES);
01932     opts.optional("mgridforce", "mgridforcechargecol", "Column of gridforcefile to "
01933                   "use for charge", PARSE_MULTIPLES);
01934     opts.require("mgridforce", "mgridforcepotfile", "Gridforce potential file",
01935                  PARSE_MULTIPLES);
01936     opts.optional("mgridforce", "mgridforcecont1", "Use continuous grid "
01937                    "in K1 direction?", PARSE_MULTIPLES);
01938     opts.optional("mgridforce", "mgridforcecont2", "Use continuous grid "
01939                    "in K2 direction?", PARSE_MULTIPLES);
01940     opts.optional("mgridforce", "mgridforcecont3", "Use continuous grid "
01941                    "in K3 direction?", PARSE_MULTIPLES);
01942     opts.optional("mgridforce", "mgridforcevoff", "Gridforce potential offsets",
01943                   PARSE_MULTIPLES);
01944     opts.optional("mgridforce", "mgridforcelite", "Use Gridforce Lite?",
01945                   PARSE_MULTIPLES);
01946     opts.optional("mgridforce", "mgridforcechecksize", "Check if grid exceeds PBC cell dimensions?", PARSE_MULTIPLES);
01947 }
01948 
01949 void SimParameters::config_parser_gridforce(ParseOptions &opts) {
01951     opts.optionalB("main", "gridforce", "Is Gridforce active?", 
01952                    &gridforceOn, FALSE);
01953     opts.optionalB("gridforce", "gridforcevolts", "Is Gridforce using Volts/eV as units?",
01954                    &gridforceVolts, FALSE);
01955     opts.require("gridforce", "gridforcescale", "Scale factor by which to multiply "
01956                  "grid forces", &gridforceScale);
01957     opts.require("gridforce", "gridforcefile", "PDB file containing force "
01958                  "multipliers in one of the columns", PARSE_STRING);
01959     opts.require("gridforce", "gridforcecol", "Column of gridforcefile to "
01960                  "use for force multiplier", PARSE_STRING);
01961     opts.optional("gridforce", "gridforcechargecol", "Column of gridforcefile to "
01962                   "use for charge", PARSE_STRING);
01963     opts.require("gridforce", "gridforcepotfile", "Gridforce potential file",
01964                  PARSE_STRING);
01965     opts.optionalB("gridforce", "gridforcecont1", "Use continuous grid "
01966                    "in A1 direction?", &gridforceContA1, FALSE);
01967     opts.optionalB("gridforce", "gridforcecont2", "Use continuous grid "
01968                    "in A2 direction?", &gridforceContA2, FALSE);
01969     opts.optionalB("gridforce", "gridforcecont3", "Use continuous grid "
01970                    "in A3 direction?", &gridforceContA3, FALSE);
01971     opts.optional("gridforce", "gridforcevoff", "Gridforce potential offsets",
01972                   &gridforceVOffset);
01973     opts.optionalB("gridforce", "gridforcelite", "Use Gridforce Lite?",
01974                    &gridforceLite, FALSE);
01975     opts.optionalB("gridforce", "gridforcechecksize", "Check if grid exceeds PBC cell dimensions?",
01976                    &gridforcechecksize, TRUE);
01977 }
01978 /* END gf */
01979 
01980 void SimParameters::config_parser_movdrag(ParseOptions &opts) {
01982    opts.optionalB("main", "movDragOn", "Do we apply moving drag?",
01983       &movDragOn, FALSE);
01984    opts.require("movDragOn", "movDragFile",
01985       "Main moving drag PDB file", movDragFile);
01986    opts.require("movDragOn", "movDragCol",
01987       "Main moving drag PDB column", PARSE_STRING);
01988    opts.require("movDragOn", "movDragGlobVel",
01989       "Global moving drag velocity (A/step)", &movDragGlobVel);
01990    opts.require("movDragOn", "movDragVelFile",
01991       "Moving drag linear velocity file", movDragVelFile);
01992 }
01993 
01994 void SimParameters::config_parser_rotdrag(ParseOptions &opts) {
01996    opts.optionalB("main", "rotDragOn", "Do we apply rotating drag?",
01997       &rotDragOn, FALSE);
01998    opts.require("rotDragOn", "rotDragFile",
01999       "Main rotating drag PDB file", rotDragFile);
02000    opts.require("rotDragOn", "rotDragCol",
02001       "Main rotating drag PDB column", PARSE_STRING);
02002    opts.require("rotDragOn", "rotDragAxisFile",
02003       "Rotating drag axis file", rotDragAxisFile);
02004    opts.require("rotDragOn", "rotDragPivotFile",
02005       "Rotating drag pivot point file", rotDragPivotFile);
02006    opts.require("rotDragOn", "rotDragGlobVel",
02007       "Global rotating drag angular velocity (deg/step)", &rotDragGlobVel);
02008    opts.require("rotDragOn", "rotDragVelFile",
02009       "Rotating drag angular velocity file", rotDragVelFile);
02010    opts.require("rotDragOn", "rotDragVelCol",
02011       "Rotating drag angular velocity column", PARSE_STRING);
02012 }
02013 
02014 void SimParameters::config_parser_constorque(ParseOptions &opts) {
02016    opts.optionalB("main", "consTorqueOn", "Do we apply \"constant\" torque?",
02017       &consTorqueOn, FALSE);
02018    opts.require("consTorqueOn", "consTorqueFile",
02019       "Main \"constant\" torque PDB file", consTorqueFile);
02020    opts.require("consTorqueOn", "consTorqueCol",
02021       "Main \"constant\" torque PDB column", PARSE_STRING);
02022    opts.require("consTorqueOn", "consTorqueAxisFile",
02023       "\"Constant\" torque axis file", consTorqueAxisFile);
02024    opts.require("consTorqueOn", "consTorquePivotFile",
02025       "\"Constant\" torque pivot point file", consTorquePivotFile);
02026    opts.require("consTorqueOn", "consTorqueGlobVal",
02027       "Global \"constant\" torque value (Kcal/(mol*A^2))", &consTorqueGlobVal);
02028    opts.require("consTorqueOn", "consTorqueValFile",
02029       "\"constant\" torque factors file", consTorqueValFile);
02030    opts.require("consTorqueOn", "consTorqueValCol",
02031       "\"constant\" torque factors column", PARSE_STRING);
02032 }
02033 
02034 void SimParameters::config_parser_boundary(ParseOptions &opts) {
02035     
02037    opts.optionalB("main", "sphericalBC", "Are spherical boundary counditions "
02038       "active?", &sphericalBCOn, FALSE);
02039    opts.require("sphericalBC", "sphericalBCCenter",
02040      "Center of spherical boundaries", &sphericalCenter);
02041    opts.require("sphericalBC", "sphericalBCr1", "Radius for first sphere "
02042      "potential", &sphericalBCr1);
02043    opts.range("sphericalBCr1", POSITIVE);
02044    opts.units("sphericalBCr1", N_ANGSTROM);
02045    opts.require("sphericalBC", "sphericalBCk1", "Force constant for first "
02046     "sphere potential (+ is an inward force, - outward)",
02047     &sphericalBCk1);
02048    opts.units("sphericalBCk1", N_KCAL);
02049    opts.optional("sphericalBC", "sphericalBCexp1", "Exponent for first "
02050     "sphere potential", &sphericalBCexp1, 2);
02051    opts.range("sphericalBCexp1", POSITIVE);
02052    
02053    opts.optional("sphericalBCr1", "sphericalBCr2", "Radius for second sphere "
02054      "potential", &sphericalBCr2);
02055    opts.range("sphericalBCr2", POSITIVE);
02056    opts.units("sphericalBCr2", N_ANGSTROM);
02057    opts.require("sphericalBCr2", "sphericalBCk2", "Force constant for second "
02058     "sphere potential (+ is an inward force, - outward)",
02059     &sphericalBCk2);
02060    opts.units("sphericalBCk2", N_KCAL);
02061    opts.optional("sphericalBCr2", "sphericalBCexp2", "Exponent for second "
02062     "sphere potential", &sphericalBCexp2, 2);
02063    opts.range("sphericalBCexp2", POSITIVE);
02064 
02066    opts.optionalB("main", "cylindricalBC", "Are cylindrical boundary counditions "
02067                   "active?", &cylindricalBCOn, FALSE);
02068    opts.require("cylindricalBC", "cylindricalBCr1", "Radius for first cylinder "
02069                  "potential", &cylindricalBCr1);
02070    opts.range("cylindricalBCr1", POSITIVE);
02071    opts.units("cylindricalBCr1", N_ANGSTROM);
02072    opts.require("cylindricalBC", "cylindricalBCk1", "Force constant for first "
02073                 "cylinder potential (+ is an inward force, - outward)",
02074                 &cylindricalBCk1);
02075    opts.units("cylindricalBCk1", N_KCAL);
02076    opts.optional("cylindricalBC", "cylindricalBCexp1", "Exponent for first "
02077                 "cylinder potential", &cylindricalBCexp1, 2);
02078    opts.range("cylindricalBCexp1", POSITIVE);
02079 
02080 
02081 // additions beyond those already found in spherical parameters    JJU
02082    opts.optional("cylindricalBC", "cylindricalBCAxis", "Cylinder axis (defaults to x)",
02083     PARSE_STRING);
02084    opts.require("cylindricalBC", "cylindricalBCCenter",
02085      "Center of cylindrical boundaries", &cylindricalCenter);
02086    opts.require ("cylindricalBC", "cylindricalBCl1", "Length of first cylinder",
02087                  &cylindricalBCl1);
02088    opts.range("cylindricalBCl1", POSITIVE);
02089    opts.units("cylindricalBCl1", N_ANGSTROM);
02090    opts.optional ("cylindricalBCl1", "cylindricalBCl2", "Length of second cylinder",
02091                   &cylindricalBCl2);
02092    opts.range ("cylindricalBCl2", POSITIVE);
02093    opts.units ("cylindricalBCl2", N_ANGSTROM);
02094 // end  additions
02095 
02096    opts.optional("cylindricalBCr1", "cylindricalBCr2", "Radius for second cylinder "
02097                  "potential", &cylindricalBCr2);
02098    opts.range("cylindricalBCr2", POSITIVE);
02099    opts.units("cylindricalBCr2", N_ANGSTROM);
02100    opts.require("cylindricalBCr2", "cylindricalBCk2", "Force constant for second "
02101                 "cylinder potential (+ is an inward force, - outward)",
02102                 &cylindricalBCk2);
02103    opts.units("cylindricalBCk2", N_KCAL);
02104    opts.optional("cylindricalBCr2", "cylindricalBCexp2", "Exponent for second "
02105                 "cylinder potential", &cylindricalBCexp2, 2);
02106    opts.range("cylindricalBCexp2", POSITIVE);
02107 
02109    opts.optionalB("main", "eFieldOn", "Should an electric field be applied",
02110                  &eFieldOn, FALSE);
02111    opts.optionalB("eFieldOn", "eFieldNormalized", "Is eField vector scaled by cell basis vectors?",
02112                  &eFieldNormalized, FALSE);
02113    opts.require("eFieldOn", "eField", "Electric field vector", &eField);
02114    opts.optional("eFieldOn", "eFieldFreq", "Electric field frequency", &eFieldFreq);
02115    opts.optional("eFieldOn", "eFieldPhase", "Electric field phase", &eFieldPhase);
02116 
02118    opts.optionalB("main", "stirOn", "Should stirring torque be applied",
02119                  &stirOn, FALSE);
02120    opts.optional("stirOn", "stirFilename", "PDB file with flags for "
02121      "stirred atoms (default is the PDB input file)",
02122                  PARSE_STRING);
02123    opts.optional("stirOn", "stirredAtomsCol", "Column in the stirredAtomsFile "
02124                  "containing the flags (nonzero means fixed);\n"
02125                  "default is 'O'", PARSE_STRING);
02126    opts.require("stirOn", "stirStartingTheta", "Stir starting theta offset", &stirStartingTheta);
02127    opts.require("stirOn", "stirK", "Stir force harmonic spring constant", &stirK);
02128    //should make this optional, compute from firsttimestep * stirVel
02129    opts.require("stirOn", "stirVel", "Stir angular velocity (deg/timestep)", &stirVel);
02130    opts.require("stirOn", "stirAxis", "Stir axis (direction vector)", &stirAxis);
02131    opts.require("stirOn", "stirPivot", "Stir pivot point (coordinate)", &stirPivot);
02132 
02134    opts.optionalB("main", "extraBonds",
02135                 "Should extra bonded forces be applied",
02136                  &extraBondsOn, FALSE);
02137    opts.optional("extraBonds", "extraBondsFile",
02138                 "file with list of extra bonds",
02139                  PARSE_MULTIPLES);
02140 
02141 }
02142 
02143 void SimParameters::config_parser_misc(ParseOptions &opts) {
02144    
02146    opts.optional("main", "ldBalancer", "Load balancer",
02147      loadBalancer);
02148    opts.optional("main", "ldbStrategy", "Load balancing strategy",
02149      loadStrategy);
02150    opts.optional("main", "ldbPeriod", "steps between load balancing", 
02151      &ldbPeriod);
02152    opts.range("ldbPeriod", POSITIVE);
02153    opts.optional("main", "firstLdbStep", "when to start load balancing",
02154      &firstLdbStep);
02155    opts.range("firstLdbStep", POSITIVE);
02156    opts.optional("main", "lastLdbStep", "when to stop load balancing",
02157      &lastLdbStep);
02158    opts.range("lastLdbStep", POSITIVE);
02159    opts.optional("main", "hybridGroupSize", "Hybrid load balancing group size",
02160      &hybridGroupSize);
02161    opts.optional("main", "ldbBackgroundScaling",
02162      "background load scaling", &ldbBackgroundScaling);
02163    opts.range("ldbBackgroundScaling", NOT_NEGATIVE);
02164    opts.optional("main", "ldbPMEBackgroundScaling",
02165      "PME node background load scaling", &ldbPMEBackgroundScaling);
02166    opts.range("ldbPMEBackgroundScaling", NOT_NEGATIVE);
02167    opts.optional("main", "ldbHomeBackgroundScaling",
02168      "home node background load scaling", &ldbHomeBackgroundScaling);
02169    opts.range("ldbHomeBackgroundScaling", NOT_NEGATIVE);
02170    opts.optional("main", "ldbRelativeGrainsize",
02171      "fraction of average load per compute", &ldbRelativeGrainsize, 0.);
02172    opts.range("ldbRelativeGrainsize", NOT_NEGATIVE);
02173    
02174    opts.optional("main", "traceStartStep", "when to start tracing", &traceStartStep);
02175    opts.range("traceStartStep", POSITIVE);
02176    opts.optional("main", "numTraceSteps", "the number of timesteps to be traced", &numTraceSteps);
02177    opts.range("numTraceSteps", POSITIVE);
02178  
02179 #ifdef MEASURE_NAMD_WITH_PAPI
02180    opts.optionalB("main", "papiMeasure", "whether use PAPI to measure performacne", &papiMeasure, FALSE);
02181    opts.optional("main", "papiMeasureStartStep", "when to measure performacne using PAPI", &papiMeasureStartStep);
02182    opts.range("papiMeasureStartStep", POSITIVE);
02183    opts.optional("main", "numPapiMeasureSteps", "the number of timesteps to be measured using PAPI", &numPapiMeasureSteps);
02184    opts.range("numPapiMeasureSteps", POSITIVE);
02185 #endif
02186 
02187    opts.optionalB("main", "outputMaps", "whether to dump compute map and patch map for analysis just before load balancing", &outputMaps, FALSE);
02188    opts.optionalB("main", "benchTimestep", "whether to do benchmarking timestep in which case final file output is disabled", &benchTimestep, FALSE);
02189    opts.optional("main", "useCkLoop", "whether to use CkLoop library to parallelize a loop in a function like OpenMP", &useCkLoop,
02190     #if CMK_SMP && USE_CKLOOP
02191      ( CkNumPes() < 2 * CkNumNodes() ? 0 : CKLOOP_CTRL_PME_FORWARDFFT ) );
02192     #else
02193      0);
02194     #endif
02195    opts.range("useCkLoop", NOT_NEGATIVE);
02196 
02197    opts.optionalB("main", "simulateInitialMapping", "whether to study the initial mapping scheme", &simulateInitialMapping, FALSE);
02198    opts.optional("main", "simulatedPEs", "the number of PEs to be used for studying initial mapping", &simulatedPEs);
02199    opts.range("simulatedPEs", POSITIVE);
02200    opts.optional("main", "simulatedNodeSize", "the node size to be used for studying initial mapping", &simulatedNodeSize);
02201    opts.range("simulatedNodeSize", POSITIVE);
02202    opts.optionalB("main", "disableTopology", "ignore torus information during patch placement", &disableTopology, FALSE);
02203    opts.optionalB("main", "verboseTopology", "print torus information during patch placement", &verboseTopology, FALSE);
02204 
02205    opts.optionalB("main", "ldbUnloadPME", "no load on PME nodes",
02206      &ldbUnloadPME, FALSE);
02207    opts.optionalB("main", "ldbUnloadZero", "no load on pe zero",
02208      &ldbUnloadZero, FALSE);
02209    opts.optionalB("main", "ldbUnloadOne", "no load on pe one",
02210      &ldbUnloadOne, FALSE);
02211    opts.optionalB("main", "ldbUnloadOutputPEs", "no load on output PEs",
02212      &ldbUnloadOutputPEs, FALSE);
02213    opts.optionalB("main", "noPatchesOnZero", "no patches on pe zero",
02214      &noPatchesOnZero, FALSE);
02215    opts.optionalB("main", "noPatchesOnOutputPEs", "no patches on Output PEs",
02216      &noPatchesOnOutputPEs, FALSE);
02217    opts.optionalB("main", "noPatchesOnOne", "no patches on pe one",
02218      &noPatchesOnOne, FALSE);
02219    opts.optionalB("main", "useCompressedPsf", "The structure file psf is in the compressed format",
02220                   &useCompressedPsf, FALSE);
02221    opts.optionalB("main", "genCompressedPsf", "Generate the compressed version of the psf file",
02222                   &genCompressedPsf, FALSE);
02223    opts.optionalB("main", "usePluginIO", "Use the plugin I/O to load the molecule system", 
02224                   &usePluginIO, FALSE);   
02225    opts.optionalB("main", "mallocTest", "test how much memory all PEs can allocate", 
02226                   &mallocTest, FALSE);   
02227    opts.optionalB("main", "printExclusions", "print exclusion lists to stdout", 
02228                   &printExclusions, FALSE);   
02229    opts.optional("main", "proxySendSpanningTree", "using spanning tree to send proxies",
02230                   &proxySendSpanningTree, -1);
02231    opts.optional("main", "proxyRecvSpanningTree", "using spanning tree to receive proxies",
02232                   &proxyRecvSpanningTree, 0);  // default off due to memory leak -1);
02233    opts.optional("main", "proxyTreeBranchFactor", "the branch factor when building a spanning tree",
02234                   &proxyTreeBranchFactor, 0);  // actual default in ProxyMgr.C
02235    opts.optionalB("main", "twoAwayX", "half-size patches in 1st dimension",
02236      &twoAwayX, -1);
02237    opts.optionalB("main", "twoAwayY", "half-size patches in 2nd dimension",
02238      &twoAwayY, -1);
02239    opts.optionalB("main", "twoAwayZ", "half-size patches in 3rd dimension",
02240      &twoAwayZ, -1);
02241    opts.optional("main", "maxPatches", "maximum patch count", &maxPatches, -1);
02242 
02244    opts.optional("main", "firsttimestep", "Timestep to start simulation at",
02245      &firstTimestep, 0);
02246    opts.range("firsttimestep", NOT_NEGATIVE);
02247  
02249    opts.optionalB("main", "test", "Perform self-tests rather than simulation",
02250                 &testOn, FALSE);
02251    opts.optionalB("main", "commOnly", "Do not evaluate forces or integrate",
02252                 &commOnly, FALSE);
02253 
02254    opts.optionalB("main", "statsOn", "counters in machine layer",
02255                 &statsOn, FALSE);
02257    opts.optionalB("main", "hbonds", "Use explicit hydrogen bond term",
02258                  &HydrogenBonds, FALSE);
02259    opts.optionalB("hbonds","hbAntecedents","Include Antecedent in hbond term",
02260                  &useAntecedent, TRUE);
02261    opts.optional("hbonds","hbAAexp","Hbond AA-A-H angle cos exponential",
02262                  &aaAngleExp, 2);
02263    opts.optional("hbonds","hbHAexp","Hbond D-H-A angle cos exponential",
02264                  &haAngleExp, 4);
02265    opts.optional("hbonds","hbDistAexp","Hbond A-D dist attractive exponential",
02266                  &distAttExp, 4);
02267    opts.optional("hbonds","hbDistRexp","Hbond A-D dist repulstive exponential",
02268                  &distRepExp, 6);
02269    opts.optional("hbonds","hbCutoffAngle","Hbond D-H-A cutoff angle",
02270                  &dhaCutoffAngle, 100.0);
02271    opts.range("hbCutoffAngle", NOT_NEGATIVE);
02272    opts.optional("hbonds","hbOnAngle","Hbond D-H-A switch function on angle",
02273                  &dhaOnAngle, 60.0);
02274    opts.range("hbOnAngle", NOT_NEGATIVE);
02275    opts.optional("hbonds","hbOffAngle","Hbond D-H-A switch function off angle",
02276                  &dhaOffAngle, 80.0);
02277    opts.range("hbOffAngle", NOT_NEGATIVE);
02278    opts.optional("hbonds","hbCutoffDist","Hbond A-D cutoff distance",
02279                  &daCutoffDist, 7.5);
02280    opts.range("hbCutoffDist", POSITIVE);
02281    opts.units("hbCutoffDist", N_ANGSTROM);
02282    opts.optional("hbonds","hbOnDist","Hbond A-D switch function on distance",
02283                  &daOnDist, 5.5);
02284    opts.range("hbOnDist", POSITIVE);
02285    opts.units("hbOnDist", N_ANGSTROM);
02286    opts.optional("hbonds","hbOffDist","Hbond A-D switch function off distance",
02287                  &daOffDist, 6.5);
02288    opts.range("hbOffDist", POSITIVE);
02289    opts.units("hbOffDist", N_ANGSTROM);
02290 
02291    // IMD options
02292    opts.optionalB("main","IMDon","Connect using IMD?",&IMDon, FALSE);
02293    opts.require("IMDon","IMDport", "Port to which to bind", &IMDport);
02294    opts.range("IMDport",POSITIVE);
02295    opts.require("IMDon","IMDfreq", "Frequency at which to report", &IMDfreq);
02296    opts.range("IMDfreq",POSITIVE);
02297    opts.optionalB("IMDon","IMDwait","Pause until IMD connection?",&IMDwait,
02298      FALSE);
02299    opts.optionalB("IMDon","IMDignore","Ignore any user input?",&IMDignore,
02300      FALSE);
02301    opts.optionalB("IMDon","IMDignoreForces","Ignore forces ONLY?",&IMDignoreForces,
02302      FALSE);
02303    // Maximum Partition options
02304    opts.optional("ldBalancer", "maxSelfPart", 
02305      "maximum number of self partitions in one patch", &maxSelfPart, 20);
02306    opts.range("maxSelfPart",POSITIVE);
02307    opts.optional("ldBalancer", "maxPairPart", 
02308      "maximum number of pair partitions in one patch", &maxPairPart, 8);
02309    opts.range("maxPairPart",POSITIVE);
02310    opts.optional("ldBalancer", "numAtomsSelf", 
02311                  "maximum number of atoms in one self compute distribution", 
02312                  &numAtomsSelf, 154);
02313    opts.range("numAtomsSelf",NOT_NEGATIVE);
02314 
02315    opts.optional("ldBalancer", "numAtomsSelf2", 
02316                  "maximum number of atoms in one self compute distribution", 
02317                  &numAtomsSelf2, 154);
02318    opts.range("numAtomsSelf2",NOT_NEGATIVE);
02319 
02320    opts.optional("ldBalancer", "numAtomsPair", 
02321                  "maximum number of atoms in one pair compute distribution", 
02322                  &numAtomsPair, 318);
02323    opts.range("numAtomsPair",NOT_NEGATIVE);
02324    opts.optional("ldBalancer", "numAtomsPair2", 
02325                "maximum number of atoms in one pair compute distribution", 
02326                &numAtomsPair2, 637);
02327    opts.range("numAtomsPair2",NOT_NEGATIVE);
02328    opts.optional("main", "minAtomsPerPatch", 
02329                "minimum average atoms per patch", 
02330                &minAtomsPerPatch, 40);
02331    opts.range("minAtomsPerPatch",NOT_NEGATIVE);
02332 
02333    // Maximum exclusion flags per atom
02334    opts.optional("main", "maxExclusionFlags", 
02335      "maximum number of exclusion flags per atom", &maxExclusionFlags, 256);
02336    opts.range("maxExclusionFlags",POSITIVE);
02337 
02338    // Bonded interactions on GPU
02339    opts.optional("main", "bondedCUDA", "Bitmask for calculating bonded interactions on GPU", &bondedCUDA, 255);
02340 
02341    // MIC specific parameters
02342    opts.optional("main", "mic_unloadMICPEs", "Indicates whether or not the load balancer should unload PEs driving Xeon Phi cards", &mic_unloadMICPEs, 1);
02343    opts.optional("main", "mic_singleKernel", "Set to non-zero to have all MIC work to be placed in a single kernel", &mic_singleKernel, 1);
02344    opts.optional("main", "mic_deviceThreshold", "Threshold to use for directing computes to Xeon Phi devices", &mic_deviceThreshold, -1);
02345    opts.optional("main", "mic_hostSplit", "DMK - reserved", &mic_hostSplit, -1);
02346    opts.optional("main", "mic_numParts_self_p1", "MIC-Specific NumParts SELF Parameter 1", &mic_numParts_self_p1, -1);
02347    opts.optional("main", "mic_numParts_pair_p1", "MIC-Specific NumParts PAIR Parameter 1", &mic_numParts_pair_p1, -1);
02348    opts.optional("main", "mic_numParts_pair_p2", "MIC-Specific NumParts PAIR Parameter 2", &mic_numParts_pair_p2, -1);
02349    opts.range("mic_unloadMICPEs", NOT_NEGATIVE);
02350    opts.range("mic_singleKernel", NOT_NEGATIVE);
02351 }
02352 
02353 void SimParameters::readExtendedSystem(const char *filename, Lattice *latptr) {
02354 
02355      if ( ! latptr ) {
02356        iout << iINFO << "EXTENDED SYSTEM FILE   " << filename << "\n" << endi;
02357      }
02358 
02359      ifstream xscFile(filename);
02360      if ( ! xscFile ) NAMD_die("Unable to open extended system file.\n");
02361 
02362      char labels[1024];
02363      do {
02364        if ( ! xscFile ) NAMD_die("Error reading extended system file.\n");
02365        xscFile.getline(labels,1023);
02366      } while ( strncmp(labels,"#$LABELS ",9) );
02367 
02368      int a_x, a_y, a_z, b_x, b_y, b_z, c_x, c_y, c_z;
02369      a_x = a_y = a_z = b_x = b_y = b_z = c_x = c_y = c_z = -1;
02370      int o_x, o_y, o_z, s_u, s_v, s_w, s_x, s_y, s_z;
02371      o_x = o_y = o_z = s_u = s_v = s_w = s_x = s_y = s_z = -1;
02372 
02373      int pos = 0;
02374      char *l_i = labels + 8;
02375      while ( *l_i ) {
02376        if ( *l_i == ' ' ) { ++l_i; continue; }
02377        char *l_i2;
02378        for ( l_i2 = l_i; *l_i2 && *l_i2 != ' '; ++l_i2 );
02379        if ( (l_i2 - l_i) == 3 && (l_i[1] == '_') ) {
02380          if (l_i[0] == 'a' && l_i[2] == 'x') a_x = pos;
02381          if (l_i[0] == 'a' && l_i[2] == 'y') a_y = pos;
02382          if (l_i[0] == 'a' && l_i[2] == 'z') a_z = pos;
02383          if (l_i[0] == 'b' && l_i[2] == 'x') b_x = pos;
02384          if (l_i[0] == 'b' && l_i[2] == 'y') b_y = pos;
02385          if (l_i[0] == 'b' && l_i[2] == 'z') b_z = pos;
02386          if (l_i[0] == 'c' && l_i[2] == 'x') c_x = pos;
02387          if (l_i[0] == 'c' && l_i[2] == 'y') c_y = pos;
02388          if (l_i[0] == 'c' && l_i[2] == 'z') c_z = pos;
02389          if (l_i[0] == 'o' && l_i[2] == 'x') o_x = pos;
02390          if (l_i[0] == 'o' && l_i[2] == 'y') o_y = pos;
02391          if (l_i[0] == 'o' && l_i[2] == 'z') o_z = pos;
02392          if (l_i[0] == 's' && l_i[2] == 'u') s_u = pos;
02393          if (l_i[0] == 's' && l_i[2] == 'v') s_v = pos;
02394          if (l_i[0] == 's' && l_i[2] == 'w') s_w = pos;
02395          if (l_i[0] == 's' && l_i[2] == 'x') s_x = pos;
02396          if (l_i[0] == 's' && l_i[2] == 'y') s_y = pos;
02397          if (l_i[0] == 's' && l_i[2] == 'z') s_z = pos;
02398        }
02399        ++pos;
02400        l_i = l_i2;
02401      }
02402      int numpos = pos;
02403 
02404      for ( pos = 0; pos < numpos; ++pos ) {
02405        double tmp;
02406        xscFile >> tmp;
02407        if ( ! xscFile ) NAMD_die("Error reading extended system file.\n");
02408        if ( pos == a_x ) cellBasisVector1.x = tmp;
02409        if ( pos == a_y ) cellBasisVector1.y = tmp;
02410        if ( pos == a_z ) cellBasisVector1.z = tmp;
02411        if ( pos == b_x ) cellBasisVector2.x = tmp;
02412        if ( pos == b_y ) cellBasisVector2.y = tmp;
02413        if ( pos == b_z ) cellBasisVector2.z = tmp;
02414        if ( pos == c_x ) cellBasisVector3.x = tmp;
02415        if ( pos == c_y ) cellBasisVector3.y = tmp;
02416        if ( pos == c_z ) cellBasisVector3.z = tmp;
02417        if ( pos == o_x ) cellOrigin.x = tmp;
02418        if ( pos == o_y ) cellOrigin.y = tmp;
02419        if ( pos == o_z ) cellOrigin.z = tmp;
02420        if ( pos == s_u ) strainRate2.x = tmp;
02421        if ( pos == s_v ) strainRate2.y = tmp;
02422        if ( pos == s_w ) strainRate2.z = tmp;
02423        if ( pos == s_x ) strainRate.x = tmp;
02424        if ( pos == s_y ) strainRate.y = tmp;
02425        if ( pos == s_z ) strainRate.z = tmp;
02426      }
02427 
02428    if ( latptr ) {
02429      Lattice test;
02430      test.set(cellBasisVector1,cellBasisVector2,cellBasisVector3,cellOrigin);
02431     
02432      if ( test.a_p() && ! lattice.a_p() ) {
02433        NAMD_die("cellBasisVector1 added during atom reinitialization");
02434      }
02435      if ( lattice.a_p() && ! test.a_p() ) {
02436        NAMD_die("cellBasisVector1 dropped during atom reinitialization");
02437      }
02438      if ( test.b_p() && ! lattice.b_p() ) {
02439        NAMD_die("cellBasisVector2 added during atom reinitialization");
02440      }
02441      if ( lattice.b_p() && ! test.b_p() ) {
02442        NAMD_die("cellBasisVector2 dropped during atom reinitialization");
02443      }
02444      if ( test.c_p() && ! lattice.c_p() ) {
02445        NAMD_die("cellBasisVector3 added during atom reinitialization");
02446      }
02447      if ( lattice.c_p() && ! test.c_p() ) {
02448        NAMD_die("cellBasisVector3 dropped during atom reinitialization");
02449      }
02450 
02451      latptr->set(cellBasisVector1,cellBasisVector2,cellBasisVector3,cellOrigin);
02452    }
02453 
02454 }
02455 
02456 #ifdef MEM_OPT_VERSION
02457 //This global var is defined in mainfunc.C
02458 extern char *gWorkDir;
02459 #endif
02460 
02461 void SimParameters::check_config(ParseOptions &opts, ConfigList *config, char *&cwd) {
02462    
02463    int len;    //  String length
02464    StringList *current; //  Pointer to config option list
02465 
02466 #ifdef MEM_OPT_VERSION
02467    char *namdWorkDir = NULL;
02468 #endif
02469 
02470   if ( opts.defined("obsolete") ) {
02471     iout << iWARN <<
02472       "\"obsolete\" defined, silently ignoring obsolete options\n" << endi;
02473   }
02474 
02475    //  Take care of cwd processing
02476    if (opts.defined("cwd"))
02477    {
02478     //  First allocate and get the cwd value
02479     current = config->find("cwd");
02480 
02481     len = strlen(current->data);
02482 
02483     if ( CHDIR(current->data) )
02484     {
02485       NAMD_die("chdir() to given cwd failed!");
02486     } else {
02487       iout << iINFO << "Changed directory to " << current->data << "\n" << endi;
02488     }
02489 
02490     if (current->data[len-1] != PATHSEP)
02491       len++;
02492 
02493     cwd = new char[len+1];
02494 
02495     strcpy(cwd, current->data);
02496 
02497     if (current->data[strlen(current->data)-1] != PATHSEP)
02498       strcat(cwd, PATHSEPSTR);
02499    }
02500 
02501 #ifdef MEM_OPT_VERSION
02502    if(cwd!=NULL)namdWorkDir = cwd;     
02503    else namdWorkDir = gWorkDir;
02504    int dirlen = strlen(namdWorkDir);
02505    //only support the path representation on UNIX-like platforms
02506    char *tmpDir;
02507    if(namdWorkDir[dirlen-1]=='/'){
02508      tmpDir = new char[dirlen+1];
02509      tmpDir[dirlen] = 0;
02510    }else{
02511      tmpDir = new char[dirlen+2];
02512      tmpDir[dirlen]='/';
02513      tmpDir[dirlen+1]=0;
02514    } 
02515    memcpy(tmpDir, namdWorkDir, dirlen);
02516    namdWorkDir = tmpDir;
02517  //finished recording the per atom files, free the space for gWorkDir
02518    delete [] gWorkDir;
02519 #endif
02520 
02521 
02522    // Don't try to specify coordinates with pluginIO
02523    if ( usePluginIO && opts.defined("coordinates") ) {
02524      NAMD_die("Separate coordinates file not allowed with plugin IO, coordinates will be taken from structure file.");
02525    }
02526 
02527    // If it's not AMBER||GROMACS, then "coordinates", "structure"
02528    // and "parameters" must be specified.
02529    if (!amberOn && !gromacsOn) {
02530 #ifndef MEM_OPT_VERSION
02531      if (useCompressedPsf)
02532        NAMD_die("useCompressedPsf requires memory-optimized build!");
02533      if (!usePluginIO && !genCompressedPsf && !opts.defined("coordinates"))
02534        NAMD_die("coordinates not found in the configuration file!");
02535 #else
02536      if(!usePluginIO && !opts.defined("bincoordinates")) {
02537        NAMD_die("bincoordinates not found in the configuration file for the memory optimized version!");
02538      }
02539      if(!usePluginIO && opts.defined("coordinates")) {
02540        NAMD_die("coordinates not allowed in the configuration file for the memory optimized version!");
02541      }
02542 #endif
02543      if (!opts.defined("structure"))
02544        NAMD_die("structure not found in the configuration file!");
02545      if (!opts.defined("parameters"))
02546        NAMD_die("parameters not found in the configuration file!");
02547    }
02548    
02549    // In any case, there should be either "coordinates" or
02550    // "ambercoor", but not both
02551    if (opts.defined("coordinates") && opts.defined("ambercoor"))
02552      NAMD_die("Cannot specify both coordinates and ambercoor!");
02553 #ifndef MEM_OPT_VERSION
02554    if (!genCompressedPsf && !opts.defined("coordinates") && !opts.defined("ambercoor")
02555        && !opts.defined("grocoorfile") && !usePluginIO)
02556      NAMD_die("Coordinate file not found!");
02557 #endif
02558 
02559    //  Make sure that both a temperature and a velocity PDB were
02560    //  specified
02561    if (opts.defined("temperature") &&
02562        (opts.defined("velocities") || opts.defined("binvelocities")) ) 
02563    {
02564       NAMD_die("Cannot specify both an initial temperature and a velocity file");
02565    }
02566 
02567 #ifdef MEM_OPT_VERSION
02568 //record the absolute file name for binAtomFile, binCoorFile and binVelFile etc.
02569    binAtomFile = NULL;
02570    binCoorFile = NULL;
02571    binVelFile = NULL;   
02572    binRefFile = NULL;
02573 
02574    char *curfile = NULL;
02575    dirlen = strlen(namdWorkDir);
02576    current = config->find("structure");;
02577    curfile = current->data;
02578    int filelen = strlen(curfile);
02579    if(*curfile == '/' || *curfile=='~') {
02580      //check whether it is an absolute path
02581      //WARNING: Only works on Unix-like platforms!
02582      //Needs to fix on Windows platform.
02583      //-Chao Mei     
02584      //adding 5 because of ".bin"+"\0"
02585      binAtomFile = new char[filelen+5];
02586      memcpy(binAtomFile, curfile, filelen);
02587      memcpy(binAtomFile+filelen, ".bin", 4);
02588      binAtomFile[filelen+4] = 0;
02589    }else{
02590      binAtomFile = new char[dirlen+filelen+5];
02591      memcpy(binAtomFile, namdWorkDir, dirlen);
02592      memcpy(binAtomFile+dirlen, curfile, filelen);
02593      memcpy(binAtomFile+dirlen+filelen, ".bin", 4);
02594      binAtomFile[dirlen+filelen+4] = 0;
02595    }
02596 
02597    current = config->find("bincoordinates");
02598    curfile = current->data;
02599    filelen = strlen(curfile);
02600    if(*curfile == '/' || *curfile=='~') {
02601      binCoorFile = new char[filelen+1];
02602      memcpy(binCoorFile, curfile, filelen);
02603      binCoorFile[filelen] = 0;
02604    }else{
02605      binCoorFile = new char[dirlen+filelen+1];
02606      memcpy(binCoorFile, namdWorkDir, dirlen);
02607      memcpy(binCoorFile+dirlen, curfile, filelen);
02608      binCoorFile[dirlen+filelen] = 0;
02609    }
02610 
02611    if(opts.defined("binvelocities")){
02612      current = config->find("binvelocities");
02613      curfile = current->data;
02614      filelen = strlen(curfile);
02615      if(*curfile == '/' || *curfile=='~') {
02616        binVelFile = new char[filelen+1];
02617        memcpy(binVelFile, curfile, filelen);
02618        binVelFile[filelen] = 0;
02619      }else{
02620        binVelFile = new char[dirlen+filelen+1];
02621        memcpy(binVelFile, namdWorkDir, dirlen);
02622        memcpy(binVelFile+dirlen, curfile, filelen);
02623        binVelFile[dirlen+filelen] = 0;
02624      }
02625    }
02626 
02627    if(opts.defined("binrefcoords")){
02628      current = config->find("binrefcoords");
02629      curfile = current->data;
02630      filelen = strlen(curfile);
02631      if(*curfile == '/' || *curfile=='~') {
02632        binRefFile = new char[filelen+1];
02633        memcpy(binRefFile, curfile, filelen);
02634        binRefFile[filelen] = 0;
02635      }else{
02636        binRefFile = new char[dirlen+filelen+1];
02637        memcpy(binRefFile, namdWorkDir, dirlen);
02638        memcpy(binRefFile+dirlen, curfile, filelen);
02639        binRefFile[dirlen+filelen] = 0;
02640      }
02641    }
02642 
02643    //deal with output file name to make it absolute path for parallel output
02644    if(outputFilename[0] != '/' && outputFilename[0]!='~') {
02645      filelen = strlen(outputFilename);
02646      char *tmpout = new char[filelen];
02647      memcpy(tmpout, outputFilename, filelen);
02648      CmiAssert(filelen+dirlen <= 120); //leave 8 chars for file suffix
02649      memcpy(outputFilename, namdWorkDir, dirlen);
02650      memcpy(outputFilename+dirlen, tmpout, filelen);
02651      outputFilename[filelen+dirlen] = 0;     
02652      delete [] tmpout;
02653    }
02654 
02655    if ( dcdFrequency && opts.defined("dcdfile") &&
02656         dcdFilename[0] != '/' && dcdFilename[0]!='~' ) {
02657      filelen = strlen(dcdFilename);
02658      char *tmpout = new char[filelen];
02659      memcpy(tmpout, dcdFilename, filelen);
02660      CmiAssert(filelen+dirlen <= 120); //leave 8 chars for file suffix
02661      memcpy(dcdFilename, namdWorkDir, dirlen);
02662      memcpy(dcdFilename+dirlen, tmpout, filelen);
02663      dcdFilename[filelen+dirlen] = 0;     
02664      delete [] tmpout;
02665    }
02666 
02667    if ( velDcdFrequency && opts.defined("veldcdfile") &&
02668         velDcdFilename[0] != '/' && velDcdFilename[0]!='~' ) {
02669      filelen = strlen(velDcdFilename);
02670      char *tmpout = new char[filelen];
02671      memcpy(tmpout, velDcdFilename, filelen);
02672      CmiAssert(filelen+dirlen <= 120); //leave 8 chars for file suffix
02673      memcpy(velDcdFilename, namdWorkDir, dirlen);
02674      memcpy(velDcdFilename+dirlen, tmpout, filelen);
02675      velDcdFilename[filelen+dirlen] = 0;     
02676      delete [] tmpout;
02677    }
02678 
02679    if ( forceDcdFrequency && opts.defined("forcedcdfile") &&
02680         forceDcdFilename[0] != '/' && forceDcdFilename[0]!='~' ) {
02681      filelen = strlen(forceDcdFilename);
02682      char *tmpout = new char[filelen];
02683      memcpy(tmpout, forceDcdFilename, filelen);
02684      CmiAssert(filelen+dirlen <= 120); //leave 8 chars for file suffix
02685      memcpy(forceDcdFilename, namdWorkDir, dirlen);
02686      memcpy(forceDcdFilename+dirlen, tmpout, filelen);
02687      forceDcdFilename[filelen+dirlen] = 0;     
02688      delete [] tmpout;
02689    }
02690 
02691    if ( restartFrequency && opts.defined("restartname") &&
02692         restartFilename[0] != '/' && restartFilename[0]!='~' ) {
02693      filelen = strlen(restartFilename);
02694      char *tmpout = new char[filelen];
02695      memcpy(tmpout, restartFilename, filelen);
02696      CmiAssert(filelen+dirlen <= 120); //leave 8 chars for file suffix
02697      memcpy(restartFilename, namdWorkDir, dirlen);
02698      memcpy(restartFilename+dirlen, tmpout, filelen);
02699      restartFilename[filelen+dirlen] = 0;     
02700      delete [] tmpout;
02701    }
02702 
02703    delete [] namdWorkDir;
02704 
02705    if (opts.defined("numinputprocs")) { 
02706      if(numinputprocs > CkNumPes()) {
02707        iout << iWARN << "The number of input processors exceeds the total number of processors. Resetting to half of the number of total processors.\n" << endi;
02708        numinputprocs = (CkNumPes()>>1)+(CkNumPes()&1);
02709      }
02710    }
02711 
02712    if (opts.defined("numoutputprocs")) {        
02713      if(numoutputprocs > CkNumPes()) {
02714        iout << iWARN << "The number of output processors exceeds the total number of processors. Resetting to half of the number of total processors.\n" << endi;
02715        numoutputprocs = (CkNumPes()>>1)+(CkNumPes()&1);
02716      }
02717    }
02718 
02719 #ifndef OUTPUT_SINGLE_FILE
02720 #error OUTPUT_SINGLE_FILE not defined!
02721 #endif
02722 
02723    #if !OUTPUT_SINGLE_FILE
02724    //create directories for multi-file output scheme   
02725    create_output_directories("coor");
02726    create_output_directories("vel");
02727    if(dcdFrequency) {
02728            create_output_directories("dcd");
02729            if(opts.defined("dcdfile")){
02730                    iout << iWARN << "The dcd file output has been changed to directory: " << outputFilename << ".\n" << endi; 
02731            }
02732    }
02733    if (velDcdFrequency) {
02734            create_output_directories("veldcd");
02735            if(opts.defined("veldcdfile")){       
02736                    iout << iWARN << "The veldcd file output has been changed to directory: " << outputFilename << ".\n" << endi;
02737            }
02738    }
02739    if (forceDcdFrequency) {
02740            create_output_directories("forcedcd");
02741            if(opts.defined("forcedcdfile")){       
02742                    iout << iWARN << "The forcedcd file output has been changed to directory: " << outputFilename << ".\n" << endi;
02743            }
02744    }
02745    #endif
02746 #endif
02747 
02748    if (! opts.defined("auxFile")) {
02749      strcpy(auxFilename,outputFilename);
02750      strcat(auxFilename,".aux");
02751    }
02752 
02753    //  Check for frequencies
02754    if (dcdFrequency) {
02755      if (! opts.defined("dcdfile")) {
02756        strcpy(dcdFilename,outputFilename);
02757        strcat(dcdFilename,".dcd");
02758      }
02759    } else {
02760      dcdFilename[0] = STRINGNULL;
02761    }
02762 
02763    if (velDcdFrequency) {
02764      if (! opts.defined("veldcdfile")) {
02765        strcpy(velDcdFilename,outputFilename);
02766        strcat(velDcdFilename,".veldcd");
02767      }
02768    } else {
02769      velDcdFilename[0] = STRINGNULL;
02770    }
02771    
02772    if (forceDcdFrequency) {
02773      if (! opts.defined("forcedcdfile")) {
02774        strcpy(forceDcdFilename,outputFilename);
02775        strcat(forceDcdFilename,".forcedcd");
02776      }
02777    } else {
02778      forceDcdFilename[0] = STRINGNULL;
02779    }
02780    
02781    if (xstFrequency) {
02782      if (! opts.defined("xstfile")) {
02783        strcpy(xstFilename,outputFilename);
02784        strcat(xstFilename,".xst");
02785      }
02786    } else {
02787      xstFilename[0] = STRINGNULL;
02788    }
02789 
02790    if (restartFrequency) {
02791      if (! opts.defined("restartname")) {
02792        strcpy(restartFilename,outputFilename);
02793        if ( ! restartSave ) strcat(restartFilename,".restart");
02794      }
02795    } else {
02796      restartFilename[0] = STRINGNULL;
02797      restartSave = FALSE;
02798      binaryRestart = FALSE;
02799    }
02800 
02801    if (storeComputeMap || loadComputeMap) {
02802      if (! opts.defined("computeMapFile")) {
02803        strcpy(computeMapFilename,"computeMapFile");
02804        strcat(computeMapFilename,".txt");
02805      }
02806    }
02807 
02808 
02809    if (!amberOn)
02810    { //****** BEGIN CHARMM/XPLOR type changes
02812      if (!paraTypeXplorOn && !paraTypeCharmmOn) 
02813      {
02814        paraTypeXplorOn = TRUE;
02815      }
02817      if (paraTypeXplorOn && paraTypeCharmmOn) 
02818      {
02819        NAMD_die("Please specify either XPLOR or CHARMM format for parameters!");
02820      }
02821      //****** END CHARMM/XPLOR type changes
02822    }
02823 
02824    
02825    //  If minimization isn't on, must have a temp or velocity
02826    if (!(minimizeOn||minimizeCGOn) && !opts.defined("temperature") && 
02827        !opts.defined("velocities") && !opts.defined("binvelocities") ) 
02828    {
02829       NAMD_die("Must have either an initial temperature or a velocity file");
02830    }
02831 
02832    if (minimizeOn||minimizeCGOn) { initialTemp = 0.0; }
02833    if (opts.defined("velocities") || opts.defined("binvelocities") )
02834    {
02835   initialTemp = -1.0;
02836    }
02837 
02839 
02840    if ( opts.defined("extendedSystem") ) readExtendedSystem(config->find("extendedSystem")->data);
02841 
02842 #ifdef MEM_OPT_VERSION
02843    if ( LJcorrection ) {
02844       NAMD_die("LJ tail corrections not yet available for memory optimized builds");
02845    }
02846 #endif
02847 
02848    if ( LJcorrection && ! cellBasisVector3.length2() ) {
02849      NAMD_die("Can't use LJ tail corrections without periodic boundary conditions!");
02850    }
02851 
02852    if ( cellBasisVector3.length2() && ! cellBasisVector2.length2() ) {
02853      NAMD_die("Used cellBasisVector3 without cellBasisVector2!");
02854    }
02855 
02856    if ( cellBasisVector2.length2() && ! cellBasisVector1.length2() ) {
02857      NAMD_die("Used cellBasisVector2 without cellBasisVector1!");
02858    }
02859 
02860    if ( cellOrigin.length2() && ! cellBasisVector1.length2() ) {
02861      NAMD_die("Used cellOrigin without cellBasisVector1!");
02862    }
02863 
02864    lattice.set(cellBasisVector1,cellBasisVector2,cellBasisVector3,cellOrigin);
02865 
02866    if (! opts.defined("DCDunitcell")) {
02867       dcdUnitCell = lattice.a_p() && lattice.b_p() && lattice.c_p();
02868    }
02869 
02870    char s[129];
02871 
02873    if ( ! opts.defined("cylindricalBCAxis") )
02874    {
02875       cylindricalBCAxis = 'x';
02876    }
02877    else
02878    {
02879      opts.get("cylindricalBCAxis", s);
02880 
02881      if (!strcasecmp(s, "x"))
02882      {
02883       cylindricalBCAxis = 'x';
02884      }
02885      else if (!strcasecmp(s, "y"))
02886      {
02887       cylindricalBCAxis = 'y';
02888      }
02889      else if (!strcasecmp(s, "z"))
02890      {
02891       cylindricalBCAxis = 'z';
02892      }
02893    else
02894      {
02895       char err_msg[128];
02896 
02897       sprintf(err_msg, "Illegal value '%s' for 'cylindricalBCAxis' in configuration file", s);
02898       NAMD_die(err_msg);
02899      }
02900    }
02901 
02902    if (!opts.defined("splitPatch"))
02903    {
02904      splitPatch = SPLIT_PATCH_HYDROGEN;
02905    }
02906    else
02907    {
02908      opts.get("splitPatch", s);
02909      if (!strcasecmp(s, "position"))
02910        splitPatch = SPLIT_PATCH_POSITION;
02911      else if (!strcasecmp(s,"hydrogen"))
02912        splitPatch = SPLIT_PATCH_HYDROGEN;
02913      else
02914      {
02915        char err_msg[129];
02916        sprintf(err_msg, 
02917           "Illegal value '%s' for 'splitPatch' in configuration file", 
02918        s);
02919        NAMD_die(err_msg);
02920      }
02921    }
02922 
02924    opts.get("exclude", s);
02925 
02926    if (!strcasecmp(s, "none"))
02927    {
02928       exclude = NONE;
02929       splitPatch = SPLIT_PATCH_POSITION;
02930    }
02931    else if (!strcasecmp(s, "1-2"))
02932    {
02933       exclude = ONETWO;
02934       splitPatch = SPLIT_PATCH_POSITION;
02935    }
02936    else if (!strcasecmp(s, "1-3"))
02937    {
02938       exclude = ONETHREE;
02939    }
02940    else if (!strcasecmp(s, "1-4"))
02941    {
02942       exclude = ONEFOUR;
02943    }
02944    else if (!strcasecmp(s, "scaled1-4"))
02945    {
02946       exclude = SCALED14;
02947    }
02948    else
02949    {
02950       char err_msg[128];
02951 
02952       sprintf(err_msg, "Illegal value '%s' for 'exclude' in configuration file",
02953    s);
02954       NAMD_die(err_msg);
02955    }
02956 
02957    if (scale14 != 1.0 && exclude != SCALED14)
02958    {
02959       iout << iWARN << "Exclude is not scaled1-4; 1-4scaling ignored.\n" << endi;
02960    }
02961 
02962    // water model stuff
02963    if (!opts.defined("waterModel")) {
02964      watmodel = WAT_TIP3;
02965    } else {
02966      opts.get("waterModel", s);
02967      if (!strncasecmp(s, "tip4", 4)) {
02968        iout << iINFO << "Using TIP4P water model.\n" << endi;
02969        watmodel = WAT_TIP4;
02970      } else if (!strncasecmp(s, "tip3", 4)) {
02971        iout << iINFO << "Using TIP3P water model.\n" << endi;
02972      } else if (!strncasecmp(s, "swm4", 4)) {
02973        iout << iINFO << "Using SWM4-DP water model.\n" << endi;
02974      } else {
02975        char err_msg[128];
02976        sprintf(err_msg,
02977            "Illegal value %s for 'waterModel' in configuration file", s);
02978        NAMD_die(err_msg);
02979      }
02980    }
02981    if (watmodel == WAT_SWM4 && !drudeOn) {
02982      NAMD_die("Must have 'drudeOn' enabled to use SWM4-DP water model.");
02983    }
02984    if (drudeOn && watmodel != WAT_SWM4) {
02985      watmodel = WAT_SWM4;
02986      iout << iWARN
02987        << "Setting water model to 'swm4' (SWM4-DP) for Drude polarization.\n"
02988        << endi;
02989    }
02990 
02991    // Drude water model uses "lonepairs"
02992    if (watmodel == WAT_SWM4) {
02993      lonepairs = TRUE;
02994    }
02995 
02996    // Added by JLai -- 8.2.11 -- Checks if Go method is defined
02997    if (goForcesOn) {
02998      iout << iINFO << "Go forces are on\n" << endi;
02999    // Added by JLai -- 6.3.11 -- Checks if Go method is defined
03000      int * gomethod = &goMethod;
03001      if (!opts.defined("GoMethod")) {
03002        *gomethod = 0;
03003        //     printf("GO METHOD IS NOT DEFINED SO WE'LL SET IT TO SOME WEIRD VALUE\n");
03004      } else {
03005        opts.get("GoMethod",s);
03006        // printf("GO METHOD IS DEFINED SO WE'LL PRINT IT OUT: %s\n",s);
03007        *gomethod = atoi(s);
03008      }
03009      if (!strcasecmp(s, "matrix")) {
03010        goMethod = 1;
03011        //GoMethod = GO_MATRIX;
03012      } else if (!strcasecmp(s, "faster")) {
03013        goMethod = 2;
03014        //GoMethod = GO_FASTER;
03015      } else if (!strcasecmp(s, "lowmem")) {
03016        goMethod = 3;
03017        //GoMethod = GO_LOWMEM;
03018      }
03019      else {
03020        char err_msg[129];     
03021        sprintf(err_msg,
03022                "Illegal value '%s' for 'GoMethod' in configuration file",
03023                s);
03024        NAMD_die(err_msg);
03025      }
03026    }  // End of NAMD code to check goMethod
03027    // End of Port -- JL
03028 
03029    //  Get multiple timestep integration scheme
03030    if (!opts.defined("MTSAlgorithm"))
03031    {
03032   MTSAlgorithm = VERLETI;
03033    }
03034    else
03035    {
03036   opts.get("MTSAlgorithm", s);
03037 
03038   if (!strcasecmp(s, "naive"))
03039   {
03040     MTSAlgorithm = NAIVE;
03041   }
03042   else if (!strcasecmp(s, "constant"))
03043   {
03044     MTSAlgorithm = NAIVE;
03045   }
03046   else if (!strcasecmp(s, "impulse"))
03047   {
03048     MTSAlgorithm = VERLETI;
03049   }
03050   else if (!strcasecmp(s, "verleti"))
03051   {
03052     MTSAlgorithm = VERLETI;
03053   }
03054   else
03055   {
03056     char err_msg[129];
03057 
03058     sprintf(err_msg, 
03059        "Illegal value '%s' for 'MTSAlgorithm' in configuration file", 
03060        s);
03061     NAMD_die(err_msg);
03062   }
03063    }
03064 
03065    //  Get the long range force splitting specification
03066    if (!opts.defined("longSplitting"))
03067    {
03068   longSplitting = C1;
03069    }
03070    else
03071    {
03072   opts.get("longSplitting", s);
03073   if (!strcasecmp(s, "sharp"))
03074     longSplitting = SHARP;
03075   else if (!strcasecmp(s, "xplor"))
03076     longSplitting = XPLOR;
03077   else if (!strcasecmp(s, "c1"))
03078     longSplitting = C1;
03079   else if (!strcasecmp(s, "c2"))
03080     longSplitting = C2;
03081   else
03082   {
03083     char err_msg[129];
03084 
03085     sprintf(err_msg, 
03086        "Illegal value '%s' for 'longSplitting' in configuration file", 
03087        s);
03088     NAMD_die(err_msg);
03089   }
03090    }
03091 
03092    // take care of rigid bond options
03093    if (!opts.defined("rigidBonds"))
03094    {
03095       rigidBonds = RIGID_NONE;
03096    }
03097    else
03098    {
03099       opts.get("rigidBonds", s); 
03100       if (!strcasecmp(s, "all"))
03101       {
03102           rigidBonds = RIGID_ALL;
03103       }
03104       else if (!strcasecmp(s, "water"))
03105       {
03106            rigidBonds = RIGID_WATER;
03107       } 
03108       else if (!strcasecmp(s, "none"))
03109       {
03110            rigidBonds = RIGID_NONE;
03111       } 
03112       else
03113       {
03114         char err_msg[256];
03115         sprintf(err_msg, 
03116           "Illegal value '%s' for 'rigidBonds' in configuration file", s);
03117         NAMD_die(err_msg);
03118       }
03119    }
03120    
03121    //  Take care of switching stuff
03122    if (switchingActive)
03123    {
03124 
03125      if (!opts.defined("switchDist")) {
03126        NAMD_die("switchDist must be defined when switching is enabled");
03127      }
03128 
03129      if ( (switchingDist>cutoff) || (switchingDist<0) )
03130      {
03131        char err_msg[129];
03132 
03133        sprintf(err_msg, 
03134          "switchDist muct be between 0 and cutoff, which is %f", cutoff);
03135        NAMD_die(err_msg);
03136      }
03137 
03138    }
03139 
03140    if ( martiniSwitching )
03141    {
03142      if ( ! switchingActive ) 
03143      { 
03144        NAMD_die("martiniSwitching requires switching");
03145      }
03146      if ( vdwForceSwitching ) 
03147      { 
03148        NAMD_die("martiniSwitching and vdwForceSwitching are exclusive to one another. Select only one."); 
03149      }
03150      if ( dielectric != 15.0 && ! martiniDielAllow ) 
03151      {
03152        iout << iWARN << "USE DIELECTRIC OF 15.0 WITH MARTINI.\n";
03153        iout << iWARN << "SETTING dielectric 15.0\n";
03154        iout << iWARN << "FOR NON-STANDARD DIELECTRIC WITH MARTINI, SET: martiniDielAllow on\n";
03155        dielectric = 15.0;
03156      }
03157      if ( ! cosAngles )
03158      {
03159        iout << iWARN << "USE COSINE BASED ANGLES WITH MARTINI.\n";
03160        iout << iWARN << "SETTING cosAngles on\n";
03161        cosAngles = TRUE;
03162      }
03163      if ( PMEOn )
03164      {
03165        NAMD_die("Do not use Particle Mesh Ewald with Martini.  Set: PME off");
03166      }
03167      if ( MSMOn )
03168      {
03169        NAMD_die("Do not use Multilevel Summation Method with Martini.  Set: MSM off");
03170      }
03171      if ( FMMOn )
03172      {
03173        NAMD_die("Do not use Fast Multipole Method with Martini.  Set: FMM off");
03174      }
03175 
03176    }
03177 
03178 
03179    if (!opts.defined("pairlistDist"))
03180    {
03181   pairlistDist = cutoff;
03182    }
03183    else if (pairlistDist < cutoff)
03184    {
03185   NAMD_die("pairlistDist must be >= cutoff distance");
03186    }
03187 
03188    patchDimension = pairlistDist;
03189 
03190    if ( splitPatch == SPLIT_PATCH_HYDROGEN ) {
03191      patchDimension += hgroupCutoff;
03192    }
03193 
03194    BigReal defaultMargin = 0.0;
03195    if (berendsenPressureOn || langevinPistonOn) {
03196       defaultMargin = ( useFlexibleCell ? 0.06 : 0.03 ) * patchDimension;
03197    }
03198    if ( margin == XXXBIGREAL ) {
03199      margin = defaultMargin;
03200    }
03201    if ( defaultMargin != 0.0 && margin == 0.0 ) {
03202      margin = defaultMargin;
03203      iout << iWARN << "ALWAYS USE NON-ZERO MARGIN WITH CONSTANT PRESSURE!\n";
03204      iout << iWARN << "CHANGING MARGIN FROM 0 to " << margin << "\n" << endi;
03205    }
03206 
03207    patchDimension += margin;
03208 
03209     //ensure patch can handle alpha_cutoff for gbis
03210     if (GBISOn) {
03211       //Check compatibility
03212       if (fullDirectOn) {
03213         NAMD_die("GBIS not compatible with FullDirect");
03214       }
03215       if (PMEOn) {
03216         NAMD_die("GBIS not compatible with PME");
03217       }
03218       if (MSMOn) {
03219         NAMD_die("GBIS not compatible with MSM");
03220       }
03221       if (FMMOn) {
03222         NAMD_die("GBIS not compatible with FMM");
03223       }
03224       if (alchOn) {
03225         NAMD_die("GBIS not compatible with Alchemical Transformations");
03226       }
03227       if (lesOn) {
03228         NAMD_die("GBIS not compatible with Locally Enhanced Sampling");
03229       }
03230       if (FMAOn) {
03231         NAMD_die("GBIS not compatible with FMA");
03232       }
03233       if (drudeOn) {
03234         NAMD_die("GBIS not compatible with Drude Polarization");
03235       }
03236 
03237       if (alpha_cutoff > patchDimension) {
03238         patchDimension = alpha_cutoff; 
03239       }
03240       //calculate kappa
03241       BigReal tmp = (initialTemp > 0) ? initialTemp : 300;
03242       kappa = 50.29216*sqrt(ion_concentration/solvent_dielectric/tmp);
03243       /*magic number = 1/sqrt(eps0*kB/(2*nA*e^2*1000))*/
03244     } // GBISOn
03245 
03246     if (LCPOOn) {
03247 #ifdef MEM_OPT_VERSION
03248       NAMD_die("SASA not yet available for memory optimized builds");
03249 #endif
03250       if ( lattice.volume() > 0 ) {
03251         NAMD_die("SASA does not yet support periodic boundary conditions.");
03252       }
03253       //LCPO requires patches to be at least 16.2Ang in each dimension
03254       // twoAway[XYZ} is ignored for now
03255     }
03256 
03257    //  Turn on global integration if not explicitly specified
03258 
03259    if ( dihedralOn ) globalOn = TRUE;
03260 
03261 #ifdef NAMD_CUDA
03262    if (loweAndersenOn) {
03263        NAMD_die("Lowe-Andersen dynamics not compatible with CUDA at this time");
03264    }
03265 #endif
03266    // END LA
03267 
03268    // BEGIN LA
03269    if (loweAndersenOn && (langevinOn || tCoupleOn))
03270    {
03271       NAMD_die("Lowe-Andersen dynamics, Langevin dynamics and temperature coupling are mutually exclusive dynamics modes");
03272    }
03273    // END LA
03274 
03275    if (tCoupleOn && opts.defined("rescaleFreq") )
03276    {
03277       NAMD_die("Temperature coupling and temperature rescaling are mutually exclusive");
03278    }
03279 
03280    if (globalOn && CkNumPes() > 1)
03281    {
03282       NAMD_die("Global integration does not run in parallel (yet).");
03283    }
03284 
03285    if (COLDOn && langevinOn)
03286    {
03287       NAMD_die("COLD and Langevin dynamics are mutually exclusive dynamics modes");
03288    }
03289    if (COLDOn && minimizeOn)
03290    {
03291       NAMD_die("COLD and minimization are mutually exclusive dynamics modes");
03292    }
03293    if (COLDOn && tCoupleOn)
03294    {
03295       NAMD_die("COLD and temperature coupling are mutually exclusive dynamics modes");
03296    }
03297    if (COLDOn && opts.defined("rescaleFreq"))
03298    {
03299       NAMD_die("COLD and velocity rescaling are mutually exclusive dynamics modes");
03300    }
03301 
03302    if (splitPatch == SPLIT_PATCH_POSITION && mollyOn )
03303    {
03304       NAMD_die("splitPatch hydrogen is required for MOLLY");
03305    }
03306 
03307    if (splitPatch == SPLIT_PATCH_POSITION && rigidBonds != RIGID_NONE)
03308    {
03309       NAMD_die("splitPatch hydrogen is required for rigidBonds");
03310    }
03311 
03312    if (accelMDOn) {
03313        if(accelMDG){
03314            char msg[128];
03315            if(accelMDGiE < 1 || accelMDGiE > 2){
03316                sprintf(msg, "accelMDGiE was set to %d but it should be 1 or 2", accelMDGiE);
03317                NAMD_die(msg);
03318            }
03319            if(accelMDGRestart && accelMDGcMDSteps == 0)
03320                accelMDGcMDPrepSteps = 0;
03321            else if(accelMDGcMDSteps - accelMDGcMDPrepSteps < 2)
03322                NAMD_die("'accelMDGcMDSteps' should be larger than 'accelMDGcMDPrepSteps'");
03323 
03324            if(accelMDGEquiSteps == 0)
03325                accelMDGEquiPrepSteps = 0;
03326            else if(accelMDGresetVaftercmd){
03327                if(accelMDGEquiPrepSteps <= 0)
03328                    NAMD_die("'accelMDGEquiPrepSteps' should be non-zero");
03329                if(accelMDGEquiSteps - accelMDGEquiPrepSteps < 1)
03330                    NAMD_die("'accelMDGEquiSteps' should be larger than 'accelMDGEquiPrepSteps'");
03331            }
03332 
03333            //warn user that accelMD params will be ignored
03334            if(opts.defined("accelMDE"))
03335                iout << iWARN << "accelMDE will be ignored with accelMDG on.\n" << endi;
03336            if(opts.defined("accelMDalpha"))
03337                iout << iWARN << "accelMDalpha will be ignored with accelMDG on.\n" << endi;
03338            if(opts.defined("accelMDTE"))
03339                iout << iWARN << "accelMDTE will be ignored with accelMDG on.\n" << endi;
03340            if(opts.defined("accelMDTalpha"))
03341                iout << iWARN << "accelMDTalpha will be ignored with accelMDG on.\n" << endi;
03342        }
03343        else{
03344            if(!opts.defined("accelMDE") || !opts.defined("accelMDalpha"))
03345                NAMD_die("accelMDE and accelMDalpha are required for accelMD with accelMDG off");
03346 
03347            if(accelMDdual && (!opts.defined("accelMDTE") || !opts.defined("accelMDTalpha"))){
03348                NAMD_die("accelMDTE and accelMDTalpha are required for accelMDdual with accelMDG off");
03349            }
03350        }
03351    }
03352 
03353    //  Set the default value for the maximum movement parameter
03354    //  for minimization
03355    if (minimizeOn && (maximumMove == 0.0)) 
03356    {
03357       maximumMove = 0.75 * pairlistDist/stepsPerCycle;
03358    }
03359    if (adaptTempOn) {
03360      if (!adaptTempRescale && !adaptTempLangevin) 
03361         NAMD_die("Adaptive tempering needs to be coupled to either the Langevin thermostat or velocity rescaling.");
03362      if (opts.defined("adaptTempInFile") && (opts.defined("adaptTempTmin") ||
03363                                              opts.defined("adaptTempTmax") ||
03364                                              adaptTempBins != 0)) 
03365         NAMD_die("cannot simultaneously specify adaptTempInFile and any of {adaptTempTmin, adaptTempTmax,adaptTempBins} as these are read from the input file");
03366      if (!opts.defined("adaptTempInFile") && !(opts.defined("adaptTempTmin") &&
03367                                              opts.defined("adaptTempTmax") &&
03368                                              adaptTempBins != 0 ))  
03369         NAMD_die("Need to specify either adaptTempInFile or all of {adaptTempTmin, adaptTempTmax,adaptTempBins} if adaptTempMD is on.");
03370    }
03371 
03372    langevinOnAtStartup = langevinOn;
03373    if (langevinOn) {
03374      if ( ! opts.defined("langevinDamping") ) langevinDamping = 0.0;
03375      if ( ! opts.defined("langevinHydrogen") ) langevinHydrogen = TRUE;
03376      if ( (opts.defined("langevinDamping") || opts.defined("langevinHydrogen"))
03377        && (opts.defined("langevinFile") || opts.defined("langevinCol")) )
03378        NAMD_die("To specify Langevin dynamics parameters, use either langevinDamping and langevinHydrogen or langevinFile and langevinCol.  Do not combine them.");
03379      if ( opts.defined("langevinHydrogen") && langevinDamping == 0.0 )
03380        NAMD_die("langevinHydrogen requires langevinDamping to be set.");
03381    }
03382    
03383    // BEGIN LA
03384    if (loweAndersenOn) {
03385        if (!opts.defined("loweAndersenRate")) loweAndersenRate = 100;
03386        if (!opts.defined("loweAndersenCutoff")) loweAndersenCutoff = 2.7;
03387    }
03388    // END LA
03389 
03390    // BKR - stochastic velocity rescaling
03391    if (stochRescaleOn) {
03392      if (langevinOn || loweAndersenOn || tCoupleOn ||
03393          opts.defined("rescaleFreq") || opts.defined("reassignFreq"))
03394        NAMD_die("Stochastic velocity rescaling is incompatible with other temperature control methods");
03395      // This is largely the same default used in GROMACS.
03396      if (!opts.defined("stochRescaleFreq")) stochRescaleFreq = stepsPerCycle;
03397    }
03398 
03399    if (opts.defined("rescaleFreq"))
03400    {
03401   if (!opts.defined("rescaleTemp"))
03402   {
03403     if (opts.defined("temperature"))
03404     {
03405       rescaleTemp = initialTemp;
03406     }
03407     else
03408     {
03409       NAMD_die("Must give a rescale temperature if rescaleFreq is defined");
03410     }
03411   }
03412    }
03413    else
03414    {
03415   rescaleFreq = -1;
03416   rescaleTemp = 0.0;
03417    }
03418 
03419    if (opts.defined("rescaleTemp"))
03420    {
03421   if (!opts.defined("rescaleFreq"))
03422   {
03423     NAMD_die("Must give a rescale freqency if rescaleTemp is given");
03424   }
03425    }
03426 
03427    if (opts.defined("reassignFreq"))
03428    {
03429   if (!opts.defined("reassignTemp"))
03430   {
03431     if (opts.defined("temperature"))
03432     {
03433       reassignTemp = initialTemp;
03434     }
03435     else
03436     {
03437       NAMD_die("Must give a reassign temperature if reassignFreq is defined");
03438     }
03439   }
03440    }
03441    else
03442    {
03443   reassignFreq = -1;
03444   reassignTemp = 0.0;
03445    }
03446 
03447    if (opts.defined("reassignTemp"))
03448    {
03449   if (!opts.defined("reassignFreq"))
03450   {
03451     NAMD_die("Must give a reassignment freqency if reassignTemp is given");
03452   }
03453    }
03454 
03455    if (opts.defined("reassignIncr"))
03456    {
03457   if (!opts.defined("reassignFreq"))
03458   {
03459     NAMD_die("Must give a reassignment freqency if reassignIncr is given");
03460   }
03461    }
03462    else
03463    {
03464   reassignIncr = 0.0;
03465    }
03466 
03467    if (opts.defined("reassignHold"))
03468    {
03469   if (!opts.defined("reassignIncr"))
03470   {
03471     NAMD_die("Must give a reassignment increment if reassignHold is given");
03472   }
03473    }
03474    else
03475    {
03476   reassignHold = 0.0;
03477    }
03478 
03479    if (!opts.defined("seed")) 
03480    {
03481       randomSeed = (unsigned int) time(NULL) + 31530001 * CmiMyPartition();
03482    }
03483 
03484    // REST2
03485    if (opts.defined("soluteScaling")) {
03486      // Parameters soluteScalingFactorCharge and soluteScalingFactorVdw
03487      // allow independent scaling of electrostatics and van der Waals.
03488      // Initialize with soluteScalingFactor if either is not already set.
03489      if ( ! opts.defined("soluteScalingFactorCharge") ) {
03490        soluteScalingFactorCharge = soluteScalingFactor;
03491      }
03492      if ( ! opts.defined("soluteScalingFactorVdw") ) {
03493        soluteScalingFactorVdw = soluteScalingFactor;
03494      }
03495    }
03496 
03497 //fepb
03498    alchFepOnAtStartup = alchFepOn = FALSE;
03499    alchThermIntOnAtStartup = alchThermIntOn = FALSE;
03500    alchOnAtStartup = alchOn;
03501 
03502    if (alchOn) {
03503      if (vdwForceSwitching && (alchFepWCARepuOn || alchFepWCADispOn)) {
03504        iout << iWARN << "vdwForceSwitching not implemented for alchemical "
03505          "interactions when WCA decomposition is on!\n" << endi;
03506      }
03507      if (martiniSwitching) {
03508        iout << iWARN << "Martini switching disabled for alchemical "
03509          "interactions.\n" << endi;
03510      }
03511 
03512      if (!opts.defined("alchType")) {
03513        NAMD_die("Must define type of alchemical simulation: fep or ti\n");
03514      }
03515      else {
03516        opts.get("alchType",s);
03517        if (!strcasecmp(s, "fep")) {
03518          alchFepOnAtStartup = alchFepOn = TRUE;
03519        }
03520        else if (!strcasecmp(s, "ti")) {
03521          alchThermIntOnAtStartup = alchThermIntOn = TRUE;
03522        }
03523        else {
03524          NAMD_die("Unknown type of alchemical simulation; choices are fep or ti\n");
03525        }
03526      }
03527 
03528      if      (rescaleFreq > 0)  alchTemp = rescaleTemp;
03529      else if (reassignFreq > 0) alchTemp = reassignTemp;
03530      else if (langevinOn)       alchTemp = langevinTemp;
03531      else if (stochRescaleOn)   alchTemp = stochRescaleTemp;
03532      else if (tCoupleOn)        alchTemp = tCoupleTemp;
03533      else NAMD_die("Alchemical FEP can be performed only in constant temperature simulations\n");
03534 
03535      if (reassignFreq > 0 && reassignIncr != 0)
03536        NAMD_die("reassignIncr cannot be used in alchemical simulations\n");
03537 
03538      if (alchLambda < 0.0 || alchLambda > 1.0)
03539        NAMD_die("alchLambda values should be in the range [0.0, 1.0]\n");
03540      
03541      if (alchVdwLambdaEnd > 1.0) 
03542        NAMD_die("Gosh tiny Elvis, you kicked soft-core in the van der Waals! alchVdwLambdaEnd should be in the range [0.0, 1.0]\n");
03543 
03544      if (alchBondLambdaEnd > 1.0)
03545        NAMD_die("alchBondLambdaEnd should be in the range [0.0, 1.0]\n");
03546 
03547      if (alchElecLambdaStart > 1.0) 
03548        NAMD_die("alchElecLambdaStart should be in the range [0.0, 1.0]\n");
03549      
03550      if (alchFepOn) {
03551        if (alchLambda2 < 0.0 || alchLambda2 > 1.0)
03552          NAMD_die("alchLambda2 values should be in the range [0.0, 1.0]\n");
03553 
03554        if (!opts.defined("alchoutfile")) {
03555          strcpy(alchOutFile, outputFilename);
03556          strcat(alchOutFile, ".fep");
03557        }
03558 
03559        if (!alchFepWhamOn && 
03560            ((!opts.defined("alchLambda")) || (!opts.defined("alchLambda2")))) {
03561          NAMD_die("alchFepOn is on, but alchLambda or alchLambda2 is not set.");
03562        }
03563        
03564        if(alchRepLambda > 1.0)
03565          NAMD_die("alchRepLambda should be in the range [0.0, 1.0].");
03566        else if(alchRepLambda >= 0.0)
03567          alchFepWCARepuOn = true;
03568        else
03569          alchFepWCARepuOn = false;
03570  
03571        if(alchDispLambda > 1.0)
03572          NAMD_die("alchDispLambda should be in the range [0.0, 1.0].");
03573        else if(alchDispLambda >= 0.0)
03574          alchFepWCADispOn = true;
03575        else
03576          alchFepWCADispOn = false;
03577  
03578        if(alchElecLambda > 1.0)
03579          NAMD_die("alchElecLambda should be in the range [0.0, 1.0].");
03580        else if(alchElecLambda >= 0.0)
03581          alchFepElecOn = true;
03582        else
03583          alchFepElecOn = false;
03584        
03585        if ((alchFepWCARepuOn || alchFepWCADispOn || alchFepElecOn) && 
03586            !alchFepWhamOn)
03587          NAMD_die("alchFepWhamOn has to be on if one of alchFepWCARepuOn/alchFepWCADispOn/alchFepElecOn is set.");
03588        if (alchFepWCARepuOn && alchFepWCADispOn)
03589           NAMD_die("With WCA decomposition, repulsion and dispersion can NOT be in the same FEP stage");
03590        if (alchFepWCARepuOn && alchFepElecOn)
03591           NAMD_die("With WCA decomposition, repulsion and electrostatic perturbation can NOT be in the same FEP stage");
03592        if (alchFepWCADispOn && alchFepElecOn)
03593           NAMD_die("With WCA decomposition, dispersion and electrostatic perturbation can NOT be in the same FEP stage");
03594        if (alchFepWCARepuOn && 
03595            (!opts.defined("alchFepWCArcut1") || 
03596             !opts.defined("alchFepWCArcut2") ||
03597             !opts.defined("alchFepWCArcut3") ))
03598           NAMD_die("When using WCA repulsion,  alchFepWCArcut1, alchFepWCArcut2, and alchFepWCArcut3 must be defined!");
03599        if (alchFepWCARepuOn && 
03600            ((alchFepWCArcut1 > alchFepWCArcut2) || 
03601             (alchFepWCArcut2 > alchFepWCArcut3) ))
03602            NAMD_die("When using WCA repulsion,  alchFepWCArcut2 must be larger than alchFEPWCArcut1, alchFepWCArcut3 must be larger than alchFEPWCArcut2!");
03603        if (alchFepWhamOn && (alchRepLambda < 0.0) && (alchDispLambda < 0.0) && 
03604            (alchElecLambda < 0.0) )     
03605            NAMD_die("One of alchRepLambda, alchDispLambda and alchElecLambda should be set up when alchFepWhamOn is true!");
03606        if (alchFepWhamOn && (!alchFepElecOn)) {
03607          alchElecLambda = 0.0;
03608          ComputeNonbondedUtil::alchElecLambda = alchElecLambda;
03609        }
03610      }
03611      else if (alchThermIntOn) {
03612        // alchLambda2 is only needed for nonequilibrium switching
03613        if (alchLambdaFreq && (alchLambda2 < 0.0 || alchLambda2 > 1.0))
03614          NAMD_die("alchLambda2 values should be in the range [0.0, 1.0]\n");
03615 
03616        if (!opts.defined("alchoutfile")) { 
03617          strcpy(alchOutFile, outputFilename); 
03618          strcat(alchOutFile, ".ti"); 
03619        } 
03620      }
03621      if (alchLambdaIDWS >= 0.) {
03622        if ( alchLambdaIDWS > 1. ) {
03623          NAMD_die("alchLambdaIDWS should be either in the range [0.0, 1.0], or negative (disabled).\n");
03624       }
03625        // Switch lambda2 every other cycle of fullElectFrequency steps
03626        // or every other nonbondedFrequency steps if undefined
03627        // or every alchOutFreq steps if larger (no need to switch faster that we output)
03628        alchIDWSfreq = fullElectFrequency > 0 ? fullElectFrequency : nonbondedFrequency;
03629        if ( alchOutFreq > alchIDWSfreq )
03630          alchIDWSfreq = alchOutFreq;
03631      }
03632    }
03633         
03634 //fepe
03635 
03636    if ( alchOn && alchFepOn && alchThermIntOn )
03637      NAMD_die("Sorry, combined TI and FEP is not implemented.\n");
03638    if ( alchOn && lesOn )
03639      NAMD_die("Sorry, combined LES with FEP or TI is not implemented.\n");
03640    if ( alchOn && alchThermIntOn && lesOn )
03641      NAMD_die("Sorry, combined LES and TI is not implemented.\n");
03642    if ( alchDecouple && !alchOn ) {
03643          iout << iWARN << "Alchemical decoupling was requested but \
03644            alchemical free energy calculation is not active. Setting \
03645            alchDecouple to off.\n" << endi;
03646          alchDecouple = FALSE;
03647    }
03648    if ( alchBondDecouple && !alchOn ) {
03649          iout << iWARN << "Alchemical bond decoupling was requested but \
03650            alchemical free energy calculation is not active. Setting \
03651            alchBondDecouple to off.\n" << endi;
03652          alchBondDecouple = FALSE;
03653    }
03654 
03655    if ( lesOn && ( lesFactor < 1 || lesFactor > 255 ) ) {
03656      NAMD_die("lesFactor must be positive and less than 256");
03657    }
03658    if ((pairInteractionOn && alchOn) || (pairInteractionOn && lesOn)) 
03659      NAMD_die("Sorry, pair interactions may not be calculated when LES, FEP or TI is enabled.");
03660 
03661    // Drude model
03662    if (drudeOn) {
03663      if ( ! langevinOn ) {
03664        NAMD_die("Drude model requires use of Langevin thermostat.");
03665      }
03666      if ( ! opts.defined("drudeDamping")) {
03667        drudeDamping = langevinDamping;
03668        iout << iWARN << "Undefined 'drudeDamping' will be set to "
03669          "value of 'langevinDamping'\n" << endi;
03670      }
03671      if ( ! opts.defined("drudeBondConst")) {
03672        drudeBondConst = 0;
03673        if (! drudeHardWallOn) {
03674          drudeBondLen = 0;
03675          if (opts.defined("drudeBondLen")) {
03676            iout << iWARN << "Resetting 'drudeBondLen' to 0 "
03677              "since 'drudeBondConst' and 'drudeHardWall' are unset\n" << endi;
03678          }
03679        }
03680      }
03681      if ( ! opts.defined("drudeNbtholeCut")) {
03682        drudeNbtholeCut = 0;
03683          iout << iWARN << "Resetting 'drudeNbtholeCut' to 0 "
03684            "since 'drudeNbtholeCut' is unset\n" << endi;
03685      }
03686    }
03687 
03688    //  Set up load balancing variables
03689    if (opts.defined("ldBalancer")) {
03690      if (strcasecmp(loadBalancer, "none") == 0)
03691        ldBalancer = LDBAL_NONE;
03692      else if (strcasecmp(loadBalancer, "hybrid") == 0)
03693        ldBalancer = LDBAL_HYBRID;
03694      else
03695        NAMD_die("Unknown ldBalancer selected");
03696    } else {
03697      ldBalancer = LDBAL_CENTRALIZED;
03698 #ifdef MEM_OPT_VERSION
03699      if ( CkNumPes() > 1400 ) ldBalancer = LDBAL_HYBRID;
03700 #endif
03701    }
03702 
03703    if (opts.defined("ldbStrategy")) {
03704      //  Assign the load balancing strategy
03705      if (strcasecmp(loadStrategy, "comprehensive") == 0)
03706        ldbStrategy = LDBSTRAT_COMPREHENSIVE;
03707      else if (strcasecmp(loadStrategy, "refineonly") == 0)
03708        ldbStrategy = LDBSTRAT_REFINEONLY;
03709      else if (strcasecmp(loadStrategy, "old") == 0)
03710        ldbStrategy = LDBSTRAT_OLD;
03711      else
03712        NAMD_die("Unknown ldbStrategy selected");
03713    } else {
03714      ldbStrategy = LDBSTRAT_DEFAULT;
03715    }
03716 
03717   if (!opts.defined("ldbPeriod")) {
03718     ldbPeriod=200*stepsPerCycle;
03719   }
03720 
03721   //  Set default values
03722   if (!opts.defined("firstLdbStep")) {
03723     firstLdbStep=5*stepsPerCycle;
03724   }
03725 
03726   if (ldbPeriod <= firstLdbStep) {
03727     NAMD_die("ldbPeriod must greater than firstLdbStep.");
03728   }
03729 
03730   if (!opts.defined("lastLdbStep")) {
03731     lastLdbStep = -1;
03732   }
03733 
03734   if (!opts.defined("hybridGroupSize")) {
03735     hybridGroupSize = 512;
03736   }
03737   if ( hybridGroupSize < CkNumPes() ) {
03738     // match load balancer boundaries to physical nodes if possible
03739     int groupsize = hybridGroupSize;
03740     int *rpelist;
03741     int nodesize;
03742     CmiGetPesOnPhysicalNode(CmiPhysicalNodeID(0), &rpelist, &nodesize);
03743     if ( CkNumPes() % nodesize ) nodesize = CmiNodeSize(CmiNodeOf(0));
03744     if ( CkNumPes() % nodesize ) nodesize = 1;
03745     groupsize += nodesize - 1;
03746     while ( 2 * groupsize > CkNumPes() ) --groupsize;
03747     if ( groupsize < nodesize ) groupsize = nodesize;
03748     while ( groupsize % nodesize ) --groupsize;
03749     while ( groupsize && CkNumPes() % groupsize ) groupsize -= nodesize;
03750     if ( 2 * groupsize < hybridGroupSize ) {
03751       groupsize += nodesize;
03752       while ( CkNumPes() % groupsize ) groupsize += nodesize;
03753     }
03754     if ( 2 * groupsize <= CkNumPes() ) hybridGroupSize = groupsize;
03755   }
03756 
03757   // tracing will be done if trace is available and user says +traceOff
03758   // in that case we set nice values for some functions
03759   bool specialTracing = traceAvailable() && (traceIsOn() == 0);
03760 
03761   if(!opts.defined("traceStartStep")) {
03762     traceStartStep = 4 * firstLdbStep + 2 * ldbPeriod;
03763   }
03764   if(!opts.defined("numTraceSteps")) {
03765     numTraceSteps = 100;
03766   }
03767 
03768   if(specialTracing) {
03769     if (!opts.defined("firstLdbStep")) firstLdbStep = 20;
03770     if (!opts.defined("ldbPeriod")) ldbPeriod = 100;
03771 
03772     if(!opts.defined("traceStartStep")) {
03773       traceStartStep = 4 * firstLdbStep + 2 * ldbPeriod; // 380
03774     }
03775 
03776     if(!opts.defined("numTraceSteps")) {
03777       numTraceSteps = 80;
03778     }
03779   }
03780 
03781 #ifdef MEASURE_NAMD_WITH_PAPI
03782   if(papiMeasure){
03783           if(!opts.defined("papiMeasureStartStep")) {
03784                   papiMeasureStartStep = 3 * firstLdbStep;
03785           }
03786           if(!opts.defined("numPapiMeasureSteps")) {
03787                   numPapiMeasureSteps = 8; //including two pme steps
03788           }
03789   }
03790 #endif
03791 
03792   if(simulateInitialMapping) {
03793           if(!opts.defined("simulatedPEs")){
03794                   simulatedPEs = CkNumPes();
03795           }
03796           if(!opts.defined("simulatedNodeSize")){
03797                   simulatedNodeSize = CkMyNodeSize();
03798           }
03799   }
03800 
03801 #ifdef MEM_OPT_VERSION
03802   //Some constraints on the values of load balancing parameters.
03803   //The reason is related to communication schemes used in sending proxy
03804   //data. If the step immediately after the load balancing is not a step
03805   //for atom migration, then it's possible there are some necessary information 
03806   // missing inside the ProxyPatch which will crash the program. Therefore,
03807   // It's better that the step immediately after the load balancing be a step
03808   // for atom migration so that the some overhead in Proxy msgs are removed. 
03809   // --Chao Mei
03810   if(ldbPeriod%stepsPerCycle!=0 || firstLdbStep%stepsPerCycle!=0) {
03811       iout << iWARN << "In memory optimized version, the ldbPeriod parameter or firstLdbStep parameter is better set to be a multiple of stepsPerCycle parameter!\n";
03812   }
03813 #endif
03814 
03815    if (N < firstTimestep) { N = firstTimestep; }
03816 
03817    if ( (firstTimestep%stepsPerCycle) != 0)
03818    {
03819   NAMD_die("First timestep must be a multiple of stepsPerCycle!!");
03820    }
03821 
03822    //  Make sure only one full electrostatics algorithm is selected
03823    {
03824      int i = 0;
03825      if ( FMAOn ) ++i;
03826      if ( PMEOn ) ++i;
03827      if ( MSMOn ) ++i;
03828      if ( FMMOn ) ++i;
03829      if ( fullDirectOn ) ++i;
03830      if ( i > 1 )
03831         NAMD_die("More than one full electrostatics algorithm selected!!!");
03832    }
03833 
03834    if (!opts.defined("ldbBackgroundScaling")) {
03835      ldbBackgroundScaling = 1.0;
03836    }
03837    if (!opts.defined("ldbPMEBackgroundScaling")) {
03838      ldbPMEBackgroundScaling = ldbBackgroundScaling;
03839    }
03840    if (!opts.defined("ldbHomeBackgroundScaling")) {
03841      ldbHomeBackgroundScaling = ldbBackgroundScaling;
03842    }
03843 
03844    //  Check on PME parameters
03845    if (PMEOn) {  // idiot checking
03846      if ( lattice.volume() == 0. ) {
03847         NAMD_die("PME requires periodic boundary conditions.");
03848      }
03849      if ( PMEGridSpacing == 0. ) {
03850        if ( PMEGridSizeX * PMEGridSizeY * PMEGridSizeZ == 0 )
03851          NAMD_die("Either PMEGridSpacing or PMEGridSizeX, PMEGridSizeY, and PMEGridSizeZ must be specified.");
03852        else PMEGridSpacing = 1.5;  // only exit in very bad cases
03853      }
03854 #ifndef TEST_PME_GRID
03855      for ( int idim = 0; idim < 3; ++idim ) {
03856         int *gridSize;
03857         BigReal cellLength;
03858         const char *direction;
03859         switch ( idim ) {
03860         case 0:  direction = "X";
03861            gridSize = &PMEGridSizeX;  cellLength = lattice.a().length();
03862            break;
03863         case 1:  direction = "Y";
03864            gridSize = &PMEGridSizeY;  cellLength = lattice.b().length();
03865            break;
03866         case 2:  direction = "Z";
03867            gridSize = &PMEGridSizeZ;  cellLength = lattice.c().length();
03868            break;
03869         }
03870         int minSize = (int) ceil(cellLength/PMEGridSpacing);
03871 #else
03872   for ( int minSize = 1; minSize < 300; ++minSize ) {
03873 #endif
03874         int bestSize = 10 * (minSize + 10);  // make sure it's big
03875         int max2, max3, ts;
03876         for ( max2=2, ts=1; ts < minSize; ++max2 ) ts *= 2;
03877         for ( max3=2, ts=1; ts < minSize; ++max3 ) ts *= 3;
03878         int max5 = 2;
03879         int max7 = 1;
03880         int max11 = 1;
03881         for ( int i2 = 0; i2 <= max2; ++i2 ) {
03882         for ( int i3 = 0; i3 <= max3; ++i3 ) {
03883         for ( int i5 = 0; i5 <= max5; ++i5 ) {
03884         for ( int i7 = 0; i7 <= max7; ++i7 ) {
03885         for ( int i11 = 0; i11 <= max11; ++i11 ) {
03886            if ( i5 + i7 + i11 > i2 ) continue;
03887            int testSize = 2;  // must be even
03888            for ( int j2 = 0; j2 < i2; ++j2 ) testSize *= 2;
03889            if ( testSize > bestSize ) continue;
03890            for ( int j3 = 0; j3 < i3; ++j3 ) testSize *= 3;
03891            if ( testSize > bestSize ) continue;
03892            for ( int j5 = 0; j5 < i5; ++j5 ) testSize *= 5;
03893            if ( testSize > bestSize ) continue;
03894            for ( int j7 = 0; j7 < i7; ++j7 ) testSize *= 7;
03895            if ( testSize > bestSize ) continue;
03896            for ( int j11 = 0; j11 < i11; ++j11 ) testSize *= 11;
03897            if ( testSize > bestSize ) continue;
03898            if ( testSize >= minSize ) bestSize = testSize;
03899         } } } } }
03900 #ifdef TEST_PME_GRID
03901   iout << minSize << " " << bestSize << "\n" << endi;
03902 #else
03903         if ( ! *gridSize ) {   // set it
03904            *gridSize = bestSize;
03905         }
03906         if ( *gridSize * PMEGridSpacing < cellLength ) {
03907            char errmsg[512];
03908            sprintf(errmsg, "PMEGridSize%s %d is too small for cell length %f and PMEGridSpacing %f\n",
03909                 direction, *gridSize, cellLength, PMEGridSpacing);
03910            NAMD_die(errmsg);
03911         }
03912 #endif
03913      }
03914      if ( PMEGridSizeX < 5 ) {
03915         NAMD_die("PMEGridSizeX (number of grid points) is very small.");
03916      }
03917      if ( PMEGridSizeY < 5 ) {
03918         NAMD_die("PMEGridSizeY (number of grid points) is very small.");
03919      }
03920      if ( PMEGridSizeZ < 5 ) {
03921         NAMD_die("PMEGridSizeZ (number of grid points) is very small.");
03922      }
03923      BigReal tolerance = PMETolerance;
03924      BigReal ewaldcof = 1.0;
03925      while ( erfc(ewaldcof*cutoff)/cutoff >= tolerance ) ewaldcof *= 2.0;
03926      BigReal ewaldcof_lo = 0.;
03927      BigReal ewaldcof_hi = ewaldcof;
03928      for ( int i = 0; i < 100; ++i ) {
03929        ewaldcof = 0.5 * ( ewaldcof_lo + ewaldcof_hi );
03930        if ( erfc(ewaldcof*cutoff)/cutoff >= tolerance ) {
03931          ewaldcof_lo = ewaldcof;
03932        } else {
03933          ewaldcof_hi = ewaldcof;
03934        }
03935      }
03936      PMEEwaldCoefficient = ewaldcof;
03937 
03938 #ifdef NAMD_CUDA
03939      bool one_device_per_node = deviceCUDA->one_device_per_node();  // only checks node 0
03940      if ( ! opts.defined("PMEOffload") ) {
03941        PMEOffload = ( (PMEInterpOrder > 4) && one_device_per_node );
03942        if ( PMEOffload ) iout << iINFO << "Enabling PMEOffload because PMEInterpOrder > 4.\n" << endi;
03943      } else if ( PMEOffload && ! one_device_per_node ) {
03944        PMEOffload = 0;
03945        iout << iWARN << "Disabling PMEOffload because multiple CUDA devices per process are not supported.\n" << endi;
03946      }
03947      if ( usePMECUDA && ! ( useCUDA2 || one_device_per_node ) ) {
03948        usePMECUDA = 0;
03949        iout << iWARN << "Disabling usePMECUDA because multiple CUDA devices per process requires useCUDA2.\n" << endi;
03950      }
03951      // if ( cellBasisVector1.y != 0 ||
03952      //      cellBasisVector1.z != 0 ||
03953      //      cellBasisVector2.x != 0 ||
03954      //      cellBasisVector2.z != 0 ||
03955      //      cellBasisVector3.x != 0 ||
03956      //      cellBasisVector3.y != 0    ) {
03957      //   if ( useCUDA2 ) {
03958      //     useCUDA2 = 0;
03959      //     iout << iWARN << "Disabling useCUDA2 because of non-orthorhombic periodic cell.\n" << endi;
03960      //   }
03961      //   if ( usePMECUDA ) {
03962      //     usePMECUDA = 0;
03963      //     iout << iWARN << "Disabling usePMECUDA because of non-orthorhombic periodic cell.\n" << endi;
03964      //   }
03965      // }
03966 #else
03967      PMEOffload = 0;
03968 #endif
03969    } else {  // initialize anyway
03970      useDPME = 0;
03971      PMEGridSizeX = 0;
03972      PMEGridSizeY = 0;
03973      PMEGridSizeZ = 0;
03974      PMEGridSpacing = 1000.;
03975      PMEEwaldCoefficient = 0;
03976      PMEOffload = 0;
03977    }
03978 
03979    //  Take care of initializing FMA values to something if FMA is not
03980    //  active
03981    if (!FMAOn)
03982    {
03983      FMALevels = 0;
03984      FMAMp = 0;
03985      FMAFFTOn = FALSE;
03986      FMAFFTBlock = 0;
03987    }
03988    else
03989    {
03990   // idiot checking: frm bug reported by Tom Bishop.
03991   // DPMTA requires: (#terms in fma)/(fft blocking factor) = integer.
03992   if (FMAFFTBlock != 4)
03993     NAMD_die("FMAFFTBlock: Block length must be 4 for short FFT's");
03994   if (FMAMp % FMAFFTBlock != 0)
03995     NAMD_die("FMAMp: multipole term must be multiple of block length (FMAFFTBlock)");
03996     }
03997 
03998    if ( (nonbondedFrequency > stepsPerCycle) || ( (stepsPerCycle % nonbondedFrequency) != 0) )
03999    {
04000      NAMD_die("stepsPerCycle must be a multiple of nonbondedFreq");
04001    }
04002 
04003    if (!LCPOOn && !GBISOn && !GBISserOn && !FMAOn && !PMEOn && !MSMOn && !fullDirectOn && !FMMOn)
04004    {
04005      fullElectFrequency = 0;
04006    }
04007    else
04008    {
04009      if (!opts.defined("fullElectFrequency"))
04010      {
04011        if (opts.defined("fmaFrequency")) {
04012          iout << iWARN << "The parameter fmaFrequency has been renamed fullElectFrequency.\n" << endi;
04013          fullElectFrequency = fmaFrequency;
04014        } else {
04015          iout << iWARN << "The parameter fullElectFrequency now defaults to nonbondedFreq (" << nonbondedFrequency << ") rather than stepsPerCycle.\n" << endi;
04016          fullElectFrequency = nonbondedFrequency;
04017        }
04018      }
04019      else
04020      {
04021        if (opts.defined("fmaFrequency")) {
04022          iout << iWARN << "Ignoring redundant parameter fmaFrequency in favor of fullElectFrequency.\n" << endi;
04023        }
04024        if ( (fullElectFrequency > stepsPerCycle) || ( (stepsPerCycle % fullElectFrequency) != 0) )
04025        {
04026          NAMD_die("stepsPerCycle must be a multiple of fullElectFrequency");
04027        }
04028      }
04029 
04030      if ( (nonbondedFrequency > fullElectFrequency) || ( (fullElectFrequency % nonbondedFrequency) != 0) )
04031      {
04032        NAMD_die("fullElectFrequency must be a multiple of nonbondedFreq");
04033      }
04034 
04035       if (multigratorOn) {
04036         if ( (multigratorTemperatureFreq > multigratorPressureFreq) || ( (multigratorPressureFreq % multigratorTemperatureFreq) != 0) )
04037         {
04038           NAMD_die("multigratorTemperatureFreq must be a multiple of multigratorPressureFreq");
04039         }
04040         if ( (fullElectFrequency > multigratorTemperatureFreq) || ( (multigratorTemperatureFreq % fullElectFrequency) != 0) )
04041         {
04042           NAMD_die("fullElectFrequency must be a multiple of multigratorTemperatureFreq");
04043         }
04044         if (multigratorNoseHooverChainLength <= 2) {
04045           NAMD_die("multigratorNoseHooverChainLength must be greater than 2");
04046         }
04047       }
04048 
04049      if (!opts.defined("fmaTheta"))
04050      fmaTheta=0.715;  /* Suggested by Duke developers */
04051    }
04052 
04053    if ( lesOn && ( FMAOn || useDPME || fullDirectOn ) ) {
04054      NAMD_die("Sorry, LES is only implemented for PME full electrostatics.");
04055    }
04056    if ( alchFepOn && ( FMAOn || useDPME || fullDirectOn ) ) {
04057      NAMD_die("Sorry, FEP is only implemented for PME full electrostatics.");
04058    }
04059    if ( alchThermIntOn && ( FMAOn || useDPME || fullDirectOn ) ) {
04060      NAMD_die("Sorry, TI is only implemented for PME full electrostatics.");
04061    }
04062    if ( pairInteractionOn && FMAOn ) {
04063      NAMD_die("Sorry, pairInteraction not implemented for FMA.");
04064    }
04065    if ( pairInteractionOn && useDPME ) {
04066      NAMD_die("Sorry, pairInteraction not implemented for DPME.");
04067    }
04068    if ( pairInteractionOn && fullDirectOn ) {
04069      NAMD_die("Sorry, pairInteraction not implemented for full direct electrostatics.");
04070    }
04071    if ( ! pairInteractionOn ) {
04072      pairInteractionSelf = 0;
04073    }
04074    if ( pairInteractionOn && !pairInteractionSelf && !config->find("pairInteractionGroup2")) 
04075      NAMD_die("pairInteractionGroup2 must be specified");
04076 
04077    if ( ! fixedAtomsOn ) {
04078      fixedAtomsForces = 0;
04079    }
04080 
04081    if ( gridforceOn || mgridforceOn ) {
04082      parse_mgrid_params(config);
04083    }
04084       
04085    if (!opts.defined("constraints"))
04086    {
04087      constraintExp = 0;     
04088      constraintScaling = 1.0;     
04089 
04090      //****** BEGIN selective restraints (X,Y,Z) changes
04091      selectConstraintsOn = FALSE;
04092      //****** END selective restraints (X,Y,Z) changes
04093  
04094      //****** BEGIN moving constraints changes 
04095      movingConstraintsOn = FALSE;
04096      //****** END moving constraints changes 
04097      //****** BEGIN rotating constraints changes 
04098      rotConstraintsOn = FALSE;
04099     //****** END rotating constraints changes 
04100    } 
04101    //****** BEGIN rotating constraints changes 
04102    else {
04103      if (rotConstraintsOn) {
04104        rotConsAxis = rotConsAxis.unit();
04105      }
04106    }
04107    if(opts.defined("rotConstraints") 
04108       && opts.defined("movingConstraints")) {
04109      NAMD_die("Rotating and moving constraints are mutually exclusive!");
04110    }
04111    //****** END rotating constraints changes 
04112 
04113    //****** BEGIN selective restraints (X,Y,Z) changes
04114    if(opts.defined("selectConstraints") && !opts.defined("selectConstrX")
04115       && !opts.defined("selectConstrY") && !opts.defined("selectConstrZ")) {
04116      NAMD_die("selectConstraints was specified, but no Cartesian components were defined!");
04117    }
04118    if (!opts.defined("selectConstraints")) {
04119        constrXOn = FALSE;
04120        constrYOn = FALSE;
04121        constrZOn = FALSE;
04122    }
04123    //****** END selective restraints (X,Y,Z) changes
04124 
04125 
04126    //****** BEGIN SMD constraints changes 
04127    
04128    if (!opts.defined("SMD")) {     
04129      SMDOn = FALSE;
04130    }
04131 
04132    if (SMDOn) {
04133      // normalize direction
04134      if (SMDDir.length2() == 0) {
04135        NAMD_die("SMD direction vector must be non-zero");
04136      }
04137      else {
04138        SMDDir = SMDDir.unit();
04139      }
04140 
04141      if (SMDOutputFreq > 0 && SMDOutputFreq < stepsPerCycle
04142          || SMDOutputFreq % stepsPerCycle != 0) {
04143        NAMD_die("SMDOutputFreq must be a multiple of stepsPerCycle");
04144      }
04145    }
04146      
04147    //****** END SMD constraints changes 
04148    
04149    if (!sphericalBCOn)
04150      {
04151   sphericalBCr1 = 0.0;
04152   sphericalBCk1 = 0.0;
04153   sphericalBCexp1 = 0;
04154   sphericalBCr2 = 0.0;
04155   sphericalBCk2 = 0.0;
04156   sphericalBCexp2 = 0;
04157    }
04158    else if (!opts.defined("sphericalBCr2"))
04159    {
04160       sphericalBCr2 = -1.0;
04161       sphericalBCk2 = 0.0;
04162       sphericalBCexp2 = 0;
04163    }
04164 
04165    if (!cylindricalBCOn)
04166    {
04167     cylindricalBCr1 = 0.0;
04168     cylindricalBCk1 = 0.0;
04169     cylindricalBCexp1 = 0;
04170     cylindricalBCr2 = 0.0;
04171     cylindricalBCk2 = 0.0;
04172     cylindricalBCexp2 = 0;
04173     cylindricalBCl1 = 0.0;
04174     cylindricalBCl2 = 0.0;
04175    }
04176    else if (!opts.defined("cylindricalBCr2"))
04177    {
04178     cylindricalBCr2 = -1.0;
04179     cylindricalBCk2 = 0.0;
04180     cylindricalBCexp2 = 0;
04181     cylindricalBCl2 = 0.0;
04182    }
04183 
04184    if (!eFieldOn)
04185    {
04186         eField.x = 0.0;
04187         eField.y = 0.0;
04188         eField.z = 0.0;
04189         eFieldFreq = 0.0;
04190         eFieldPhase = 0.0;
04191    }
04192    else
04193    {
04194         if (!opts.defined("eFieldFreq")) eFieldFreq = 0.0;
04195         if (!opts.defined("eFieldPhase")) eFieldPhase = 0.0;
04196    }
04197 
04198    if (!stirOn)
04199    { 
04200      stirFilename[0] = STRINGNULL;
04201      stirStartingTheta = 0.0;
04202      stirVel = 0.0;
04203      stirK = 0.0;
04204      stirAxis.x = 0.0;
04205      stirAxis.y = 0.0;
04206      stirAxis.z = 0.0;
04207      stirPivot.x = 0.0;
04208      stirPivot.y = 0.0;
04209      stirPivot.z = 0.0;
04210    }
04211   
04212    if (!opts.defined("langevin"))
04213    {
04214   langevinTemp = 0.0;
04215    }
04216    
04217    // BEGIN LA
04218    if (!opts.defined("loweAndersen"))
04219    {
04220        loweAndersenTemp = 0.0;
04221    }
04222    // END LA
04223 
04224    if (!opts.defined("tcouple"))
04225    {
04226   tCoupleTemp = 0.0;
04227    }
04228 
04229    if (HydrogenBonds)
04230    {
04231      if (daCutoffDist > pairlistDist)
04232        NAMD_die("Hydrogen bond cutoff distance must be <= pairlist distance");
04233    }
04234 
04235    // If we're doing pair interaction, set 
04236    // outputEnergies to 1 to make NAMD not die (the other nonbonded code paths 
04237    // aren't defined when these options are enabled), and set nonbondedFreq to 
04238    // 1 to avoid getting erroneous output.  Warn the user of what we're doing.
04239    if (pairInteractionOn) {
04240            if (outputEnergies != 1) {
04241                    iout << iWARN << "Setting outputEnergies to 1 due to\n";
04242                    iout << iWARN << "pairInteraction calculations\n" << endi;
04243                    outputEnergies  = 1;
04244            }
04245    }
04246    if (pairInteractionOn || pressureProfileOn) {
04247            if (nonbondedFrequency != 1) {
04248                    iout << iWARN << "Setting nonbondedFreq to 1 due to\n";
04249                    iout << iWARN << "pairInteraction or pressure profile calculations\n" << endi;
04250            }
04251    }
04252 
04253    // print timing at a reasonable interval by default
04254    if (!opts.defined("outputTiming"))
04255    {
04256       outputTiming = firstLdbStep;
04257       int ot2 = 10 * outputEnergies;
04258       if ( outputTiming < ot2 ) outputTiming = ot2;
04259    }
04260 
04261     // Checks if a secondary process was added in the configuration, and sets
04262     // the appropriated variable
04263     if(qmForcesOn){
04264         
04265         if (opts.defined("QMSecProc")){
04266             qmSecProcOn = true;
04267         }
04268         else {
04269             qmSecProcOn = false;
04270         }
04271         
04272         if (opts.defined("qmPrepProc")){
04273             qmPrepProcOn = true;
04274         }
04275         else {
04276             qmPrepProcOn = false;
04277         }
04278         
04279         if (opts.defined("QMParamPDB")){
04280             qmParamPDBDefined = true;
04281         }
04282         else {
04283             qmParamPDBDefined = false;
04284         }
04285         
04286         if (opts.defined("QMBondColumn")){
04287             qmBondOn = true;
04288         }
04289         else {
04290             qmBondOn = false;
04291         }
04292         
04293         if ( strcasecmp(qmSoftware,"orca") != 0 &&
04294              strcasecmp(qmSoftware,"mopac") != 0 &&
04295              strcasecmp(qmSoftware,"custom") != 0 ) {
04296             NAMD_die("Available QM software options are \'mopac\', \'orca\', or \'custom\'.");
04297         }
04298         else {
04299             if ( strcasecmp(qmSoftware,"orca") == 0 ) 
04300                 qmFormat = QMFormatORCA;
04301             if ( strcasecmp(qmSoftware,"mopac") == 0 ) 
04302                 qmFormat = QMFormatMOPAC;
04303             if ( strcasecmp(qmSoftware,"custom") == 0 ) 
04304                 qmFormat = QMFormatUSR;
04305             
04306             if (qmFormat == QMFormatORCA || qmFormat == QMFormatMOPAC) {
04307                 
04308                 if (! opts.defined("QMConfigLine"))
04309                     NAMD_die("If the selected QM software is \'mopac\' or \'orca\'\
04310 , QMConfigLine needs to be defined.");
04311                 
04312             }
04313         }
04314         
04315         qmChrgMode = QMCHRGMULLIKEN;
04316         if (opts.defined("QMChargeMode")) {
04317             if ( strcasecmp(qmChrgModeS,"none") != 0 &&
04318                  strcasecmp(qmChrgModeS,"mulliken") != 0 &&
04319                  strcasecmp(qmChrgModeS,"chelpg") != 0) {
04320                 NAMD_die("Available charge options are \'none\', \'mulliken\' or \'chelpg\'.");
04321             }
04322             else {
04323                 if ( strcasecmp(qmChrgModeS,"none") == 0 ) 
04324                     qmChrgMode = QMCHRGNONE;
04325                 if ( strcasecmp(qmChrgModeS,"mulliken") == 0 ) 
04326                     qmChrgMode = QMCHRGMULLIKEN;
04327                 if ( strcasecmp(qmChrgModeS,"chelpg") == 0 ) 
04328                     qmChrgMode = QMCHRGCHELPG;
04329             }
04330         }
04331         
04332         if (qmFormat == QMFormatMOPAC && qmChrgMode == QMCHRGCHELPG)
04333             NAMD_die("Available charge options for MOPAC are \'none\' and \'mulliken\'.");
04334         
04335         if (qmFormat == QMFormatUSR && qmChrgMode == QMCHRGCHELPG)
04336             NAMD_die("Available charge options for MOPAC are \'none\' and \'mulliken\'.");
04337         
04338         if (qmBondOn && (opts.defined("QMBondValueType"))) {
04339             if ( strcasecmp(qmBondValueTypeS,"len") != 0 &&
04340                 strcasecmp(qmBondValueTypeS,"ratio") != 0 ) {
04341                 NAMD_die("Available QM bond value type options are \'len\' or \'ratio\'.");
04342             }
04343             else {
04344     //         #define QMLENTYPE 1
04345     //         #define QMRATIOTYPE 2
04346                 if ( strcasecmp(qmBondValueTypeS,"len") == 0 ) 
04347                     qmBondValType = 1;
04348                 if ( strcasecmp(qmBondValueTypeS,"ratio") == 0 ) 
04349                     qmBondValType = 2;
04350             }
04351         }
04352         else if (qmBondOn && ! (opts.defined("QMBondValueType")))
04353             qmBondValType = 1;
04354         
04355         if ( strcmp(qmColumn,"beta") != 0 &&
04356              strcmp(qmColumn,"occ") != 0 ) {
04357             NAMD_die("Available column options are \'beta\' and \'occ\'.");
04358         }
04359         
04360         if (qmBondOn) {
04361             if ( strcmp(qmBondColumn,"beta") != 0 &&
04362                  strcmp(qmBondColumn,"occ") != 0 ) {
04363                 NAMD_die("Available column options are \'beta\' and \'occ\'.");
04364             }
04365             
04366             if (strcmp(qmBondColumn,qmColumn) == 0)
04367                 NAMD_die("QM column and bond-column must be different!");
04368         }
04369         
04370         qmBondScheme = 1;
04371         if (opts.defined("QMBondScheme")) {
04372             if ( strcasecmp(qmBondSchemeS,"CS") == 0 )
04373                 qmBondScheme = QMSCHEMECS;
04374             if ( strcasecmp(qmBondSchemeS,"RCD") == 0 )
04375                 qmBondScheme = QMSCHEMERCD;
04376             if ( strcasecmp(qmBondSchemeS,"Z1") == 0 )
04377                 qmBondScheme = QMSCHEMEZ1;
04378             if ( strcasecmp(qmBondSchemeS,"Z2") == 0 )
04379                 qmBondScheme = QMSCHEMEZ2;
04380             if ( strcasecmp(qmBondSchemeS,"Z3") == 0 )
04381                 qmBondScheme = QMSCHEMEZ3;
04382         }
04383         
04384 //         #define QMPCSCHEMENONE 1
04385 //         #define QMPCSCHEMEROUND 2
04386 //         #define QMPCSCHEMEZERO 3
04387         qmPCScheme = 1;
04388         if (opts.defined("QMPointChargeScheme") && qmPCSwitchOn) {
04389             if ( strcasecmp(qmPCSchemeS,"none") == 0 )
04390                 qmPCScheme = 1;
04391             
04392             if ( strcasecmp(qmPCSchemeS,"round") == 0 )
04393                 qmPCScheme = 2;
04394             if ( strcasecmp(qmPCSchemeS,"zero") == 0 )
04395                 qmPCScheme = 3;
04396             
04397             if ( qmPCScheme > 1 && ! qmPCSwitchOn)
04398                 NAMD_die("QM Charge Schemes \'round\' or \'zero\' can only be applied with QMswitching set to \'on\'!");
04399         }
04400         
04401         // Redundant option to deprecate "qmNoPC" option.
04402         if (qmElecEmbed)
04403             qmNoPC = FALSE;
04404         
04405 //         #define QMLSSMODEDIST 1
04406 //         #define QMLSSMODECOM 2
04407         if (qmLSSOn) {
04408             
04409             if (qmNoPC)
04410                 NAMD_die("QM Live Solvent Selection cannot be done with QMNoPntChrg set to \'on\'!") ;
04411             
04412             if (rigidBonds != RIGID_NONE)
04413                 NAMD_die("QM Live Solvent Selection cannot be done with fixed bonds!") ;
04414             
04415             if (qmLSSFreq % qmPCSelFreq != 0)
04416                 NAMD_die("Frequency of QM solvent update must be a multiple of frequency of point charge selection.");
04417             
04418             if (qmLSSFreq % stepsPerCycle != 0)
04419                 NAMD_die("Frequency of QM solvent update must be a multiple of steps per cycle.");
04420             
04421             if (opts.defined("QMLSSMode") ) {
04422                 if ( strcasecmp(qmLSSModeS,"dist") != 0 &&
04423                      strcasecmp(qmLSSModeS,"COM") != 0 ) {
04424                     NAMD_die("Available LSS mode options are \'dist\' and \'COM\'.");
04425                 }
04426                 if ( strcasecmp(qmLSSModeS,"dist") == 0 )
04427                     qmLSSMode = 1;
04428                 else if ( strcasecmp(qmLSSModeS,"COM") == 0 )
04429                     qmLSSMode = 2;
04430             }
04431             else
04432                 qmLSSMode = 1;
04433         }
04434         
04435 //         #define QMPCSCALESHIFT 1
04436 //         #define QMPCSCALESWITCH 2
04437         if (qmPCSwitchOn) {
04438             
04439             if (opts.defined("QMSwitchingType") ) {
04440                 if ( strcasecmp(qmPCSwitchTypeS,"shift") != 0 &&
04441                      strcasecmp(qmPCSwitchTypeS,"switch") != 0 ) {
04442                     NAMD_die("Available scaling options are \'shift\' and \'switch\'.");
04443                 }
04444                 if ( strcasecmp(qmPCSwitchTypeS,"shift") == 0 )
04445                     qmPCSwitchType = 1;
04446                 else if ( strcasecmp(qmPCSwitchTypeS,"switch") == 0 )
04447                     qmPCSwitchType = 2;
04448             }
04449             else
04450                 qmPCSwitchType = 1;
04451         }
04452         
04453         if (qmNoPC && qmPCSelFreq > 1) {
04454             iout << iWARN << "QMPCStride being IGNORED since QMNoPntChrg is set to \'on\'!\n" << endi;
04455             qmPCSelFreq = 1;
04456         }
04457         
04458         if (qmNoPC && qmPCSwitchOn)
04459             NAMD_die("QM PC switching can only be applied with QMNoPntChrg set to \'off\'!");
04460         
04461 //         if (qmNoPC && qmBondOn)
04462 //             NAMD_die("QM-MM bonds can only be applied with QMNoPntChrg set to \'off\'!");
04463         
04464         if (qmPCSelFreq <= 0)
04465             NAMD_die("QMPCFreq can only be a positive number! For static point charge selection, see QMCutomPC.");
04466         
04467         if (qmCustomPCSel && qmNoPC)
04468             NAMD_die("QM Custom PC Selection is incompatible with QMNoPntChrg!");
04469         
04470 //         if (qmCustomPCSel && qmPCSwitchOn)
04471 //             NAMD_die("QM Custom PC Selection is incompatible with QMSwitching!");
04472         
04473         if (qmCustomPCSel && qmPCSelFreq > 1)
04474             NAMD_die("QM Custom PC Selection is incompatible with QMPCStride > 1!");
04475         
04476         if (qmCSMD && (! opts.defined("QMCSMDFile") ))
04477             NAMD_die("QM Conditional SMD is ON, but no CSMD configuration file was profided!");
04478     }
04479 }
04480 
04481 void SimParameters::print_config(ParseOptions &opts, ConfigList *config, char *&cwd) {
04482 
04483    StringList *current; //  Pointer to config option list
04484 
04485    //  Now that we have read everything, print it out so that
04486    //  the user knows what is going on
04487    iout << iINFO << "SIMULATION PARAMETERS:\n";
04488    iout << iINFO << "TIMESTEP               " << dt << "\n" << endi;
04489    iout << iINFO << "NUMBER OF STEPS        " << N << "\n";
04490    iout << iINFO << "STEPS PER CYCLE        " << stepsPerCycle << "\n";
04491    iout << endi;
04492 
04493    if ( lattice.a_p() || lattice.b_p() || lattice.c_p() ) {
04494      if ( lattice.a_p() )
04495        iout << iINFO << "PERIODIC CELL BASIS 1  " << lattice.a() << "\n";
04496      if ( lattice.b_p() )
04497        iout << iINFO << "PERIODIC CELL BASIS 2  " << lattice.b() << "\n";
04498      if ( lattice.c_p() )
04499        iout << iINFO << "PERIODIC CELL BASIS 3  " << lattice.c() << "\n";
04500      iout << iINFO << "PERIODIC CELL CENTER   " << lattice.origin() << "\n";
04501      if (wrapWater) {
04502        iout << iINFO << "WRAPPING WATERS AROUND PERIODIC BOUNDARIES ON OUTPUT.\n";
04503      }
04504      if (wrapAll) {
04505        iout << iINFO << "WRAPPING ALL CLUSTERS AROUND PERIODIC BOUNDARIES ON OUTPUT.\n";
04506      }
04507      if (wrapNearest) {
04508        iout << iINFO << "WRAPPING TO IMAGE NEAREST TO PERIODIC CELL CENTER.\n";
04509      }
04510      iout << endi;
04511    }
04512 
04513    if ( CkNumPes() > 512 ) ldbUnloadOne = TRUE;
04514    if ( ldbUnloadOne || CkNumPes() > 128 ) ldbUnloadZero = TRUE;
04515 
04516    if (ldBalancer == LDBAL_NONE) {
04517      iout << iINFO << "LOAD BALANCER  None\n" << endi;
04518    } else {
04519      if (ldBalancer == LDBAL_CENTRALIZED) {
04520        iout << iINFO << "LOAD BALANCER  Centralized\n" << endi;
04521      } else if (ldBalancer == LDBAL_HYBRID) {
04522        iout << iINFO << "LOAD BALANCER  Hybrid\n" << endi;
04523      }
04524 
04525      if (ldbStrategy == LDBSTRAT_DEFAULT) {
04526        iout << iINFO << "LOAD BALANCING STRATEGY  New Load Balancers -- DEFAULT\n";
04527      } else if (ldbStrategy == LDBSTRAT_REFINEONLY) {
04528        iout << iINFO << "LOAD BALANCING STRATEGY  Refinement Only\n";
04529      } else if (ldbStrategy == LDBSTRAT_COMPREHENSIVE) {
04530        iout << iINFO << "LOAD BALANCING STRATEGY  Comprehensive\n";
04531      } else if (ldbStrategy == LDBSTRAT_OLD) {
04532        iout << iINFO << "LOAD BALANCING STRATEGY  Old Load Balancers\n";
04533      }
04534 
04535      iout << iINFO << "LDB PERIOD             " << ldbPeriod << " steps\n";
04536      iout << iINFO << "FIRST LDB TIMESTEP     " << firstLdbStep << "\n";
04537      if (ldBalancer == LDBAL_HYBRID)
04538        iout << iINFO << "HYBRIDLB GROUP SIZE     " << hybridGroupSize << "\n";
04539      iout << iINFO << "LAST LDB TIMESTEP     " << lastLdbStep << "\n";
04540      if ( ldbRelativeGrainsize > 0. )
04541        iout << iINFO << "LDB RELATIVE GRAINSIZE " << ldbRelativeGrainsize << "\n";
04542      iout << iINFO << "LDB BACKGROUND SCALING " << ldbBackgroundScaling << "\n";
04543      iout << iINFO << "HOM BACKGROUND SCALING " << ldbHomeBackgroundScaling << "\n";
04544      if ( PMEOn ) {
04545        iout << iINFO << "PME BACKGROUND SCALING "
04546                                 << ldbPMEBackgroundScaling << "\n";
04547      if ( ldbUnloadPME )
04548      iout << iINFO << "REMOVING LOAD FROM PME NODES" << "\n";
04549      }
04550      if ( ldbUnloadZero ) iout << iINFO << "REMOVING LOAD FROM NODE 0\n";
04551      if ( ldbUnloadOne ) iout << iINFO << "REMOVING LOAD FROM NODE 1\n";
04552      if ( ldbUnloadOutputPEs ) iout << iINFO << "REMOVING LOAD FROM OUTPUT PES\n";
04553      iout << endi;
04554    }
04555 
04556    if ( ldbUnloadOne || CkNumPes() > 256 ) noPatchesOnOne = TRUE;
04557    if ( ldbUnloadZero || noPatchesOnOne ||
04558           CkNumPes() > 64 || ( IMDon && CkNumPes() > 8 ) ) {
04559      noPatchesOnZero = TRUE;
04560    }
04561    if ( noPatchesOnZero ) iout << iINFO << "REMOVING PATCHES FROM PROCESSOR 0\n";
04562    if ( noPatchesOnOne ) iout << iINFO << "REMOVING PATCHES FROM PROCESSOR 1\n";     
04563    iout << endi;
04564 
04565 #if defined(NAMD_CUDA) || defined(NAMD_MIC)
04566     maxSelfPart = maxPairPart = 1;
04567 #endif
04568 
04569    if (ldBalancer == LDBAL_HYBRID) {
04570      iout << iINFO << "MAX SELF PARTITIONS    " << maxSelfPart << "\n"
04571           << iINFO << "MAX PAIR PARTITIONS    " << maxPairPart << "\n"
04572           << iINFO << "SELF PARTITION ATOMS   " << numAtomsSelf << "\n"
04573           << iINFO << "SELF2 PARTITION ATOMS   " << numAtomsSelf2 << "\n"
04574           << iINFO << "PAIR PARTITION ATOMS   " << numAtomsPair << "\n"
04575           << iINFO << "PAIR2 PARTITION ATOMS  " << numAtomsPair2 << "\n";
04576    }
04577    iout << iINFO << "MIN ATOMS PER PATCH    " << minAtomsPerPatch << "\n"
04578         << endi;
04579    
04580    if (initialTemp < 0)
04581    {
04582   current = config->find("velocities");
04583 
04584   if (current == NULL)
04585   {
04586     current = config->find("binvelocities");
04587   }
04588 
04589   iout << iINFO << "VELOCITY FILE          " << current->data << "\n";
04590    }
04591    else
04592    {
04593   iout << iINFO << "INITIAL TEMPERATURE    " 
04594      << initialTemp << "\n";
04595    }
04596    iout << endi;
04597 
04598    iout << iINFO << "CENTER OF MASS MOVING INITIALLY? ";
04599 
04600    if (comMove)
04601    {
04602      iout << "YES\n";
04603    }
04604    else
04605    {
04606      iout << "NO\n";
04607    }
04608    iout << endi;
04609 
04610    if ( zeroMomentum ) {
04611      iout << iINFO << "REMOVING CENTER OF MASS DRIFT DURING SIMULATION";
04612      if ( zeroMomentumAlt ) iout << " (ALT METHOD)";
04613      iout << "\n" << endi;
04614    }
04615 
04616    iout << iINFO << "DIELECTRIC             " 
04617       << dielectric << "\n";
04618 
04619    if ( nonbondedScaling != 1.0 )
04620    {
04621      iout << iINFO << "NONBONDED SCALING    " << nonbondedScaling << "\n" << endi;
04622    }
04623    iout << iINFO << "EXCLUDE                ";
04624 
04625    switch (exclude)
04626    {
04627      case NONE:
04628        iout << "NONE\n";
04629        break;
04630      case ONETWO:
04631        iout << "ONETWO\n";
04632        break;
04633      case ONETHREE:
04634        iout << "ONETHREE\n";
04635        break;
04636      case ONEFOUR:
04637        iout << "ONE-FOUR\n";
04638        break;
04639      default:
04640        iout << "SCALED ONE-FOUR\n";
04641        break;
04642    }
04643    iout << endi;
04644 
04645    if (exclude == SCALED14)
04646    {
04647      iout << iINFO << "1-4 ELECTROSTATICS SCALED BY " << scale14 << "\n";
04648      iout << iINFO << "MODIFIED 1-4 VDW PARAMETERS WILL BE USED\n" << endi;
04649    } else {
04650      iout << iWARN << "MODIFIED 1-4 VDW PARAMETERS WILL BE IGNORED\n" << endi;
04651    }
04652 
04653 #ifdef SPEC_DISABLED_VERSION
04654    if (dcdFrequency > 0) {
04655      dcdFrequency = 0;
04656      iout << iWARN << "DCD TRAJECTORY OUTPUT IS DISABLED IN SPEC RELEASE\n";
04657    }
04658 #endif
04659 
04660    if (dcdFrequency > 0)
04661    {
04662      iout << iINFO << "DCD FILENAME           " 
04663         << dcdFilename << "\n";
04664      iout << iINFO << "DCD FREQUENCY          " 
04665         << dcdFrequency << "\n";
04666      iout << iINFO << "DCD FIRST STEP         " 
04667         << ( ((firstTimestep + dcdFrequency)/dcdFrequency)*dcdFrequency ) << "\n";
04668      if ( dcdUnitCell ) {
04669        iout << iINFO << "DCD FILE WILL CONTAIN UNIT CELL DATA\n";
04670      }
04671    }
04672    else
04673    {
04674      iout << iINFO << "NO DCD TRAJECTORY OUTPUT\n";
04675    }
04676    iout << endi;
04677    
04678    if (xstFrequency > 0)
04679    {
04680      iout << iINFO << "XST FILENAME           " 
04681         << xstFilename << "\n";
04682      iout << iINFO << "XST FREQUENCY          " 
04683         << xstFrequency << "\n";
04684    }
04685    else
04686    {
04687      iout << iINFO << "NO EXTENDED SYSTEM TRAJECTORY OUTPUT\n";
04688    }
04689    iout << endi;
04690    
04691    if (velDcdFrequency > 0)
04692    {
04693      iout << iINFO << "VELOCITY DCD FILENAME    " 
04694         << velDcdFilename << "\n";
04695      iout << iINFO << "VELOCITY DCD FREQUENCY   " 
04696         << velDcdFrequency << "\n";
04697      iout << iINFO << "VELOCITY DCD FIRST STEP  " 
04698         << ( ((firstTimestep + velDcdFrequency)/velDcdFrequency)*velDcdFrequency ) << "\n";
04699    }
04700    else
04701    {
04702      iout << iINFO << "NO VELOCITY DCD OUTPUT\n";
04703    }
04704    iout << endi;
04705    
04706    if (forceDcdFrequency > 0)
04707    {
04708      iout << iINFO << "FORCE DCD FILENAME     " 
04709         << forceDcdFilename << "\n";
04710      iout << iINFO << "FORCE DCD FREQUENCY    " 
04711         << forceDcdFrequency << "\n";
04712      iout << iINFO << "FORCE DCD FIRST STEP   " 
04713         << ( ((firstTimestep + forceDcdFrequency)/forceDcdFrequency)*forceDcdFrequency ) << "\n";
04714    }
04715    else
04716    {
04717      iout << iINFO << "NO FORCE DCD OUTPUT\n";
04718    }
04719    iout << endi;
04720    
04721    iout << iINFO << "OUTPUT FILENAME        " 
04722       << outputFilename << "\n" << endi;
04723    if (binaryOutput)
04724    {
04725      iout << iINFO << "BINARY OUTPUT FILES WILL BE USED\n" << endi;
04726    }
04727 #ifdef MEM_OPT_VERSION
04728     if(!binaryOutput){
04729         iout << iWARN <<"SINCE MEMORY OPTIMIZED VERSION IS USED, OUTPUT IN TEXT FORMAT IS DISABLED!\n" << endi;
04730         binaryOutput = TRUE;
04731     }
04732 #endif
04733 
04734    if (! restartFrequency)
04735    {
04736      iout << iINFO << "NO RESTART FILE\n";
04737    }
04738    else
04739    {
04740      iout << iINFO << "RESTART FILENAME       "
04741         << restartFilename << "\n";
04742      iout << iINFO << "RESTART FREQUENCY      " 
04743         << restartFrequency << "\n";
04744   if (restartSave) {
04745     iout << iINFO << "RESTART FILES WILL NOT BE OVERWRITTEN\n";
04746   }
04747   if (restartSaveDcd) {
04748     iout << iINFO << "DCD FILE WILL BE SPLIT WHEN RESTART FILES ARE WRITTEN\n";
04749   }
04750 
04751   if (binaryRestart)
04752   {
04753     iout << iINFO << "BINARY RESTART FILES WILL BE USED\n";
04754   }
04755    }
04756    iout << endi;
04757    
04758    if (switchingActive)
04759    {
04760       iout << iINFO << "SWITCHING ACTIVE\n";
04761       if ( vdwForceSwitching ) {
04762         iout << iINFO << "VDW FORCE SWITCHING ACTIVE\n";
04763       }
04764       if ( martiniSwitching ) { 
04765         iout << iINFO << "MARTINI RESIDUE-BASED COARSE-GRAIN SWITCHING ACTIVE\n";
04766       }
04767       iout << iINFO << "SWITCHING ON           "
04768                << switchingDist << "\n";
04769       iout << iINFO << "SWITCHING OFF          "
04770                << cutoff << "\n";
04771    }
04772    else
04773    {
04774       iout << iINFO << "CUTOFF                 " 
04775          << cutoff << "\n";
04776    }
04777 
04778    iout << iINFO << "PAIRLIST DISTANCE      " << pairlistDist << "\n";
04779    iout << iINFO << "PAIRLIST SHRINK RATE   " << pairlistShrink << "\n";
04780    iout << iINFO << "PAIRLIST GROW RATE     " << pairlistGrow << "\n";
04781    iout << iINFO << "PAIRLIST TRIGGER       " << pairlistTrigger << "\n";
04782    iout << iINFO << "PAIRLISTS PER CYCLE    " << pairlistsPerCycle << "\n";
04783    if ( outputPairlists )
04784      iout << iINFO << "PAIRLIST OUTPUT STEPS  " << outputPairlists << "\n";
04785    iout << endi;
04786 
04787    if ( pairlistMinProcs > 1 )
04788      iout << iINFO << "REQUIRING " << pairlistMinProcs << " PROCESSORS FOR PAIRLISTS\n";
04789    usePairlists = ( CkNumPes() >= pairlistMinProcs );
04790 
04791 #ifdef OPENATOM_VERSION
04792 if ( openatomOn ) 
04793 {
04794   iout << iINFO << "OPENATOM QM/MM CAR-PARINELLO ACTIVE\n";
04795   iout << iINFO << "OPENATOM CONFIG FILE:  " << openatomConfig << "\n";
04796   iout << iINFO << "OPENATOM STRUCT FILE:  " << openatomStruct << "\n";
04797   iout << iINFO << "OPENATOM PDB FILE:     " << openatomPDB << "\n";
04798 }
04799 #endif // OPENATOM_VERSION
04800 
04801    // FB - FEP and TI are now dependent on pairlists - disallow usePairlists=0
04802    if ( (alchOn) && (!usePairlists)) {
04803      NAMD_die("Sorry, Alchemical simulations require pairlists to be enabled\n");
04804    }
04805 #ifdef NAMD_CUDA
04806    if ( ! usePairlists ) {
04807      usePairlists = 1;
04808      iout << iINFO << "CUDA ACCELERATION REQUIRES PAIRLISTS\n";
04809    }
04810 #endif
04811      
04812    iout << iINFO << "PAIRLISTS " << ( usePairlists ? "ENABLED" : "DISABLED" )
04813                                                         << "\n" << endi;
04814 
04815    iout << iINFO << "MARGIN                 " << margin << "\n";
04816 
04817    if ( splitPatch == SPLIT_PATCH_HYDROGEN ) {
04818       iout << iINFO << "HYDROGEN GROUP CUTOFF  " << hgroupCutoff << "\n";
04819    }
04820    
04821    iout << iINFO << "PATCH DIMENSION        "
04822             << patchDimension << "\n";
04823 
04824    iout << endi;
04825 
04826    if (outputEnergies != 1)
04827    {
04828       iout << iINFO << "ENERGY OUTPUT STEPS    "
04829          << outputEnergies << "\n";
04830       iout << endi;
04831    }
04832 
04833    if (mergeCrossterms) {
04834       iout << iINFO << "CROSSTERM ENERGY INCLUDED IN DIHEDRAL\n" << endi;
04835    }
04836    
04837    if (outputMomenta != 0)
04838    {
04839       iout << iINFO << "MOMENTUM OUTPUT STEPS  "
04840          << outputMomenta << "\n";
04841       iout << endi;
04842    }
04843    
04844    if (outputTiming != 0)
04845    {
04846       iout << iINFO << "TIMING OUTPUT STEPS    "
04847          << outputTiming << "\n";
04848       iout << endi;
04849    }
04850    
04851    if (outputCudaTiming != 0)
04852    {
04853       iout << iINFO << "CUDA TIMING OUTPUT STEPS    "
04854          << outputCudaTiming << "\n";
04855       iout << endi;
04856    }
04857    
04858    if (outputPressure != 0)
04859    {
04860       iout << iINFO << "PRESSURE OUTPUT STEPS  "
04861          << outputPressure << "\n";
04862       iout << endi;
04863    }
04864    
04865    if (fixedAtomsOn)
04866    {
04867       iout << iINFO << "FIXED ATOMS ACTIVE\n";
04868       if ( fixedAtomsForces )
04869         iout << iINFO << "FORCES BETWEEN FIXED ATOMS ARE CALCULATED\n";
04870       iout << endi;
04871    }
04872 
04873    if (constraintsOn)
04874    {
04875       iout << iINFO << "HARMONIC CONSTRAINTS ACTIVE\n";
04876 
04877       iout << iINFO << "HARMONIC CONS EXP      "
04878          << constraintExp << "\n";
04879 
04880       if (constraintScaling != 1.0) {
04881         iout << iINFO << "HARMONIC CONS SCALING  "
04882          << constraintScaling << "\n";
04883       }
04884 
04885       //****** BEGIN selective restraints (X,Y,Z) changes 
04886 
04887       if (selectConstraintsOn) {
04888         iout << iINFO << "SELECTED CARTESIAN COMPONENTS OF HARMONIC RESTRAINTS ACTIVE\n";
04889 
04890         if (constrXOn)
04891         iout << iINFO << "RESTRAINING X-COMPONENTS OF CARTESIAN COORDINATES!\n";
04892 
04893         if (constrYOn)
04894         iout << iINFO << "RESTRAINING Y-COMPONENTS OF CARTESIAN COORDINATES!\n";
04895 
04896         if (constrZOn)
04897         iout << iINFO << "RESTRAINING Z-COMPONENTS OF CARTESIAN COORDINATES!\n";
04898       }
04899       //****** END selective restraints (X,Y,Z) changes 
04900 
04901       if (sphericalConstraintsOn) {
04902         iout << iINFO << "SPHERICAL HARMONIC CONSTRAINTS ACTIVE\n";
04903         iout << iINFO << "RESTRAINING DISTANCE TO " << sphericalConstrCenter <<"\n";
04904       }
04905       iout << endi;
04906 
04907       //****** BEGIN moving constraints changes 
04908 
04909       if (movingConstraintsOn) {
04910         iout << iINFO << "MOVING HARMONIC CONSTRAINTS ACTIVE\n";
04911 
04912         iout << iINFO << "MOVING CONSTRAINT VELOCITY    "
04913              << movingConsVel << " ANGSTROM/TIMESTEP\n";
04914         
04915         iout << iINFO << "ALL CONSTRAINED ATOMS WILL MOVE\n";
04916       }
04917       //****** END moving constraints changes 
04918       iout << endi;
04919 
04920       //****** BEGIN rotating constraints changes 
04921 
04922       if (rotConstraintsOn) {
04923         iout << iINFO << "ROTATING HARMONIC CONSTRAINTS ACTIVE\n";
04924 
04925         iout << iINFO << "AXIS OF ROTATION    "
04926              << rotConsAxis << "\n";
04927         
04928         iout << iINFO << "PIVOT OF ROTATION   "
04929              << rotConsPivot << "\n";
04930 
04931         iout << iINFO << "ROTATING CONSTRAINT VELOCITY    "
04932              << rotConsVel << " DEGREES/TIMESTEP\n";
04933       }
04934       iout << endi;
04935       //****** END rotating constraints changes 
04936    }
04937 
04938    // moving drag
04939    if (movDragOn) {
04940      iout << iINFO << "MOVING DRAG ACTIVE.\n";
04941      
04942      iout << iINFO << "MOVING DRAG MAIN PDB FILE "
04943           << movDragFile << "\n";
04944      
04945      iout << iINFO << "MOVING DRAG GLOBAL VELOCITY (A/step) "
04946           << movDragGlobVel << "\n";
04947      
04948      iout << iINFO << "MOVING DRAG LINEAR VELOCITY FILE " 
04949           << movDragVelFile << "\n";
04950      
04951      iout << endi;
04952    }
04953    
04954    // rotating drag
04955    if (rotDragOn) {
04956      iout << iINFO << "ROTATING DRAG ACTIVE.\n";
04957      
04958      iout << iINFO << "ROTATING DRAG MAIN PDB FILE "
04959           << rotDragFile << "\n";
04960      
04961      iout << iINFO << "ROTATING DRAG AXIS FILE " 
04962           << rotDragAxisFile << "\n";
04963      
04964      iout << iINFO << "ROTATING DRAG PIVOT POINT FILE " 
04965           << rotDragPivotFile << "\n";
04966      
04967      iout << iINFO << "ROTATING DRAG GLOBAL ANGULAR VELOCITY (deg/step) "
04968           << rotDragGlobVel << "\n";
04969      
04970      iout << iINFO << "ROTATING DRAG ANGULAR VELOCITY FILE " 
04971           << rotDragVelFile << "\n";
04972      
04973      iout << endi;
04974    }
04975    
04976 
04977    // "constant" torque
04978    if (consTorqueOn) {
04979      iout << iINFO << "\"CONSTANT\" TORQUE ACTIVE.\n";
04980      
04981      iout << iINFO << "\"CONSTANT\" TORQUE MAIN PDB FILE "
04982           << consTorqueFile << "\n";
04983      
04984      iout << iINFO << "\"CONSTANT\" TORQUE AXIS FILE " 
04985           << consTorqueAxisFile << "\n";
04986      
04987      iout << iINFO << "\"CONSTANT\" TORQUE PIVOT POINT FILE " 
04988           << consTorquePivotFile << "\n";
04989      
04990      iout << iINFO << "\"CONSTANT\" TORQUE GLOBAL VALUE (Kcal/(mol*A^2)) "
04991           << consTorqueGlobVal << "\n";
04992      
04993      iout << iINFO << "\"CONSTANT\" TORQUE DACTORS FILE " 
04994           << consTorqueValFile << "\n";
04995      
04996      iout << endi;
04997    }
04998 
04999    if (mgridforceOn) {
05000      iout << iINFO << "GRID FORCE ACTIVE\n";
05001      iout << iINFO << " Please include this reference in published work using\n";
05002      iout << iINFO << " the Gridforce module of NAMD: David Wells, Volha Abramkina,\n";
05003      iout << iINFO << " and Aleksei Aksimentiev, J. Chem. Phys. 127:125101-10 (2007).\n";
05004      print_mgrid_params();
05005    }
05006    
05007    //****** BEGIN SMD constraints changes 
05008    
05009    if (SMDOn) {
05010      iout << iINFO << "SMD ACTIVE\n";
05011      
05012      iout << iINFO << "SMD VELOCITY    "
05013           << SMDVel << " ANGSTROM/TIMESTEP\n";
05014         
05015      iout << iINFO << "SMD DIRECTION   "
05016           << SMDDir << "\n";
05017  
05018      iout << iINFO << "SMD K   " 
05019           << SMDk << "\n";
05020 
05021      iout << iINFO << "SMD K2  " 
05022           << SMDk2 << "\n";
05023 
05024      iout << iINFO << "SMD OUTPUT FREQUENCY   "
05025           << SMDOutputFreq << " TIMESTEPS\n";
05026     
05027      iout << iINFO << "SMD FILE " << SMDFile << "\n"; 
05028 
05029      iout << endi;
05030    }
05031    
05032    //****** END SMD constraints changes 
05033 
05034    if (TMDOn) {
05035      iout << iINFO << "TMD ACTIVE BETWEEN STEPS " << TMDFirstStep 
05036           << " and " << TMDLastStep << "\n";
05037      iout << iINFO << "TMD K  " << TMDk << "\n";
05038      iout << iINFO << "TMD FILE  " << TMDFile << "\n";
05039      iout << iINFO << "TMD OUTPUT FREQUENCY  " << TMDOutputFreq << "\n";
05040      if (TMDInitialRMSD) {
05041        iout << iINFO << "TMD TARGET RMSD AT FIRST STEP  " << TMDInitialRMSD << "\n";
05042      } else {
05043        iout << iINFO << "TMD TARGET RMSD AT FIRST STEP COMPUTED FROM INITIAL COORDINATES\n";
05044      }
05045      iout << iINFO << "TMD TARGET RMSD AT FINAL STEP  " << TMDFinalRMSD << "\n";
05046      iout << endi;
05047    }
05048 
05049    if (symmetryOn) {
05050      if (symmetryLastStep == -1){
05051        iout << iINFO << "SYMMETRY RESTRAINTS ACTIVE BETWEEN STEPS " << symmetryFirstStep << " and " << "INFINITY" << "\n";
05052      }
05053      else{
05054        iout << iINFO << "SYMMETRY RESTRAINTS ACTIVE BETWEEN STEPS " << symmetryFirstStep << " and " << symmetryLastStep << "\n";
05055      }
05056     // iout << iINFO << "SYMMETRY FILE " << symmetryFile << "\n";
05057 
05058      current = config->find("symmetryFile");
05059      for ( ; current; current = current->next ) {
05060        iout << iINFO << "SYMMETRY FILE  " << current->data << "\n";
05061      }
05062 
05063      current = config->find("symmetryMatrixFile");
05064      for ( ; current; current = current->next ) {
05065       iout << iINFO << "SYMMETRY MATRIX FILE " << current->data << "\n";
05066      }
05067      iout << iINFO << "SYMMETRY FORCE CONSTANT " << symmetryk << "\n";
05068      if (symmetryScaleForces){
05069       iout << iINFO << "SYMMETRY SCALE FORCES ON\n";
05070      }
05071      iout << iINFO << "SYMMETRY FIRST FULL STEP " << symmetryFirstFullStep << "\n";
05072      if (symmetryLastFullStep == -1){
05073       iout << iINFO << "SYMMETRY LAST FULL STEP " << "INFINITY" << "\n"; 
05074       //iout << iINFO << "FULL SYMMETRY FORCE BETWEEN STEPS " << symmetryFirstFullStep << " and " << "INFINITY" << "\n";
05075      }
05076      else {
05077       iout << iINFO << "SYMMETRY LAST FULL STEP " << symmetryLastFullStep << "\n"; 
05078      // iout << iINFO << "FULL SYMMETRY FORCE BETWEEN STEPS " << symmetryFirstFullStep << " and " << symmetryLastFullStep << "\n";
05079      }
05080 
05081      iout << endi;
05082    }
05083 //Modifications for alchemical fep
05084 //  Alchemical FEP status
05085 
05086 //   current = config->find("alchOutFile");
05087    if (alchFepOn)
05088    {
05089      iout << iINFO << "ALCHEMICAL FEP ON\n";
05090      iout << iINFO << "FEP CURRENT LAMBDA VALUE     "
05091           << alchLambda << "\n";
05092      iout << iINFO << "FEP COMPARISON LAMBDA VALUE  "
05093           << alchLambda2 << "\n";
05094      if (alchLambdaIDWS >= 0.) {
05095         iout << iINFO << "FEP ALTERNATE COMPARISON LAMBDA VALUE  "
05096           << alchLambdaIDWS << "\n";
05097      }
05098      if (alchLambdaFreq > 0) {
05099        iout << iINFO << "FEP CURRENT LAMBDA VALUE SET TO INCREASE IN EVERY  "
05100             << alchLambdaFreq << " STEPS\n";
05101      }
05102      if (!alchDecouple) {
05103        iout << iINFO << "FEP INTRA-ALCHEMICAL NON-BONDED INTERACTIONS WILL BE "
05104             << "DECOUPLED\n";
05105      }else{
05106        iout << iINFO << "FEP INTRA-ALCHEMICAL NON-BONDED INTERACTIONS WILL BE "
05107             << "RETAINED\n";
05108      }
05109      if (alchBondDecouple) {
05110        iout << iINFO << "FEP INTRA-ALCHEMICAL BONDED INTERACTIONS WILL BE "
05111             << "DECOUPLED\n";
05112      }else{
05113        iout << iINFO << "FEP INTRA-ALCHEMICAL BONDED INTERACTIONS WILL BE "
05114             << "RETAINED\n";
05115      }
05116      iout << iINFO << "FEP VDW SHIFTING COEFFICIENT "
05117           << alchVdwShiftCoeff << "\n";
05118      iout << iINFO << "FEP ELEC. ACTIVE FOR ANNIHILATED "
05119           << "PARTICLES BETWEEN LAMBDA = 0 AND LAMBDA = "
05120           << (1 - alchElecLambdaStart) << "\n";
05121      iout << iINFO << "FEP ELEC. ACTIVE FOR EXNIHILATED "
05122           << "PARTICLES BETWEEN LAMBDA = "
05123           << alchElecLambdaStart << " AND LAMBDA = 1\n";
05124      iout << iINFO << "FEP VDW ACTIVE FOR ANNIHILATED "
05125           << "PARTICLES BETWEEN LAMBDA = "
05126           << (1 - alchVdwLambdaEnd) << " AND LAMBDA = 1\n";
05127      iout << iINFO << "FEP VDW ACTIVE FOR EXNIHILATED "
05128           << "PARTICLES BETWEEN LAMBDA = 0 AND LAMBDA = "
05129           << alchVdwLambdaEnd << "\n";
05130      iout << iINFO << "FEP BOND ACTIVE FOR ANNIHILATED "
05131           << "PARTICLES BETWEEN LAMBDA = "
05132           << (1 - alchBondLambdaEnd) << " AND LAMBDA = 1\n";
05133      iout << iINFO << "FEP BOND ACTIVE FOR EXNIHILATED "
05134           << "PARTICLES BETWEEN LAMBDA = 0 AND LAMBDA = "
05135           << alchBondLambdaEnd << "\n";
05136 
05137      if (alchFepWCADispOn)
05138      {
05139        iout << iINFO << "FEP WEEKS-CHANDLER-ANDERSEN DECOMPOSITION (DISPERSION) ON\n";
05140      }
05141      if (alchFepWCARepuOn)
05142      {
05143        iout << iINFO << "FEP WEEKS-CHANDLER-ANDERSEN DECOMPOSITION (REPULSION) ON\n";
05144        iout << iINFO << "FEP WEEKS-CHANDLER-ANDERSEN RCUT1 = " 
05145             << alchFepWCArcut1 << " , RCUT2 = " 
05146             << alchFepWCArcut2  << " AND RCUT3 = " << alchFepWCArcut3 << "\n";
05147      }
05148    }
05149 //fepe
05150 
05151    if (alchThermIntOn)
05152    {
05153      iout << iINFO << "THERMODYNAMIC INTEGRATION (TI) ON\n";
05154      iout << iINFO << "TI LAMBDA VALUE     "
05155           << alchLambda << "\n";
05156      if (alchLambdaFreq > 0) {
05157        iout << iINFO << "TI COMPARISON LAMBDA VALUE  "
05158             << alchLambda2 << "\n";
05159        iout << iINFO << "TI CURRENT LAMBDA VALUE SET TO INCREASE IN EVERY  "
05160             << alchLambdaFreq << " STEPS\n";
05161      }
05162      if (!alchDecouple) {
05163        iout << iINFO << "TI INTRA-ALCHEMICAL NON-BONDED INTERACTIONS WILL BE "
05164             << "DECOUPLED\n";
05165      }else{
05166        iout << iINFO << "TI INTRA-ALCHEMICAL NON-BONDED INTERACTIONS WILL BE "
05167             << "RETAINED\n";
05168      }
05169      if (alchBondDecouple) {
05170        iout << iINFO << "TI INTRA-ALCHEMICAL BONDED INTERACTIONS WILL BE "
05171             << "DECOUPLED\n";
05172      }else{
05173        iout << iINFO << "TI INTRA-ALCHEMICAL BONDED INTERACTIONS WILL BE "
05174             << "RETAINED\n";
05175      }
05176      iout << iINFO << "TI VDW SHIFTING COEFFICIENT "
05177           << alchVdwShiftCoeff << "\n";
05178      iout << iINFO << "TI ELEC. ACTIVE FOR ANNIHILATED "
05179           << "PARTICLES BETWEEN LAMBDA = 0 AND LAMBDA = "
05180           << (1 - alchElecLambdaStart) << "\n";
05181      iout << iINFO << "TI ELEC. ACTIVE FOR EXNIHILATED "
05182           << "PARTICLES BETWEEN LAMBDA = "
05183           << alchElecLambdaStart << " AND LAMBDA = 1\n";
05184      iout << iINFO << "TI VDW ACTIVE FOR ANNIHILATED "
05185           << "PARTICLES BETWEEN LAMBDA = "
05186           << (1 - alchVdwLambdaEnd) << " AND LAMBDA = 1\n";
05187      iout << iINFO << "TI VDW ACTIVE FOR EXNIHILATED "
05188           << "PARTICLES BETWEEN LAMBDA = 0 AND LAMBDA = "
05189           << alchVdwLambdaEnd << "\n";
05190      iout << iINFO << "TI BOND ACTIVE FOR ANNIHILATED "
05191           << "PARTICLES BETWEEN LAMBDA = "
05192           << (1 - alchBondLambdaEnd) << " AND LAMBDA = 1\n";
05193      iout << iINFO << "TI BOND ACTIVE FOR EXNIHILATED "
05194           << "PARTICLES BETWEEN LAMBDA = 0 AND LAMBDA = "
05195           << alchBondLambdaEnd << "\n";
05196    }
05197 
05198 
05199    if ( lesOn ) {
05200      iout << iINFO << "LOCALLY ENHANCED SAMPLING ACTIVE\n";
05201      iout << iINFO << "LOCAL ENHANCEMENT FACTOR IS "
05202           << lesFactor << "\n";
05203      if ( lesReduceTemp ) iout << iINFO
05204        << "SCALING ENHANCED ATOM TEMPERATURE BY 1/" << lesFactor << "\n";
05205      if ( lesReduceMass ) iout << iINFO
05206        << "SCALING ENHANCED ATOM MASS BY 1/" << lesFactor << "\n";
05207    }
05208 
05209    // REST2
05210    if ( soluteScalingOn ) {
05211      iout << iINFO << "SOLUTE SCALING IS ACTIVE\n";
05212      if (soluteScalingFactorCharge != soluteScalingFactorVdw) {
05213        iout << iINFO << "SCALING FOR ELECTROSTATIC INTERACTIONS IS "
05214             << soluteScalingFactorCharge << "\n";
05215        iout << iINFO << "SCALING FOR VAN DER WAALS INTERACTIONS IS "
05216             << soluteScalingFactorVdw << "\n";
05217        iout << iINFO << "SCALING FOR BONDED INTERACTIONS IS "
05218             << soluteScalingFactor << "\n";
05219      }
05220      else {
05221        iout << iINFO << "SOLUTE SCALING FACTOR IS "
05222             << soluteScalingFactor << "\n";
05223      }
05224      if ( ! soluteScalingAll ) {
05225        iout << iINFO << "SOLUTE SCALING DISABLED FOR BONDS AND ANGLES\n";
05226      }
05227    }
05228    
05229    if ( pairInteractionOn ) {
05230      iout << iINFO << "PAIR INTERACTION CALCULATIONS ACTIVE\n";
05231      iout << iINFO << "USING FLAG " << pairInteractionGroup1 
05232           << " FOR GROUP 1\n";
05233      if (pairInteractionSelf) {
05234        iout << iINFO << "COMPUTING ONLY SELF INTERACTIONS FOR GROUP 1 ATOMS\n";
05235      } else {
05236        iout << iINFO << "USING FLAG " << pairInteractionGroup2 
05237             << " FOR GROUP 2\n";
05238      }
05239    }
05240 
05241    if (consForceOn) {
05242      iout << iINFO << "CONSTANT FORCE ACTIVE\n";
05243      if ( consForceScaling != 1.0 ) {
05244        iout << iINFO << "CONSTANT FORCE SCALING   "
05245                                 << consForceScaling << "\n" << endi;
05246      }
05247    }
05248 
05249 
05250    // external command forces
05251 
05252    if (extForcesOn) {
05253      iout << iINFO << "EXTERNAL COMMAND FORCES ACTIVE\n";
05254      iout << iINFO << "EXT FORCES COMMAND: " << extForcesCommand << "\n";
05255      iout << iINFO << "EXT COORD FILENAME: " << extCoordFilename << "\n";
05256      iout << iINFO << "EXT FORCE FILENAME: " << extForceFilename << "\n";
05257      iout << endi;
05258    }
05259 
05260     // QM command forces
05261 
05262     if (qmForcesOn) {
05263         iout << iINFO << "QM FORCES ACTIVE\n";
05264         if (qmParamPDBDefined){
05265             iout << iINFO << "QM PDB PARAMETER FILE: " << qmParamPDB << "\n";
05266         }
05267         iout << iINFO << "QM SOFTWARE: " << qmSoftware << "\n";
05268         
05269         if ( qmChrgMode == QMCHRGNONE ) 
05270             iout << iINFO << "QM ATOM CHARGES FROM QM SOFTWARE: NONE\n";
05271         if ( qmChrgMode == QMCHRGMULLIKEN ) 
05272             iout << iINFO << "QM ATOM CHARGES FROM QM SOFTWARE: MULLIKEN\n";
05273         if ( qmChrgMode == QMCHRGCHELPG ) 
05274             iout << iINFO << "QM ATOM CHARGES FROM QM SOFTWARE: CHELPG\n";
05275         
05276         iout << iINFO << "QM EXECUTABLE PATH: " << qmExecPath << "\n";
05277         iout << iINFO << "QM COLUMN: " << qmColumn << "\n";
05278         if (qmBondOn) {
05279             iout << iINFO << "QM BOND COLUMN: " << qmBondColumn << "\n";
05280             iout << iINFO << "QM WILL DETECT BONDS BETWEEN QM AND MM ATOMS.\n";
05281             if (qmBondDist) {
05282                 iout << iINFO << "QM BOND COLUMN WILL DEFINE LINK AOTM DISTANCE.\n";
05283                 if (qmBondValType == 1)
05284                     iout << iINFO << "QM BOND COLUMN HAS LENGTH INFORMATION.\n";
05285                 else if (qmBondValType == 2)
05286                     iout << iINFO << "QM BOND COLUMN HAS RATIO INFORMATION.\n";
05287             }
05288             if (qmNoPC) {
05289                 iout << iINFO << "MECHANICHAL EMBEDDING SELECTED."
05290                 " BOND SCHEME WILL BE IGNORED!\n" << endi;
05291                 qmBondScheme = QMSCHEMEZ1;
05292             }
05293             else {
05294                 if (qmBondScheme == QMSCHEMECS)
05295                     iout << iINFO << "QM-MM BOND SCHEME: Charge Shift.\n";
05296                 else if (qmBondScheme == QMSCHEMERCD)
05297                     iout << iINFO << "QM-MM BOND SCHEME: Redistributed Charge and Dipole.\n";
05298                 else if (qmBondScheme == QMSCHEMEZ1)
05299                     iout << iINFO << "QM-MM BOND SCHEME: Z1.\n";
05300                 else if (qmBondScheme == QMSCHEMEZ2)
05301                     iout << iINFO << "QM-MM BOND SCHEME: Z2.\n";
05302                 else if (qmBondScheme == QMSCHEMEZ3)
05303                     iout << iINFO << "QM-MM BOND SCHEME: Z3.\n";
05304             }
05305             
05306         }
05307         
05308         if (qmChrgFromPSF) {
05309             iout << iINFO << "QM Will use PSF charges.\n";
05310         }
05311         
05312         iout << iINFO << "QM BASE DIRECTORY: " << qmBaseDir << "\n";
05313         
05314         if (qmPrepProcOn) {
05315             iout << iINFO << "QM PREPARATION PROCESS: " << qmPrepProc << "\n";
05316         }
05317         if (qmSecProcOn) {
05318             iout << iINFO << "QM SECONDARY PROCESS: " << qmSecProc << "\n";
05319         }
05320         
05321         current = config->find("QMConfigLine");
05322         for ( ; current; current = current->next ) {
05323             
05324             if ( strstr(current->data,"\n") ) {
05325                 iout << iINFO << "QM configuration lines from NADM config file\n";
05326                 continue;
05327             }
05328             
05329             iout << iINFO << "QM CONFIG LINE: " << current->data << "\n";
05330             
05331         }
05332         
05333         if (qmReplaceAll) {
05334             iout << iINFO << "QM FORCES WILL REPLACE ALL NAMD FORCES!\n";
05335         }
05336         
05337         if (qmNoPC)
05338             iout << iINFO << "QM NO POINT CHARGE: ON.\n";
05339         
05340         if (qmCustomPCSel)
05341             iout << iINFO << "QM CUSTOM POINT CHARGE SELECTION IS ACTIVATED\n";
05342         
05343         if (! qmNoPC && ! qmCustomPCSel)
05344             iout << iINFO << "QM POINT CHARGES WILL BE SELECTED EVERY " 
05345             << qmPCSelFreq << " STEPS.\n";
05346         
05347         if (qmPCSwitchOn) {
05348             iout << iINFO << "QM Point Charge Switching: ON.\n";
05349         
05350             if (qmPCScheme == 1)
05351                 iout << iINFO << "QM Point Charge SCHEME: none.\n";
05352             else if (qmPCScheme == 2)
05353                 iout << iINFO << "QM Point Charge SCHEME: round.\n";
05354             else if (qmPCScheme == 3)
05355                 iout << iINFO << "QM Point Charge SCHEME: zero.\n";
05356         }
05357         
05358         if (qmLSSOn) {
05359             iout << iINFO << "QM LIVE SOLVENT SELECTION IS ACTIVE.\n" ;
05360             iout << iINFO << "QM LIVE SOLVENT SELECTION FREQUENCY: " 
05361             << qmLSSFreq << "\n" << endi;
05362             
05363             current = config->find("QMLSSSize");
05364             for ( ; current; current = current->next ) {
05365                 iout << iINFO << "QM LIVE SOLVENT SELECTION SIZE (\"qmGrpID numMolecules\"): " << current->data << "\n";
05366             }
05367             
05368             if (! opts.defined("QMLWSResname"))
05369                 strcpy(qmLSSResname,"TIP3");
05370             iout << iINFO << "QM LIVE SOLVENT SELECTION WILL USE RESIDUE TYPE: " << qmLSSResname << "\n" << endi;
05371         }
05372         
05373         iout << iINFO << "QM executions per node: " << qmSimsPerNode << "\n";
05374         
05375         iout << endi;
05376     }
05377     
05378     
05379    // gbis gbobc implicit solvent parameters
05380 
05381   if (GBISserOn) {
05382       GBISOn = 0;//turning gbis-ser on turns gbis-parallel off
05383      iout << iINFO<< "GBIS GENERALIZED BORN IMPLICIT SOLVENT ACTIVE (SERIAL)\n";
05384   }
05385   if (GBISOn) {
05386      iout << iINFO << "GBIS GENERALIZED BORN IMPLICIT SOLVENT ACTIVE\n";
05387   }
05388   if (GBISOn || GBISserOn) {
05389      iout << iINFO << "GBIS SOLVENT DIELECTRIC: " << solvent_dielectric<< "\n";
05390      iout << iINFO << "GBIS PROTEIN DIELECTRIC: " << dielectric<< "\n";
05391      iout <<iINFO<<"GBIS COULOMB RADIUS OFFSET: "<< coulomb_radius_offset<<" Ang\n";
05392      iout << iINFO << "GBIS ION CONCENTRATION: " << ion_concentration << " M\n";
05393      iout << iINFO << "GBIS DEBYE SCREENING LENGTH: " << 1.0/kappa << " Ang\n";
05394      iout << iINFO << "GBIS DELTA: " << gbis_delta << "\n";
05395      iout << iINFO << "GBIS BETA: " << gbis_beta << "\n";
05396      iout << iINFO << "GBIS GAMMA: " << gbis_gamma << "\n";
05397      iout << iINFO << "GBIS BORN RADIUS CUTOFF: " << alpha_cutoff << " Ang\n";
05398      iout << iINFO << "GBIS MAX BORN RADIUS: " << alpha_max << " Ang\n";
05399      iout << endi;
05400   }
05401 
05402   if (LCPOOn) {
05403     iout << iINFO << "SASA SURFACE TENSION: " << surface_tension<< " kcal/mol/Ang^2\n";
05404   }
05405 
05406    tclBCScript = 0;
05407    if (tclBCOn) {
05408      iout << iINFO << "TCL BOUNDARY FORCES ACTIVE\n";
05409      current = config->find("tclBCScript");
05410      if ( current ) {
05411        tclBCScript = current->data;
05412        iout << iINFO << "TCL BOUNDARY FORCES SCRIPT   " << current->data << "\n";
05413      }
05414        iout << iINFO << "TCL BOUNDARY FORCES ARGS     " << tclBCArgs << "\n";
05415      iout << endi;
05416    }
05417    
05418    // Global forces configuration
05419 
05420    globalForcesOn = ( tclForcesOn || freeEnergyOn || miscForcesOn ||
05421                       (IMDon && ! (IMDignore || IMDignoreForces)) || SMDOn || TMDOn || 
05422                       colvarsOn || symmetryOn || qmForcesOn );
05423 
05424 
05425    if (tclForcesOn)
05426    {
05427      iout << iINFO << "TCL GLOBAL FORCES ACTIVE\n";
05428 
05429      current = config->find("tclForcesScript");
05430 
05431      for ( ; current; current = current->next ) {
05432 
05433      if ( strstr(current->data,"\n") ) {
05434        iout << iINFO << "TCL GLOBAL FORCES SCRIPT INLINED IN CONFIG FILE\n";
05435        continue;
05436      }
05437 
05438      iout << iINFO << "TCL GLOBAL FORCES SCRIPT   " << current->data << "\n";
05439 
05440      }
05441      iout << endi;
05442    }
05443 
05444    if (miscForcesOn)
05445    {
05446      iout << iINFO << "MISC FORCES ACTIVE\n";
05447 
05448      current = config->find("miscForcesScript");
05449 
05450      for ( ; current; current = current->next ) {
05451 
05452      if ( strstr(current->data,"\n") ) {
05453        iout << iINFO << "MISC FORCES SCRIPT INLINED IN CONFIG FILE\n";
05454        continue;
05455      }
05456 
05457      iout << iINFO << "MISC FORCES SCRIPT   " << current->data << "\n";
05458 
05459      }
05460      iout << endi;
05461    }
05462 
05463    if (freeEnergyOn)
05464    {
05465      iout << iINFO << "FREE ENERGY PERTURBATION ACTIVE\n";
05466 
05467      current = config->find("freeEnergyConfig");
05468 
05469      for ( ; current; current = current->next ) {
05470 
05471      if ( strstr(current->data,"\n") ) {
05472        iout << iINFO << "FREE ENERGY PERTURBATION SCRIPT INLINED IN CONFIG FILE\n";
05473        continue;
05474      }
05475 
05476      iout << iINFO << "FREE ENERGY PERTURBATION SCRIPT   " << current->data << "\n";
05477 
05478      }
05479      iout << endi;
05480    }
05481 
05482    if (colvarsOn)
05483    {
05484      iout << iINFO << "COLLECTIVE VARIABLES CALCULATION REQUESTED\n";
05485 
05486      current = config->find ("colvarsConfig");
05487      for ( ; current; current = current->next ) {
05488        if ( strstr(current->data,"\n") ) {
05489          iout << iINFO << "COLLECTIVE VARIABLES CONFIGURATION INLINED IN CONFIG FILE\n";
05490          continue;
05491        }
05492        iout << iINFO << "COLLECTIVE VARIABLES CONFIGURATION   " << current->data << "\n";
05493      }
05494 
05495      current = config->find ("colvarsInput");
05496      for ( ; current; current = current->next ) {
05497        if ( strstr(current->data,"\n") ) {
05498          iout << iINFO << "COLLECTIVE VARIABLES RESTART INFORMATION INLINED IN CONFIG FILE\n";
05499          continue;
05500        }
05501        iout << iINFO << "COLLECTIVE VARIABLES RESTART INFORMATION   " << current->data << "\n";
05502      }
05503 
05504      iout << endi;
05505    }
05506 
05507    if (IMDon)
05508    {
05509      iout << iINFO << "INTERACTIVE MD ACTIVE\n";
05510      iout << iINFO << "INTERACTIVE MD PORT    " << IMDport << "\n";
05511      iout << iINFO << "INTERACTIVE MD FREQ    " << IMDfreq << "\n";
05512      if (IMDignore) {
05513         iout << iINFO << "INTERACTIVE MD WILL NOT INFLUENCE SIMULATION\n";
05514      } else {
05515        if (IMDignoreForces) 
05516          {
05517             iout << iINFO << "INTERACTIVE FORCES ARE DISABLED\n";
05518             iout << iINFO << "PAUSE, RESUME, DETACH AND FINISH INTERACTIVE MD ARE ENABLED\n";
05519          }
05520        if (IMDwait) iout << iINFO << "WILL AWAIT INTERACTIVE MD CONNECTION\n";
05521      }
05522      iout << endi;
05523    }
05524 
05525    if (globalOn && !dihedralOn)
05526    {
05527       iout << iINFO << "GLOBAL INTEGRATION TEST MODE ACTIVE\n";
05528    }
05529 
05530 
05531    if (dihedralOn)
05532    {
05533       iout << iINFO << "DIHEDRAL ANGLE DYNAMICS ACTIVE\n";
05534       if (!COLDOn)
05535       {
05536          iout << iINFO << "*** DIHEDRAL ANGLE DYNAMICS IS HIGHLY EXPERIMENTAL ***\n";
05537          iout << iINFO << "PLEASE CONSIDER USING THE COLD OPTION AS WELL\n";
05538       }
05539    }
05540 
05541    // This function is so long that it exceeds the emacs brace
05542    // matching default max length of 25600 (a bit before this comment). We
05543    // should take this is a not too subtle hint about scale of this
05544    // violation of good coding practices.  Especially considering the
05545    // fact that this function still has about a thousand lines to go
05546    // before its done, and is doomed to grow with new features. 
05547 
05548    if (COLDOn)
05549    {
05550       iout << iINFO << "COLD (CONSTRAINED OVERDAMPED LANGEVIN DYNAMICS) ACTIVE\n";
05551 
05552       iout << iINFO << "COLD TARGET TEMP       "
05553          << COLDTemp << "\n";
05554 
05555       iout << iINFO << "COLD COLLISION RATE    "
05556          << COLDRate << "\n";
05557    }
05558 
05559    if (cylindricalBCOn)
05560    {
05561     iout << iINFO << "CYLINDRICAL BOUNDARY CONDITIONS ACTIVE\n";
05562     iout << iINFO << "AXIS                     " << cylindricalBCAxis << "\n";
05563     iout << iINFO << "RADIUS #1                " << cylindricalBCr1 << "\n";
05564     iout << iINFO << "FORCE CONSTANT #1        " << cylindricalBCk1 << "\n";
05565     iout << iINFO << "EXPONENT #1              " << cylindricalBCexp1 << "\n";
05566     iout << iINFO << "LENGTH #1                " << cylindricalBCl1 << "\n";
05567     if (cylindricalBCr2 > 0.0)
05568     {
05569      iout << iINFO << "RADIUS #2               " << cylindricalBCr2 << "\n";
05570      iout << iINFO << "FORCE CONSTANT #2       " << cylindricalBCk2 << "\n";
05571      iout << iINFO << "EXPONENT #2             " << cylindricalBCexp2 << "\n";
05572      iout << iINFO << "LENGTH #2               " << cylindricalBCl2 << "\n";
05573     }
05574     iout << iINFO << "CYLINDER BOUNDARY CENTER(" << cylindricalCenter.x << ", "
05575              << cylindricalCenter.y << ", " << cylindricalCenter.z << ")\n";
05576     iout << endi;
05577   }
05578 
05579    if (sphericalBCOn)
05580    {
05581       iout << iINFO << "SPHERICAL BOUNDARY CONDITIONS ACTIVE\n";
05582 
05583       iout << iINFO << "RADIUS #1              "
05584          << sphericalBCr1 << "\n";
05585       iout << iINFO << "FORCE CONSTANT #1      "
05586          << sphericalBCk1 << "\n";
05587       iout << iINFO << "EXPONENT #1            "
05588          << sphericalBCexp1 << "\n";
05589 
05590       if (sphericalBCr2 > 0)
05591       {
05592         iout << iINFO << "RADIUS #2              "
05593               << sphericalBCr2 << "\n";
05594         iout << iINFO << "FORCE CONSTANT #2      "
05595             << sphericalBCk2 << "\n";
05596         iout << iINFO << "EXPONENT #2            "
05597         << sphericalBCexp2 << "\n";
05598       }
05599 
05600       iout << iINFO << "SPHERE BOUNDARY CENTER(" << sphericalCenter.x << ", "
05601                << sphericalCenter.y << ", " << sphericalCenter.z << ")\n";
05602       iout << endi;
05603    }
05604 
05605    if (eFieldOn)
05606    {
05607       iout << iINFO << "ELECTRIC FIELD ACTIVE\n";
05608       
05609       iout << iINFO << "E-FIELD VECTOR         ("
05610          << eField.x << ", " << eField.y
05611          << ", " << eField.z << ")\n";
05612       if ( eFieldNormalized ) iout << iINFO << "E-FIELD VECTOR IS SCALED BY CELL BASIS VECTORS\n";
05613       iout << iINFO << "E-FIELD FREQUENCY IS (1/ps) " << eFieldFreq << "\n";
05614       iout << iINFO << "E-FIELD PHASE IS     (deg)  " << eFieldPhase << "\n";
05615 
05616       iout << endi;
05617    }
05618 
05619       if (stirOn)
05620    {
05621       iout << iINFO << "STIRRING TORQUES ACTIVE\n";
05622       
05623       iout << iINFO << "STIR STARTING THETA   (deg)  "<< stirStartingTheta << "\n";
05624       iout << iINFO << "STIR ANGULAR VELOCITY (deg/ts)   " << stirVel <<"\n";
05625       iout << iINFO << "STIR FORCE HARMONIC SPRING CONSTANT "<< stirK << "\n";
05626       iout << iINFO << "STIR AXIS OF ROTATION (DIRECTION)      ("
05627          << stirAxis.x << ", " << stirAxis.y
05628          << ", " << stirAxis.z << ")\n";
05629                   iout << iINFO << "STIR PIVOT POINT (COORDINATE)           ("
05630          << stirPivot.x << ", " << stirPivot.y
05631          << ", " << stirPivot.z << ")\n";
05632       current = config->find("stirFilename");
05633                   
05634       iout << iINFO << "STIR ATOMS AND ORIGINAL POSITIONS FROM FILE    " <<current ->data << '\n';
05635       current = config->find("stirredAtomsCol");
05636       iout << iINFO <<"STIR FILE COLUMN " << current ->data << '\n';
05637       iout << endi;
05638    }
05639 
05640    if (drudeOn)
05641    {
05642       iout << iINFO << "DRUDE MODEL DUAL THERMOSTAT IS ACTIVE\n";
05643       iout << iINFO << "DRUDE BOND TEMPERATURE " << drudeTemp << "\n";
05644       if (drudeDamping > 0.0) {
05645         iout << iINFO << "DRUDE DAMPING COEFFICIENT IS "
05646              << drudeDamping << " INVERSE PS\n";
05647       }
05648       if (drudeBondConst > 0.0) {
05649         iout << iINFO << "DRUDE QUARTIC RESTRAINT IS ACTIVE FOR DRUDE BONDS\n";
05650         iout << iINFO << "DRUDE MAXIMUM BOND LENGTH BEFORE RESTRAINT IS   "
05651              << drudeBondLen << "\n";
05652         iout << iINFO << "DRUDE BOND RESTRAINT CONSTANT IS                "
05653              << drudeBondConst << "\n";
05654       }
05655       if (drudeHardWallOn) {
05656         iout << iINFO << "DRUDE HARD WALL RESTRAINT IS ACTIVE FOR DRUDE BONDS\n";
05657         iout << iINFO << "DRUDE MAXIMUM BOND LENGTH BEFORE RESTRAINT IS   "
05658              << drudeBondLen << "\n";
05659       }
05660       if (drudeNbtholeCut > 0.0) {
05661         iout << iINFO << "DRUDE NBTHOLE IS ACTIVE\n";
05662         iout << iINFO << "DRUDE NBTHOLE RADIUS IS   "
05663              << drudeNbtholeCut << "\n";
05664       }
05665    }
05666 
05667    if (langevinOn)
05668    {
05669       iout << iINFO << "LANGEVIN DYNAMICS ACTIVE\n";
05670       iout << iINFO << "LANGEVIN TEMPERATURE   "
05671          << langevinTemp << "\n";
05672       if (! langevin_useBAOAB) iout << iINFO << "LANGEVIN USING BBK INTEGRATOR\n";
05673       else  iout << iINFO << "LANGEVIN USING BAOAB INTEGRATOR\n"; // [!!] Info file
05674       if (langevinDamping > 0.0) {
05675         iout << iINFO << "LANGEVIN DAMPING COEFFICIENT IS "
05676                 << langevinDamping << " INVERSE PS\n";
05677         if (langevinHydrogen)
05678                 iout << iINFO << "LANGEVIN DYNAMICS APPLIED TO HYDROGENS\n";
05679         else
05680                 iout << iINFO << "LANGEVIN DYNAMICS NOT APPLIED TO HYDROGENS\n";
05681       } else {
05682         iout << iINFO << "LANGEVIN DAMPING COEFFICIENTS DETERMINED FROM FILES\n";
05683         current = config->find("langevinFile");
05684         if ( current ) iout << iINFO << "LANGEVIN DAMPING FILE:  " <<
05685           current->data << "\n";
05686         else iout << iINFO << "LANGEVIN DAMPING FILE IS COORDINATE PDB\n";
05687         current = config->find("langevinCol");
05688         if ( current ) iout << iINFO << "LANGEVIN DAMPING COLUMN:  " <<
05689           current->data << "\n";
05690         else iout << iINFO << "LANGEVIN DAMPING COLUMN:  DEFAULT (4TH, O)\n";
05691       }
05692       iout << endi;
05693    }
05694    
05695    // BEGIN LA
05696    if (loweAndersenOn)
05697    {
05698       iout << iINFO << "LOWE-ANDERSEN DYNAMICS ACTIVE\n";
05699       iout << iINFO << "LOWE-ANDERSEN TEMPERATURE     "
05700          << loweAndersenTemp << " K\n";
05701       iout << iINFO << "LOWE-ANDERSEN RATE            "
05702          << loweAndersenRate << " INVERSE PS\n";
05703       iout << iINFO << "LOWE-ANDERSEN CUTOFF          "
05704          << loweAndersenCutoff << " ANGSTROMS\n";
05705       iout << endi;
05706    }
05707    // END LA
05708 
05709    if (tCoupleOn)
05710    {
05711       iout << iINFO << "TEMPERATURE COUPLING ACTIVE\n";
05712       iout << iINFO << "COUPLING TEMPERATURE   "
05713          << tCoupleTemp << "\n";
05714       iout << endi;
05715    }
05716 
05717    if (stochRescaleOn)
05718    {
05719       iout << iINFO << "STOCHASTIC RESCALING ACTIVE\n";
05720       iout << iINFO << "STOCHASTIC RESCALING TEMPERATURE "
05721            << stochRescaleTemp << " K\n";
05722       iout << iINFO << "STOCHASTIC RESCALING PERIOD " 
05723            << stochRescalePeriod << " PS\n";
05724       iout << iINFO << "STOCHASTIC RESCALING WILL OCCUR EVERY "
05725            << stochRescaleFreq << " STEPS\n";
05726       iout << endi;
05727    }
05728 
05729    if (minimizeOn)
05730    {
05731       iout << iINFO << "OLD STYLE MINIMIZATION ACTIVE\n";
05732       iout << endi;
05733    }
05734 
05735    if (minimizeCGOn)
05736    {
05737       iout << iINFO << "CONJUGATE GRADIENT MINIMIZATION ACTIVE\n";
05738       iout << iINFO << "LINE MINIMIZATION GOAL = " << minLineGoal << "\n";
05739       iout << iINFO << "BABY STEP SIZE = " << minBabyStep << "\n";
05740       iout << iINFO << "TINY STEP SIZE = " << minTinyStep << "\n";
05741       iout << endi;
05742    }
05743 
05744    if (maximumMove)
05745    {
05746       iout << iINFO << "MAXIMUM MOVEMENT       "
05747          << maximumMove << "\n";
05748       iout << endi;
05749    }
05750 
05751    if (rescaleFreq > 0)
05752    {
05753      iout << iINFO << "VELOCITY RESCALE FREQ  "
05754         << rescaleFreq << "\n";
05755      iout << iINFO << "VELOCITY RESCALE TEMP  "
05756         << rescaleTemp << "\n";
05757      iout << endi;
05758    }
05759 
05760    if (reassignFreq > 0)
05761    {
05762      iout << iINFO << "VELOCITY REASSIGNMENT FREQ  "
05763         << reassignFreq << "\n";
05764      iout << iINFO << "VELOCITY REASSIGNMENT TEMP  "
05765         << reassignTemp << "\n";
05766      if ( reassignIncr != 0. )
05767        iout << iINFO << "VELOCITY REASSIGNMENT INCR  "
05768         << reassignIncr << "\n";
05769      if ( reassignHold != 0. )
05770        iout << iINFO << "VELOCITY REASSIGNMENT HOLD  "
05771         << reassignHold << "\n";
05772      iout << endi;
05773    }
05774 
05775    if ((int)berendsenPressureOn + (int)langevinPistonOn + (int)multigratorOn > 1)
05776    {
05777       NAMD_die("Multiple pressure control algorithms selected!\n");
05778    }
05779 
05780    if (excludeFromPressure) {
05781      iout << iINFO << "EXCLUDE FROM PRESSURE ACTIVE\n";
05782    }
05783    if (useConstantArea && useConstantRatio) {
05784      NAMD_die("useConstantArea and useConstantRatio are mutually exclusive.\n");
05785    }
05786    if (useConstantRatio && !useFlexibleCell) {
05787      NAMD_die("useConstantRatio requires useFlexibleCell.\n");
05788    }
05789    if (useConstantArea && surfaceTensionTarget) {
05790      NAMD_die("surfaceTensionTarget and useConstantArea are mutually exclusive.\n");
05791    }
05792    if (useConstantArea && !useFlexibleCell) {
05793      NAMD_die("useConstantArea requires useFlexibleCell.\n");
05794    }
05795 
05796    if (berendsenPressureOn || langevinPistonOn) {
05797      if (rigidBonds != RIGID_NONE && useGroupPressure == FALSE) {
05798        useGroupPressure = TRUE;
05799        iout << iWARN << "Option useGroupPressure is being enabled "
05800             << "due to pressure control with rigidBonds.\n" << endi;
05801      }
05802    }
05803 
05804    if (berendsenPressureOn)
05805    {
05806      if ( ! opts.defined("BerendsenPressureFreq") ) {
05807         berendsenPressureFreq = nonbondedFrequency;
05808         if ( fullElectFrequency )
05809                 berendsenPressureFreq = fullElectFrequency;
05810      }
05811      if ( (berendsenPressureFreq % nonbondedFrequency) || ( fullElectFrequency
05812                 && (berendsenPressureFreq % fullElectFrequency) ) )
05813         NAMD_die("berendsenPressureFreq must be a multiple of both fullElectFrequency and nonbondedFrequency\n");
05814      iout << iINFO << "BERENDSEN PRESSURE COUPLING ACTIVE\n";
05815      iout << iINFO << "    TARGET PRESSURE IS "
05816         << berendsenPressureTarget << " BAR\n";
05817      iout << iINFO << "    COMPRESSIBILITY ESTIMATE IS "
05818         << berendsenPressureCompressibility << " BAR^(-1)\n";
05819      iout << iINFO << "    RELAXATION TIME IS "
05820         << berendsenPressureRelaxationTime << " FS\n";
05821      iout << iINFO << "    APPLIED EVERY "
05822         << berendsenPressureFreq << " STEPS\n";
05823      iout << iINFO << "    PRESSURE CONTROL IS "
05824         << (useGroupPressure?"GROUP":"ATOM") << "-BASED\n";
05825      iout << endi;
05826      berendsenPressureTarget /= PRESSUREFACTOR;
05827      berendsenPressureCompressibility *= PRESSUREFACTOR;
05828    }
05829 
05830    if (langevinPistonOn)
05831    {
05832      iout << iINFO << "LANGEVIN PISTON PRESSURE CONTROL ACTIVE\n";
05833      iout << iINFO << "       TARGET PRESSURE IS "
05834         << langevinPistonTarget << " BAR\n";
05835      iout << iINFO << "    OSCILLATION PERIOD IS "
05836         << langevinPistonPeriod << " FS\n";
05837      iout << iINFO << "            DECAY TIME IS "
05838         << langevinPistonDecay << " FS\n";
05839      iout << iINFO << "    PISTON TEMPERATURE IS "
05840         << langevinPistonTemp << " K\n";
05841      iout << iINFO << "      PRESSURE CONTROL IS "
05842         << (useGroupPressure?"GROUP":"ATOM") << "-BASED\n";
05843      iout << iINFO << "   INITIAL STRAIN RATE IS "
05844         << strainRate << "\n";
05845      iout << endi;
05846      langevinPistonTarget /= PRESSUREFACTOR;
05847    }
05848 
05849     if (multigratorOn) {
05850       multigratorPressureTarget /= PRESSUREFACTOR;
05851     }
05852 
05853    if (berendsenPressureOn || langevinPistonOn) {
05854      iout << iINFO << "      CELL FLUCTUATION IS "
05855             << (useFlexibleCell?"AN":"") << "ISOTROPIC\n";
05856      if (useConstantRatio) 
05857        iout << iINFO << "    SHAPE OF CELL IS CONSTRAINED IN X-Y PLANE\n";
05858      if (useConstantArea) 
05859        iout << iINFO << "    CONSTANT AREA PRESSURE CONTROL ACTIVE\n";
05860    }
05861 
05862    if (surfaceTensionTarget != 0)
05863    {
05864      iout << iINFO << "SURFACE TENSION CONTROL ACTIVE\n";
05865      iout << iINFO << "      TARGET SURFACE TENSION IS "
05866           << surfaceTensionTarget << " DYN/CM\n";
05867      iout << endi;
05868      // multiply by 100 to convert from dyn/cm to bar-Angstroms, then divide
05869      // by PRESSURE factor to convert bar to NAMD internal pressure units. 
05870      surfaceTensionTarget *= 100.0 / PRESSUREFACTOR;
05871    }
05872 
05873    if (pressureProfileOn) {
05874      if ((berendsenPressureOn || langevinPistonOn) && !dcdUnitCell) {
05875 #if 1
05876        iout << iWARN << "Turning on dcdUnitCell so that trajectory files contain unit cell data.\n" << endi;
05877        dcdUnitCell = 1;
05878 #else
05879        NAMD_die("Sorry, pressure profile not implemented for constant pressure.");
05880 #endif
05881      }
05882      // if Ewald is on, only calculate Ewald
05883      if (pressureProfileEwaldOn)
05884        pressureProfileOn = 0;
05885 
05886      if (pressureProfileSlabs < 1) 
05887        NAMD_die("pressureProfileSlabs must be positive.");
05888      iout << iINFO << "PRESSURE PROFILE CALCULATIONS ACTIVE\n";
05889      iout << iINFO << "      NUMBER OF SLABS: " << pressureProfileSlabs << "\n";
05890      iout << iINFO << "      SLAB THICKNESS: " << cellBasisVector3.z / pressureProfileSlabs
05891                    << "\n";
05892      iout << iINFO << "      TIMESTEPS BETWEEN DATA OUTPUT: " 
05893                    << pressureProfileFreq << "\n";
05894      iout << iINFO << "      NUMBER OF ATOM TYPES: " << pressureProfileAtomTypes << "\n";
05895      iout << endi;
05896    } else {
05897      pressureProfileEwaldOn = 0;
05898      pressureProfileAtomTypes = 1;
05899    }
05900 
05901    if (accelMDOn) {
05902      iout << iINFO << "ACCELERATED MD ACTIVE\n";
05903 
05904      if ( accelMDdual) {
05905         accelMDdihe = FALSE;
05906         iout << iINFO << "APPLYING DUAL BOOST\n";
05907      }
05908      else if ( accelMDdihe ) {
05909         iout << iINFO << "BOOSTING DIHEDRAL POTENTIAL\n";
05910      } else {
05911         iout << iINFO << "BOOSTING TOTAL POTENTIAL\n";
05912      }
05913 
05914      if(accelMDG){
05915          switch(accelMDGiE) {
05916              case 1:
05917                  iout << iINFO << "accelMDG THRESHOLD ENERGY SET TO LOWER BOUND Vmax\n";
05918                  break;
05919              case 2:
05920                  iout << iINFO << "accelMDG THRESHOLD ENERGY SET TO UPPER BOUND Vmin+(Vmax-Vmin)/k0\n";
05921                  break;
05922          }
05923          if(accelMDGRestart)
05924              iout << iINFO << "accelMDG USING RESTART FILE " << accelMDGRestartFile << "\n";
05925          if(accelMDGresetVaftercmd)
05926              iout << iINFO << "accelMDG WILL RESET STATISTICS AFTER FIRST CMD STEPS\n";
05927 
05928          iout << iINFO << "accelMDG " << accelMDGcMDSteps << " CONVENTIONAL MD STEPS "
05929              << "(WITH " << accelMDGcMDPrepSteps << " PREPARATION STEPS)\n";
05930          if(accelMDGcMDSteps == 0)
05931                  iout << iINFO << "(accelMDGcMDPrepSteps is set to zero automatically)\n";
05932 
05933          iout << iINFO << "accelMDG " << accelMDGEquiSteps << " EQUILIBRATION STEPS "
05934              << "(WITH " << accelMDGEquiPrepSteps << " PREPARATION STEPS)\n";
05935          if(accelMDGEquiSteps == 0)
05936                  iout << iINFO << "(accelMDGEquiPrepSteps is set to zero automatically)\n";
05937 
05938          if(accelMDdihe)
05939              iout << iINFO << "accelMDGSigma0D: " << accelMDGSigma0D << " KCAL/MOL\n";
05940          else if(accelMDdual)
05941              iout << iINFO << "accelMDGSigma0P: " << accelMDGSigma0P << " KCAL/MOL, "
05942                  << "accelMDGSigma0D: " << accelMDGSigma0D << " KCAL/MOL\n";
05943          else
05944              iout << iINFO << "accelMDGSigma0P: " << accelMDGSigma0P << " KCAL/MOL\n";
05945      }
05946      else{
05947          iout << iINFO << "accelMDE: " << accelMDE << " KCAL/MOL, accelMDalpha: " << accelMDalpha << " KCAL/MOL\n";
05948          if (accelMDdual) {
05949              iout << iINFO << "accelMDTE: " << accelMDTE << " KCAL/MOL, "
05950                  << "accelMDTalpha: " << accelMDTalpha << " KCAL/MOL\n";
05951          }
05952      }
05953      if ( accelMDLastStep > 0) {
05954         iout << iINFO << "accelMD WILL BE DONE FROM STEP " << accelMDFirstStep << " TO STEP " << accelMDLastStep << "\n";
05955      } else {
05956         iout << iINFO << "accelMD WILL BE DONE FROM STEP " << accelMDFirstStep << " TO THE END OF THE SIMULATION \n";
05957      }        
05958      iout << iINFO << "accelMD OUTPUT FREQUENCY " << accelMDOutFreq << "\n";
05959      iout << endi;
05960    }
05961 
05962    if (adaptTempOn) {
05963      iout << iINFO << "ADAPTIVE TEMPERING ACTIVE:\n";
05964      iout << iINFO << "      OUTPUT FREQUENCY: " << adaptTempOutFreq << "\n";
05965      iout << iINFO << "      TEMPERATURE UPDATE FREQUENCY: " << adaptTempFreq << "\n";
05966      if ( adaptTempLastStep > 0 )
05967         iout << iINFO << "      ADAPTIVE TEMPERING WILL BE DONE FROM STEP " << adaptTempFirstStep  << " TO " << adaptTempLastStep << "\n";
05968      else
05969         iout << iINFO << "      ADAPTIVE TEMPERING WILL BE DONE FROM STEP " << adaptTempFirstStep << "\n";
05970      if ( adaptTempLangevin )
05971         iout << iINFO << "      ADAPTIVE TEMPERING COUPLED TO LANGEVIN THERMOSTAT\n";
05972      if ( adaptTempRescale )
05973         iout << iINFO << "      ADAPTIVE TEMPERING COUPLED TO VELOCITY RESCALING\n";
05974      if (adaptTempRestartFreq > 0) {
05975         iout << iINFO << "      WRITING RESTART INFORMATION TO " << adaptTempRestartFile << " EVERY " << adaptTempRestartFreq << " STEPS\n";
05976      }
05977         
05978    }
05979 
05980    if (FMAOn)
05981    {
05982      iout << iINFO << "FMA ACTIVE\n";
05983      iout << iINFO << "FMA THETA              "
05984         << fmaTheta << "\n";
05985      iout << endi;
05986    }
05987 
05988    FFTWWisdomString = 0;
05989    if (PMEOn)
05990    {
05991      iout << iINFO << "PARTICLE MESH EWALD (PME) ACTIVE\n";
05992      iout << iINFO << "PME TOLERANCE               "
05993         << PMETolerance << "\n";
05994      iout << iINFO << "PME EWALD COEFFICIENT       "
05995         << PMEEwaldCoefficient << "\n";
05996      iout << iINFO << "PME INTERPOLATION ORDER     "
05997         << PMEInterpOrder << "\n";
05998      iout << iINFO << "PME GRID DIMENSIONS         "
05999         << PMEGridSizeX << " "
06000         << PMEGridSizeY << " "
06001         << PMEGridSizeZ << "\n";
06002      iout << iINFO << "PME MAXIMUM GRID SPACING    "
06003         << PMEGridSpacing << "\n";
06004      if ( PMEBarrier ) {
06005        iout << iINFO << "PME BARRIER ENABLED\n";
06006      }
06007      if ( PMEOffload ) {
06008        iout << iINFO << "PME RECIPROCAL SUM OFFLOADED TO GPU\n";
06009      }
06010      iout << endi;
06011      if ( useDPME ) iout << iINFO << "USING OLD DPME CODE\n";
06012 #ifdef NAMD_FFTW
06013      else if ( FFTWUseWisdom ) {  // handle FFTW wisdom
06014 #ifdef NAMD_FFTW_3
06015        iout << iINFO << "Attempting to read FFTW data from system" <<"\n" <<endi;
06016        fftwf_import_system_wisdom();
06017 #endif
06018        if (! opts.defined("FFTWWisdomFile")) {
06019          strcpy(FFTWWisdomFile,"FFTW_NAMD_");
06020          strcat(FFTWWisdomFile,NAMD_VERSION);
06021          strcat(FFTWWisdomFile,"_");
06022          strcat(FFTWWisdomFile,NAMD_PLATFORM);
06023 #ifdef NAMD_FFTW_3
06024          strcat(FFTWWisdomFile,"_FFTW3");
06025 #endif
06026          strcat(FFTWWisdomFile,".txt");
06027        }
06028 
06029        iout << iINFO << "Attempting to read FFTW data from "
06030                 << FFTWWisdomFile << "\n" << endi;
06031        FILE *wisdom_file = fopen(FFTWWisdomFile,"r");
06032        if ( wisdom_file ) {
06033 #ifdef NAMD_FFTW_3
06034          fftwf_import_wisdom_from_file(wisdom_file);
06035 #else
06036          fftw_import_wisdom_from_file(wisdom_file);
06037 #endif
06038          fclose(wisdom_file);
06039        }
06040        int nrp = 1;
06041 
06042        // rules based on work available
06043        int minslices = PMEMinSlices;
06044        int dimx = PMEGridSizeX;
06045        int nrpx = ( dimx + minslices - 1 ) / minslices;
06046        if ( nrpx > nrp ) nrp = nrpx;
06047        int dimy = PMEGridSizeY;
06048        int nrpy = ( dimy + minslices - 1 ) / minslices;
06049        if ( nrpy > nrp ) nrp = nrpy;
06050 
06051        // rules based on processors available
06052        int nrpp = CkNumPes();
06053        // if ( nrpp > 32 ) nrpp = 32;  // cap to limit messages
06054        if ( nrpp < nrp ) nrp = nrpp;
06055 
06056        // user override
06057        int nrps = PMEProcessors;
06058        if ( nrps > CkNumPes() ) nrps = CkNumPes();
06059        if ( nrps > 0 ) nrp = nrps;
06060 
06061        // make sure there aren't any totally empty processors
06062        int bx = ( dimx + nrp - 1 ) / nrp;
06063        int nrpbx = ( dimx + bx - 1 ) / bx;
06064        int by = ( dimy + nrp - 1 ) / nrp;
06065        int nrpby = ( dimy + by - 1 ) / by;
06066        nrp = ( nrpby > nrpbx ? nrpby : nrpbx );
06067        if ( bx != ( dimx + nrp - 1 ) / nrp )
06068          NAMD_bug("Error in selecting number of PME processors.");
06069        if ( by != ( dimy + nrp - 1 ) / nrp )
06070          NAMD_bug("Error in selecting number of PME processors.");
06071 
06072        // numGridPes = nrpbx;
06073        // numTransPes = nrpby;
06074        // numRecipPes = nrp;
06075        int block2 = (PMEGridSizeY + nrp - 1) / nrp;
06076        int block2_min = PMEGridSizeY % block2;
06077        if ( ! block2_min ) block2_min = block2;
06078        int dim3 = 2 * (PMEGridSizeZ/2 + 1);
06079 
06080        int n[3]; n[0] = PMEGridSizeX; n[1] = PMEGridSizeY; n[2] = PMEGridSizeZ;
06081        fftw_complex *work = new fftw_complex[n[0]];
06082        float *grid1 = (float *) fftwf_malloc(sizeof(float) *n[1]*dim3);
06083        float *grid2 = (float *) fftwf_malloc(sizeof(float) *n[0]*block2*dim3*2);
06084        iout << iINFO << "Optimizing 6 FFT steps.  1..." << endi;
06085 #ifdef NAMD_FFTW_3
06086        int fftwFlags = FFTWPatient ? FFTW_PATIENT  : FFTWEstimate ? FFTW_ESTIMATE  : FFTW_MEASURE ;
06087        int planLineSizes[1];
06088        planLineSizes[0]=n[2];
06089        int nx= n[0];
06090        int ny=block2;
06091        int sizeLines=nx*ny;
06092        int zdim = dim3;
06093        int nz=zdim;
06094        int xStride=block2 * dim3 / 2;
06095        fftwf_destroy_plan(
06096                          fftwf_plan_many_dft_r2c(1, planLineSizes, sizeLines,
06097                                                  (float *) grid2, NULL, 1, 
06098                                                  dim3,
06099                                                  (fftwf_complex *) grid2, 
06100                                                  NULL, 1,
06101                                                  dim3/2,
06102                                                  fftwFlags));
06103 
06104        iout << " 2..." << endi;
06105        fftwf_destroy_plan(
06106                          fftwf_plan_many_dft_c2r(1, planLineSizes, sizeLines,
06107                                                  (fftwf_complex *) grid2,
06108                                                  NULL, 1, 
06109                                                  dim3/2,
06110                                                  (float *) grid2, NULL, 1,
06111                                                  dim3,
06112                                                  fftwFlags));
06113        iout << " 3..." << endi;
06114        sizeLines=nz;
06115        planLineSizes[0]=block2;
06116        fftwf_destroy_plan(fftwf_plan_many_dft(1, planLineSizes, sizeLines, 
06117                                               (fftwf_complex *) grid2, NULL, 
06118                                               sizeLines, 1,
06119                                               (fftwf_complex *) grid2, NULL, 
06120                                               sizeLines, 1,
06121                                               FFTW_FORWARD, 
06122                                               fftwFlags));
06123        iout << " 4..." << endi;
06124        fftwf_destroy_plan(fftwf_plan_many_dft(1, planLineSizes, sizeLines, 
06125                                               (fftwf_complex *) grid2, NULL, 
06126                                               sizeLines, 1,
06127                                               (fftwf_complex *) grid2, NULL, 
06128                                               sizeLines, 1,
06129                                               FFTW_FORWARD, 
06130                                               fftwFlags));
06131        iout << " 5..." << endi;
06132        sizeLines=ny*nz;
06133        planLineSizes[0]=n[0];
06134        fftwf_destroy_plan(fftwf_plan_many_dft(1, planLineSizes, sizeLines,
06135                                               (fftwf_complex *) grid2, NULL,
06136                                               sizeLines, 1,
06137                                               (fftwf_complex *) grid2, NULL, 
06138                                               sizeLines, 1,
06139                                               FFTW_FORWARD,
06140                                               fftwFlags));
06141        iout << " 6..." << endi;
06142        fftwf_destroy_plan(fftwf_plan_many_dft(1, planLineSizes, sizeLines,
06143                                               (fftwf_complex *) grid2, NULL, 
06144                                               sizeLines, 1,
06145                                               (fftwf_complex *) grid2, NULL, 
06146                                               sizeLines, 1,
06147                                               FFTW_BACKWARD,
06148                                               fftwFlags));
06149 
06150 #else
06151        rfftwnd_destroy_plan( rfftwnd_create_plan_specific(
06152          2, n+1, FFTW_REAL_TO_COMPLEX,
06153          ( FFTWEstimate ? FFTW_ESTIMATE : FFTW_MEASURE )
06154          | FFTW_IN_PLACE | FFTW_USE_WISDOM, grid1, 1, 0, 0) );
06155        iout << " 2..." << endi;
06156        fftw_destroy_plan( fftw_create_plan_specific(n[0], FFTW_REAL_TO_COMPLEX,
06157          ( FFTWEstimate ? FFTW_ESTIMATE : FFTW_MEASURE )
06158          | FFTW_IN_PLACE | FFTW_USE_WISDOM, (fftw_complex *) grid2,
06159          block2*dim3/2, work, 1) );
06160        iout << " 3..." << endi;
06161        fftw_destroy_plan( fftw_create_plan_specific(n[0], FFTW_REAL_TO_COMPLEX,
06162          ( FFTWEstimate ? FFTW_ESTIMATE : FFTW_MEASURE )
06163          | FFTW_IN_PLACE | FFTW_USE_WISDOM, (fftw_complex *) grid2,
06164          block2_min*dim3/2, work, 1) );
06165        iout << " 4..." << endi;
06166        fftw_destroy_plan( fftw_create_plan_specific(n[0], FFTW_COMPLEX_TO_REAL,
06167          ( FFTWEstimate ? FFTW_ESTIMATE : FFTW_MEASURE )
06168          | FFTW_IN_PLACE | FFTW_USE_WISDOM, (fftw_complex *) grid2,
06169          block2*dim3/2, work, 1) );
06170        iout << " 5..." << endi;
06171        fftw_destroy_plan( fftw_create_plan_specific(n[0], FFTW_COMPLEX_TO_REAL,
06172          ( FFTWEstimate ? FFTW_ESTIMATE : FFTW_MEASURE )
06173          | FFTW_IN_PLACE | FFTW_USE_WISDOM, (fftw_complex *) grid2,
06174          block2_min*dim3/2, work, 1) );
06175        iout << " 6..." << endi;
06176        rfftwnd_destroy_plan( rfftwnd_create_plan_specific(
06177          2, n+1, FFTW_COMPLEX_TO_REAL,
06178          ( FFTWEstimate ? FFTW_ESTIMATE : FFTW_MEASURE )
06179          | FFTW_IN_PLACE | FFTW_USE_WISDOM, grid1, 1, 0, 0) );
06180 #endif
06181        iout << "   Done.\n" << endi;
06182        delete [] work;
06183        fftwf_free(grid1);
06184        fftwf_free(grid2);
06185 
06186 #ifdef NAMD_FFTW_3 
06187        FFTWWisdomString = fftwf_export_wisdom_to_string();
06188 #else
06189        FFTWWisdomString = fftw_export_wisdom_to_string();
06190 #endif
06191 
06192       if ( FFTWWisdomString && (CmiNumPartitions() == 1) ) {
06193        iout << iINFO << "Writing FFTW data to "
06194                 << FFTWWisdomFile << "\n" << endi;
06195        wisdom_file = fopen(FFTWWisdomFile,"w");
06196        if ( wisdom_file ) {
06197 #ifdef NAMD_FFTW_3 
06198          fftwf_export_wisdom_to_file(wisdom_file);
06199 #else
06200          fftw_export_wisdom_to_file(wisdom_file);
06201 #endif
06202          fclose(wisdom_file);
06203        }
06204       }
06205      }
06206 #endif
06207      iout << endi;
06208    }
06209    if (fullDirectOn)
06210    {
06211      iout << iINFO << "DIRECT FULL ELECTROSTATIC CALCULATIONS ACTIVE\n";
06212      iout << endi;
06213    }
06214 
06215    // MSM configure
06216    if (MSMOn)
06217    {
06218      // check MSMQuality
06219      enum { LO=0, MEDLO, MED, MEDHI, HI };
06220 
06221      // MSMApprox
06222      enum { CUBIC=0, QUINTIC, QUINTIC2,
06223        SEPTIC, SEPTIC3, NONIC, NONIC4, C1HERMITE, NUM_APPROX };
06224 
06225      // MSMSplit
06226      enum { TAYLOR2=0, TAYLOR3, TAYLOR4,
06227        TAYLOR5, TAYLOR6, TAYLOR7, TAYLOR8, NUM_SPLIT };
06228 
06229      if (MSMApprox || MSMSplit) {  // take these definitions
06230        if (MSMApprox < 0 || MSMApprox >= NUM_APPROX) {
06231          NAMD_die("MSM: unknown approximation requested (MSMApprox)");
06232        }
06233        if (MSMSplit < 0 || MSMSplit >= NUM_SPLIT) {
06234          NAMD_die("MSM: unknown splitting requested (MSMSplit)");
06235        }
06236      }
06237      else {  // otherwise use MSMQuality to set MSMApprox and MSMSplit
06238        switch (MSMQuality) {
06239          case LO:
06240            MSMApprox = CUBIC;
06241            MSMSplit = TAYLOR2;
06242            break;
06243          case MEDLO:
06244            MSMApprox = C1HERMITE;
06245            MSMSplit = TAYLOR3;
06246            break;
06247          case MED:
06248            MSMApprox = QUINTIC;
06249            MSMSplit = TAYLOR3;
06250            break;
06251          case MEDHI:
06252            MSMApprox = SEPTIC;
06253            MSMSplit = TAYLOR4;
06254            break;
06255          case HI:
06256            MSMApprox = NONIC;
06257            MSMSplit = TAYLOR5;
06258            break;
06259          default:
06260            NAMD_die("MSM: unknown quality requested (MSMQuality)");
06261        }
06262      }
06263 
06264      iout << iINFO
06265        << "MULTILEVEL SUMMATION METHOD (MSM) FOR ELECTROSTATICS ACTIVE\n";
06266      if (MsmSerialOn) {
06267        iout << iINFO
06268          << "PERFORMING SERIAL MSM CALCULATION FOR LONG-RANGE PART\n";
06269      }
06270      const char *approx_str, *split_str;
06271      switch (MSMApprox) {
06272        case CUBIC:    approx_str = "C1 CUBIC";   break;
06273        case QUINTIC:  approx_str = "C1 QUINTIC"; break;
06274        case QUINTIC2: approx_str = "C2 QUINTIC"; break;
06275        case SEPTIC:   approx_str = "C1 SEPTIC";  break;
06276        case SEPTIC3:  approx_str = "C3 SEPTIC";  break;
06277        case NONIC:    approx_str = "C1 NONIC";   break;
06278        case NONIC4:   approx_str = "C4 NONIC";   break;
06279        case C1HERMITE:approx_str = "C1 HERMITE"; break;
06280        default:       approx_str = "UNKNOWN";    break;
06281      }
06282      switch (MSMSplit) {
06283        case TAYLOR2:  split_str = "C2 TAYLOR";   break;
06284        case TAYLOR3:  split_str = "C3 TAYLOR";   break;
06285        case TAYLOR4:  split_str = "C4 TAYLOR";   break;
06286        case TAYLOR5:  split_str = "C5 TAYLOR";   break;
06287        case TAYLOR6:  split_str = "C6 TAYLOR";   break;
06288        case TAYLOR7:  split_str = "C7 TAYLOR";   break;
06289        case TAYLOR8:  split_str = "C8 TAYLOR";   break;
06290        default:       split_str = "UNKNOWN";     break;
06291      }
06292      iout << iINFO
06293        << "MSM WITH " << approx_str << " INTERPOLATION "
06294        << "AND " << split_str << " SPLITTING\n"
06295        << endi;
06296 
06297    } // end MSM configure
06298    if (FMMOn)
06299    {
06300 #ifdef FMM_SOLVER
06301      iout << iINFO << "FAST MULTIPOLE METHOD (FMM) FOR ELECTROSTATICS ACTIVE\n";
06302      iout << iINFO << "PERFORMING SERIAL FMM CALCULATION\n";
06303      iout << iINFO << "FMM LEVELS = " << FMMLevels << "\n";
06304      iout << iINFO << "FMM PADDING = " << FMMPadding << " ANGSTROMS\n";
06305      iout << endi;
06306 #else
06307      NAMD_die("Must link to FMM library to use FMM\n");
06308 #endif
06309    }
06310 
06311    if ( FMAOn || PMEOn || MSMOn || fullDirectOn || GBISOn || FMMOn )
06312    {
06313      iout << iINFO << "FULL ELECTROSTATIC EVALUATION FREQUENCY      "
06314         << fullElectFrequency << "\n";
06315      iout << endi;
06316 
06317      if ( ( outputEnergies % fullElectFrequency ) &&
06318           ( fullElectFrequency % outputEnergies ) )
06319         NAMD_die("Either outputEnergies must be a multiple of fullElectFrequency or vice versa.\n");
06320    }
06321 
06322   if (MTSAlgorithm == NAIVE)
06323   {
06324     iout << iINFO << "USING NAIVE (CONSTANT FORCE) MTS SCHEME.\n" << endi;
06325   }
06326   if (MTSAlgorithm == VERLETI )
06327   {
06328     iout << iINFO << "USING VERLET I (r-RESPA) MTS SCHEME.\n" << endi;
06329   }
06330 
06331    if (longSplitting == SHARP)
06332   iout << iINFO << "SHARP SPLITTING OF LONG RANGE ELECTROSTATICS\n";
06333    else if (longSplitting == XPLOR)
06334   iout << iINFO << "XPLOR SPLITTING OF LONG RANGE ELECTROSTATICS\n";
06335    else if (longSplitting == C1)
06336   iout << iINFO << "C1 SPLITTING OF LONG RANGE ELECTROSTATICS\n";
06337    else if (longSplitting == C2)
06338   iout << iINFO << "C2 SPLITTING OF LONG RANGE ELECTROSTATICS\n";
06339 
06340    if (splitPatch == SPLIT_PATCH_POSITION)
06341   iout << iINFO << "PLACING ATOMS IN PATCHES BY POSITION\n";
06342    else if (splitPatch == SPLIT_PATCH_HYDROGEN)
06343   iout << iINFO << "PLACING ATOMS IN PATCHES BY HYDROGEN GROUPS\n";
06344 
06345    iout << endi;
06346 
06347    if (mollyOn)
06348    {
06349      iout << iINFO << "SLOW FORCE MOLLIFICATION : \n";
06350      iout << iINFO << "         ERROR TOLERANCE : " << mollyTol << "\n";
06351      iout << iINFO << "          MAX ITERATIONS : " << mollyIter << "\n";
06352      iout << endi;
06353    }
06354 
06355    if (rigidBonds != RIGID_NONE)
06356    {
06357      iout << iINFO << "RIGID BONDS TO HYDROGEN : ";
06358      if (rigidBonds == RIGID_ALL)    iout << "ALL\n";
06359      if (rigidBonds == RIGID_WATER)  iout << "WATER\n";
06360      iout << iINFO << "        ERROR TOLERANCE : " << rigidTol << "\n";
06361      iout << iINFO << "         MAX ITERATIONS : " << rigidIter << "\n";
06362      if (useSettle) iout << iINFO << "RIGID WATER USING SETTLE ALGORITHM\n";
06363      iout << endi;
06364    }
06365    
06366 
06367    if (nonbondedFrequency != 1)
06368    {
06369      iout << iINFO << "NONBONDED FORCES EVALUATED EVERY " << nonbondedFrequency << " STEPS\n";
06370    }
06371 
06372    iout << iINFO << "RANDOM NUMBER SEED     "
06373       << randomSeed << "\n";
06374 
06375    iout << endi;
06376 
06377    iout << iINFO << "USE HYDROGEN BONDS?    ";
06378    if (HydrogenBonds)
06379    {
06380   iout << "YES\n" << endi;
06381   iout << iINFO << "USE ANTECEDENT ATOMS?  ";
06382   iout << (useAntecedent ? "YES" : "NO");
06383         iout << "\nHB DIST CUT, ON, OFF   ";
06384   iout << daCutoffDist << " , " << daOnDist << " , " << daOffDist;
06385         iout << "\nHB ANGLE CUT, ON, OFF  ";
06386   iout << dhaCutoffAngle << " , " << dhaOnAngle << " , ";
06387   iout << dhaOffAngle;
06388         iout << "\nHB ATT, REP exponents  ";
06389   iout << distAttExp << " , " << distRepExp;
06390         iout << "\nHB AA, HA exponents    ";
06391   iout << aaAngleExp << " , " << haAngleExp;
06392   iout << "\n" << endi;
06393    }
06394    else
06395    {
06396   iout << "NO\n" << endi;
06397    }
06398 
06399 // If this is AMBER, then print AMBER options
06400 
06401    if (amberOn)
06402    { iout << iINFO << "Using AMBER format force field!\n";
06403      current = config->find("parmfile");
06404      iout << iINFO << "AMBER PARM FILE        " << current->data << '\n';
06405      if (opts.defined("coordinates"))
06406      { current = config->find("coordinates");
06407        iout << iINFO << "COORDINATE PDB         " << current->data << '\n';
06408      }
06409      else
06410      { current = config->find("ambercoor");
06411        iout << iINFO << "AMBER COORDINATE FILE  " << current->data << '\n';
06412      }
06413      if (readExclusions)
06414        iout << iINFO << "Exclusions will be read from PARM file!\n";
06415      else
06416        iout << iINFO << "Exclusions in PARM file will be ignored!\n";
06417      iout << iINFO << "SCNB (VDW SCALING)     " << vdwscale14 << "\n" << endi;
06418    }
06419    else if(gromacsOn)
06420    {
06421      iout << iINFO << "Using GROMACS format force field!\n";
06422 
06423      current = config->find("grotopfile");
06424      // it should be defined, but, just in case...
06425      if (current == NULL)
06426        NAMD_die("no GROMACS topology file defined!?");
06427      iout << iINFO << "GROMACS TOPO FILE        " << current->data << '\n';
06428 
06429      // XXX handle the two types of coordinates more gracefully
06430      current = config->find("grocoorfile");
06431      if (current == NULL) {
06432        current = config->find("coordinates");
06433        if (current == NULL) {
06434          NAMD_die("no coordinate file defined!?");
06435        }
06436      }
06437      iout << iINFO << "GROMACS COOR FILE        " << current->data << '\n' 
06438           << endi;
06439 
06440    }
06441    else {
06442      if ( !usePluginIO ) {
06443        if ( current = config->find("coordinates") )
06444        iout << iINFO << "COORDINATE PDB         " << current->data << '\n' << endi;
06445      }
06446 
06447      current = config->find("structure");
06448 
06449      iout << iINFO << "STRUCTURE FILE         " 
06450         << current->data << "\n" << endi;
06451 
06452      if (cosAngles) 
06453      {
06454        iout << iINFO << "COSANGLES ON. SOME ANGLES WILL BE COSINE-BASED\n" << endi;
06455      }
06456 
06457      //****** BEGIN CHARMM/XPLOR type changes
06458      if (paraTypeXplorOn)
06459      {
06460        iout << iINFO << "PARAMETER file: XPLOR format! (default) \n" << endi;
06461      }
06462      else if (paraTypeCharmmOn)
06463      {
06464        iout << iINFO << "PARAMETER file: CHARMM format! \n" << endi;
06465      }
06466      //****** END CHARMM/XPLOR type changes
06467 
06468      current = config->find("parameters");
06469 
06470      while (current != NULL)
06471      {
06472        iout << iINFO << "PARAMETERS             " 
06473           << current->data << "\n" << endi;
06474        current = current->next;
06475      }
06476    }
06477 
06478      iout << iINFO << "USING " <<
06479         ( vdwGeometricSigma ? "GEOMETRIC" : "ARITHMETIC" ) <<
06480         " MEAN TO COMBINE L-J SIGMA PARAMETERS\n" << endi;
06481 
06482    if (opts.defined("bincoordinates"))
06483    {
06484      current = config->find("bincoordinates");
06485 
06486      iout << iINFO << "BINARY COORDINATES     " 
06487               << current->data << "\n";
06488    }
06489 
06490 #ifdef MEM_OPT_VERSION
06491    if (opts.defined("binrefcoords"))
06492    {
06493      current = config->find("binrefcoords");
06494 
06495      iout << iINFO << "BINARY REF COORDS      " 
06496               << current->data << "\n";
06497    }
06498 #endif
06499 
06500    if (firstTimestep)
06501    {
06502   iout << iINFO << "FIRST TIMESTEP         "
06503      << firstTimestep << "\n" << endi;
06504    }
06505 }
06506 /*    END OF FUNCTION initialize_config_data    */
06507    
06508    
06509 /****************************************************************/
06510 /*                                                              */
06511 /*      FUNCTION parse_mgrid_params                             */
06512 /*                                                              */
06513 /*                                                              */
06514 /****************************************************************/
06515 void SimParameters::parse_mgrid_params(ConfigList *config)
06516 {
06517   StringList *current;
06518 
06519   mgridforcelist.clear();
06520   char *key = new char[81];
06521   char *valstr = new char[256];
06522   // If the old gridforce commands are still in use, parse them too.
06523   if (gridforceOn) {
06524     mgridforceOn = TRUE;
06525     const char *default_key = MGRIDFORCEPARAMS_DEFAULTKEY;
06526     MGridforceParams* mgfp = NULL;
06527     mgfp = mgridforcelist.find_key(default_key);
06528     if (mgfp != NULL) {
06529       iout << iINFO << "MGRIDFORCEPOTFILE key " 
06530         << key << " redefined for file " << valstr << "\n" << endi;
06531     } else {
06532       mgfp = mgridforcelist.add(default_key);
06533     }
06534     mgfp->gridforceVolts = gridforceVolts;
06535     mgfp->gridforceScale = gridforceScale;
06536 
06537     parse_mgrid_string_param(config,"gridforcefile",&(mgfp->gridforceFile));
06538     parse_mgrid_string_param(config,"gridforcecol",&(mgfp->gridforceCol));
06539     parse_mgrid_string_param(config,"gridforcechargecol",&(mgfp->gridforceQcol));
06540     parse_mgrid_string_param(config,"gridforcepotfile",&(mgfp->gridforceVfile));
06541     
06542     mgfp->gridforceCont[0] = gridforceContA1;
06543     mgfp->gridforceCont[1] = gridforceContA2;
06544     mgfp->gridforceCont[2] = gridforceContA3;
06545     mgfp->gridforceVOffset = gridforceVOffset;
06546     
06547     mgfp->gridforceLite = gridforceLite;
06548     mgfp->gridforceCheckSize = gridforcechecksize;
06549   }
06550   
06551   // Create multigrid parameter structures
06552   current = config->find("mgridforcepotfile");
06553   while (current != NULL) {
06554     int curlen = strlen(current->data);
06555     //    iout << iINFO << "MGRIDFORCEPOTFILE " << current->data 
06556     //         << " " << curlen << "\n"  << endi;
06557     sscanf(current->data,"%80s%255s",key,valstr);
06558     
06559     MGridforceParams* mgfp = NULL;
06560     mgfp = mgridforcelist.find_key(key);
06561     if ( mgfp != NULL) {
06562       iout << iINFO << "MGRIDFORCEPOTFILE key " 
06563         << key << " redefined for file " << valstr << "\n" << endi;
06564     } else {
06565       mgfp = mgridforcelist.add(key);
06566     }
06567     int fnamelen = strlen(valstr);
06568     mgfp->gridforceVfile = new char[fnamelen+1];
06569     strncpy(mgfp->gridforceVfile,valstr,fnamelen+1);
06570     mgfp->gridforceScale.x = 
06571       mgfp->gridforceScale.y = 
06572         mgfp->gridforceScale.z = 1.;
06573     mgfp->gridforceVOffset.x = 
06574       mgfp->gridforceVOffset.y = 
06575         mgfp->gridforceVOffset.z = 0.;
06576     
06577     current = current->next;
06578   }
06579 
06580   current = config->find("mgridforcefile");
06581   while (current != NULL) {
06582     int curlen = strlen(current->data);
06583     //    iout << iINFO << "MGRIDFORCEFILE " << current->data          
06584     //         << " " << curlen << "\n"  << endi;
06585     sscanf(current->data,"%80s%255s",key,valstr);
06586     
06587     MGridforceParams* mgfp = NULL;
06588     mgfp = mgridforcelist.find_key(key);
06589     if ( mgfp == NULL) {
06590       iout << iINFO << "MGRIDFORCEFILE no key " 
06591       << key << " defined for file " << valstr << "\n" << endi;
06592     } else {
06593       int fnamelen = strlen(valstr);
06594       if (mgfp->gridforceFile != NULL) {
06595         delete [] mgfp->gridforceFile;
06596       }
06597       mgfp->gridforceFile = new char[fnamelen+1];
06598       strncpy(mgfp->gridforceFile,valstr,fnamelen+1);
06599     }
06600 
06601     current = current->next;
06602   }
06603   
06604   current = config->find("mgridforcevolts");
06605   while (current != NULL) {
06606     //    iout << iINFO << "MGRIDFORCEVOLTS " << current->data << "\n"  
06607     //         << endi;
06608     int curlen = strlen(current->data);
06609     sscanf(current->data,"%80s%255s",key,valstr);
06610     
06611     MGridforceParams* mgfp = NULL;
06612     mgfp = mgridforcelist.find_key(key);
06613     if ( mgfp == NULL) {
06614       iout << iINFO << "MGRIDFORCEVOLTS no key " 
06615       << key << " defined for file " << valstr << "\n" << endi;
06616     } else {
06617       int boolval = MGridforceParamsList::atoBool(valstr);
06618       if (boolval == -1) {
06619         iout << iINFO << "MGRIDFORCEVOLTS  key " 
06620           << key << " boolval " << valstr << " badly defined" << endi;
06621       } else {
06622         mgfp->gridforceVolts = (boolval == 1);
06623       }
06624     }
06625 
06626     current = current->next;
06627   }
06628   
06629   current = config->find("mgridforcescale");
06630   while (current != NULL) {
06631     //    iout << iINFO << "MGRIDFORCESCALE " << current->data 
06632     //         << "\n"  << endi;
06633     int curlen = strlen(current->data);
06634     int nread;
06635     sscanf(current->data,"%80s%n",key,&nread);
06636     char *val = current->data + nread + 1;
06637     
06638     MGridforceParams* mgfp = NULL;
06639     mgfp = mgridforcelist.find_key(key);
06640     if ( mgfp == NULL) {
06641       iout << iINFO << "MGRIDFORCESCALE no key " 
06642       << key << " defined for vector " << val << "\n" <