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