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