SimParameters.C

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