00001
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <stdio.h>
00016 #include <stdlib.h>
00017 #include <string.h>
00018 #include <vector>
00019 #ifndef WIN32
00020 #include <strings.h>
00021 #endif
00022 #include "InfoStream.h"
00023 #include <charm++.h>
00024 #include "Parameters.h"
00025 #include "Communicate.h"
00026 #include "ConfigList.h"
00027
00028 #include "SimParameters.h"
00029
00030
00031 #define MIN_DEBUG_LEVEL 3
00032
00033 #include "Debug.h"
00034
00035 #define INDEX(ncols,i,j) ((i)*ncols + (j))
00036
00037 #define ENABLETABLES
00038
00039 static char** table_types;
00040
00041
00042
00043
00044
00045 struct bond_params
00046 {
00047 char atom1name[11];
00048 char atom2name[11];
00049 Real forceconstant;
00050 Real distance;
00051 Index index;
00052 struct bond_params *left;
00053 struct bond_params *right;
00054 };
00055
00056
00057
00058
00059
00060 struct angle_params
00061 {
00062 char atom1name[11];
00063 char atom2name[11];
00064 char atom3name[11];
00065 Real forceconstant;
00066 int normal;
00067 Real angle;
00068 Real k_ub;
00069 Real r_ub;
00070 Index index;
00071 struct angle_params *left;
00072 struct angle_params *right;
00073 };
00074
00075
00076
00077
00078
00079
00080
00081 struct dihedral_params
00082 {
00083 char atom1name[11];
00084 char atom2name[11];
00085 char atom3name[11];
00086 char atom4name[11];
00087 char atom1wild;
00088 char atom2wild;
00089 char atom3wild;
00090 char atom4wild;
00091 int multiplicity;
00092 FourBodyConsts values[MAX_MULTIPLICITY];
00093 Index index;
00094 struct dihedral_params *next;
00095 dihedral_params() { memset(this, 0, sizeof(dihedral_params)); }
00096 };
00097
00098
00099
00100
00101
00102
00103
00104 struct improper_params
00105 {
00106 char atom1name[11];
00107 char atom2name[11];
00108 char atom3name[11];
00109 char atom4name[11];
00110 int multiplicity;
00111 FourBodyConsts values[MAX_MULTIPLICITY];
00112 Index index;
00113 struct improper_params *next;
00114 };
00115
00116 struct crossterm_params
00117 {
00118 crossterm_params(int dim) : dimension(dim) {
00119 values = new double[dimension*dimension];
00120 }
00121 ~crossterm_params() {
00122 delete [] values;
00123 }
00124 char atom1name[11];
00125 char atom2name[11];
00126 char atom3name[11];
00127 char atom4name[11];
00128 char atom5name[11];
00129 char atom6name[11];
00130 char atom7name[11];
00131 char atom8name[11];
00132 int dimension;
00133 double *values;
00134 Index index;
00135 struct crossterm_params *next;
00136 };
00137
00138
00139
00140
00141 struct vdw_params
00142 {
00143 char atomname[11];
00144 Real sigma;
00145 Real epsilon;
00146 Real sigma14;
00147 Real epsilon14;
00148 Index index;
00149 struct vdw_params *left;
00150 struct vdw_params *right;
00151 };
00152
00153
00154
00155
00156 struct vdw_pair_params
00157 {
00158 char atom1name[11];
00159 char atom2name[11];
00160 Real A;
00161 Real B;
00162 Real A14;
00163 Real B14;
00164 struct vdw_pair_params *next;
00165 };
00166
00167 struct table_pair_params
00168 {
00169 char atom1name[11];
00170 char atom2name[11];
00171 int K;
00172 struct table_pair_params *next;
00173 };
00174
00175 Parameters::Parameters() {
00176 initialize();
00177 }
00178
00179 void Parameters::initialize() {
00180
00181 paramType = -1;
00182
00183
00184 atomTypeNames=NULL;
00185 bondp=NULL;
00186 anglep=NULL;
00187 improperp=NULL;
00188 dihedralp=NULL;
00189 crosstermp=NULL;
00190 vdwp=NULL;
00191 vdw_pairp=NULL;
00192 table_pairp=NULL;
00193 bond_array=NULL;
00194 angle_array=NULL;
00195 dihedral_array=NULL;
00196 improper_array=NULL;
00197 crossterm_array=NULL;
00198 vdw_array=NULL;
00199 vdw_pair_tree=NULL;
00200 tab_pair_tree=NULL;
00201 maxDihedralMults=NULL;
00202 maxImproperMults=NULL;
00203
00204
00205 NumBondParams=0;
00206 NumAngleParams=0;
00207 NumDihedralParams=0;
00208 NumImproperParams=0;
00209 NumCrosstermParams=0;
00210 NumVdwParams=0;
00211 NumVdwPairParams=0;
00212 NumTablePairParams=0;
00213 NumCosAngles=0;
00214 }
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 Parameters::Parameters(SimParameters *simParams, StringList *f)
00228 {
00229 initialize();
00230
00231
00233 if (simParams->paraTypeXplorOn)
00234 {
00235 paramType = paraXplor;
00236 }
00237 else if (simParams->paraTypeCharmmOn)
00238 {
00239 paramType = paraCharmm;
00240 }
00241
00242
00243 if (simParams->cosAngles) {
00244 cosAngles = true;
00245 } else {
00246 cosAngles = false;
00247 }
00248
00249
00250
00251
00252 AllFilesRead = FALSE;
00253
00254 numenerentries=0;
00255 table_ener = NULL;
00256 if (simParams->tabulatedEnergies) {
00257
00258 fprintf(stdout,"Working on tables\n");
00259 read_ener_table(simParams);
00260 }
00261
00262 if (NULL != f)
00263 {
00264 do
00265 {
00266
00267 if (paramType == paraXplor)
00268 {
00269 read_parameter_file(f->data);
00270 }
00271 else if (paramType == paraCharmm)
00272 {
00273 read_charmm_parameter_file(f->data);
00274 }
00275
00276 f = f->next;
00277 } while ( f != NULL );
00278
00279 done_reading_files();
00280 }
00281
00282 }
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 Parameters::~Parameters()
00295
00296 {
00297 if (atomTypeNames)
00298 delete [] atomTypeNames;
00299
00300 if (bondp != NULL)
00301 free_bond_tree(bondp);
00302
00303 if (anglep != NULL)
00304 free_angle_tree(anglep);
00305
00306 if (dihedralp != NULL)
00307 free_dihedral_list(dihedralp);
00308
00309 if (improperp != NULL)
00310 free_improper_list(improperp);
00311
00312 if (crosstermp != NULL)
00313 free_crossterm_list(crosstermp);
00314
00315 if (vdwp != NULL)
00316 free_vdw_tree(vdwp);
00317
00318 if (vdw_pairp != NULL)
00319 free_vdw_pair_list();
00320
00321 if (bond_array != NULL)
00322 delete [] bond_array;
00323
00324 if (angle_array != NULL)
00325 delete [] angle_array;
00326
00327 if (dihedral_array != NULL)
00328 delete [] dihedral_array;
00329
00330 if (improper_array != NULL)
00331 delete [] improper_array;
00332
00333 if (crossterm_array != NULL)
00334 delete [] crossterm_array;
00335
00336 if (vdw_array != NULL)
00337 delete [] vdw_array;
00338
00339 if (tab_pair_tree != NULL)
00340 free_table_pair_tree(tab_pair_tree);
00341
00342 if (vdw_pair_tree != NULL)
00343 free_vdw_pair_tree(vdw_pair_tree);
00344
00345 if (maxDihedralMults != NULL)
00346 delete [] maxDihedralMults;
00347
00348 if (maxImproperMults != NULL)
00349 delete [] maxImproperMults;
00350
00351 for( int i = 0; i < error_msgs.size(); ++i ) {
00352 delete [] error_msgs[i];
00353 }
00354 error_msgs.resize(0);
00355 }
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374 void Parameters::read_parameter_file(char *fname)
00375
00376 {
00377 char buffer[512];
00378 char first_word[512];
00379 FILE *pfile;
00380
00381
00382
00383 if (AllFilesRead)
00384 {
00385 NAMD_die("Tried to read another parameter file after being told that all files were read!");
00386 }
00387
00388
00389 if ( (pfile = Fopen(fname, "r")) == NULL)
00390 {
00391 char err_msg[256];
00392
00393 sprintf(err_msg, "UNABLE TO OPEN XPLOR PARAMETER FILE %s\n", fname);
00394 NAMD_die(err_msg);
00395 }
00396
00397
00398 while (NAMD_read_line(pfile, buffer) != -1)
00399 {
00400
00401 NAMD_find_first_word(buffer, first_word);
00402
00403
00404
00405
00406
00407
00408
00409 if ((buffer[0] != '!') &&
00410 !NAMD_blank_string(buffer) &&
00411 (strncasecmp(first_word, "REMARK", 6) != 0) &&
00412 (strcasecmp(first_word, "set")!=0) &&
00413 (strncasecmp(first_word, "AEXP", 4) != 0) &&
00414 (strncasecmp(first_word, "REXP", 4) != 0) &&
00415 (strncasecmp(first_word, "HAEX", 4) != 0) &&
00416 (strncasecmp(first_word, "AAEX", 4) != 0) &&
00417 (strncasecmp(first_word, "NBOND", 5) != 0) &&
00418 (strncasecmp(first_word, "CUTNB", 5) != 0) &&
00419 (strncasecmp(first_word, "END", 3) != 0) &&
00420 (strncasecmp(first_word, "CTONN", 5) != 0) &&
00421 (strncasecmp(first_word, "EPS", 3) != 0) &&
00422 (strncasecmp(first_word, "VSWI", 4) != 0) &&
00423 (strncasecmp(first_word, "NBXM", 4) != 0) &&
00424 (strncasecmp(first_word, "INHI", 4) != 0) )
00425 {
00426
00427
00428 if (strncasecmp(first_word, "bond", 4)==0)
00429 {
00430 add_bond_param(buffer);
00431 NumBondParams++;
00432 }
00433 else if (strncasecmp(first_word, "angl", 4)==0)
00434 {
00435 add_angle_param(buffer);
00436 NumAngleParams++;
00437 }
00438 else if (strncasecmp(first_word, "dihe", 4)==0)
00439 {
00440 add_dihedral_param(buffer, pfile);
00441 NumDihedralParams++;
00442 }
00443 else if (strncasecmp(first_word, "impr", 4)==0)
00444 {
00445 add_improper_param(buffer, pfile);
00446 NumImproperParams++;
00447 }
00448 else if (strncasecmp(first_word, "nonb", 4)==0)
00449 {
00450 add_vdw_param(buffer);
00451 NumVdwParams++;
00452 }
00453 else if (strncasecmp(first_word, "nbfi", 4)==0)
00454 {
00455 add_vdw_pair_param(buffer);
00456 NumVdwPairParams++;
00457 }
00458 else if (strncasecmp(first_word, "nbta", 4)==0)
00459 {
00460
00461 if (table_ener == NULL) {
00462 continue;
00463 }
00464
00465 add_table_pair_param(buffer);
00466 NumTablePairParams++;
00467 }
00468 else if (strncasecmp(first_word, "hbon", 4)==0)
00469 {
00470 add_hb_pair_param(buffer);
00471 }
00472 else
00473 {
00474
00475
00476 char err_msg[512];
00477
00478 sprintf(err_msg, "UNKNOWN PARAMETER IN XPLOR PARAMETER FILE %s\nLINE=*%s*",
00479 fname, buffer);
00480 NAMD_die(err_msg);
00481 }
00482 }
00483 }
00484
00485
00486 Fclose(pfile);
00487
00488 return;
00489 }
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509 void Parameters::read_charmm_parameter_file(char *fname)
00510
00511 {
00512 int par_type=0;
00513
00514 int skipline;
00515 int skipall = 0;
00516 char buffer[512];
00517 char first_word[512];
00518 FILE *pfile;
00519
00520
00521
00522 if (AllFilesRead)
00523 {
00524 NAMD_die("Tried to read another parameter file after being told that all files were read!");
00525 }
00526
00527
00528 if ( (pfile = fopen(fname, "r")) == NULL)
00529 {
00530 char err_msg[256];
00531
00532 sprintf(err_msg, "UNABLE TO OPEN CHARMM PARAMETER FILE %s\n", fname);
00533 NAMD_die(err_msg);
00534 }
00535
00536
00537 while (NAMD_read_line(pfile, buffer) != -1)
00538 {
00539
00540 NAMD_find_first_word(buffer, first_word);
00541 skipline=0;
00542
00543
00544
00545
00546 if (!NAMD_blank_string(buffer) &&
00547 (strncmp(first_word, "!", 1) != 0) &&
00548 (strncmp(first_word, "*", 1) != 0) &&
00549 (strncasecmp(first_word, "END", 3) != 0))
00550 {
00551 if ( skipall ) {
00552 iout << iWARN << "SKIPPING PART OF PARAMETER FILE AFTER RETURN STATEMENT\n" << endi;
00553 break;
00554 }
00555
00556 if (strncasecmp(first_word, "bond", 4)==0)
00557 {
00558 par_type=1; skipline=1;
00559 }
00560 else if (strncasecmp(first_word, "angl", 4)==0)
00561 {
00562 par_type=2; skipline=1;
00563 }
00564 else if (strncasecmp(first_word, "thet", 4)==0)
00565 {
00566 par_type=2; skipline=1;
00567 }
00568 else if (strncasecmp(first_word, "dihe", 4)==0)
00569 {
00570 par_type=3; skipline=1;
00571 }
00572 else if (strncasecmp(first_word, "phi", 3)==0)
00573 {
00574 par_type=3; skipline=1;
00575 }
00576 else if (strncasecmp(first_word, "impr", 4)==0)
00577 {
00578 par_type=4; skipline=1;
00579 }
00580 else if (strncasecmp(first_word, "imph", 4)==0)
00581 {
00582 par_type=4; skipline=1;
00583 }
00584 else if (strncasecmp(first_word, "nbon", 4)==0)
00585 {
00586 par_type=5; skipline=1;
00587 }
00588 else if (strncasecmp(first_word, "nonb", 4)==0)
00589 {
00590 par_type=5; skipline=1;
00591 }
00592 else if (strncasecmp(first_word, "nbfi", 4)==0)
00593 {
00594 par_type=6; skipline=1;
00595 }
00596 else if (strncasecmp(first_word, "hbon", 4)==0)
00597 {
00598 par_type=7; skipline=1;
00599 }
00600 else if (strncasecmp(first_word, "cmap", 4)==0)
00601 {
00602 par_type=8; skipline=1;
00603 }
00604 else if (strncasecmp(first_word, "nbta", 4)==0)
00605 {
00606 par_type=9; skipline=1;
00607 }
00608 else if (strncasecmp(first_word, "read", 4)==0)
00609 {
00610 skip_stream_read(buffer, pfile); skipline=1;
00611 }
00612 else if (strncasecmp(first_word, "return", 4)==0)
00613 {
00614 skipall=1; skipline=1;
00615 }
00616 else if ((strncasecmp(first_word, "nbxm", 4) == 0) ||
00617 (strncasecmp(first_word, "grou", 4) == 0) ||
00618 (strncasecmp(first_word, "cdie", 4) == 0) ||
00619 (strncasecmp(first_word, "shif", 4) == 0) ||
00620 (strncasecmp(first_word, "vgro", 4) == 0) ||
00621 (strncasecmp(first_word, "vdis", 4) == 0) ||
00622 (strncasecmp(first_word, "vswi", 4) == 0) ||
00623 (strncasecmp(first_word, "cutn", 4) == 0) ||
00624 (strncasecmp(first_word, "ctof", 4) == 0) ||
00625 (strncasecmp(first_word, "cton", 4) == 0) ||
00626 (strncasecmp(first_word, "eps", 3) == 0) ||
00627 (strncasecmp(first_word, "e14f", 4) == 0) ||
00628 (strncasecmp(first_word, "wmin", 4) == 0) ||
00629 (strncasecmp(first_word, "aexp", 4) == 0) ||
00630 (strncasecmp(first_word, "rexp", 4) == 0) ||
00631 (strncasecmp(first_word, "haex", 4) == 0) ||
00632 (strncasecmp(first_word, "aaex", 4) == 0) ||
00633 (strncasecmp(first_word, "noac", 4) == 0) ||
00634 (strncasecmp(first_word, "hbno", 4) == 0) ||
00635 (strncasecmp(first_word, "cuth", 4) == 0) ||
00636 (strncasecmp(first_word, "ctof", 4) == 0) ||
00637 (strncasecmp(first_word, "cton", 4) == 0) ||
00638 (strncasecmp(first_word, "cuth", 4) == 0) ||
00639 (strncasecmp(first_word, "ctof", 4) == 0) ||
00640 (strncasecmp(first_word, "cton", 4) == 0) )
00641 {
00642 if ((par_type != 5) && (par_type != 6) && (par_type != 7) && (par_type != 9))
00643 {
00644 char err_msg[512];
00645
00646 sprintf(err_msg, "ERROR IN CHARMM PARAMETER FILE %s\nLINE=*%s*",fname, buffer);
00647 NAMD_die(err_msg);
00648 }
00649 else
00650 {
00651 skipline = 1;
00652 }
00653 }
00654 else if (par_type == 0)
00655 {
00656
00657
00658 char err_msg[512];
00659
00660 sprintf(err_msg, "UNKNOWN PARAMETER IN CHARMM PARAMETER FILE %s\nLINE=*%s*",fname, buffer);
00661 NAMD_die(err_msg);
00662 }
00663 }
00664 else
00665 {
00666 skipline=1;
00667 }
00668
00669 if ( (par_type != 0) && (!skipline) )
00670 {
00671
00672
00673
00674 if (par_type == 1)
00675 {
00676 add_bond_param(buffer);
00677 NumBondParams++;
00678 }
00679 else if (par_type == 2)
00680 {
00681 add_angle_param(buffer);
00682 NumAngleParams++;
00683 }
00684 else if (par_type == 3)
00685 {
00686 add_dihedral_param(buffer, pfile);
00687 NumDihedralParams++;
00688 }
00689 else if (par_type == 4)
00690 {
00691 add_improper_param(buffer, pfile);
00692 NumImproperParams++;
00693 }
00694 else if (par_type == 5)
00695 {
00696 add_vdw_param(buffer);
00697 NumVdwParams++;
00698 }
00699 else if (par_type == 6)
00700 {
00701 add_vdw_pair_param(buffer);
00702 NumVdwPairParams++;
00703 }
00704 else if (par_type == 7)
00705 {
00706 add_hb_pair_param(buffer);
00707 }
00708 else if (par_type == 8)
00709 {
00710 add_crossterm_param(buffer, pfile);
00711 NumCrosstermParams++;
00712 }
00713 else if (par_type == 9)
00714 {
00715
00716 if (table_ener == NULL) {
00717 continue;
00718 }
00719
00720 add_table_pair_param(buffer);
00721 NumTablePairParams++;
00722 }
00723 else
00724 {
00725
00726
00727
00728 char err_msg[512];
00729
00730 sprintf(err_msg, "INTERNAL ERROR IN CHARMM PARAMETER FILE %s\nLINE=*%s*",fname, buffer);
00731 NAMD_die(err_msg);
00732 }
00733 }
00734 }
00735
00736
00737 fclose(pfile);
00738
00739 return;
00740 }
00741
00742
00743
00744
00745 void Parameters::skip_stream_read(char *buf, FILE *fd) {
00746
00747 char buffer[513];
00748 char first_word[513];
00749 char s1[128];
00750 char s2[128];
00751 int rval = sscanf(buf, "%s %s", s1, s2);
00752 if (rval != 2) {
00753 char err_msg[512];
00754 sprintf(err_msg, "BAD FORMAT IN CHARMM PARAMETER FILE\nLINE=*%s*", buf);
00755 NAMD_die(err_msg);
00756 }
00757 if ( ! strncasecmp(s2,"PARA",4) ) return;
00758
00759 iout << iINFO << "SKIPPING " << s2 << " SECTION IN STREAM FILE\n" << endi;
00760
00761 while (NAMD_read_line(fd, buffer) != -1)
00762 {
00763
00764 NAMD_find_first_word(buffer, first_word);
00765 if (!NAMD_blank_string(buffer) &&
00766 (strncmp(first_word, "!", 1) != 0) &&
00767 (strncmp(first_word, "*", 1) != 0) &&
00768 (strncasecmp(first_word, "END", 3) == 0) ) return;
00769 }
00770
00771 }
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787 void Parameters::add_bond_param(char *buf)
00788
00789 {
00790 char atom1name[11];
00791 char atom2name[11];
00792 Real forceconstant;
00793 Real distance;
00794 int read_count;
00795 struct bond_params *new_node;
00796
00797
00798
00799 if (paramType == paraXplor)
00800 {
00801
00802 read_count=sscanf(buf, "%*s %s %s %f %f\n", atom1name, atom2name,
00803 &forceconstant, &distance);
00804 }
00805 else if (paramType == paraCharmm)
00806 {
00807
00808 read_count=sscanf(buf, "%s %s %f %f\n", atom1name, atom2name,
00809 &forceconstant, &distance);
00810 }
00811
00812
00813
00814 if (read_count != 4)
00815 {
00816 char err_msg[512];
00817
00818 if (paramType == paraXplor)
00819 {
00820 sprintf(err_msg, "BAD BOND FORMAT IN XPLOR PARAMETER FILE\nLINE=*%s*\n", buf);
00821 }
00822 else if (paramType == paraCharmm)
00823 {
00824 sprintf(err_msg, "BAD BOND FORMAT IN CHARMM PARAMETER FILE\nLINE=*%s*\n", buf);
00825 }
00826 NAMD_die(err_msg);
00827 }
00828
00829
00830 new_node = new bond_params;
00831
00832 if (new_node == NULL)
00833 {
00834 NAMD_die("memory allocation failed in Parameters::add_bond_param\n");
00835 }
00836
00837
00838
00839
00840
00841 if (strcasecmp(atom1name, atom2name) < 0)
00842 {
00843 strcpy(new_node->atom1name, atom1name);
00844 strcpy(new_node->atom2name, atom2name);
00845 }
00846 else
00847 {
00848 strcpy(new_node->atom2name, atom1name);
00849 strcpy(new_node->atom1name, atom2name);
00850 }
00851
00852
00853 new_node->forceconstant = forceconstant;
00854 new_node->distance = distance;
00855
00856
00857 new_node->left = NULL;
00858 new_node->right = NULL;
00859
00860
00861
00862 bondp=add_to_bond_tree(new_node, bondp);
00863
00864 return;
00865 }
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886 struct bond_params *Parameters::add_to_bond_tree(struct bond_params *new_node,
00887 struct bond_params *tree)
00888
00889 {
00890 int compare_code;
00891
00892
00893
00894 if (tree == NULL)
00895 return(new_node);
00896
00897
00898
00899 compare_code = strcasecmp(new_node->atom1name, tree->atom1name);
00900
00901
00902 if (compare_code == 0)
00903 {
00904
00905 compare_code = strcasecmp(new_node->atom2name, tree->atom2name);
00906
00907
00908 if (compare_code == 0)
00909 {
00910
00911
00912
00913
00914
00915 if ((tree->forceconstant != new_node->forceconstant) ||
00916 (tree->distance != new_node->distance))
00917 {
00918 iout << "\n" << iWARN << "DUPLICATE BOND ENTRY FOR "
00919 << new_node->atom1name << "-"
00920 << new_node->atom2name
00921 << "\nPREVIOUS VALUES k=" << tree->forceconstant
00922 << " x0=" << tree->distance
00923 << "\n USING VALUES k=" << new_node->forceconstant
00924 << " x0=" << new_node->distance
00925 << "\n" << endi;
00926
00927 tree->forceconstant=new_node->forceconstant;
00928 tree->distance=new_node->distance;
00929 }
00930
00931
00932 delete new_node;
00933
00934 return(tree);
00935 }
00936 }
00937
00938
00939
00940
00941 if (compare_code < 0)
00942 {
00943 tree->left = add_to_bond_tree(new_node, tree->left);
00944 }
00945 else
00946 {
00947 tree->right = add_to_bond_tree(new_node, tree->right);
00948 }
00949
00950 return(tree);
00951 }
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967 void Parameters::add_angle_param(char *buf)
00968
00969 {
00970 char atom1name[11];
00971 char atom2name[11];
00972 char atom3name[11];
00973 char norm[4]="xxx";
00974 Real forceconstant;
00975 Real angle;
00976 Real k_ub;
00977 Real r_ub;
00978 int read_count;
00979 struct angle_params *new_node;
00980
00981
00982
00983 if (paramType == paraXplor)
00984 {
00985
00986 read_count=sscanf(buf, "%*s %s %s %s %f %f UB %f %f\n",
00987 atom1name, atom2name, atom3name, &forceconstant, &angle,
00988 &k_ub, &r_ub);
00989 }
00990 else if ((paramType == paraCharmm) && cosAngles) {
00991 read_count=sscanf(buf, "%s %s %s %f %f %3s %f %f\n",
00992 atom1name, atom2name, atom3name, &forceconstant, &angle, norm,
00993 &k_ub, &r_ub);
00994
00995
00996 }
00997 else if (paramType == paraCharmm)
00998 {
00999
01000 read_count=sscanf(buf, "%s %s %s %f %f %f %f\n",
01001 atom1name, atom2name, atom3name, &forceconstant, &angle,
01002 &k_ub, &r_ub);
01003
01004
01005 }
01006
01007
01008
01009 if ( (read_count != 5) && (read_count != 7) && !(cosAngles && read_count == 6))
01010 {
01011 char err_msg[512];
01012
01013 if (paramType == paraXplor)
01014 {
01015 sprintf(err_msg, "BAD ANGLE FORMAT IN XPLOR PARAMETER FILE\nLINE=*%s*\n", buf);
01016 }
01017 else if (paramType == paraCharmm)
01018 {
01019 sprintf(err_msg, "BAD ANGLE FORMAT IN CHARMM PARAMETER FILE\nLINE=*%s*\n", buf);
01020 }
01021 NAMD_die(err_msg);
01022 }
01023
01024
01025 new_node = new angle_params;
01026
01027 if (new_node == NULL)
01028 {
01029 NAMD_die("memory allocation failed in Parameters::add_angle_param");
01030 }
01031
01032
01033
01034
01035 if (strcasecmp(atom1name, atom3name) < 0)
01036 {
01037 strcpy(new_node->atom1name, atom1name);
01038 strcpy(new_node->atom2name, atom2name);
01039 strcpy(new_node->atom3name, atom3name);
01040 }
01041 else
01042 {
01043 strcpy(new_node->atom3name, atom1name);
01044 strcpy(new_node->atom2name, atom2name);
01045 strcpy(new_node->atom1name, atom3name);
01046 }
01047
01048
01049 new_node->forceconstant = forceconstant;
01050 new_node->angle = angle;
01051
01052 if (cosAngles) {
01053 if (strcmp("cos",norm)==0) {
01054
01055 NumCosAngles++;
01056 new_node->normal = 0;
01057 } else {
01058
01059 new_node->normal = 1;
01060 }
01061 } else {
01062 new_node->normal = 1;
01063 }
01064
01065 if (read_count == 7)
01066 {
01067
01068 if (new_node->normal == 0) {
01069 NAMD_die("ERROR: Urey-Bradley angles can't be used with cosine-based terms\n");
01070 }
01071 new_node->k_ub = k_ub;
01072 new_node->r_ub = r_ub;
01073 }
01074 else
01075 {
01076 new_node->k_ub = 0.0;
01077 new_node->r_ub = 0.0;
01078 }
01079
01080 new_node->left = NULL;
01081 new_node->right = NULL;
01082
01083
01084 anglep = add_to_angle_tree(new_node, anglep);
01085
01086 return;
01087 }
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110 struct angle_params *Parameters::add_to_angle_tree(struct angle_params *new_node,
01111 struct angle_params *tree)
01112
01113 {
01114 int compare_code;
01115
01116
01117 if (tree == NULL)
01118 return(new_node);
01119
01120
01121 compare_code = strcasecmp(new_node->atom1name, tree->atom1name);
01122
01123 if (compare_code == 0)
01124 {
01125
01126 compare_code = strcasecmp(new_node->atom2name, tree->atom2name);
01127
01128 if (compare_code == 0)
01129 {
01130
01131 compare_code = strcasecmp(new_node->atom3name,
01132 tree->atom3name);
01133
01134 if (compare_code == 0)
01135 {
01136
01137
01138
01139
01140
01141
01142 if ((tree->forceconstant != new_node->forceconstant) ||
01143 (tree->angle != new_node->angle) ||
01144 (tree->k_ub != new_node->k_ub) ||
01145 (tree->r_ub != new_node->r_ub) || (tree->normal != new_node->normal))
01146 {
01147 iout << "\n" << iWARN << "DUPLICATE ANGLE ENTRY FOR "
01148 << new_node->atom1name << "-"
01149 << new_node->atom2name << "-"
01150 << new_node->atom3name
01151 << "\nPREVIOUS VALUES k="
01152 << tree->forceconstant << " theta0="
01153 << tree->angle << " k_ub="
01154 << tree->k_ub << " r_ub="
01155 << tree->r_ub
01156 << "\n USING VALUES k="
01157 << new_node->forceconstant << " theta0="
01158 << new_node->angle << " k_ub="
01159 << new_node->k_ub << " r_ub=" << new_node->r_ub
01160 << "\n" << endi;
01161
01162 tree->forceconstant=new_node->forceconstant;
01163 tree->angle=new_node->angle;
01164 tree->k_ub=new_node->k_ub;
01165 tree->r_ub=new_node->r_ub;
01166 tree->normal=new_node->normal;
01167 }
01168
01169
01170 delete new_node;
01171
01172 return(tree);
01173 }
01174 }
01175 }
01176
01177
01178
01179
01180 if (compare_code < 0)
01181 {
01182 tree->left = add_to_angle_tree(new_node, tree->left);
01183 }
01184 else
01185 {
01186 tree->right = add_to_angle_tree(new_node, tree->right);
01187 }
01188
01189 return(tree);
01190 }
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206 void Parameters::add_dihedral_param(char *buf, FILE *fd)
01207
01208 {
01209 char atom1name[11];
01210 char atom2name[11];
01211 char atom3name[11];
01212 char atom4name[11];
01213 Real forceconstant;
01214 int periodicity;
01215 Real phase_shift;
01216 int read_count;
01217 struct dihedral_params *new_node;
01218 int multiplicity;
01219 int i;
01220 char buffer[513];
01221 int ret_code;
01222
01223
01224
01225 if (paramType == paraXplor)
01226 {
01227
01228 read_count=sscanf(buf, "%*s %s %s %s %s MULTIPLE= %d %f %d %f\n",
01229 atom1name, atom2name, atom3name, atom4name, &multiplicity,
01230 &forceconstant, &periodicity, &phase_shift);
01231 }
01232 else if (paramType == paraCharmm)
01233 {
01234
01235 read_count=sscanf(buf, "%s %s %s %s %f %d %f\n",
01236 atom1name, atom2name, atom3name, atom4name,
01237 &forceconstant, &periodicity, &phase_shift);
01238 multiplicity=1;
01239 }
01240
01241 if ( (read_count != 4) && (read_count != 8) && (paramType == paraXplor) )
01242 {
01243 char err_msg[512];
01244
01245 sprintf(err_msg, "BAD DIHEDRAL FORMAT IN XPLOR PARAMETER FILE\nLINE=*%s*\n", buf);
01246 NAMD_die(err_msg);
01247 }
01248 else if ( (read_count != 7) && (paramType == paraCharmm) )
01249 {
01250 char err_msg[512];
01251
01252 sprintf(err_msg, "BAD DIHEDRAL FORMAT IN CHARMM PARAMETER FILE\nLINE=*%s*\n", buf);
01253 NAMD_die(err_msg);
01254 }
01255
01256 if ( (read_count == 4) && (paramType == paraXplor) )
01257
01258 {
01259 read_count=sscanf(buf, "%*s %*s %*s %*s %*s %f %d %f\n",
01260 &forceconstant, &periodicity, &phase_shift);
01261
01262
01263 if (read_count != 3)
01264 {
01265 char err_msg[512];
01266
01267 sprintf(err_msg, "BAD DIHEDRAL FORMAT IN XPLOR PARAMETER FILE\nLINE=*%s*\n", buf);
01268 NAMD_die(err_msg);
01269 }
01270
01271 multiplicity = 1;
01272 }
01273
01274 if (multiplicity > MAX_MULTIPLICITY)
01275 {
01276 char err_msg[181];
01277
01278 sprintf(err_msg, "Multiple dihedral with multiplicity of %d greater than max of %d",
01279 multiplicity, MAX_MULTIPLICITY);
01280 NAMD_die(err_msg);
01281 }
01282
01283
01284 new_node = new dihedral_params;
01285
01286 if (new_node == NULL)
01287 {
01288 NAMD_die("memory allocation failed in Parameters::add_dihedral_param\n");
01289 }
01290
01291
01292
01293
01294
01295 strcpy(new_node->atom1name, atom1name);
01296 strcpy(new_node->atom2name, atom2name);
01297 strcpy(new_node->atom3name, atom3name);
01298 strcpy(new_node->atom4name, atom4name);
01299 new_node->atom1wild = ! strcasecmp(atom1name, "X");
01300 new_node->atom2wild = ! strcasecmp(atom2name, "X");
01301 new_node->atom3wild = ! strcasecmp(atom3name, "X");
01302 new_node->atom4wild = ! strcasecmp(atom4name, "X");
01303 new_node->multiplicity = multiplicity;
01304 if (paramType == paraXplor && periodicity != 0) phase_shift *= -1;
01305 new_node->values[0].k = forceconstant;
01306 new_node->values[0].n = periodicity;
01307 new_node->values[0].delta = phase_shift;
01308
01309 new_node->next = NULL;
01310
01311
01312 if (multiplicity > 1)
01313 {
01314 for (i=1; i<multiplicity; i++)
01315 {
01316 ret_code = NAMD_read_line(fd, buffer);
01317
01318
01319 if (ret_code == 0)
01320 {
01321 NAMD_remove_comment(buffer);
01322 }
01323
01324
01325 while ( (ret_code == 0) && (NAMD_blank_string(buffer)) )
01326 {
01327 ret_code = NAMD_read_line(fd, buffer);
01328 }
01329
01330 if (ret_code != 0)
01331 {
01332 NAMD_die("EOF encoutner in middle of multiple dihedral");
01333 }
01334
01335 read_count=sscanf(buffer, "%f %d %f\n",
01336 &forceconstant, &periodicity, &phase_shift);
01337
01338 if (read_count != 3)
01339 {
01340 char err_msg[512];
01341
01342 sprintf(err_msg, "BAD MULTIPLE FORMAT IN XPLOR PARAMETER FILE\nLINE=*%s*\n", buffer);
01343 NAMD_die(err_msg);
01344 }
01345
01346 if (paramType == paraXplor && periodicity != 0) phase_shift *= -1;
01347 new_node->values[i].k = forceconstant;
01348 new_node->values[i].n = periodicity;
01349 new_node->values[i].delta = phase_shift;
01350 }
01351 }
01352
01353
01354
01355 if (paramType == paraXplor)
01356 {
01357 add_to_dihedral_list(new_node);
01358 }
01359 else if (paramType == paraCharmm)
01360 {
01361 add_to_charmm_dihedral_list(new_node);
01362 }
01363
01364
01365 return;
01366 }
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387 void Parameters::add_to_dihedral_list(
01388 struct dihedral_params *new_node)
01389
01390 {
01391 static struct dihedral_params *ptr;
01392 static struct dihedral_params *tail;
01393
01394
01395
01396 int i;
01397
01398
01399 if (dihedralp == NULL)
01400 {
01401 dihedralp=new_node;
01402 tail=new_node;
01403
01404 return;
01405 }
01406
01407
01408 ptr=dihedralp;
01409
01410 while (ptr != NULL)
01411 {
01412 if ( ( (strcasecmp(new_node->atom1name, ptr->atom1name) == 0) &&
01413 (strcasecmp(new_node->atom2name, ptr->atom2name) == 0) &&
01414 (strcasecmp(new_node->atom3name, ptr->atom3name) == 0) &&
01415 (strcasecmp(new_node->atom4name, ptr->atom4name) == 0) ) ||
01416 ( (strcasecmp(new_node->atom4name, ptr->atom1name) == 0) &&
01417 (strcasecmp(new_node->atom3name, ptr->atom2name) == 0) &&
01418 (strcasecmp(new_node->atom2name, ptr->atom3name) == 0) &&
01419 (strcasecmp(new_node->atom1name, ptr->atom4name) == 0) ) )
01420 {
01421
01422
01423
01424 int echoWarn=0;
01425
01426 if (ptr->multiplicity != new_node->multiplicity) {echoWarn=1;}
01427
01428 if (!echoWarn)
01429 {
01430 for (i=0; i<ptr->multiplicity; i++)
01431 {
01432 if (ptr->values[i].k != new_node->values[i].k) {echoWarn=1; break;}
01433 if (ptr->values[i].n != new_node->values[i].n) {echoWarn=1; break;}
01434 if (ptr->values[i].delta != new_node->values[i].delta) {echoWarn=1; break;}
01435 }
01436 }
01437
01438 if (echoWarn)
01439 {
01440 iout << "\n" << iWARN << "DUPLICATE DIHEDRAL ENTRY FOR "
01441 << ptr->atom1name << "-"
01442 << ptr->atom2name << "-"
01443 << ptr->atom3name << "-"
01444 << ptr->atom4name
01445 << "\nPREVIOUS VALUES MULTIPLICITY " << ptr->multiplicity << "\n";
01446
01447 for (i=0; i<ptr->multiplicity; i++)
01448 {
01449 iout << " k=" << ptr->values[i].k
01450 << " n=" << ptr->values[i].n
01451 << " delta=" << ptr->values[i].delta;
01452 }
01453
01454 iout << "\nUSING VALUES MULTIPLICITY " << new_node->multiplicity << "\n";
01455
01456 for (i=0; i<new_node->multiplicity; i++)
01457 {
01458 iout << " k=" << new_node->values[i].k
01459 << " n=" << new_node->values[i].n
01460 << " delta=" << new_node->values[i].delta;
01461 }
01462
01463 iout << endi;
01464
01465 ptr->multiplicity = new_node->multiplicity;
01466
01467 for (i=0; i<new_node->multiplicity; i++)
01468 {
01469 ptr->values[i].k = new_node->values[i].k;
01470 ptr->values[i].n = new_node->values[i].n;
01471 ptr->values[i].delta = new_node->values[i].delta;
01472 }
01473
01474 }
01475
01476
01477 delete new_node;
01478
01479 return;
01480 }
01481
01482 ptr=ptr->next;
01483 }
01484
01485
01486
01487
01488
01489
01490
01491 if ( new_node->atom1wild ||
01492 new_node->atom2wild ||
01493 new_node->atom3wild ||
01494 new_node->atom4wild )
01495 {
01496
01497 tail->next=new_node;
01498 tail=new_node;
01499
01500 return;
01501 }
01502 else
01503 {
01504
01505 new_node->next=dihedralp;
01506 dihedralp=new_node;
01507
01508 return;
01509 }
01510
01511 }
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536 void Parameters::add_to_charmm_dihedral_list(
01537 struct dihedral_params *new_node)
01538
01539 {
01540 static struct dihedral_params *ptr;
01541 static struct dihedral_params *tail;
01542
01543
01544
01545 int i;
01546 int replace;
01547
01548
01549
01550 static struct dihedral_params last_dihedral;
01551
01552
01553 if (dihedralp == NULL)
01554 {
01555 dihedralp=new_node;
01556 tail=new_node;
01557 memcpy(&last_dihedral, new_node, sizeof(dihedral_params));
01558
01559 return;
01560 }
01561
01562
01563 ptr=dihedralp;
01564
01565 while (ptr != NULL)
01566 {
01567 int same_as_last = 0;
01568 if ( ( (strcasecmp(new_node->atom1name, ptr->atom1name) == 0) &&
01569 (strcasecmp(new_node->atom2name, ptr->atom2name) == 0) &&
01570 (strcasecmp(new_node->atom3name, ptr->atom3name) == 0) &&
01571 (strcasecmp(new_node->atom4name, ptr->atom4name) == 0) ) ||
01572 ( (strcasecmp(new_node->atom4name, ptr->atom1name) == 0) &&
01573 (strcasecmp(new_node->atom3name, ptr->atom2name) == 0) &&
01574 (strcasecmp(new_node->atom2name, ptr->atom3name) == 0) &&
01575 (strcasecmp(new_node->atom1name, ptr->atom4name) == 0) )
01576 )
01577 {
01578
01579
01580
01581
01582
01583
01584 if ( ( !strcmp(ptr->atom1name, last_dihedral.atom1name) &&
01585 !strcmp(ptr->atom2name, last_dihedral.atom2name) &&
01586 !strcmp(ptr->atom3name, last_dihedral.atom3name) &&
01587 !strcmp(ptr->atom4name, last_dihedral.atom4name)))
01588 same_as_last = 1;
01589
01590
01591
01592 int echoWarn=1;
01593
01594
01595 for (i=0; i<ptr->multiplicity; i++)
01596 {
01597 if ((ptr->values[i].k == new_node->values[0].k) &&
01598 (ptr->values[i].n == new_node->values[0].n) &&
01599 (ptr->values[i].delta == new_node->values[0].delta))
01600 {
01601
01602 echoWarn=0;
01603 break;
01604 }
01605
01606 }
01607
01608 if (echoWarn)
01609 {
01610 if (!same_as_last) {
01611 iout << "\n" << iWARN << "DUPLICATE DIHEDRAL ENTRY FOR "
01612 << ptr->atom1name << "-"
01613 << ptr->atom2name << "-"
01614 << ptr->atom3name << "-"
01615 << ptr->atom4name
01616 << "\nPREVIOUS VALUES MULTIPLICITY: " << ptr->multiplicity << "\n";
01617 }
01618 replace=0;
01619
01620 for (i=0; i<ptr->multiplicity; i++)
01621 {
01622 if (!same_as_last) {
01623 iout << " k=" << ptr->values[i].k
01624 << " n=" << ptr->values[i].n
01625 << " delta=" << ptr->values[i].delta << "\n";
01626 }
01627 if (ptr->values[i].n == new_node->values[0].n)
01628 {
01629 iout << iWARN << "IDENTICAL PERIODICITY! REPLACING OLD VALUES BY: \n";
01630 ptr->values[i].k = new_node->values[0].k;
01631 ptr->values[i].delta = new_node->values[0].delta;
01632 iout << " k=" << ptr->values[i].k
01633 << " n=" << ptr->values[i].n
01634 << " delta=" << ptr->values[i].delta<< "\n";
01635 replace=1;
01636 break;
01637 }
01638 }
01639
01640 if (!replace)
01641 {
01642 ptr->multiplicity += 1;
01643
01644 if (ptr->multiplicity > MAX_MULTIPLICITY)
01645 {
01646 char err_msg[181];
01647
01648 sprintf(err_msg, "Multiple dihedral with multiplicity of %d greater than max of %d",
01649 ptr->multiplicity, MAX_MULTIPLICITY);
01650 NAMD_die(err_msg);
01651 }
01652 if (!same_as_last)
01653 iout << "INCREASING MULTIPLICITY TO: " << ptr->multiplicity << "\n";
01654
01655 i= ptr->multiplicity - 1;
01656 ptr->values[i].k = new_node->values[0].k;
01657 ptr->values[i].n = new_node->values[0].n;
01658 ptr->values[i].delta = new_node->values[0].delta;
01659
01660 if (!same_as_last)
01661 iout << " k=" << ptr->values[i].k
01662 << " n=" << ptr->values[i].n
01663 << " delta=" << ptr->values[i].delta<< "\n";
01664 }
01665
01666 iout << endi;
01667 }
01668
01669
01670 memcpy(&last_dihedral, new_node, sizeof(dihedral_params));
01671 delete new_node;
01672
01673 return;
01674 }
01675
01676 ptr=ptr->next;
01677 }
01678
01679
01680
01681
01682
01683
01684
01685
01686 if ( new_node->atom1wild ||
01687 new_node->atom2wild ||
01688 new_node->atom3wild ||
01689 new_node->atom4wild )
01690 {
01691
01692 tail->next=new_node;
01693 tail=new_node;
01694
01695 memcpy(&last_dihedral, new_node, sizeof(dihedral_params));
01696 return;
01697 }
01698 else
01699 {
01700
01701 new_node->next=dihedralp;
01702 dihedralp=new_node;
01703
01704 memcpy(&last_dihedral, new_node, sizeof(dihedral_params));
01705 return;
01706 }
01707
01708 }
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725 void Parameters::add_improper_param(char *buf, FILE *fd)
01726
01727 {
01728 char atom1name[11];
01729 char atom2name[11];
01730 char atom3name[11];
01731 char atom4name[11];
01732 Real forceconstant;
01733 int periodicity;
01734 Real phase_shift;
01735 int read_count;
01736 struct improper_params *new_node;
01737 int multiplicity;
01738 int i;
01739 char buffer[513];
01740 int ret_code;
01741
01742
01743
01744 if (paramType == paraXplor)
01745 {
01746
01747 read_count=sscanf(buf, "%*s %s %s %s %s MULTIPLE= %d %f %d %f\n",
01748 atom1name, atom2name, atom3name, atom4name, &multiplicity,
01749 &forceconstant, &periodicity, &phase_shift);
01750 }
01751 else if (paramType == paraCharmm)
01752 {
01753
01754 read_count=sscanf(buf, "%s %s %s %s %f %d %f\n",
01755 atom1name, atom2name, atom3name, atom4name,
01756 &forceconstant, &periodicity, &phase_shift);
01757 multiplicity=1;
01758 }
01759
01760 if ( (read_count != 4) && (read_count != 8) && (paramType == paraXplor) )
01761 {
01762 char err_msg[512];
01763
01764 sprintf(err_msg, "BAD IMPROPER FORMAT IN XPLOR PARAMETER FILE\nLINE=*%s*", buf);
01765 NAMD_die(err_msg);
01766 }
01767 else if ( (read_count != 7) && (paramType == paraCharmm) )
01768 {
01769 char err_msg[512];
01770
01771 sprintf(err_msg, "BAD IMPROPER FORMAT IN CHARMM PARAMETER FILE\nLINE=*%s*", buf);
01772 NAMD_die(err_msg);
01773 }
01774
01775 if ( (read_count == 4) && (paramType == paraXplor) )
01776
01777 {
01778 read_count=sscanf(buf, "%*s %*s %*s %*s %*s %f %d %f\n",
01779 &forceconstant, &periodicity, &phase_shift);
01780
01781
01782 if (read_count != 3)
01783 {
01784 char err_msg[512];
01785
01786 sprintf(err_msg, "BAD IMPROPER FORMAT IN XPLOR PARAMETER FILE\nLINE=*%s*\n", buf);
01787 NAMD_die(err_msg);
01788 }
01789
01790 multiplicity = 1;
01791 }
01792
01793 if (multiplicity > MAX_MULTIPLICITY)
01794 {
01795 char err_msg[181];
01796
01797 sprintf(err_msg, "Multiple improper with multiplicity of %d greater than max of %d",
01798 multiplicity, MAX_MULTIPLICITY);
01799 NAMD_die(err_msg);
01800 }
01801
01802
01803 new_node = new improper_params;
01804
01805 if (new_node == NULL)
01806 {
01807 NAMD_die("memory allocation failed in Parameters::add_improper_param");
01808 }
01809
01810
01811
01812 strcpy(new_node->atom1name, atom1name);
01813 strcpy(new_node->atom2name, atom2name);
01814 strcpy(new_node->atom3name, atom3name);
01815 strcpy(new_node->atom4name, atom4name);
01816 new_node->multiplicity = multiplicity;
01817 if (paramType == paraXplor && periodicity != 0) phase_shift *= -1;
01818 new_node->values[0].k = forceconstant;
01819 new_node->values[0].n = periodicity;
01820 new_node->values[0].delta = phase_shift;
01821
01822 new_node->next = NULL;
01823
01824
01825 if (multiplicity > 1)
01826 {
01827
01828 for (i=1; i<multiplicity; i++)
01829 {
01830 ret_code = NAMD_read_line(fd, buffer);
01831
01832
01833 if (ret_code == 0)
01834 {
01835 NAMD_remove_comment(buffer);
01836 }
01837
01838
01839 while ( (ret_code == 0) && (NAMD_blank_string(buffer)) )
01840 {
01841 ret_code = NAMD_read_line(fd, buffer);
01842 }
01843
01844 if (ret_code != 0)
01845 {
01846 NAMD_die("EOF encoutner in middle of multiple improper");
01847 }
01848
01849
01850 read_count=sscanf(buffer, "%f %d %f\n",
01851 &forceconstant, &periodicity, &phase_shift);
01852
01853 if (read_count != 3)
01854 {
01855 char err_msg[512];
01856
01857 sprintf(err_msg, "BAD MULTIPLE FORMAT IN XPLOR PARAMETER FILE\nLINE=*%s*\n", buffer);
01858 NAMD_die(err_msg);
01859 }
01860
01861 if (paramType == paraXplor && periodicity != 0) phase_shift *= -1;
01862 new_node->values[i].k = forceconstant;
01863 new_node->values[i].n = periodicity;
01864 new_node->values[i].delta = phase_shift;
01865 }
01866 }
01867
01868
01869 add_to_improper_list(new_node);
01870
01871 return;
01872 }
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893 void Parameters::add_to_improper_list(struct improper_params *new_node)
01894
01895 {
01896 int i;
01897 static struct improper_params *ptr;
01898 static struct improper_params *tail;
01899
01900
01901
01902
01903
01904 if (improperp == NULL)
01905 {
01906 improperp=new_node;
01907 tail=new_node;
01908
01909 return;
01910 }
01911
01912
01913 ptr=improperp;
01914
01915 while (ptr != NULL)
01916 {
01917 if ( ( (strcasecmp(new_node->atom1name, ptr->atom1name) == 0) &&
01918 (strcasecmp(new_node->atom2name, ptr->atom2name) == 0) &&
01919 (strcasecmp(new_node->atom3name, ptr->atom3name) == 0) &&
01920 (strcasecmp(new_node->atom4name, ptr->atom4name) == 0) ) ||
01921 ( (strcasecmp(new_node->atom4name, ptr->atom1name) == 0) &&
01922 (strcasecmp(new_node->atom3name, ptr->atom2name) == 0) &&
01923 (strcasecmp(new_node->atom2name, ptr->atom3name) == 0) &&
01924 (strcasecmp(new_node->atom1name, ptr->atom4name) == 0) ) )
01925 {
01926
01927
01928
01929 int echoWarn=0;
01930
01931 if (ptr->multiplicity != new_node->multiplicity) {echoWarn=1;}
01932
01933 if (!echoWarn)
01934 {
01935 for (i=0; i<ptr->multiplicity; i++)
01936 {
01937 if (ptr->values[i].k != new_node->values[i].k) {echoWarn=1; break;}
01938 if (ptr->values[i].n != new_node->values[i].n) {echoWarn=1; break;}
01939 if (ptr->values[i].delta != new_node->values[i].delta) {echoWarn=1; break;}
01940 }
01941 }
01942
01943 if (echoWarn)
01944 {
01945 iout << "\n" << iWARN << "DUPLICATE IMPROPER DIHEDRAL ENTRY FOR "
01946 << ptr->atom1name << "-"
01947 << ptr->atom2name << "-"
01948 << ptr->atom3name << "-"
01949 << ptr->atom4name
01950 << "\nPREVIOUS VALUES MULTIPLICITY " << ptr->multiplicity << "\n";
01951
01952 for (i=0; i<ptr->multiplicity; i++)
01953 {
01954 iout << " k=" << ptr->values[i].k
01955 << " n=" << ptr->values[i].n
01956 << " delta=" << ptr->values[i].delta;
01957 }
01958
01959 iout << "\n" << "USING VALUES MULTIPLICITY " << new_node->multiplicity << "\n";
01960
01961 for (i=0; i<new_node->multiplicity; i++)
01962 {
01963 iout << " k=" << new_node->values[i].k
01964 << " n=" << new_node->values[i].n
01965 << " delta=" << new_node->values[i].delta;
01966 }
01967
01968 iout << endi;
01969
01970 ptr->multiplicity = new_node->multiplicity;
01971
01972 for (i=0; i<new_node->multiplicity; i++)
01973 {
01974 ptr->values[i].k = new_node->values[i].k;
01975 ptr->values[i].n = new_node->values[i].n;
01976 ptr->values[i].delta = new_node->values[i].delta;
01977 }
01978 }
01979
01980
01981 delete new_node;
01982
01983 return;
01984 }
01985
01986 ptr=ptr->next;
01987 }
01988
01989
01990
01991
01992
01993
01994
01995 if ( (strcasecmp(new_node->atom1name, "X") == 0) ||
01996 (strcasecmp(new_node->atom2name, "X") == 0) ||
01997 (strcasecmp(new_node->atom3name, "X") == 0) ||
01998 (strcasecmp(new_node->atom4name, "X") == 0) )
01999 {
02000
02001 tail->next=new_node;
02002 tail=new_node;
02003
02004 return;
02005 }
02006 else
02007 {
02008
02009 new_node->next=improperp;
02010 improperp=new_node;
02011
02012 return;
02013 }
02014 }
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028
02029
02030 void Parameters::add_crossterm_param(char *buf, FILE *fd)
02031
02032 {
02033 char atom1name[11];
02034 char atom2name[11];
02035 char atom3name[11];
02036 char atom4name[11];
02037 char atom5name[11];
02038 char atom6name[11];
02039 char atom7name[11];
02040 char atom8name[11];
02041 int dimension;
02042 int read_count;
02043 struct crossterm_params *new_node;
02044 char buffer[513];
02045 int ret_code;
02046
02047
02048 read_count=sscanf(buf, "%s %s %s %s %s %s %s %s %d\n",
02049 atom1name, atom2name, atom3name, atom4name,
02050 atom5name, atom6name, atom7name, atom8name,
02051 &dimension);
02052
02053 if ( (read_count != 9) || dimension < 1 || dimension > 1000 )
02054 {
02055 char err_msg[512];
02056
02057 sprintf(err_msg, "BAD CMAP FORMAT IN CHARMM PARAMETER FILE\nLINE=*%s*", buf);
02058 NAMD_die(err_msg);
02059 }
02060
02061
02062 new_node = new crossterm_params(dimension);
02063
02064
02065
02066 strcpy(new_node->atom1name, atom1name);
02067 strcpy(new_node->atom2name, atom2name);
02068 strcpy(new_node->atom3name, atom3name);
02069 strcpy(new_node->atom4name, atom4name);
02070 strcpy(new_node->atom5name, atom5name);
02071 strcpy(new_node->atom6name, atom6name);
02072 strcpy(new_node->atom7name, atom7name);
02073 strcpy(new_node->atom8name, atom8name);
02074
02075 new_node->next = NULL;
02076
02077 int nterms = dimension * dimension;
02078 int nread = 0;
02079
02080
02081 while ( nread < nterms ) {
02082 ret_code = NAMD_read_line(fd, buffer);
02083
02084
02085 if (ret_code == 0) {
02086 NAMD_remove_comment(buffer);
02087 }
02088
02089
02090 while ( (ret_code == 0) && (NAMD_blank_string(buffer)) ) {
02091 ret_code = NAMD_read_line(fd, buffer);
02092 if (ret_code == 0) {
02093 NAMD_remove_comment(buffer);
02094 }
02095 }
02096
02097 if (ret_code != 0) {
02098 NAMD_die("EOF encoutner in middle of CMAP");
02099 }
02100
02101
02102 read_count=sscanf(buffer, "%lf %lf %lf %lf %lf %lf %lf %lf\n",
02103 new_node->values + nread,
02104 new_node->values + nread+1,
02105 new_node->values + nread+2,
02106 new_node->values + nread+3,
02107 new_node->values + nread+4,
02108 new_node->values + nread+5,
02109 new_node->values + nread+6,
02110 new_node->values + nread+7);
02111
02112 nread += read_count;
02113
02114 if (read_count == 0 || nread > nterms) {
02115 char err_msg[512];
02116
02117 sprintf(err_msg, "BAD CMAP FORMAT IN PARAMETER FILE\nLINE=*%s*\n", buffer);
02118 NAMD_die(err_msg);
02119 }
02120 }
02121
02122
02123 add_to_crossterm_list(new_node);
02124
02125 return;
02126 }
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147 void Parameters::add_to_crossterm_list(struct crossterm_params *new_node)
02148
02149 {
02150 int i;
02151 static struct crossterm_params *ptr;
02152 static struct crossterm_params *tail;
02153
02154
02155
02156
02157
02158 if (crosstermp == NULL)
02159 {
02160 crosstermp=new_node;
02161 tail=new_node;
02162
02163 return;
02164 }
02165
02166
02167 ptr=crosstermp;
02168
02169 while (ptr != NULL)
02170 {
02171 if ( ( (strcasecmp(new_node->atom1name, ptr->atom1name) == 0) &&
02172 (strcasecmp(new_node->atom2name, ptr->atom2name) == 0) &&
02173 (strcasecmp(new_node->atom3name, ptr->atom3name) == 0) &&
02174 (strcasecmp(new_node->atom4name, ptr->atom4name) == 0) &&
02175 (strcasecmp(new_node->atom5name, ptr->atom5name) == 0) &&
02176 (strcasecmp(new_node->atom6name, ptr->atom6name) == 0) &&
02177 (strcasecmp(new_node->atom7name, ptr->atom7name) == 0) &&
02178 (strcasecmp(new_node->atom8name, ptr->atom8name) == 0) ) )
02179 {
02180
02181
02182 int echoWarn=0;
02183
02184 if (ptr->dimension != new_node->dimension) {echoWarn=1;}
02185
02186 if (!echoWarn)
02187 {
02188 int nvals = ptr->dimension * ptr->dimension;
02189 for (i=0; i<nvals; i++)
02190 {
02191 if (ptr->values[i] != new_node->values[i]) {echoWarn=1; break;}
02192 }
02193 }
02194
02195 if (echoWarn)
02196 {
02197 iout << "\n" << iWARN << "DUPLICATE CMAP ENTRY FOR "
02198 << ptr->atom1name << "-"
02199 << ptr->atom2name << "-"
02200 << ptr->atom3name << "-"
02201 << ptr->atom4name << " "
02202 << ptr->atom5name << "-"
02203 << ptr->atom6name << "-"
02204 << ptr->atom7name << "-"
02205 << ptr->atom8name << ", USING NEW VALUES\n";
02206
02207 iout << endi;
02208
02209 ptr->dimension = new_node->dimension;
02210
02211 BigReal *tmpvalues = ptr->values;
02212 ptr->values = new_node->values;
02213 new_node->values = tmpvalues;
02214 }
02215
02216 delete new_node;
02217
02218 return;
02219 }
02220
02221 ptr=ptr->next;
02222 }
02223
02224
02225
02226
02227
02228
02229
02230 if ( (strcasecmp(new_node->atom1name, "X") == 0) ||
02231 (strcasecmp(new_node->atom2name, "X") == 0) ||
02232 (strcasecmp(new_node->atom3name, "X") == 0) ||
02233 (strcasecmp(new_node->atom4name, "X") == 0) ||
02234 (strcasecmp(new_node->atom5name, "X") == 0) ||
02235 (strcasecmp(new_node->atom6name, "X") == 0) ||
02236 (strcasecmp(new_node->atom7name, "X") == 0) ||
02237 (strcasecmp(new_node->atom8name, "X") == 0) )
02238 {
02239
02240 tail->next=new_node;
02241 tail=new_node;
02242
02243 return;
02244 }
02245 else
02246 {
02247
02248 new_node->next=crosstermp;
02249 crosstermp=new_node;
02250
02251 return;
02252 }
02253 }
02254
02255
02256
02257
02258
02259
02260
02261
02262
02263
02264
02265
02266
02267
02268 void Parameters::add_vdw_param(char *buf)
02269
02270 {
02271 char atomname[11];
02272 Real sigma;
02273 Real epsilon;
02274 Real sigma14;
02275 Real epsilon14;
02276 Real sqrt26;
02277 int read_count;
02278 struct vdw_params *new_node;
02279
02280
02281
02282 if (paramType == paraXplor)
02283 {
02284
02285 read_count=sscanf(buf, "%*s %s %f %f %f %f\n", atomname,
02286 &epsilon, &sigma, &epsilon14, &sigma14);
02287 }
02288 else if (paramType == paraCharmm)
02289 {
02290
02291 read_count=sscanf(buf, "%s %*f %f %f %*f %f %f\n", atomname,
02292 &epsilon, &sigma, &epsilon14, &sigma14);
02293 }
02294
02295
02296 if ((read_count != 5) && (paramType == paraXplor))
02297 {
02298 char err_msg[512];
02299
02300 sprintf(err_msg, "BAD vdW FORMAT IN XPLOR PARAMETER FILE\nLINE=*%s*\n", buf);
02301 NAMD_die(err_msg);
02302 }
02303 else if ( ((read_count != 5) && (read_count != 3)) && (paramType == paraCharmm))
02304 {
02305 char err_msg[512];
02306
02307 sprintf(err_msg, "BAD vdW FORMAT IN CHARMM PARAMETER FILE\nLINE=*%s*\n", buf);
02308 NAMD_die(err_msg);
02309 }
02310
02311 if (paramType == paraCharmm)
02312 {
02313
02314 epsilon*=-1.;
02315 sqrt26=pow(2.,(1./6.));
02316 sigma=2.*sigma/sqrt26;
02317
02318 if (read_count == 3)
02319 {
02320 epsilon14=epsilon;
02321 sigma14=sigma;
02322 }
02323 else
02324 {
02325 epsilon14*=-1.;
02326 sigma14=2.*sigma14/sqrt26;
02327 }
02328 }
02329
02330
02331 if ( epsilon < 0. || epsilon14 < 0. ) {
02332 iout << iWARN << "Ignoring VDW parameter with negative epsilon:\n"
02333 << buf << "\n" << endi;
02334 return;
02335 }
02336
02337
02338 new_node = new vdw_params;
02339
02340 if (new_node == NULL)
02341 {
02342 NAMD_die("memory allocation failed in Parameters::add_vdw_param");
02343 }
02344
02345
02346 strcpy(new_node->atomname, atomname);
02347 new_node->sigma = sigma;
02348 new_node->sigma14 = sigma14;
02349 new_node->epsilon = epsilon;
02350 new_node->epsilon14 = epsilon14;
02351
02352 new_node->left = NULL;
02353 new_node->right = NULL;
02354
02355
02356 vdwp=add_to_vdw_tree(new_node, vdwp);
02357
02358 return;
02359 }
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369
02370
02371
02372
02373
02374
02375
02376
02377
02378 struct vdw_params *Parameters::add_to_vdw_tree(struct vdw_params *new_node,
02379 struct vdw_params *tree)
02380
02381 {
02382 int compare_code;
02383
02384
02385 if (tree == NULL)
02386 return(new_node);
02387
02388 compare_code = strcasecmp(new_node->atomname, tree->atomname);
02389
02390
02391 if (compare_code==0)
02392 {
02393
02394
02395
02396 if ((tree->sigma != new_node->sigma) ||
02397 (tree->epsilon != new_node->epsilon) ||
02398 (tree->sigma14 != new_node->sigma14) ||
02399 (tree->epsilon14 != new_node->epsilon14))
02400 {
02401 iout << iWARN << "DUPLICATE vdW ENTRY FOR " << tree->atomname
02402 << "\nPREVIOUS VALUES sigma=" << tree->sigma
02403 << " epsilon=" << tree->epsilon
02404 << " sigma14=" << tree->sigma14
02405 << " epsilon14=" << tree->epsilon14
02406 << "\n USING VALUES sigma=" << new_node->sigma
02407 << " epsilon=" << new_node->epsilon
02408 << " sigma14=" << new_node->sigma14
02409 << " epsilon14=" << new_node->epsilon14
02410 << "\n" << endi;
02411
02412 tree->sigma=new_node->sigma;
02413 tree->epsilon=new_node->epsilon;
02414 tree->sigma14=new_node->sigma14;
02415 tree->epsilon14=new_node->epsilon14;
02416 }
02417
02418 delete new_node;
02419
02420 return(tree);
02421 }
02422
02423
02424
02425
02426 if (compare_code < 0)
02427 {
02428 tree->left = add_to_vdw_tree(new_node, tree->left);
02429 }
02430 else
02431 {
02432 tree->right = add_to_vdw_tree(new_node, tree->right);
02433 }
02434
02435 return(tree);
02436 }
02437
02438
02439
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449
02450
02451 void Parameters::add_table_pair_param(char *buf)
02452
02453 {
02454 char atom1name[11];
02455 char atom2name[11];
02456 char tabletype[11];
02457 int K;
02458 int read_count;
02459 struct table_pair_params *new_node;
02460
02461
02462 read_count=sscanf(buf, "%s %s %s\n", atom1name,
02463 atom2name, tabletype);
02464
02465
02466 if ((read_count != 3))
02467 {
02468 char err_msg[512];
02469
02470 sprintf(err_msg, "BAD TABLE PAIR FORMAT IN PARAMETER FILE\nLINE=*%s*", buf);
02471 NAMD_die(err_msg);
02472 }
02473
02474
02475 new_node = new table_pair_params;
02476
02477 if (new_node == NULL)
02478 {
02479 NAMD_die("memory allocation failed in Parameters::add_table_pair_param\n");
02480 }
02481
02482 strcpy(new_node->atom1name, atom1name);
02483 strcpy(new_node->atom2name, atom2name);
02484
02485
02486 K = get_int_table_type(tabletype);
02487
02488 if (K < 0) {
02489 char err_msg[512];
02490 sprintf(err_msg, "Couldn't find table parameters for table interaction %s!\n", tabletype);
02491 NAMD_die(err_msg);
02492 }
02493
02494
02495 new_node->K = K;
02496
02497 new_node->next = NULL;
02498
02499
02500
02501 add_to_table_pair_list(new_node);
02502
02503 return;
02504 }
02505
02506
02507
02508
02509
02510
02511
02512
02513
02514
02515
02516
02517
02518
02519 void Parameters::add_vdw_pair_param(char *buf)
02520
02521 {
02522 char atom1name[11];
02523 char atom2name[11];
02524 Real A;
02525 Real B;
02526 Real A14;
02527 Real B14;
02528 Real sqrt26;
02529 Real expo;
02530 int read_count;
02531 struct vdw_pair_params *new_node;
02532
02533
02534 if (paramType == paraXplor)
02535 {
02536
02537 read_count=sscanf(buf, "%*s %s %s %f %f %f %f\n", atom1name,
02538 atom2name, &A, &B, &A14, &B14);
02539 }
02540 else if (paramType == paraCharmm)
02541 {
02542
02543
02544 read_count=sscanf(buf, "%s %s %f %f\n", atom1name,
02545 atom2name, &A, &B);
02546
02547
02548
02549
02550
02551
02552 A14=-A;
02553 sqrt26=pow(2.,(1./6.));
02554 B14=B/sqrt26;
02555 expo=12.;
02556 A=pow(B14,expo);
02557 A=A*4.*A14;
02558 expo=6.;
02559 B=pow(B14,expo);
02560 B=B*4.*A14;
02561 A14=A;
02562 B14=B;
02563 }
02564
02565
02566 if ((read_count != 6) && (paramType == paraXplor))
02567 {
02568 char err_msg[512];
02569
02570 sprintf(err_msg, "BAD vdW PAIR FORMAT IN XPLOR PARAMETER FILE\nLINE=*%s*", buf);
02571 NAMD_die(err_msg);
02572 }
02573 if ((read_count != 4) && (paramType == paraCharmm))
02574 {
02575 char err_msg[512];
02576
02577 sprintf(err_msg, "BAD vdW PAIR FORMAT IN CHARMM PARAMETER FILE\nLINE=*%s*", buf);
02578 NAMD_die(err_msg);
02579 }
02580
02581
02582
02583 new_node = new vdw_pair_params;
02584
02585 if (new_node == NULL)
02586 {
02587 NAMD_die("memory allocation failed in Parameters::add_vdw_pair_param\n");
02588 }
02589
02590 strcpy(new_node->atom1name, atom1name);
02591 strcpy(new_node->atom2name, atom2name);
02592
02593
02594 new_node->A = A;
02595 new_node->A14 = A14;
02596 new_node->B = B;
02597 new_node->B14 = B14;
02598
02599 new_node->next = NULL;
02600
02601
02602 add_to_vdw_pair_list(new_node);
02603
02604 return;
02605 }
02606
02607
02608
02609
02610
02611
02612
02613
02614
02615
02616
02617
02618
02619
02620 void Parameters::add_hb_pair_param(char *buf)
02621
02622 {
02623 #if 0
02624 char a1n[11];
02625 char a2n[11];
02626 Real A, B;
02627
02628
02630
02631 if (paramType == paraXplor) {
02632 if (sscanf(buf, "%*s %s %s %f %f\n", a1n, a2n, &A, &B) != 4) {
02633 char err_msg[512];
02634 sprintf(err_msg, "BAD HBOND PAIR FORMAT IN XPLOR PARAMETER FILE\nLINE=*%s*", buf);
02635 NAMD_die(err_msg);
02636 }
02637 }
02638 else if (paramType == paraCharmm) {
02639 if (sscanf(buf, "%s %s %f %f\n", a1n, a2n, &A, &B) != 4) {
02640 char err_msg[512];
02641 sprintf(err_msg, "BAD HBOND PAIR FORMAT IN CHARMM PARAMETER FILE\nLINE=*%s*", buf);
02642 NAMD_die(err_msg);
02643 }
02644 }
02645
02646
02647
02648 if (hbondParams.add_hbond_pair(a1n, a2n, A, B) == FALSE) {
02649 iout << "\n" << iWARN << "Duplicate HBOND parameters for types " << a1n
02650 << " and " << a2n << " found; using latest values." << "\n" << endi;
02651 }
02652 #endif
02653 }
02654
02655
02656
02657
02658
02659
02660
02661
02662
02663
02664
02665
02666
02667 void Parameters::add_to_table_pair_list(struct table_pair_params *new_node)
02668
02669 {
02670 static struct table_pair_params *tail=NULL;
02671 struct table_pair_params *ptr;
02672 int compare_code;
02673
02674
02675
02676 if (table_pairp == NULL)
02677 {
02678 table_pairp = new_node;
02679 tail = new_node;
02680 return;
02681 }
02682
02683 ptr = table_pairp;
02684
02685
02686 while (ptr!=NULL)
02687 {
02688
02689 compare_code = strncasecmp(new_node->atom1name, ptr->atom1name, 5);
02690
02691 if (compare_code == 0)
02692 {
02693
02694 compare_code = strcasecmp(new_node->atom2name, ptr->atom2name);
02695
02696 if (compare_code==0)
02697 {
02698
02699
02700
02701 iout << iWARN << "DUPLICATE TABLE PAIR ENTRY FOR "
02702 << new_node->atom1name << "-"
02703 << new_node->atom2name
02704 << "\n" << endi;
02705
02706 ptr->K=new_node->K;
02707
02708 delete new_node;
02709
02710 return;
02711 }
02712 }
02713
02714 ptr = ptr->next;
02715 }
02716
02717
02718
02719 tail->next = new_node;
02720 tail = new_node;
02721 }
02722
02723
02724
02725
02726
02727
02728
02729
02730
02731
02732
02733
02734
02735 void Parameters::add_to_vdw_pair_list(struct vdw_pair_params *new_node)
02736
02737 {
02738 static struct vdw_pair_params *tail=NULL;
02739 struct vdw_pair_params *ptr;
02740 int compare_code;
02741
02742
02743
02744 if (vdw_pairp == NULL)
02745 {
02746 vdw_pairp = new_node;
02747 tail = new_node;
02748 return;
02749 }
02750
02751 ptr = vdw_pairp;
02752
02753
02754 while (ptr!=NULL)
02755 {
02756
02757 compare_code = strcasecmp(new_node->atom1name, ptr->atom1name);
02758
02759 if (compare_code == 0)
02760 {
02761
02762 compare_code = strcasecmp(new_node->atom2name, ptr->atom2name);
02763
02764 if (compare_code==0)
02765 {
02766
02767
02768
02769 if ((ptr->A != new_node->A) ||
02770 (ptr->B != new_node->B) ||
02771 (ptr->A14 != new_node->A14) ||
02772 (ptr->B14 != new_node->B14))
02773 {
02774 iout << iWARN << "DUPLICATE vdW PAIR ENTRY FOR "
02775 << new_node->atom1name << "-"
02776 << new_node->atom2name
02777 << "\nPREVIOUS VALUES A=" << ptr->A
02778 << " B=" << ptr->B
02779 << " A14=" << ptr->A14
02780 << " B14" << ptr->B14
02781 << "\n USING VALUES A=" << new_node->A
02782 << " B=" << new_node->B
02783 << " A14=" << new_node->A14
02784 << " B14" << new_node->B14
02785 << "\n" << endi;
02786
02787 ptr->A=new_node->A;
02788 ptr->B=new_node->B;
02789 ptr->A14=new_node->A14;
02790 ptr->B14=new_node->B14;
02791 }
02792
02793 delete new_node;
02794
02795 return;
02796 }
02797 }
02798
02799 ptr = ptr->next;
02800 }
02801
02802
02803
02804 tail->next = new_node;
02805 tail = new_node;
02806 }
02807
02808
02809
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821 void Parameters::done_reading_files()
02822
02823 {
02824 AllFilesRead = TRUE;
02825
02826
02827 if (NumBondParams)
02828 {
02829 bond_array = new BondValue[NumBondParams];
02830
02831 if (bond_array == NULL)
02832 {
02833 NAMD_die("memory allocation of bond_array failed!");
02834 }
02835 }
02836
02837 if (NumAngleParams)
02838 {
02839 angle_array = new AngleValue[NumAngleParams];
02840
02841 if (angle_array == NULL)
02842 {
02843 NAMD_die("memory allocation of angle_array failed!");
02844 }
02845 }
02846
02847 if (NumDihedralParams)
02848 {
02849 dihedral_array = new DihedralValue[NumDihedralParams];
02850
02851 if (dihedral_array == NULL)
02852 {
02853 NAMD_die("memory allocation of dihedral_array failed!");
02854 }
02855 memset(dihedral_array, 0, NumDihedralParams*sizeof(DihedralValue));
02856 }
02857
02858 if (NumImproperParams)
02859 {
02860 improper_array = new ImproperValue[NumImproperParams];
02861
02862 if (improper_array == NULL)
02863 {
02864 NAMD_die("memory allocation of improper_array failed!");
02865 }
02866 memset(improper_array, 0, NumImproperParams*sizeof(ImproperValue));
02867 }
02868
02869 if (NumCrosstermParams)
02870 {
02871 crossterm_array = new CrosstermValue[NumCrosstermParams];
02872 memset(crossterm_array, 0, NumCrosstermParams*sizeof(CrosstermValue));
02873 }
02874
02875 if (NumVdwParams)
02876 {
02877 atomTypeNames = new char[NumVdwParams*(MAX_ATOMTYPE_CHARS+1)];
02878 vdw_array = new VdwValue[NumVdwParams];
02879
02880 if (vdw_array == NULL)
02881 {
02882 NAMD_die("memory allocation of vdw_array failed!");
02883 }
02884 }
02885
02886
02887
02888
02889 index_bonds(bondp, 0);
02890 index_angles(anglep, 0);
02891 NumVdwParamsAssigned = index_vdw(vdwp, 0);
02892 index_dihedrals();
02893 index_impropers();
02894 index_crossterms();
02895
02896
02897 convert_vdw_pairs();
02898 convert_table_pairs();
02899 }
02900
02901
02902
02903
02904
02905
02906
02907
02908
02909
02910
02911
02912
02913
02914
02915
02916
02917 Index Parameters::index_bonds(struct bond_params *tree, Index index)
02918
02919 {
02920
02921 if (tree==NULL)
02922 return(index);
02923
02924
02925 if (tree->left != NULL)
02926 {
02927 index=index_bonds(tree->left, index);
02928 }
02929
02930
02931 tree->index = index;
02932 bond_array[index].k = tree->forceconstant;
02933 bond_array[index].x0 = tree->distance;
02934 index++;
02935
02936
02937 if (tree->right != NULL)
02938 {
02939 index=index_bonds(tree->right, index);
02940 }
02941
02942 return(index);
02943 }
02944
02945
02946
02947
02948
02949
02950
02951
02952
02953
02954
02955
02956
02957
02958
02959
02960
02961 Index Parameters::index_angles(struct angle_params *tree, Index index)
02962
02963 {
02964
02965 if (tree==NULL)
02966 return(index);
02967
02968
02969 if (tree->left != NULL)
02970 {
02971 index=index_angles(tree->left, index);
02972 }
02973
02974
02975 tree->index = index;
02976
02977 angle_array[index].k = tree->forceconstant;
02978 angle_array[index].k_ub = tree->k_ub;
02979 angle_array[index].r_ub = tree->r_ub;
02980 angle_array[index].normal = tree->normal;
02981
02982
02983 angle_array[index].theta0 = (tree->angle*PI)/180.0;
02984 index++;
02985
02986
02987 if (tree->right != NULL)
02988 {
02989 index=index_angles(tree->right, index);
02990 }
02991
02992 return(index);
02993 }
02994
02995
02996
02997
02998
02999
03000
03001
03002
03003
03004
03005
03006 void Parameters::index_dihedrals()
03007
03008 {
03009 struct dihedral_params *ptr;
03010 Index index=0;
03011 int i;
03012
03013
03014
03015
03016
03017
03018
03019
03020
03021
03022
03023
03024
03025
03026
03027
03028
03029 maxDihedralMults = new int[NumDihedralParams];
03030
03031 if (maxDihedralMults == NULL)
03032 {
03033 NAMD_die("memory allocation failed in Parameters::index_dihedrals()");
03034 }
03035
03036
03037 ptr = dihedralp;
03038
03039 while (ptr != NULL)
03040 {
03041
03042
03043
03044 maxDihedralMults[index] = ptr->multiplicity;
03045
03046
03047
03048 if (paramType == paraXplor)
03049 {
03050
03051
03052 dihedral_array[index].multiplicity = -1;
03053 }
03054 else if (paramType == paraCharmm)
03055 {
03056
03057
03058
03059 dihedral_array[index].multiplicity = ptr->multiplicity;
03060 }
03061
03062
03063 for (i=0; i<ptr->multiplicity; i++)
03064 {
03065 dihedral_array[index].values[i].k = ptr->values[i].k;
03066 dihedral_array[index].values[i].n = ptr->values[i].n;
03067
03068
03069 dihedral_array[index].values[i].delta = ptr->values[i].delta*PI/180.0;
03070 }
03071
03072 ptr->index = index;
03073
03074 index++;
03075 ptr=ptr->next;
03076 }
03077 }
03078
03079
03080
03081
03082
03083
03084
03085
03086
03087
03088
03089
03090 void Parameters::index_impropers()
03091
03092 {
03093 struct improper_params *ptr;
03094 Index index=0;
03095 int i;
03096
03097
03098
03099
03100
03101
03102
03103
03104
03105
03106
03107
03108
03109
03110
03111
03112 maxImproperMults = new int[NumImproperParams];
03113
03114 if (maxImproperMults == NULL)
03115 {
03116 NAMD_die("memory allocation failed in Parameters::index_impropers()");
03117 }
03118
03119
03120 ptr = improperp;
03121
03122 while (ptr != NULL)
03123 {
03124
03125
03126
03127 maxImproperMults[index] = ptr->multiplicity;
03128
03129
03130
03131 improper_array[index].multiplicity = -1;
03132
03133 for (i=0; i<ptr->multiplicity; i++)
03134 {
03135 improper_array[index].values[i].k = ptr->values[i].k;
03136 improper_array[index].values[i].n = ptr->values[i].n;
03137
03138
03139 improper_array[index].values[i].delta = ptr->values[i].delta*PI/180.0;
03140 }
03141
03142 ptr->index=index;
03143
03144 index++;
03145 ptr=ptr->next;
03146 }
03147 }
03148
03149
03150
03151
03152
03153
03154
03155
03156
03157
03158
03159
03160
03161 void crossterm_setup(CrosstermData *);
03162
03163 void Parameters::index_crossterms()
03164
03165 {
03166 struct crossterm_params *ptr;
03167 Index index=0;
03168 int i,j,k;
03169
03170
03171 ptr = crosstermp;
03172
03173 while (ptr != NULL)
03174 {
03175
03176
03177 int N = CrosstermValue::dim - 1;
03178
03179 if ( ptr->dimension != N ) {
03180 NAMD_die("Sorry, only CMAP dimension of 24 is supported");
03181 }
03182
03183 k = 0;
03184 for (i=0; i<N; i++) {
03185 for (j=0; j<N; j++) {
03186 crossterm_array[index].c[i][j].d00 = ptr->values[k];
03187 ++k;
03188 }
03189 }
03190 for (i=0; i<N; i++) {
03191 crossterm_array[index].c[i][N].d00 =
03192 crossterm_array[index].c[i][0].d00;
03193 crossterm_array[index].c[N][i].d00 =
03194 crossterm_array[index].c[0][i].d00;
03195 }
03196 crossterm_array[index].c[N][N].d00 =
03197 crossterm_array[index].c[0][0].d00;
03198
03199 crossterm_setup(&crossterm_array[index].c[0][0]);
03200
03201 ptr->index=index;
03202
03203 index++;
03204 ptr=ptr->next;
03205 }
03206 }
03207
03208
03209
03210
03211
03212
03213
03214
03215
03216
03217
03218
03219
03220
03221
03222
03223
03224 Index Parameters::index_vdw(struct vdw_params *tree, Index index)
03225
03226 {
03227
03228 if (tree==NULL)
03229 return(index);
03230
03231
03232 if (tree->left != NULL)
03233 {
03234 index=index_vdw(tree->left, index);
03235 }
03236
03237
03238 tree->index = index;
03239
03240 vdw_array[index].sigma = tree->sigma;
03241 vdw_array[index].epsilon = tree->epsilon;
03242 vdw_array[index].sigma14 = tree->sigma14;
03243 vdw_array[index].epsilon14 = tree->epsilon14;
03244
03245 char *nameloc = atom_type_name(index);
03246 strncpy(nameloc, tree->atomname, MAX_ATOMTYPE_CHARS);
03247 nameloc[MAX_ATOMTYPE_CHARS] = '\0';
03248
03249
03250
03251
03252 index++;
03253
03254
03255 if (tree->right != NULL)
03256 {
03257 index=index_vdw(tree->right, index);
03258 }
03259
03260 return(index);
03261 }
03262
03263
03264
03265
03266
03267
03268
03269
03270
03271
03272
03273
03274
03275
03276
03277
03278
03279
03280
03281
03282 #ifdef MEM_OPT_VERSION
03283 void Parameters::assign_vdw_index(char *atomtype, AtomCstInfo *atom_ptr)
03284 #else
03285 void Parameters::assign_vdw_index(char *atomtype, Atom *atom_ptr)
03286 #endif
03287 {
03288 struct vdw_params *ptr;
03289 int found=0;
03290 int comp_code;
03291
03292
03293 if (!AllFilesRead)
03294 {
03295 NAMD_die("Tried to assign vdw index before all parameter files were read");
03296 }
03297
03298
03299 ptr=vdwp;
03300
03301
03302
03303
03304
03305 while (!found && (ptr!=NULL))
03306 {
03307 comp_code = strcasecmp(atomtype, ptr->atomname);
03308
03309 if (comp_code == 0)
03310 {
03311
03312 atom_ptr->vdw_type=ptr->index;
03313 found=1;
03314 }
03315 else if (comp_code < 0)
03316 {
03317
03318 ptr=ptr->left;
03319 }
03320 else
03321 {
03322
03323 ptr=ptr->right;
03324 }
03325 }
03326
03327
03328 if (!found)
03329 {
03330
03331
03332
03333 size_t windx;
03334
03335
03336 ptr=vdwp;
03337
03338 while (!found && (ptr!=NULL))
03339 {
03340
03341
03342 windx= strcspn(ptr->atomname,"*");
03343 if (windx == strlen(ptr->atomname))
03344 {
03345
03346 comp_code = strcasecmp(atomtype, ptr->atomname);
03347 }
03348 else
03349 {
03350 comp_code = strncasecmp(atomtype, ptr->atomname, windx);
03351 }
03352
03353 if (comp_code == 0)
03354 {
03355
03356 atom_ptr->vdw_type=ptr->index;
03357 found=1;
03358 char errbuf[100];
03359 sprintf(errbuf,"VDW TYPE NAME %s MATCHES PARAMETER TYPE NAME %s",
03360 atomtype, ptr->atomname);
03361 int i;
03362 for(i=0; i<error_msgs.size(); i++) {
03363 if ( strcmp(errbuf,error_msgs[i]) == 0 ) break;
03364 }
03365 if ( i == error_msgs.size() ) {
03366 char *newbuf = new char[strlen(errbuf)+1];
03367 strcpy(newbuf,errbuf);
03368 error_msgs.add(newbuf);
03369 iout << iWARN << newbuf << "\n" << endi;
03370 }
03371 }
03372 else if (comp_code < 0)
03373 {
03374
03375 ptr=ptr->left;
03376 }
03377 else
03378 {
03379
03380 ptr=ptr->right;
03381 }
03382
03383 }
03384
03385 }
03386
03387
03388
03389 if (!found)
03390 {
03391 char err_msg[100];
03392
03393 sprintf(err_msg, "DIDN'T FIND vdW PARAMETER FOR ATOM TYPE %s",
03394 atomtype);
03395 NAMD_die(err_msg);
03396 }
03397
03398 return;
03399 }
03400
03401
03402
03403
03404
03405
03406
03407
03408
03409
03410
03411
03412
03413
03414
03415
03416
03417
03418
03419
03420 int Parameters::get_table_pair_params(Index ind1, Index ind2, int *K) {
03421 IndexedTablePair *ptr;
03422 Index temp;
03423 int found=FALSE;
03424
03425 ptr=tab_pair_tree;
03426
03427
03428
03429 if (ind1 > ind2)
03430 {
03431 temp = ind1;
03432 ind1 = ind2;
03433 ind2 = temp;
03434 }
03435
03436
03437
03438 while (!found && (ptr!=NULL))
03439 {
03440
03441 if ( (ind1 == ptr->ind1) && (ind2 == ptr->ind2) )
03442 {
03443 found = TRUE;
03444 }
03445 else if ( (ind1 < ptr->ind1) ||
03446 ( (ind1==ptr->ind1) && (ind2 < ptr->ind2) ) )
03447 {
03448
03449 ptr=ptr->left;
03450 }
03451 else
03452 {
03453
03454 ptr=ptr->right;
03455 }
03456 }
03457
03458
03459 if (found)
03460 {
03461 *K = ptr->K;
03462 return(TRUE);
03463 }
03464 else
03465 {
03466 return(FALSE);
03467 }
03468 }
03469
03470
03471
03472
03473
03474
03475
03476
03477
03478
03479
03480
03481
03482
03483
03484
03485
03486
03487
03488
03489
03490
03491
03492
03493
03494
03495 int Parameters::get_vdw_pair_params(Index ind1, Index ind2, Real *A,
03496 Real *B, Real *A14, Real *B14)
03497
03498 {
03499 IndexedVdwPair *ptr;
03500 Index temp;
03501
03502 int found=FALSE;
03503
03504 ptr=vdw_pair_tree;
03505
03506
03507
03508 if (ind1 > ind2)
03509 {
03510 temp = ind1;
03511 ind1 = ind2;
03512 ind2 = temp;
03513 }
03514
03515
03516
03517 while (!found && (ptr!=NULL))
03518 {
03519 if ( (ind1 == ptr->ind1) && (ind2 == ptr->ind2) )
03520 {
03521 found = TRUE;
03522 }
03523 else if ( (ind1 < ptr->ind1) ||
03524 ( (ind1==ptr->ind1) && (ind2 < ptr->ind2) ) )
03525 {
03526
03527 ptr=ptr->left;
03528 }
03529 else
03530 {
03531
03532 ptr=ptr->right;
03533 }
03534 }
03535
03536
03537 if (found)
03538 {
03539 *A = ptr->A;
03540 *B = ptr->B;
03541 *A14 = ptr->A14;
03542 *B14 = ptr->B14;
03543
03544 return(TRUE);
03545 }
03546 else
03547 {
03548 return(FALSE);
03549 }
03550 }
03551
03552
03553
03554
03555
03556
03557
03558
03559
03560
03561
03562
03563
03564
03565
03566
03567
03568
03569
03570
03571
03572
03573 void Parameters::assign_bond_index(char *atom1, char *atom2, Bond *bond_ptr)
03574
03575 {
03576 struct bond_params *ptr;
03577 int found=0;
03578 int cmp_code;
03579 char tmp_name[15];
03580
03581
03582 if (!AllFilesRead)
03583 {
03584 NAMD_die("Tried to assign bond index before all parameter files were read");
03585 }
03586
03587
03588
03589 if (strcasecmp(atom1, atom2) > 0)
03590 {
03591 strcpy(tmp_name, atom1);
03592 strcpy(atom1, atom2);
03593 strcpy(atom2, tmp_name);
03594 }
03595
03596
03597 ptr=bondp;
03598
03599
03600
03601 while (!found && (ptr!=NULL))
03602 {
03603 cmp_code=strcasecmp(atom1, ptr->atom1name);
03604
03605 if (cmp_code == 0)
03606 {
03607 cmp_code=strcasecmp(atom2, ptr->atom2name);
03608 }
03609
03610 if (cmp_code == 0)
03611 {
03612
03613 found=1;
03614 bond_ptr->bond_type = ptr->index;
03615 }
03616 else if (cmp_code < 0)
03617 {
03618
03619 ptr=ptr->left;
03620 }
03621 else
03622 {
03623
03624 ptr=ptr->right;
03625 }
03626 }
03627
03628
03629 if (!found)
03630 {
03631 char err_msg[128];
03632
03633 sprintf(err_msg, "CAN'T FIND BOND PARAMETERS FOR BOND %s - %s IN PARAMETER FILES", atom1, atom2);
03634 NAMD_die(err_msg);
03635 }
03636
03637 return;
03638 }
03639
03640
03641
03642
03643
03644
03645
03646
03647
03648
03649
03650
03651
03652
03653
03654
03655
03656
03657
03658
03659
03660
03661 void Parameters::assign_angle_index(char *atom1, char *atom2, char*atom3,
03662 Angle *angle_ptr)
03663
03664 {
03665 struct angle_params *ptr;
03666 int comp_val;
03667 int found=0;
03668 char tmp_name[15];
03669
03670
03671 if (!AllFilesRead)
03672 {
03673 NAMD_die("Tried to assign angle index before all parameter files were read");
03674 }
03675
03676
03677
03678 if (strcasecmp(atom1, atom3) > 0)
03679 {
03680 strcpy(tmp_name, atom1);
03681 strcpy(atom1, atom3);
03682 strcpy(atom3, tmp_name);
03683 }
03684
03685
03686 ptr=anglep;
03687
03688
03689
03690 while (!found && (ptr != NULL))
03691 {
03692 comp_val = strcasecmp(atom1, ptr->atom1name);
03693
03694 if (comp_val == 0)
03695 {
03696
03697 comp_val = strcasecmp(atom2, ptr->atom2name);
03698
03699 if (comp_val == 0)
03700 {
03701
03702 comp_val = strcasecmp(atom3, ptr->atom3name);
03703 }
03704 }
03705
03706 if (comp_val == 0)
03707 {
03708
03709 found = 1;
03710 angle_ptr->angle_type = ptr->index;
03711 }
03712 else if (comp_val < 0)
03713 {
03714
03715 ptr=ptr->left;
03716 }
03717 else
03718 {
03719
03720 ptr=ptr->right;
03721 }
03722 }
03723
03724
03725 if (!found)
03726 {
03727 char err_msg[128];
03728
03729 sprintf(err_msg, "UNABLE TO FIND ANGLE PARAMETERS FOR %s %s %s",
03730 atom1, atom2, atom3);
03731 NAMD_die(err_msg);
03732 }
03733
03734 return;
03735 }
03736
03737
03738
03739
03740
03741
03742
03743
03744
03745
03746
03747
03748
03749
03750
03751
03752
03753
03754
03755
03756
03757
03758
03759 void Parameters::assign_dihedral_index(char *atom1, char *atom2, char *atom3,
03760 char *atom4, Dihedral *dihedral_ptr,
03761 int multiplicity)
03762
03763 {
03764 struct dihedral_params *ptr;
03765 int found=0;
03766
03767
03768 ptr=dihedralp;
03769
03770
03771
03772 while (!found && (ptr!=NULL))
03773 {
03774
03775
03776
03777
03778
03779
03780
03781
03782 if ( ( ptr->atom1wild || (strcasecmp(ptr->atom1name, atom1)==0) ) &&
03783 ( ptr->atom2wild || (strcasecmp(ptr->atom2name, atom2)==0) ) &&
03784 ( ptr->atom3wild || (strcasecmp(ptr->atom3name, atom3)==0) ) &&
03785 ( ptr->atom4wild || (strcasecmp(ptr->atom4name, atom4)==0) ) )
03786 {
03787
03788 found=1;
03789 }
03790 else if ( ( ptr->atom4wild || (strcasecmp(ptr->atom4name, atom1)==0) ) &&
03791 ( ptr->atom3wild || (strcasecmp(ptr->atom3name, atom2)==0) ) &&
03792 ( ptr->atom2wild || (strcasecmp(ptr->atom2name, atom3)==0) ) &&
03793 ( ptr->atom1wild || (strcasecmp(ptr->atom1name, atom4)==0) ) )
03794 {
03795
03796 found=1;
03797 }
03798 else
03799 {
03800
03801 ptr=ptr->next;
03802 }
03803 }
03804
03805
03806 if (!found)
03807 {
03808 char err_msg[128];
03809
03810 sprintf(err_msg, "CAN'T FIND DIHEDRAL PARAMETERS FOR %s %s %s %s",
03811 atom1, atom2, atom3, atom4);
03812
03813 NAMD_die(err_msg);
03814 }
03815
03816
03817
03818
03819 if (multiplicity > maxDihedralMults[ptr->index])
03820 {
03821 char err_msg[257];
03822
03823 sprintf(err_msg, "Multiplicity of Paramters for diehedral bond %s %s %s %s of %d exceeded", atom1, atom2, atom3, atom4, maxDihedralMults[ptr->index]);
03824 NAMD_die(err_msg);
03825 }
03826
03827
03828
03829 if (multiplicity > dihedral_array[ptr->index].multiplicity)
03830 {
03831 dihedral_array[ptr->index].multiplicity = multiplicity;
03832 }
03833
03834 dihedral_ptr->dihedral_type = ptr->index;
03835
03836 return;
03837 }
03838
03839
03840
03841
03842
03843
03844
03845
03846
03847
03848
03849
03850
03851
03852
03853
03854
03855
03856
03857
03858
03859
03860
03861 void Parameters::assign_improper_index(char *atom1, char *atom2, char *atom3,
03862 char *atom4, Improper *improper_ptr,
03863 int multiplicity)
03864
03865 {
03866 struct improper_params *ptr;
03867 int found=0;
03868
03869
03870 ptr=improperp;
03871
03872
03873
03874 while (!found && (ptr!=NULL))
03875 {
03876
03877
03878
03879
03880
03881
03882
03883
03884 if ( ( (strcasecmp(ptr->atom1name, atom1)==0) ||
03885 (strcasecmp(ptr->atom1name, "X")==0) ) &&
03886 ( (strcasecmp(ptr->atom2name, atom2)==0) ||
03887 (strcasecmp(ptr->atom2name, "X")==0) ) &&
03888 ( (strcasecmp(ptr->atom3name, atom3)==0) ||
03889 (strcasecmp(ptr->atom3name, "X")==0) ) &&
03890 ( (strcasecmp(ptr->atom4name, atom4)==0) ||
03891 (strcasecmp(ptr->atom4name, "X")==0) ) )
03892 {
03893
03894 found=1;
03895 }
03896 else if ( ( (strcasecmp(ptr->atom4name, atom1)==0) ||
03897 (strcasecmp(ptr->atom4name, "X")==0) ) &&
03898 ( (strcasecmp(ptr->atom3name, atom2)==0) ||
03899 (strcasecmp(ptr->atom3name, "X")==0) ) &&
03900 ( (strcasecmp(ptr->atom2name, atom3)==0) ||
03901 (strcasecmp(ptr->atom2name, "X")==0) ) &&
03902 ( (strcasecmp(ptr->atom1name, atom4)==0) ||
03903 (strcasecmp(ptr->atom1name, "X")==0) ) )
03904 {
03905
03906 found=1;
03907 }
03908 else
03909 {
03910
03911 ptr=ptr->next;
03912 }
03913 }
03914
03915
03916 if (!found)
03917 {
03918 char err_msg[128];
03919
03920 sprintf(err_msg, "CAN'T FIND IMPROPER PARAMETERS FOR %s %s %s %s",
03921 atom1, atom2, atom3, atom4);
03922
03923 NAMD_die(err_msg);
03924 }
03925
03926
03927
03928
03929 if (multiplicity > maxImproperMults[ptr->index])
03930 {
03931 char err_msg[257];
03932
03933 sprintf(err_msg, "Multiplicity of Paramters for improper bond %s %s %s %s of %d exceeded", atom1, atom2, atom3, atom4, maxImproperMults[ptr->index]);
03934 NAMD_die(err_msg);
03935 }
03936
03937
03938
03939 if (multiplicity > improper_array[ptr->index].multiplicity)
03940 {
03941 improper_array[ptr->index].multiplicity = multiplicity;
03942 }
03943
03944
03945 improper_ptr->improper_type = ptr->index;
03946
03947 return;
03948 }
03949
03950
03951
03952
03953
03954
03955
03956
03957 void Parameters::assign_crossterm_index(char *atom1, char *atom2, char *atom3,
03958 char *atom4, char *atom5, char *atom6, char *atom7,
03959 char *atom8, Crossterm *crossterm_ptr)
03960 {
03961 struct crossterm_params *ptr;
03962 int found=0;
03963
03964
03965 ptr=crosstermp;
03966
03967
03968
03969 while (!found && (ptr!=NULL))
03970 {
03971
03972
03973
03974
03975
03976
03977
03978
03979 if ( ( (strcasecmp(ptr->atom1name, atom1)==0) ||
03980 (strcasecmp(ptr->atom1name, "X")==0) ) &&
03981 ( (strcasecmp(ptr->atom2name, atom2)==0) ||
03982 (strcasecmp(ptr->atom2name, "X")==0) ) &&
03983 ( (strcasecmp(ptr->atom3name, atom3)==0) ||
03984 (strcasecmp(ptr->atom3name, "X")==0) ) &&
03985 ( (strcasecmp(ptr->atom4name, atom4)==0) ||
03986 (strcasecmp(ptr->atom4name, "X")==0) ) )
03987 {
03988
03989 found=1;
03990 }
03991 else if ( ( (strcasecmp(ptr->atom4name, atom1)==0) ||
03992 (strcasecmp(ptr->atom4name, "X")==0) ) &&
03993 ( (strcasecmp(ptr->atom3name, atom2)==0) ||
03994 (strcasecmp(ptr->atom3name, "X")==0) ) &&
03995 ( (strcasecmp(ptr->atom2name, atom3)==0) ||
03996 (strcasecmp(ptr->atom2name, "X")==0) ) &&
03997 ( (strcasecmp(ptr->atom1name, atom4)==0) ||
03998 (strcasecmp(ptr->atom1name, "X")==0) ) )
03999 {
04000
04001 found=1;
04002 }
04003 if ( ! found ) {
04004
04005 ptr=ptr->next;
04006 continue;
04007 }
04008 found = 0;
04009 if ( ( (strcasecmp(ptr->atom5name, atom5)==0) ||
04010 (strcasecmp(ptr->atom5name, "X")==0) ) &&
04011 ( (strcasecmp(ptr->atom6name, atom6)==0) ||
04012 (strcasecmp(ptr->atom6name, "X")==0) ) &&
04013 ( (strcasecmp(ptr->atom7name, atom7)==0) ||
04014 (strcasecmp(ptr->atom7name, "X")==0) ) &&
04015 ( (strcasecmp(ptr->atom8name, atom8)==0) ||
04016 (strcasecmp(ptr->atom8name, "X")==0) ) )
04017 {
04018
04019 found=1;
04020 }
04021 else if ( ( (strcasecmp(ptr->atom8name, atom5)==0) ||
04022 (strcasecmp(ptr->atom8name, "X")==0) ) &&
04023 ( (strcasecmp(ptr->atom7name, atom6)==0) ||
04024 (strcasecmp(ptr->atom7name, "X")==0) ) &&
04025 ( (strcasecmp(ptr->atom6name, atom7)==0) ||
04026 (strcasecmp(ptr->atom6name, "X")==0) ) &&
04027 ( (strcasecmp(ptr->atom5name, atom8)==0) ||
04028 (strcasecmp(ptr->atom5name, "X")==0) ) )
04029 {
04030
04031 found=1;
04032 }
04033 if ( ! found ) {
04034
04035 ptr=ptr->next;
04036 }
04037 }
04038
04039
04040 if (!found)
04041 {
04042 char err_msg[128];
04043
04044 sprintf(err_msg, "CAN'T FIND CROSSTERM PARAMETERS FOR %s %s %s %s %s %s %s %s",
04045 atom1, atom2, atom3, atom4, atom5, atom6, atom7, atom8);
04046
04047 NAMD_die(err_msg);
04048 }
04049
04050
04051 crossterm_ptr->crossterm_type = ptr->index;
04052
04053 return;
04054 }
04055
04056
04057
04058
04059
04060
04061
04062
04063
04064
04065
04066
04067
04068
04069
04070
04071 void Parameters::free_bond_tree(struct bond_params *bond_ptr)
04072
04073 {
04074 if (bond_ptr->left != NULL)
04075 {
04076 free_bond_tree(bond_ptr->left);
04077 }
04078
04079 if (bond_ptr->right != NULL)
04080 {
04081 free_bond_tree(bond_ptr->right);
04082 }
04083
04084 delete bond_ptr;
04085
04086 return;
04087 }
04088
04089
04090
04091
04092
04093
04094
04095
04096
04097
04098
04099
04100
04101
04102
04103
04104 void Parameters::free_angle_tree(struct angle_params *angle_ptr)
04105
04106 {
04107 if (angle_ptr->left != NULL)
04108 {
04109 free_angle_tree(angle_ptr->left);
04110 }
04111
04112 if (angle_ptr->right != NULL)
04113 {
04114 free_angle_tree(angle_ptr->right);
04115 }
04116
04117 delete angle_ptr;
04118
04119 return;
04120 }
04121
04122
04123
04124
04125
04126
04127
04128
04129
04130
04131
04132
04133
04134
04135 void Parameters::free_dihedral_list(struct dihedral_params *dih_ptr)
04136
04137 {
04138 struct dihedral_params *ptr;
04139 struct dihedral_params *next;
04140
04141 ptr=dih_ptr;
04142
04143 while (ptr != NULL)
04144 {
04145 next=ptr->next;
04146 delete ptr;
04147 ptr=next;
04148 }
04149
04150 return;
04151 }
04152
04153
04154
04155
04156
04157
04158
04159
04160
04161
04162
04163
04164
04165
04166 void Parameters::free_improper_list(struct improper_params *imp_ptr)
04167
04168 {
04169 struct improper_params *ptr;
04170 struct improper_params *next;
04171
04172 ptr=imp_ptr;
04173
04174 while (ptr != NULL)
04175 {
04176 next=ptr->next;
04177 delete ptr;
04178 ptr=next;
04179 }
04180
04181 return;
04182 }
04183
04184
04185
04186
04187
04188
04189
04190
04191
04192
04193
04194
04195
04196
04197 void Parameters::free_crossterm_list(struct crossterm_params *imp_ptr)
04198
04199 {
04200 struct crossterm_params *ptr;
04201 struct crossterm_params *next;
04202
04203 ptr=imp_ptr;
04204
04205 while (ptr != NULL)
04206 {
04207 next=ptr->next;
04208 delete ptr;
04209 ptr=next;
04210 }
04211
04212 return;
04213 }
04214
04215
04216
04217
04218
04219
04220
04221
04222
04223
04224
04225
04226
04227
04228
04229
04230 void Parameters::free_vdw_tree(struct vdw_params *vdw_ptr)
04231
04232 {
04233 if (vdw_ptr->left != NULL)
04234 {
04235 free_vdw_tree(vdw_ptr->left);
04236 }
04237
04238 if (vdw_ptr->right != NULL)
04239 {
04240 free_vdw_tree(vdw_ptr->right);
04241 }
04242
04243 delete vdw_ptr;
04244
04245 return;
04246 }
04247
04248
04249
04250
04251
04252
04253
04254
04255
04256
04257 void Parameters::free_vdw_pair_list()
04258 {
04259 struct vdw_pair_params *ptr, *next;
04260
04261 ptr=vdw_pairp;
04262
04263 while (ptr != NULL)
04264 {
04265 next = ptr->next;
04266
04267 delete ptr;
04268
04269 ptr = next;
04270 }
04271
04272 vdw_pairp = NULL;
04273 }
04274
04275
04276
04277
04278
04279
04280
04281
04282 void Parameters::free_table_pair_tree(IndexedTablePair *table_pair_ptr) {
04283 if (table_pair_ptr->left != NULL)
04284 {
04285 free_table_pair_tree(table_pair_ptr->left);
04286 }
04287
04288 if (table_pair_ptr->right != NULL)
04289 {
04290 free_table_pair_tree(table_pair_ptr->right);
04291 }
04292
04293 delete table_pair_ptr;
04294
04295 return;
04296 }
04297
04298
04299
04300
04301
04302
04303
04304
04305
04306
04307
04308
04309
04310
04311
04312
04313 void Parameters::free_vdw_pair_tree(IndexedVdwPair *vdw_pair_ptr)
04314
04315 {
04316 if (vdw_pair_ptr->left != NULL)
04317 {
04318 free_vdw_pair_tree(vdw_pair_ptr->left);
04319 }
04320
04321 if (vdw_pair_ptr->right != NULL)
04322 {
04323 free_vdw_pair_tree(vdw_pair_ptr->right);
04324 }
04325
04326 delete vdw_pair_ptr;
04327
04328 return;
04329 }
04330
04331
04332
04333
04334
04335
04336
04337
04338
04339
04340
04341
04342
04343
04344
04345 void Parameters::traverse_bond_params(struct bond_params *tree)
04346
04347 {
04348 if (tree==NULL)
04349 return;
04350
04351 if (tree->left != NULL)
04352 {
04353 traverse_bond_params(tree->left);
04354 }
04355
04356 DebugM(3,"BOND " << tree->atom1name << " " << tree->atom2name \
04357 << " index=" << tree->index << " k=" << tree->forceconstant \
04358 << " x0=" << tree->distance);
04359
04360 if (tree->right != NULL)
04361 {
04362 traverse_bond_params(tree->right);
04363 }
04364 }
04365
04366
04367
04368
04369
04370
04371
04372
04373
04374
04375
04376
04377
04378
04379
04380 void Parameters::traverse_angle_params(struct angle_params *tree)
04381
04382 {
04383 if (tree==NULL)
04384 return;
04385
04386 if (tree->left != NULL)
04387 {
04388 traverse_angle_params(tree->left);
04389 }
04390 DebugM(3,"ANGLE " << tree->atom1name << " " << tree->atom2name \
04391 << " " << tree->atom3name << " index=" << tree->index \
04392 << " k=" << tree->forceconstant << " theta0=" << tree->angle \
04393 );
04394
04395 if (tree->right != NULL)
04396 {
04397 traverse_angle_params(tree->right);
04398 }
04399 }
04400
04401
04402
04403
04404
04405
04406
04407
04408
04409
04410
04411
04412
04413
04414
04415 void Parameters::traverse_dihedral_params(struct dihedral_params *list)
04416
04417 {
04418 int i;
04419
04420 while (list != NULL)
04421 {
04422 DebugM(3,"DIHEDRAL " << list->atom1name << " " \
04423 << list->atom2name << " " << list->atom3name \
04424 << " " << list->atom4name << " index=" \
04425 << list->index \
04426 << " multiplicity=" << list->multiplicity << "\n");
04427
04428 for (i=0; i<list->multiplicity; i++)
04429 {
04430 DebugM(3,"k=" << list->values[i].k \
04431 << " n=" << list->values[i].n \
04432 << " delta=" << list->values[i].delta);
04433 }
04434
04435 list=list->next;
04436 }
04437 }
04438
04439
04440
04441
04442
04443
04444
04445
04446
04447
04448
04449
04450
04451
04452
04453 void Parameters::traverse_improper_params(struct improper_params *list)
04454
04455 {
04456 int i;
04457
04458 while (list != NULL)
04459 {
04460 DebugM(3,"Improper " << list->atom1name << " " \
04461 << list->atom2name << " " << list->atom3name \
04462 << " " << list->atom4name << " index=" \
04463 << list->index \
04464 << " multiplicity=" << list->multiplicity << "\n");
04465
04466 for (i=0; i<list->multiplicity; i++)
04467 {
04468 DebugM(3,"k=" << list->values[i].k \
04469 << " n=" << list->values[i].n \
04470 << " delta=" << list->values[i].delta);
04471 }
04472
04473 list=list->next;
04474 }
04475 }
04476
04477
04478
04479
04480
04481
04482
04483
04484
04485
04486
04487
04488
04489
04490
04491
04492 void Parameters::traverse_vdw_params(struct vdw_params *tree)
04493
04494 {
04495 if (tree==NULL)
04496 return;
04497
04498 if (tree->left != NULL)
04499 {
04500 traverse_vdw_params(tree->left);
04501 }
04502
04503 DebugM(3,"vdW " << tree->atomname << " index=" << tree->index \
04504 << " sigma=" << tree->sigma << " epsilon=" << \
04505 tree->epsilon << " sigma 1-4=" << tree->sigma14 \
04506 << " epsilon 1-4=" << tree->epsilon14 << std::endl);
04507
04508 if (tree->right != NULL)
04509 {
04510 traverse_vdw_params(tree->right);
04511 }
04512 }
04513
04514
04515
04516
04517
04518
04519
04520
04521
04522
04523
04524
04525
04526
04527 void Parameters::traverse_vdw_pair_params(struct vdw_pair_params *list)
04528
04529 {
04530 if (list==NULL)
04531 return;
04532
04533 DebugM(3,"vdW PAIR " << list->atom1name << " " \
04534 << list->atom2name << " A=" << list->A \
04535 << " B=" << list->B << " A 1-4=" \
04536 << list->A14 << " B 1-4=" << list->B14 \
04537 );
04538
04539 traverse_vdw_pair_params(list->next);
04540 }
04541
04542
04543
04544
04545
04546
04547
04548
04549
04550
04551
04552 void Parameters::print_bond_params()
04553 {
04554 DebugM(3,NumBondParams << " BOND PARAMETERS\n" \
04555 << "*****************************************" \
04556 );
04557
04558 traverse_bond_params(bondp);
04559 }
04560
04561
04562
04563
04564
04565
04566
04567
04568
04569
04570 void Parameters::print_angle_params()
04571 {
04572 DebugM(3,NumAngleParams << " ANGLE PARAMETERS\n"
04573 << "*****************************************" );
04574 traverse_angle_params(anglep);
04575 }
04576
04577
04578
04579
04580
04581
04582
04583
04584
04585
04586 void Parameters::print_dihedral_params()
04587 {
04588 DebugM(3,NumDihedralParams << " DIHEDRAL PARAMETERS\n" \
04589 << "*****************************************" );
04590
04591 traverse_dihedral_params(dihedralp);
04592 }
04593
04594
04595
04596
04597
04598
04599
04600
04601
04602
04603 void Parameters::print_improper_params()
04604 {
04605 DebugM(3,NumImproperParams << " IMPROPER PARAMETERS\n" \
04606 << "*****************************************" );
04607
04608 traverse_improper_params(improperp);
04609 }
04610
04611
04612
04613
04614
04615
04616
04617
04618
04619
04620 void Parameters::print_vdw_params()
04621 {
04622 DebugM(3,NumVdwParams << " vdW PARAMETERS\n" \
04623 << "*****************************************" );
04624
04625 traverse_vdw_params(vdwp);
04626 }
04627
04628
04629
04630
04631
04632
04633
04634
04635
04636
04637 void Parameters::print_vdw_pair_params()
04638 {
04639 DebugM(3,NumVdwPairParams << " vdW PAIR PARAMETERS\n" \
04640 << "*****************************************" );
04641
04642 traverse_vdw_pair_params(vdw_pairp);
04643 }
04644
04645
04646
04647
04648
04649
04650
04651
04652
04653
04654 void Parameters::print_param_summary()
04655 {
04656 iout << iINFO << "SUMMARY OF PARAMETERS:\n"
04657 << iINFO << NumBondParams << " BONDS\n"
04658 << iINFO << NumAngleParams << " ANGLES\n" << endi;
04659 if (cosAngles) {
04660 iout << iINFO << " " << (NumAngleParams - NumCosAngles) << " HARMONIC\n"
04661 << iINFO << " " << NumCosAngles << " COSINE-BASED\n" << endi;
04662 }
04663 iout << iINFO << NumDihedralParams << " DIHEDRAL\n"
04664 << iINFO << NumImproperParams << " IMPROPER\n"
04665 << iINFO << NumCrosstermParams << " CROSSTERM\n"
04666 << iINFO << NumVdwParams << " VDW\n"
04667 << iINFO << NumVdwPairParams << " VDW_PAIRS\n" << endi;
04668 }
04669
04670
04671
04672
04673
04674
04675
04676
04677
04678
04679
04680
04681
04682
04683
04684
04685
04686 void Parameters::done_reading_structure()
04687
04688 {
04689 if (bondp != NULL)
04690 free_bond_tree(bondp);
04691
04692 if (anglep != NULL)
04693 free_angle_tree(anglep);
04694
04695 if (dihedralp != NULL)
04696 free_dihedral_list(dihedralp);
04697
04698 if (improperp != NULL)
04699 free_improper_list(improperp);
04700
04701 if (crosstermp != NULL)
04702 free_crossterm_list(crosstermp);
04703
04704 if (vdwp != NULL)
04705 free_vdw_tree(vdwp);
04706
04707
04708
04709 if (maxDihedralMults != NULL)
04710 delete [] maxDihedralMults;
04711
04712 if (maxImproperMults != NULL)
04713 delete [] maxImproperMults;
04714
04715 bondp=NULL;
04716 anglep=NULL;
04717 dihedralp=NULL;
04718 improperp=NULL;
04719 crosstermp=NULL;
04720 vdwp=NULL;
04721 maxImproperMults=NULL;
04722 maxDihedralMults=NULL;
04723 }
04724
04725
04726
04727
04728
04729
04730
04731
04732
04733
04734
04735 void Parameters::send_Parameters(MOStream *msg)
04736 {
04737 Real *a1, *a2, *a3, *a4;
04738 int *i1, *i2, *i3;
04739 int i, j;
04740 Real **kvals;
04741 int **nvals;
04742 Real **deltavals;
04743
04744
04745
04746
04747
04748
04749
04750 msg->put(NumBondParams);
04751
04752 if (NumBondParams)
04753 {
04754 a1 = new Real[NumBondParams];
04755 a2 = new Real[NumBondParams];
04756
04757 if ( (a1 == NULL) || (a2 == NULL) )
04758 {
04759 NAMD_die("memory allocation failed in Parameters::send_Parameters");
04760 }
04761
04762 for (i=0; i<NumBondParams; i++)
04763 {
04764 a1[i] = bond_array[i].k;
04765 a2[i] = bond_array[i].x0;
04766 }
04767
04768 msg->put(NumBondParams, a1)->put(NumBondParams, a2);
04769
04770 delete [] a1;
04771 delete [] a2;
04772 }
04773
04774
04775 msg->put(NumAngleParams);
04776
04777 if (NumAngleParams)
04778 {
04779 a1 = new Real[NumAngleParams];
04780 a2 = new Real[NumAngleParams];
04781 a3 = new Real[NumAngleParams];
04782 a4 = new Real[NumAngleParams];
04783 i1 = new int[NumAngleParams];
04784
04785 if ( (a1 == NULL) || (a2 == NULL) || (a3 == NULL) ||
04786 (a4 == NULL) || (i1 == NULL))
04787 {
04788 NAMD_die("memory allocation failed in Parameters::send_Parameters");
04789 }
04790
04791 for (i=0; i<NumAngleParams; i++)
04792 {
04793 a1[i] = angle_array[i].k;
04794 a2[i] = angle_array[i].theta0;
04795 a3[i] = angle_array[i].k_ub;
04796 a4[i] = angle_array[i].r_ub;
04797 i1[i] = angle_array[i].normal;
04798 }
04799
04800 msg->put(NumAngleParams, a1)->put(NumAngleParams, a2);
04801 msg->put(NumAngleParams, a3)->put(NumAngleParams, a4);
04802 msg->put(NumAngleParams, i1);
04803
04804 delete [] a1;
04805 delete [] a2;
04806 delete [] a3;
04807 delete [] a4;
04808 delete [] i1;
04809 }
04810
04811
04812 msg->put(NumDihedralParams);
04813
04814 if (NumDihedralParams)
04815 {
04816 i1 = new int[NumDihedralParams];
04817 kvals = new Real *[MAX_MULTIPLICITY];
04818 nvals = new int *[MAX_MULTIPLICITY];
04819 deltavals = new Real *[MAX_MULTIPLICITY];
04820
04821 if ( (i1 == NULL) || (kvals == NULL) || (nvals == NULL) ||
04822 (deltavals == NULL) )
04823 {
04824 NAMD_die("memory allocation failed in Parameters::send_Parameters");
04825 }
04826
04827 for (i=0; i<MAX_MULTIPLICITY; i++)
04828 {
04829 kvals[i] = new Real[NumDihedralParams];
04830 nvals[i] = new int[NumDihedralParams];
04831 deltavals[i] = new Real[NumDihedralParams];
04832
04833 if ( (kvals[i] == NULL) || (nvals[i] == NULL) || (deltavals[i] == NULL) )
04834 {
04835 NAMD_die("memory allocation failed in Parameters::send_Parameters");
04836 }
04837 }
04838
04839 for (i=0; i<NumDihedralParams; i++)
04840 {
04841 i1[i] = dihedral_array[i].multiplicity;
04842
04843 for (j=0; j<MAX_MULTIPLICITY; j++)
04844 {
04845 kvals[j][i] = dihedral_array[i].values[j].k;
04846 nvals[j][i] = dihedral_array[i].values[j].n;
04847 deltavals[j][i] = dihedral_array[i].values[j].delta;
04848 }
04849 }
04850
04851 msg->put(NumDihedralParams, i1);
04852
04853 for (i=0; i<MAX_MULTIPLICITY; i++)
04854 {
04855 msg->put(NumDihedralParams, kvals[i]);
04856 msg->put(NumDihedralParams, nvals[i]);
04857 msg->put(NumDihedralParams, deltavals[i]);
04858
04859 delete [] kvals[i];
04860 delete [] nvals[i];
04861 delete [] deltavals[i];
04862 }
04863
04864 delete [] i1;
04865 delete [] kvals;
04866 delete [] nvals;
04867 delete [] deltavals;
04868 }
04869
04870
04871 msg->put(NumImproperParams);
04872
04873 if (NumImproperParams)
04874 {
04875 i1 = new int[NumImproperParams];
04876 kvals = new Real *[MAX_MULTIPLICITY];
04877 nvals = new int *[MAX_MULTIPLICITY];
04878 deltavals = new Real *[MAX_MULTIPLICITY];
04879
04880 if ( (i1 == NULL) || (kvals == NULL) || (nvals == NULL) ||
04881 (deltavals == NULL) )
04882 {
04883 NAMD_die("memory allocation failed in Parameters::send_Parameters");
04884 }
04885
04886 for (i=0; i<MAX_MULTIPLICITY; i++)
04887 {
04888 kvals[i] = new Real[NumImproperParams];
04889 nvals[i] = new int[NumImproperParams];
04890 deltavals[i] = new Real[NumImproperParams];
04891
04892 if ( (kvals[i] == NULL) || (nvals[i] == NULL) || (deltavals[i] == NULL) )
04893 {
04894 NAMD_die("memory allocation failed in Parameters::send_Parameters");
04895 }
04896 }
04897
04898 for (i=0; i<NumImproperParams; i++)
04899 {
04900 i1[i] = improper_array[i].multiplicity;
04901
04902 for (j=0; j<MAX_MULTIPLICITY; j++)
04903 {
04904 kvals[j][i] = improper_array[i].values[j].k;
04905 nvals[j][i] = improper_array[i].values[j].n;
04906 deltavals[j][i] = improper_array[i].values[j].delta;
04907 }
04908 }
04909
04910 msg->put(NumImproperParams, i1);
04911
04912 for (i=0; i<MAX_MULTIPLICITY; i++)
04913 {
04914 msg->put(NumImproperParams, kvals[i]);
04915 msg->put(NumImproperParams, nvals[i]);
04916 msg->put(NumImproperParams, deltavals[i]);
04917
04918 delete [] kvals[i];
04919 delete [] nvals[i];
04920 delete [] deltavals[i];
04921 }
04922
04923 delete [] i1;
04924 delete [] kvals;
04925 delete [] nvals;
04926 delete [] deltavals;
04927 }
04928
04929
04930 msg->put(NumCrosstermParams);
04931
04932 if (NumCrosstermParams)
04933 {
04934 for (i=0; i<NumCrosstermParams; ++i) {
04935 int nvals = CrosstermValue::dim * CrosstermValue::dim * 2 * 2;
04936 msg->put(nvals,&crossterm_array[i].c[0][0].d00);
04937 }
04938 }
04939
04940
04941 msg->put(numenerentries);
04942
04943 if (numenerentries) {
04944
04945
04946
04947
04948
04949
04950
04951
04952 msg->put(numenerentries, table_ener);
04953 }
04954
04955
04956 msg->put(NumVdwParams);
04957 msg->put(NumVdwParamsAssigned);
04958
04959 if (NumVdwParams)
04960 {
04961 a1 = new Real[NumVdwParams];
04962 a2 = new Real[NumVdwParams];
04963 a3 = new Real[NumVdwParams];
04964 a4 = new Real[NumVdwParams];
04965
04966 if ( (a1 == NULL) || (a2 == NULL) || (a3 == NULL) )
04967 {
04968 NAMD_die("memory allocation failed in Parameters::send_Parameters");
04969 }
04970
04971 for (i=0; i<NumVdwParams; i++)
04972 {
04973 a1[i] = vdw_array[i].sigma;
04974 a2[i] = vdw_array[i].epsilon;
04975 a3[i] = vdw_array[i].sigma14;
04976 a4[i] = vdw_array[i].epsilon14;
04977 }
04978
04979 msg->put(NumVdwParams * (MAX_ATOMTYPE_CHARS+1), atomTypeNames);
04980 msg->put(NumVdwParams, a1);
04981 msg->put(NumVdwParams, a2);
04982 msg->put(NumVdwParams, a3);
04983 msg->put(NumVdwParams, a4);
04984
04985 delete [] a1;
04986 delete [] a2;
04987 delete [] a3;
04988 delete [] a4;
04989 }
04990
04991
04992 msg->put(NumVdwPairParams);
04993
04994 if (NumVdwPairParams)
04995 {
04996 a1 = new Real[NumVdwPairParams];
04997 a2 = new Real[NumVdwPairParams];
04998 a3 = new Real[NumVdwPairParams];
04999 a4 = new Real[NumVdwPairParams];
05000 i1 = new int[NumVdwPairParams];
05001 i2 = new int[NumVdwPairParams];
05002
05003 if ( (a1 == NULL) || (a2 == NULL) || (a3 == NULL) || (a4 == NULL) ||
05004 (i1 == NULL) || (i2 == NULL) )
05005 {
05006 NAMD_die("memory allocation failed in Parameters::send_Parameters");
05007 }
05008
05009 vdw_pair_to_arrays(i1, i2, a1, a2, a3, a4, 0, vdw_pair_tree);
05010
05011 msg->put(NumVdwPairParams, i1)->put(NumVdwPairParams, i2);
05012 msg->put(NumVdwPairParams, a1);
05013 msg->put(NumVdwPairParams, a2)->put(NumVdwPairParams, a3);
05014 msg->put(NumVdwPairParams, a4);
05015 }
05016
05017
05018
05019 msg->put(NumTablePairParams);
05020
05021 if (NumTablePairParams)
05022 {
05023 i1 = new int[NumTablePairParams];
05024 i2 = new int[NumTablePairParams];
05025 i3 = new int[NumTablePairParams];
05026
05027 if ( (i3 == NULL) || (i1 == NULL) || (i2 == NULL) )
05028 {
05029 NAMD_die("memory allocation failed in Parameters::send_Parameters");
05030 }
05031
05032 table_pair_to_arrays(i1, i2, i3, 0, tab_pair_tree);
05033
05034 msg->put(NumTablePairParams, i1)->put(NumTablePairParams, i2);
05035 msg->put(NumTablePairParams, i3);
05036 }
05037
05038
05039
05040 msg->end();
05041 delete msg;
05042 }
05043
05044
05045
05046
05047
05048
05049
05050
05051
05052
05053 void Parameters::receive_Parameters(MIStream *msg)
05054
05055 {
05056 int i, j;
05057 Real *a1, *a2, *a3, *a4;
05058 int *i1, *i2, *i3;
05059 IndexedVdwPair *new_node;
05060 IndexedTablePair *new_tab_node;
05061 Real **kvals;
05062 int **nvals;
05063 Real **deltavals;
05064
05065
05066 msg->get(NumBondParams);
05067
05068 if (NumBondParams)
05069 {
05070 bond_array = new BondValue[NumBondParams];
05071 a1 = new Real[NumBondParams];
05072 a2 = new Real[NumBondParams];
05073
05074 if ( (bond_array == NULL) || (a1 == NULL) || (a2 == NULL) )
05075 {
05076 NAMD_die("memory allocation failed in Parameters::receive_Parameters");
05077 }
05078
05079 msg->get(NumBondParams, a1);
05080 msg->get(NumBondParams, a2);
05081
05082 for (i=0; i<NumBondParams; i++)
05083 {
05084 bond_array[i].k = a1[i];
05085 bond_array[i].x0 = a2[i];
05086 }
05087
05088 delete [] a1;
05089 delete [] a2;
05090 }
05091
05092
05093 msg->get(NumAngleParams);
05094
05095 if (NumAngleParams)
05096 {
05097 angle_array = new AngleValue[NumAngleParams];
05098 a1 = new Real[NumAngleParams];
05099 a2 = new Real[NumAngleParams];
05100 a3 = new Real[NumAngleParams];
05101 a4 = new Real[NumAngleParams];
05102 i1 = new int[NumAngleParams];
05103
05104 if ( (angle_array == NULL) || (a1 == NULL) || (a2 == NULL) ||
05105 (a3 == NULL) || (a4 == NULL) || (i1 == NULL))
05106 {
05107 NAMD_die("memory allocation failed in Parameters::receive_Parameters");
05108 }
05109
05110 msg->get(NumAngleParams, a1);
05111 msg->get(NumAngleParams, a2);
05112 msg->get(NumAngleParams, a3);
05113 msg->get(NumAngleParams, a4);
05114 msg->get(NumAngleParams, i1);
05115
05116 for (i=0; i<NumAngleParams; i++)
05117 {
05118 angle_array[i].k = a1[i];
05119 angle_array[i].theta0 = a2[i];
05120 angle_array[i].k_ub = a3[i];
05121 angle_array[i].r_ub = a4[i];
05122 angle_array[i].normal = i1[i];
05123 }
05124
05125 delete [] a1;
05126 delete [] a2;
05127 delete [] a3;
05128 delete [] a4;
05129 delete [] i1;
05130 }
05131
05132
05133 msg->get(NumDihedralParams);
05134
05135 if (NumDihedralParams)
05136 {
05137 dihedral_array = new DihedralValue[NumDihedralParams];
05138
05139 i1 = new int[NumDihedralParams];
05140 kvals = new Real *[MAX_MULTIPLICITY];
05141 nvals = new int *[MAX_MULTIPLICITY];
05142 deltavals = new Real *[MAX_MULTIPLICITY];
05143
05144 if ( (i1 == NULL) || (kvals == NULL) || (nvals == NULL) ||
05145 (deltavals == NULL) || (dihedral_array == NULL) )
05146 {
05147 NAMD_die("memory allocation failed in Parameters::send_Parameters");
05148 }
05149
05150 for (i=0; i<MAX_MULTIPLICITY; i++)
05151 {
05152 kvals[i] = new Real[NumDihedralParams];
05153 nvals[i] = new int[NumDihedralParams];
05154 deltavals[i] = new Real[NumDihedralParams];
05155
05156 if ( (kvals[i] == NULL) || (nvals[i] == NULL) || (deltavals[i] == NULL) )
05157 {
05158 NAMD_die("memory allocation failed in Parameters::send_Parameters");
05159 }
05160 }
05161
05162 msg->get(NumDihedralParams, i1);
05163
05164 for (i=0; i<MAX_MULTIPLICITY; i++)
05165 {
05166 msg->get(NumDihedralParams, kvals[i]);
05167 msg->get(NumDihedralParams, nvals[i]);
05168 msg->get(NumDihedralParams, deltavals[i]);
05169 }
05170
05171 for (i=0; i<NumDihedralParams; i++)
05172 {
05173 dihedral_array[i].multiplicity = i1[i];
05174
05175 for (j=0; j<MAX_MULTIPLICITY; j++)
05176 {
05177 dihedral_array[i].values[j].k = kvals[j][i];
05178 dihedral_array[i].values[j].n = nvals[j][i];
05179 dihedral_array[i].values[j].delta = deltavals[j][i];
05180 }
05181 }
05182
05183 for (i=0; i<MAX_MULTIPLICITY; i++)
05184 {
05185 delete [] kvals[i];
05186 delete [] nvals[i];
05187 delete [] deltavals[i];
05188 }
05189
05190 delete [] i1;
05191 delete [] kvals;
05192 delete [] nvals;
05193 delete [] deltavals;
05194 }
05195
05196
05197 msg->get(NumImproperParams);
05198
05199 if (NumImproperParams)
05200 {
05201 improper_array = new ImproperValue[NumImproperParams];
05202 i1 = new int[NumImproperParams];
05203 kvals = new Real *[MAX_MULTIPLICITY];
05204 nvals = new int *[MAX_MULTIPLICITY];
05205 deltavals = new Real *[MAX_MULTIPLICITY];
05206
05207 if ( (i1 == NULL) || (kvals == NULL) || (nvals == NULL) ||
05208 (deltavals == NULL) || (improper_array==NULL) )
05209 {
05210 NAMD_die("memory allocation failed in Parameters::send_Parameters");
05211 }
05212
05213 for (i=0; i<MAX_MULTIPLICITY; i++)
05214 {
05215 kvals[i] = new Real[NumImproperParams];
05216 nvals[i] = new int[NumImproperParams];
05217 deltavals[i] = new Real[NumImproperParams];
05218
05219 if ( (kvals[i] == NULL) || (nvals[i] == NULL) || (deltavals[i] == NULL) )
05220 {
05221 NAMD_die("memory allocation failed in Parameters::send_Parameters");
05222 }
05223 }
05224
05225 msg->get(NumImproperParams,i1);
05226
05227 for (i=0; i<MAX_MULTIPLICITY; i++)
05228 {
05229 msg->get(NumImproperParams,kvals[i]);
05230 msg->get(NumImproperParams,nvals[i]);
05231 msg->get(NumImproperParams,deltavals[i]);
05232 }
05233
05234 for (i=0; i<NumImproperParams; i++)
05235 {
05236 improper_array[i].multiplicity = i1[i];
05237
05238 for (j=0; j<MAX_MULTIPLICITY; j++)
05239 {
05240 improper_array[i].values[j].k = kvals[j][i];
05241 improper_array[i].values[j].n = nvals[j][i];
05242 improper_array[i].values[j].delta = deltavals[j][i];
05243 }
05244 }
05245
05246 for (i=0; i<MAX_MULTIPLICITY; i++)
05247 {
05248 delete [] kvals[i];
05249 delete [] nvals[i];
05250 delete [] deltavals[i];
05251 }
05252
05253 delete [] i1;
05254 delete [] kvals;
05255 delete [] nvals;
05256 delete [] deltavals;
05257 }
05258
05259
05260 msg->get(NumCrosstermParams);
05261
05262 if (NumCrosstermParams)
05263 {
05264 crossterm_array = new CrosstermValue[NumCrosstermParams];
05265
05266 for (i=0; i<NumCrosstermParams; ++i) {
05267 int nvals = CrosstermValue::dim * CrosstermValue::dim * 2 * 2;
05268 msg->get(nvals,&crossterm_array[i].c[0][0].d00);
05269 }
05270 }
05271
05272
05273 msg->get(numenerentries);
05274 if (numenerentries > 0) {
05275
05276
05277 table_ener = new BigReal[numenerentries];
05278
05279 if (table_ener==NULL)
05280 {
05281 NAMD_die("memory allocation failed in Parameters::receive_Parameters");
05282 }
05283
05284 msg->get(numenerentries, table_ener);
05285 }
05286
05287
05288 msg->get(NumVdwParams);
05289 msg->get(NumVdwParamsAssigned);
05290
05291 if (NumVdwParams)
05292 {
05293 atomTypeNames = new char[NumVdwParams*(MAX_ATOMTYPE_CHARS+1)];
05294 vdw_array = new VdwValue[NumVdwParams];
05295 a1 = new Real[NumVdwParams];
05296 a2 = new Real[NumVdwParams];
05297 a3 = new Real[NumVdwParams];
05298 a4 = new Real[NumVdwParams];
05299
05300 if ( (vdw_array==NULL) || (a1==NULL) || (a2==NULL) || (a3==NULL)
05301 || (a4==NULL) || (atomTypeNames==NULL))
05302 {
05303 NAMD_die("memory allocation failed in Parameters::receive_Parameters");
05304 }
05305
05306 msg->get(NumVdwParams * (MAX_ATOMTYPE_CHARS+1), atomTypeNames);
05307 msg->get(NumVdwParams, a1);
05308 msg->get(NumVdwParams, a2);
05309 msg->get(NumVdwParams, a3);
05310 msg->get(NumVdwParams, a4);
05311
05312 for (i=0; i<NumVdwParams; i++)
05313 {
05314 vdw_array[i].sigma = a1[i];
05315 vdw_array[i].epsilon = a2[i];
05316 vdw_array[i].sigma14 = a3[i];
05317 vdw_array[i].epsilon14 = a4[i];
05318 }
05319
05320 delete [] a1;
05321 delete [] a2;
05322 delete [] a3;
05323 delete [] a4;
05324 }
05325
05326
05327 msg->get(NumVdwPairParams);
05328
05329 if (NumVdwPairParams)
05330 {
05331 a1 = new Real[NumVdwPairParams];
05332 a2 = new Real[NumVdwPairParams];
05333 a3 = new Real[NumVdwPairParams];
05334 a4 = new Real[NumVdwPairParams];
05335 i1 = new int[NumVdwPairParams];
05336 i2 = new int[NumVdwPairParams];
05337
05338 if ( (a1 == NULL) || (a2 == NULL) || (a3 == NULL) || (a4 == NULL) ||
05339 (i1 == NULL) || (i2 == NULL) )
05340 {
05341 NAMD_die("memory allocation failed in Parameters::send_Parameters");
05342 }
05343
05344 msg->get(NumVdwPairParams, i1);
05345 msg->get(NumVdwPairParams, i2);
05346 msg->get(NumVdwPairParams, a1);
05347 msg->get(NumVdwPairParams, a2);
05348 msg->get(NumVdwPairParams, a3);
05349 msg->get(NumVdwPairParams, a4);
05350
05351 for (i=0; i<NumVdwPairParams; i++)
05352 {
05353 new_node = (IndexedVdwPair *) malloc(sizeof(IndexedVdwPair));
05354
05355 if (new_node == NULL)
05356 {
05357 NAMD_die("memory allocation failed in Parameters::receive_Parameters");
05358 }
05359
05360 new_node->ind1 = i1[i];
05361 new_node->ind2 = i2[i];
05362 new_node->A = a1[i];
05363 new_node->A14 = a2[i];
05364 new_node->B = a3[i];
05365 new_node->B14 = a4[i];
05366 new_node->left = NULL;
05367 new_node->right = NULL;
05368
05369 vdw_pair_tree = add_to_indexed_vdw_pairs(new_node, vdw_pair_tree);
05370 }
05371
05372 delete [] i1;
05373 delete [] i2;
05374 delete [] a1;
05375 delete [] a2;
05376 delete [] a3;
05377 delete [] a4;
05378 }
05379
05380
05381 msg->get(NumTablePairParams);
05382
05383 if (NumTablePairParams)
05384 {
05385 i1 = new int[NumTablePairParams];
05386 i2 = new int[NumTablePairParams];
05387 i3 = new int[NumTablePairParams];
05388
05389 if ( (i3 == NULL) || (i1 == NULL) || (i2 == NULL) )
05390 {
05391 NAMD_die("memory allocation failed in Parameters::send_Parameters");
05392 }
05393
05394 msg->get(NumTablePairParams, i1);
05395 msg->get(NumTablePairParams, i2);
05396 msg->get(NumTablePairParams, i3);
05397
05398 for (i=0; i<NumTablePairParams; i++)
05399 {
05400 new_tab_node = (IndexedTablePair *) malloc(sizeof(IndexedTablePair));
05401
05402 if (new_tab_node == NULL)
05403 {
05404 NAMD_die("memory allocation failed in Parameters::receive_Parameters");
05405 }
05406
05407
05408 new_tab_node->ind1 = i1[i];
05409 new_tab_node->ind2 = i2[i];
05410 new_tab_node->K = i3[i];
05411 new_tab_node->left = NULL;
05412 new_tab_node->right = NULL;
05413
05414 tab_pair_tree = add_to_indexed_table_pairs(new_tab_node, tab_pair_tree);
05415 }
05416
05417 delete [] i1;
05418 delete [] i2;
05419 delete [] i3;
05420 }
05421
05422
05423
05424
05425 AllFilesRead = TRUE;
05426
05427 delete msg;
05428 }
05429
05430
05431
05432
05433
05434
05435
05436
05437
05438
05439
05440
05441
05442 void Parameters::convert_vdw_pairs()
05443
05444 {
05445 #ifdef MEM_OPT_VERSION
05446 AtomCstInfo atom_struct;
05447 #else
05448 Atom atom_struct;
05449 #endif
05450 Index index1, index2;
05451 IndexedVdwPair *new_node;
05452 struct vdw_pair_params *ptr, *next;
05453
05454 ptr = vdw_pairp;
05455
05456
05457
05458 while (ptr != NULL)
05459 {
05460 new_node = (IndexedVdwPair *) malloc(sizeof(IndexedVdwPair));
05461
05462 if (new_node == NULL)
05463 {
05464 NAMD_die("memory allocation failed in Parameters::convert_vdw_pairs");
05465 }
05466
05467
05468
05469 assign_vdw_index(ptr->atom1name, &atom_struct);
05470 index1 = atom_struct.vdw_type;
05471 assign_vdw_index(ptr->atom2name, &atom_struct);
05472 index2 = atom_struct.vdw_type;
05473
05474 if (index1 > index2)
05475 {
05476 new_node->ind1 = index2;
05477 new_node->ind2 = index1;
05478 }
05479 else
05480 {
05481 new_node->ind1 = index1;
05482 new_node->ind2 = index2;
05483 }
05484
05485 new_node->A = ptr->A;
05486 new_node->B = ptr->B;
05487 new_node->A14 = ptr->A14;
05488 new_node->B14 = ptr->B14;
05489
05490 new_node->left = NULL;
05491 new_node->right = NULL;
05492
05493
05494 vdw_pair_tree = add_to_indexed_vdw_pairs(new_node, vdw_pair_tree);
05495
05496
05497 next = ptr->next;
05498
05499 delete ptr;
05500
05501 ptr = next;
05502 }
05503
05504 vdw_pairp = NULL;
05505
05506 }
05507
05508
05509
05510
05511
05512
05513
05514
05515
05516
05517
05518
05519
05520 void Parameters::convert_table_pairs()
05521
05522 {
05523 #ifdef MEM_OPT_VERSION
05524 AtomCstInfo atom_struct;
05525 #else
05526 Atom atom_struct;
05527 #endif
05528 Index index1, index2;
05529 IndexedTablePair *new_node;
05530 struct table_pair_params *ptr, *next;
05531
05532 ptr = table_pairp;
05533
05534
05535
05536 while (ptr != NULL)
05537 {
05538 new_node = (IndexedTablePair *) malloc(sizeof(IndexedTablePair));
05539
05540 if (new_node == NULL)
05541 {
05542 NAMD_die("memory allocation failed in Parameters::convert_table_pairs");
05543 }
05544
05545
05546
05547 assign_vdw_index(ptr->atom1name, &atom_struct);
05548 index1 = atom_struct.vdw_type;
05549 assign_vdw_index(ptr->atom2name, &atom_struct);
05550 index2 = atom_struct.vdw_type;
05551
05552
05553
05554 if (index1 > index2)
05555 {
05556 new_node->ind1 = index2;
05557 new_node->ind2 = index1;
05558 }
05559 else
05560 {
05561 new_node->ind1 = index1;
05562 new_node->ind2 = index2;
05563 }
05564
05565 new_node->K = ptr->K;
05566
05567 new_node->left = NULL;
05568 new_node->right = NULL;
05569
05570
05571 tab_pair_tree = add_to_indexed_table_pairs(new_node, tab_pair_tree);
05572
05573
05574 next = ptr->next;
05575
05576 delete ptr;
05577
05578 ptr = next;
05579 }
05580
05581 table_pairp = NULL;
05582
05583 }
05584
05585
05586
05587
05588
05589
05590
05591
05592
05593
05594
05595
05596
05597
05598
05599 IndexedTablePair *Parameters::add_to_indexed_table_pairs(IndexedTablePair *new_node,
05600 IndexedTablePair *tree)
05601
05602 {
05603 if (tree == NULL)
05604 return(new_node);
05605
05606 if ( (new_node->ind1 < tree->ind1) ||
05607 ((new_node->ind1 == tree->ind1) && (new_node->ind2 < tree->ind2)) )
05608 {
05609 tree->left = add_to_indexed_table_pairs(new_node, tree->left);
05610 }
05611 else
05612 {
05613 tree->right = add_to_indexed_table_pairs(new_node, tree->right);
05614 }
05615
05616 return(tree);
05617 }
05618
05619
05620
05621
05622
05623
05624
05625
05626
05627
05628
05629
05630
05631
05632
05633 IndexedVdwPair *Parameters::add_to_indexed_vdw_pairs(IndexedVdwPair *new_node,
05634 IndexedVdwPair *tree)
05635
05636 {
05637 if (tree == NULL)
05638 return(new_node);
05639
05640 if ( (new_node->ind1 < tree->ind1) ||
05641 ((new_node->ind1 == tree->ind1) && (new_node->ind2 < tree->ind2)) )
05642 {
05643 tree->left = add_to_indexed_vdw_pairs(new_node, tree->left);
05644 }
05645 else
05646 {
05647 tree->right = add_to_indexed_vdw_pairs(new_node, tree->right);
05648 }
05649
05650 return(tree);
05651 }
05652
05653
05654
05655
05656
05657
05658
05659
05660
05661
05662
05663
05664
05665
05666
05667
05668
05669
05670
05671
05672
05673
05674
05675 int Parameters::vdw_pair_to_arrays(int *ind1_array, int *ind2_array,
05676 Real *A, Real *A14,
05677 Real *B, Real *B14,
05678 int arr_index, IndexedVdwPair *tree)
05679
05680 {
05681 if (tree == NULL)
05682 return(arr_index);
05683
05684 ind1_array[arr_index] = tree->ind1;
05685 ind2_array[arr_index] = tree->ind2;
05686 A[arr_index] = tree->A;
05687 A14[arr_index] = tree->A14;
05688 B[arr_index] = tree->B;
05689 B14[arr_index] = tree->B14;
05690
05691 arr_index++;
05692
05693 arr_index = vdw_pair_to_arrays(ind1_array, ind2_array, A, A14, B, B14,
05694 arr_index, tree->left);
05695 arr_index = vdw_pair_to_arrays(ind1_array, ind2_array, A, A14, B, B14,
05696 arr_index, tree->right);
05697
05698 return(arr_index);
05699 }
05700
05701
05702
05703
05704
05705
05706
05707
05708
05709
05710
05711
05712
05713
05714
05715
05716
05717
05718 int Parameters::table_pair_to_arrays(int *ind1_array, int *ind2_array,
05719 int *K,
05720 int arr_index, IndexedTablePair *tree)
05721
05722 {
05723 if (tree == NULL)
05724 return(arr_index);
05725
05726 ind1_array[arr_index] = tree->ind1;
05727 ind2_array[arr_index] = tree->ind2;
05728 K[arr_index] = tree->K;
05729
05730 arr_index++;
05731
05732 arr_index = table_pair_to_arrays(ind1_array, ind2_array, K,
05733 arr_index, tree->left);
05734 arr_index = table_pair_to_arrays(ind1_array, ind2_array, K,
05735 arr_index, tree->right);
05736
05737 return(arr_index);
05738 }
05739
05740
05741
05742
05743
05744
05745
05746
05747
05748
05749 Parameters::Parameters(Ambertoppar *amber_data, BigReal vdw14)
05750 {
05751 initialize();
05752
05753
05754 read_parm(amber_data,vdw14);
05755 }
05756
05757
05758
05759
05760
05761
05762
05763
05764
05765
05766
05767
05768
05769
05770
05771 void Parameters::read_parm(Ambertoppar *amber_data, BigReal vdw14)
05772 {
05773 int i,j,ico,numtype,mul;
05774 IndexedVdwPair *new_node;
05775
05776 if (!amber_data->data_read)
05777 NAMD_die("No data read from parm file yet!");
05778
05779
05780 NumBondParams = amber_data->Numbnd;
05781 if (NumBondParams)
05782 { bond_array = new BondValue[NumBondParams];
05783 if (bond_array == NULL)
05784 NAMD_die("memory allocation of bond_array failed!");
05785 }
05786 for (i=0; i<NumBondParams; ++i)
05787 { bond_array[i].k = amber_data->Rk[i];
05788 bond_array[i].x0 = amber_data->Req[i];
05789 }
05790
05791
05792 NumAngleParams = amber_data->Numang;
05793 if (NumAngleParams)
05794 { angle_array = new AngleValue[NumAngleParams];
05795 if (angle_array == NULL)
05796 NAMD_die("memory allocation of angle_array failed!");
05797 }
05798 for (i=0; i<NumAngleParams; ++i)
05799 { angle_array[i].k = amber_data->Tk[i];
05800 angle_array[i].theta0 = amber_data->Teq[i];
05801
05802 angle_array[i].k_ub = angle_array[i].r_ub = 0;
05803
05804 angle_array[i].normal = 1;
05805 }
05806
05807
05808
05809
05810
05811
05812
05813
05814 NumDihedralParams = amber_data->Nptra;
05815 if (NumDihedralParams)
05816 { dihedral_array = new DihedralValue[amber_data->Nptra];
05817 if (dihedral_array == NULL)
05818 NAMD_die("memory allocation of dihedral_array failed!");
05819 }
05820 mul = 0;
05821 for (i=0; i<NumDihedralParams; ++i)
05822 { dihedral_array[i-mul].values[mul].k = amber_data->Pk[i];
05823 dihedral_array[i-mul].values[mul].n = int(fabs(amber_data->Pn[i])+0.5);
05824 if (dihedral_array[i-mul].values[mul].n == 0)
05825 { char err_msg[128];
05826 sprintf(err_msg, "The periodicity of dihedral # %d is zero!", i+1);
05827 NAMD_die(err_msg);
05828 }
05829 dihedral_array[i-mul].values[mul].delta = amber_data->Phase[i];
05830
05831
05832 if (amber_data->Pn[i] > 0)
05833 { dihedral_array[i-mul].multiplicity = mul+1;
05834 mul = 0;
05835 }
05836 else if (++mul >= MAX_MULTIPLICITY)
05837 { char err_msg[181];
05838 sprintf(err_msg, "Multiple dihedral with multiplicity of %d greater than max of %d",
05839 mul+1, MAX_MULTIPLICITY);
05840 NAMD_die(err_msg);
05841 }
05842 }
05843 if (mul > 0)
05844 NAMD_die("Negative periodicity in the last dihedral entry!");
05845
05846
05847
05848
05849 NumVdwParamsAssigned = numtype = amber_data->Ntypes;
05850 NumVdwPairParams = numtype * (numtype+1) / 2;
05851 for (i=0; i<numtype; ++i)
05852 for (j=i; j<numtype; ++j)
05853 { new_node = new IndexedVdwPair;
05854 if (new_node == NULL)
05855 NAMD_die("memory allocation of vdw_pair_tree failed!");
05856 new_node->ind1 = i;
05857 new_node->ind2 = j;
05858 new_node->left = new_node->right = NULL;
05859
05860
05861
05862
05863
05864 ico = amber_data->Cno[numtype*i+j];
05865 if (ico>0)
05866 { new_node->A = amber_data->Cn1[ico-1];
05867 new_node->A14 = new_node->A / vdw14;
05868 new_node->B = amber_data->Cn2[ico-1];
05869 new_node->B14 = new_node->B / vdw14;
05870 }
05871 else if (amber_data->HB12[abs(ico)-1]==0.0 && amber_data->HB6[abs(ico)-1]==0.0)
05872 { new_node->A = new_node->A14 = new_node->B = new_node->B14 = 0.0;
05873 iout << iWARN << "Encounter 10-12 H-bond term\n";
05874 }
05875 else
05876 NAMD_die("Encounter non-zero 10-12 H-bond term!");
05877
05878 vdw_pair_tree = add_to_indexed_vdw_pairs(new_node, vdw_pair_tree);
05879 }
05880 }
05881
05882
05883
05884
05885
05886
05887
05888
05889
05890
05891 Parameters::Parameters(const GromacsTopFile *gf, Bool min)
05892 {
05893 initialize();
05894
05895
05896 read_parm(gf,min);
05897 }
05898
05899
05900
05901
05902
05903
05904
05905
05906
05907
05908
05909
05910
05911
05912
05913 void Parameters::read_parm(const GromacsTopFile *gf, Bool min)
05914 {
05915 int numtype;
05916 IndexedVdwPair *new_node;
05917 int i,j,funct;
05918 Real test1,test2;
05919
05920
05921 NumBondParams = gf->getNumBondParams();
05922 NumAngleParams = gf->getNumAngleParams();
05923 NumDihedralParams = gf->getNumDihedralParams();
05924 if (NumBondParams) {
05925 bond_array = new BondValue[NumBondParams];
05926 if (bond_array == NULL)
05927 NAMD_die("memory allocation of bond_array failed!");
05928 }
05929 if (NumDihedralParams) {
05930 dihedral_array = new DihedralValue[NumDihedralParams];
05931 if (dihedral_array == NULL)
05932 NAMD_die("memory allocation of dihedral_array failed!");
05933 }
05934 if (NumAngleParams) {
05935 angle_array = new AngleValue[NumAngleParams];
05936 if (angle_array == NULL)
05937 NAMD_die("memory allocation of angle_array failed!");
05938 }
05939
05940
05941
05942
05943 for (i=0;i<NumBondParams;i++) {
05944 Real x0,k;
05945 gf->getBondParams(i,
05946 &x0,
05947 &k,
05948 &funct);
05949 bond_array[i].x0 = x0;
05950 bond_array[i].k = k;
05951 }
05952
05953
05954
05955
05956 for (i=0;i<NumAngleParams;i++) {
05957 Real theta0,k;
05958 gf->getAngleParams(i,
05959 &theta0,
05960 &k,
05961 &funct);
05962 angle_array[i].theta0 = theta0*PI/180;
05963 angle_array[i].k = k;
05964
05965 angle_array[i].k_ub = angle_array[i].r_ub = 0;
05966 angle_array[i].normal = 1;
05967 }
05968
05969
05970
05971 for (i=0; i<NumDihedralParams; ++i) {
05972 Real c[6];
05973 int num_periods;
05974 int funct;
05975
05976 gf->getDihedralParams(i,c,&num_periods,&funct);
05977
05978 switch(funct) {
05979 case 1:
05980 dihedral_array[i].values[0].delta = c[0]*PI/180;
05981 dihedral_array[i].values[0].k = c[1];
05982 dihedral_array[i].values[0].n = num_periods;
05983 dihedral_array[i].multiplicity = 1;
05984 break;
05985 case 2:
05986 dihedral_array[i].values[0].delta = c[0]*PI/180;
05987 dihedral_array[i].values[0].k = c[1];
05988 dihedral_array[i].values[0].n = 0;
05989 dihedral_array[i].multiplicity = 1;
05990 break;
05991 case 3:
05992
05993
05994 if(MAX_MULTIPLICITY < 5)
05995 NAMD_die("I can't do RB dihedrals with MAX_MULTIPLICITY < 5");
05996 dihedral_array[i].multiplicity = 5;
05997
05998
05999
06000 for(j=0;j<6;j++) {
06001 if(j%2 == 1) c[j] = -c[j];
06002 }
06003
06004
06005
06006 for(j=0;j<5;j++) dihedral_array[i].values[j].delta = 0;
06007 for(j=0;j<5;j++) dihedral_array[i].values[j].n = j+1;
06008
06009
06010
06011
06012 dihedral_array[i].values[0].k = 1*c[1] + 3/4.*c[3] + 10/16.*c[5];
06013 dihedral_array[i].values[1].k = 1/2.*c[2] + 4/8.*c[4] ;
06014 dihedral_array[i].values[2].k = 1/4.*c[3] + 5/16.*c[5];
06015 dihedral_array[i].values[3].k = 1/8.*c[4] ;
06016 dihedral_array[i].values[4].k = 1/16.*c[5];
06017
06018
06019
06020 test1 = 0;
06021 for(j=5;j>=0;j--) {
06022 test1 *= cos(0.5);
06023 test1 += c[j];
06024 }
06025
06026 test2 = c[0]+1/2.*c[2]+3/8.*c[4];
06027 for(j=0;j<5;j++) {
06028 test2 += dihedral_array[i].values[j].k * cos((j+1)*0.5);
06029 }
06030
06031 if(fabs(test1-test2) > 0.0001)
06032 NAMD_die("Internal error: failed to handle RB dihedrals");
06033
06034
06035
06036
06037
06038
06039
06040
06041
06042
06043
06044
06045
06046
06047 break;
06048 default:
06049 NAMD_die("unknown dihedral type found");
06050 }
06051 }
06052
06053
06054
06055 Bool warned=false;
06056
06057 NumVdwParamsAssigned = numtype = gf->getNumAtomParams();
06058 NumVdwPairParams = numtype * (numtype+1) / 2;
06059 for (i=0; i<numtype; i++) {
06060 for (j=i; j<numtype; j++) {
06061
06062
06063 new_node = new IndexedVdwPair;
06064 if (new_node == NULL)
06065 NAMD_die("memory allocation of vdw_pair_tree failed!");
06066 new_node->ind1 = i;
06067 new_node->ind2 = j;
06068 new_node->left = new_node->right = NULL;
06069
06070 gf->getVDWParams(i,j, &(new_node->B), &(new_node->A),
06071 &(new_node->B14), &(new_node->A14));
06072
06073
06074
06075
06076
06077 if(min && ( fabs(new_node->A) < 1.0 )) {
06078 new_node->A = 1.0;
06079 if(!warned) {
06080 iout << iWARN <<
06081 "Adding small LJ repulsion term to some atoms.\n" << endi;
06082 warned=true;
06083 }
06084 }
06085
06086 vdw_pair_tree = add_to_indexed_vdw_pairs(new_node, vdw_pair_tree);
06087 }
06088 }
06089 }
06090
06091
06092
06093
06094
06095
06096
06097
06098
06099
06100
06101
06102
06103 void Parameters::read_ener_table(SimParameters *simParams) {
06104 char* table_file = simParams->tabulatedEnergiesFile;
06105 char* interp_type = simParams->tableInterpType;
06106 FILE* enertable;
06107 enertable = fopen(table_file, "r");
06108
06109 if (enertable == NULL) {
06110 NAMD_die("ERROR: Could not open energy table file!\n");
06111 }
06112
06113 char tableline[121];
06114 char* newtypename;
06115 int numtypes;
06116 int atom1;
06117 int atom2;
06118 int distbin;
06119 int readcount;
06120 Real dist;
06121 Real energy;
06122 Real force;
06123 Real table_spacing;
06124 Real maxdist;
06125
06126
06127 iout << "Beginning table read\n" << endi;
06128 while(fgets(tableline,120,enertable)) {
06129 if (strncmp(tableline,"#",1)==0) {
06130 continue;
06131 }
06132 readcount = sscanf(tableline, "%i %f %f", &numtypes, &table_spacing, &maxdist);
06133 if (readcount != 3) {
06134 NAMD_die("ERROR: Couldn't parse table header line\n");
06135 }
06136 break;
06137 }
06138
06139 if (maxdist < simParams->cutoff) {
06140 NAMD_die("Tabulated energies must at least extend to the cutoff distance\n");
06141 }
06142
06143 if (maxdist > simParams->cutoff) {
06144 iout << "Info: Reducing max table size to match nonbond cutoff\n";
06145 maxdist = ceil(simParams->cutoff);
06146 }
06147
06148
06149 numenerentries = 2 * numtypes * int (mynearbyint(maxdist/table_spacing) + 1);
06150
06151
06152 fprintf(stdout, "Table has %i entries\n",numenerentries);
06153
06154 if ( table_ener ) delete [] table_ener;
06155 table_ener = new BigReal[numenerentries];
06156 if ( table_types ) delete [] table_types;
06157 table_types = new char*[numtypes];
06158
06159
06160 int numtypesread = 0;
06161
06162 while(fgets(tableline,120,enertable)) {
06163 if (strncmp(tableline,"#",1)==0) {
06164 continue;
06165 }
06166 if (strncmp(tableline,"TYPE",4)==0) {
06167
06168 newtypename = new char[5];
06169 int readcount = sscanf(tableline, "%*s %s", newtypename);
06170 if (readcount != 1) {
06171 NAMD_die("Couldn't read interaction type from TYPE line\n");
06172 }
06173
06174 table_types[numtypesread] = newtypename;
06175
06176 if (numtypesread == numtypes) {
06177 NAMD_die("Error: Number of types in table doesn't match table header\n");
06178 }
06179
06180
06181 if (!strncasecmp(interp_type, "linear", 6)) {
06182 if (read_energy_type(enertable, numtypesread, table_ener, table_spacing, maxdist) != 0) {
06183 char err_msg[512];
06184 sprintf(err_msg, "Failed to read table energy (linear) type %s\n", newtypename);
06185 NAMD_die(err_msg);
06186 }
06187 } else if (!strncasecmp(interp_type, "cubic", 5)) {
06188 if (read_energy_type_bothcubspline(enertable, numtypesread, table_ener, table_spacing, maxdist) != 0) {
06189 char err_msg[512];
06190 sprintf(err_msg, "Failed to read table energy (cubic) type %s\n", newtypename);
06191 NAMD_die(err_msg);
06192 }
06193 } else {
06194 NAMD_die("Table interpolation type must be linear or cubic\n");
06195 }
06196
06197 numtypesread++;
06198 continue;
06199 }
06200
06201
06202
06203 }
06204
06205
06206 if (numtypesread != numtypes) {
06207 char err_msg[512];
06208 sprintf(err_msg, "ERROR: Expected %i tabulated energy types but got %i\n", numtypes, numtypesread);
06209 NAMD_die(err_msg);
06210 }
06211
06212
06213 simParams->tableNumTypes = numtypes;
06214 simParams->tableSpacing = table_spacing;
06215 simParams->tableMaxDist = maxdist;
06216 tablenumtypes = numtypes;
06217
06218
06219
06220
06221
06222
06223
06224
06225
06226
06227
06228
06229
06230
06231
06232
06233
06234
06235
06236
06237
06238
06239
06240
06241
06242
06243
06244
06245
06246
06247
06248
06249
06250
06251
06252
06253
06254
06255
06256
06257
06258
06259
06260
06261
06262
06263
06264
06265
06266
06267
06268
06269
06270
06271
06272
06273
06274
06275
06276
06277
06278
06279
06280
06281
06282
06283
06284
06285
06286
06287
06288
06289
06290
06291
06292
06293
06294
06295
06296
06297
06298
06299
06300
06301
06302
06303
06304
06305
06306
06307
06308
06309
06310
06311
06312
06313
06314
06315
06316
06317
06318
06319
06320
06321
06322
06323 }
06324
06325
06326
06327
06328
06329
06330
06331
06332
06333
06334
06335
06336
06337
06338
06339
06340
06341
06342
06343
06344
06345
06346 int Parameters::read_energy_type_bothcubspline(FILE* enertable, const int typeindex, BigReal* table_ener, const float table_spacing, const float maxdist) {
06347
06348 char tableline[120];
06349 int i,j;
06350
06351
06352 BigReal readdist;
06353 BigReal readener;
06354 BigReal readforce;
06355 BigReal spacing;
06356
06357 BigReal lastdist;
06358
06359
06360
06361
06362
06363
06364
06365 std::vector<BigReal> dists;
06366 std::vector<BigReal> enervalues;
06367 std::vector<BigReal> forcevalues;
06368 int numentries = 0;
06369
06370
06371
06372 BigReal currdist;
06373 int distbin;
06374 currdist = 0.0;
06375 lastdist = -1.0;
06376 distbin = 0;
06377
06378
06379 while(fgets(tableline,120,enertable) && distbin <= (int) (mynearbyint(maxdist / table_spacing) + 1)) {
06380 if (strncmp(tableline,"#",1)==0) {
06381 continue;
06382 }
06383 if (strncmp(tableline,"TYPE",4)==0) {
06384 fseek(enertable, -1 * strlen(tableline), SEEK_CUR);
06385 break;
06386 }
06387
06388
06389 int readcount = sscanf(tableline, "%lf %lf %lf", &readdist, &readener, &readforce);
06390
06391
06392 if (readcount != 3) {
06393 char err_msg[512];
06394 sprintf(err_msg, "ERROR: Failed to parse table line %s!\n", tableline);
06395 NAMD_die(err_msg);
06396 }
06397
06398
06399 if (readdist < lastdist) {
06400 NAMD_die("ERROR: Encountered badly ordered entries in energy table!\n");
06401 }
06402
06403 lastdist = readdist;
06404 dists.push_back(readdist);
06405 enervalues.push_back(readener);
06406 forcevalues.push_back(readforce);
06407 numentries++;
06408 }
06409
06410
06411 if (dists[0] != 0.0) {
06412 NAMD_die("ERROR: First data point for energy table must be at r=0\n");
06413 }
06414 spacing = dists[1] - dists[0];
06415 for (i=2; i<(numentries - 1); i++) {
06416 BigReal myspacing;
06417 myspacing = dists[i] - dists[i-1];
06418 if (fabs(myspacing - spacing) > 0.00001) {
06419 printf("Bad spacing in table: %f should be %f (between distances %f and %f)\n", myspacing, spacing, dists[i-1], dists[i]);
06420 NAMD_die("ERROR: Nonuniform table encountered on cubic interpolation. Use a uniformly spaced table or switch to linear interpolation.\n");
06421 }
06422 }
06423
06424
06425
06426
06427
06428 double* m = new double[numentries*numentries];
06429 double* xe = new double[numentries];
06430 double* xf = new double[numentries];
06431 double* be = new double[numentries];
06432 double* bf = new double[numentries];
06433
06434 be[0] = 3 * (enervalues[1] - enervalues[0]);
06435 for (i=1; i < (numentries - 1); i++) {
06436
06437 be[i] = 3 * (enervalues[i+1] - enervalues[i-1]);
06438
06439 }
06440 be[numentries - 1] = 3 * (enervalues[numentries - 1] - enervalues[numentries - 2]);
06441
06442 bf[0] = 3 * (forcevalues[1] - forcevalues[0]);
06443 for (i=1; i < (numentries - 1); i++) {
06444
06445 bf[i] = 3 * (forcevalues[i+1] - forcevalues[i-1]);
06446
06447 }
06448 bf[numentries - 1] = 3 * (forcevalues[numentries - 1] - forcevalues[numentries - 2]);
06449
06450 memset(m,0,numentries*numentries*sizeof(double));
06451
06452
06453 m[0] = 2;
06454 for (i = 1; i < numentries; i++) {
06455 m[INDEX(numentries,i-1,i)] = 1;
06456 m[INDEX(numentries,i,i-1)] = 1;
06457 m[INDEX(numentries,i,i)] = 4;
06458 }
06459 m[INDEX(numentries,numentries-1,numentries-1)] = 2;
06460
06461
06462
06463
06464
06465 for (i=0; i<numentries; i++) {
06466
06467 const BigReal baseval = m[INDEX(numentries,i,i)];
06468 for (j=i+1; j<numentries; j++) {
06469 const BigReal myval = m[INDEX(numentries,j,i)];
06470 const BigReal factor = myval / baseval;
06471
06472 for (int k=i; k<numentries; k++) {
06473 const BigReal subval = m[INDEX(numentries,i,k)];
06474 m[INDEX(numentries,j,k)] -= (factor * subval);
06475 }
06476
06477 be[j] -= (factor * be[i]);
06478 bf[j] -= (factor * bf[i]);
06479
06480 }
06481 }
06482
06483
06484 for (i=numentries-1; i>=0; i--) {
06485
06486
06487 for (j=i+1; j<numentries; j++) {
06488 be[i] -= ( m[INDEX(numentries,i,j)] * xe[j] );
06489 bf[i] -= ( m[INDEX(numentries,i,j)] * xf[j] );
06490 }
06491
06492 xe[i] = be[i] / m[INDEX(numentries,i,i)];
06493 xf[i] = bf[i] / m[INDEX(numentries,i,i)];
06494
06495 }
06496
06497
06498
06499
06500 distbin = 0;
06501 int entriesperseg = (int) ceil(spacing / table_spacing);
06502 int table_prefix = 2 * typeindex * (int) (mynearbyint(maxdist / table_spacing) + 1);
06503
06504 for (i=0; i<numentries-1; i++) {
06505 BigReal Ae,Be,Ce,De;
06506 BigReal Af,Bf,Cf,Df;
06507 currdist = dists[i];
06508
06509
06510
06511
06512 Ae = enervalues[i];
06513 Be = xe[i];
06514 Ce = 3 * (enervalues[i+1] - enervalues[i]) - (2 * xe[i]) - xe[i+1];
06515 De = 2 * (enervalues[i] - enervalues[i+1]) + xe[i] + xe[i+1];
06516
06517 Af = forcevalues[i];
06518 Bf = xf[i];
06519 Cf = 3 * (forcevalues[i+1] - forcevalues[i]) - (2 * xf[i]) - xf[i+1];
06520 Df = 2 * (forcevalues[i] - forcevalues[i+1]) + xf[i] + xf[i+1];
06521
06522
06523 for (j=0; j<entriesperseg; j++) {
06524 const BigReal mydist = currdist + (j * table_spacing);
06525 const BigReal mydistfrac = (float) j / (entriesperseg - 1);
06526 distbin = (int) mynearbyint(mydist / table_spacing);
06527 if (distbin >= (int) mynearbyint(maxdist / table_spacing)) break;
06528 BigReal energy;
06529 BigReal force;
06530
06531 energy = Ae + (Be * mydistfrac) + (Ce * mydistfrac * mydistfrac) + (De * mydistfrac * mydistfrac * mydistfrac);
06532 force = Af + (Bf * mydistfrac) + (Cf * mydistfrac * mydistfrac) + (Df * mydistfrac * mydistfrac * mydistfrac);
06533
06534
06535 table_ener[table_prefix + 2 * distbin] = energy;
06536 table_ener[table_prefix + 2 * distbin + 1] = force;
06537 distbin++;
06538 }
06539 if (currdist >= maxdist) break;
06540 }
06541
06542
06543 distbin = (int) mynearbyint(maxdist / table_spacing);
06544
06545 table_ener[table_prefix + 2 * distbin] = enervalues[numentries - 1];
06546 table_ener[table_prefix + 2 * distbin + 1] = 0.0;
06547 distbin++;
06548
06549
06550
06551 delete m;
06552 delete xe;
06553 delete xf;
06554 delete be;
06555 delete bf;
06556 distbin--;
06557 printf("Testing: %i vs %i (from %f / %f)\n", distbin, (int) (mynearbyint(maxdist / table_spacing)), maxdist, table_spacing);
06558 if (distbin != (int) (mynearbyint(maxdist / table_spacing))) return 1;
06559 return 0;
06560 }
06561
06562
06563
06564
06565
06566
06567
06568
06569
06570
06571
06572
06573
06574
06575
06576
06577
06578
06579
06580
06581
06582 int Parameters::read_energy_type_cubspline(FILE* enertable, const int typeindex, BigReal* table_ener, const float table_spacing, const float maxdist) {
06583
06584 char tableline[120];
06585 int i,j;
06586
06587
06588 BigReal readdist;
06589 BigReal readener;
06590 BigReal spacing;
06591
06592 BigReal lastdist;
06593
06594
06595
06596
06597
06598
06599
06600 std::vector<BigReal> dists;
06601 std::vector<BigReal> enervalues;
06602 int numentries = 0;
06603
06604
06605
06606 BigReal currdist;
06607 int distbin;
06608 currdist = 0.0;
06609 lastdist = -1.0;
06610 distbin = 0;
06611
06612
06613 while(fgets(tableline,120,enertable) && distbin <= (int) (mynearbyint(maxdist / table_spacing) + 1)) {
06614 if (strncmp(tableline,"#",1)==0) {
06615 continue;
06616 }
06617 if (strncmp(tableline,"TYPE",4)==0) {
06618 fseek(enertable, -1 * strlen(tableline), SEEK_CUR);
06619 break;
06620 }
06621
06622
06623 int readcount = sscanf(tableline, "%lf %lf", &readdist, &readener);
06624
06625
06626 if (readcount != 2) {
06627 char err_msg[512];
06628 sprintf(err_msg, "ERROR: Failed to parse table line %s!\n", tableline);
06629 NAMD_die(err_msg);
06630 }
06631
06632
06633 if (readdist < lastdist) {
06634 NAMD_die("ERROR: Encountered badly ordered entries in energy table!\n");
06635 }
06636
06637 lastdist = readdist;
06638 dists.push_back(readdist);
06639 enervalues.push_back(readener);
06640 numentries++;
06641 }
06642
06643
06644 if (dists[0] != 0.0) {
06645 NAMD_die("ERROR: First data point for energy table must be at r=0\n");
06646 }
06647 spacing = dists[1] - dists[0];
06648 for (i=2; i<(numentries - 1); i++) {
06649 BigReal myspacing;
06650 myspacing = dists[i] - dists[i-1];
06651 if (fabs(myspacing - spacing) > 0.00001) {
06652 printf("Bad spacing in table: %f should be %f (between distances %f and %f)\n", myspacing, spacing, dists[i-1], dists[i]);
06653 NAMD_die("ERROR: Nonuniform table encountered on cubic interpolation. Use a uniformly spaced table or switch to linear interpolation.\n");
06654 }
06655 }
06656
06657
06658
06659
06660 double* m = new double[numentries*numentries];
06661 double* x = new double[numentries];
06662 double* b = new double[numentries];
06663
06664 b[0] = 3 * (enervalues[1] - enervalues[0]);
06665 for (i=1; i < (numentries - 1); i++) {
06666 printf("Control point %i at %f\n", i, enervalues[i]);
06667 b[i] = 3 * (enervalues[i+1] - enervalues[i-1]);
06668 printf("b is %f\n", b[i]);
06669 }
06670 b[numentries - 1] = 3 * (enervalues[numentries - 1] - enervalues[numentries - 2]);
06671
06672 memset(m,0,numentries*numentries*sizeof(double));
06673
06674
06675 m[0] = 2;
06676 for (i = 1; i < numentries; i++) {
06677 m[INDEX(numentries,i-1,i)] = 1;
06678 m[INDEX(numentries,i,i-1)] = 1;
06679 m[INDEX(numentries,i,i)] = 4;
06680 }
06681 m[INDEX(numentries,numentries-1,numentries-1)] = 2;
06682
06683
06684
06685 printf("Solving the matrix equation: \n");
06686
06687 for (i=0; i<numentries; i++) {
06688 printf(" ( ");
06689 for (j=0; j<numentries; j++) {
06690 printf(" %6.3f,", m[INDEX(numentries, i, j)]);
06691 }
06692 printf(" ) ( D%-3i ) = ( %6.3f )\n", i, b[i]);
06693 }
06694
06695
06696 for (i=0; i<numentries; i++) {
06697
06698 const BigReal baseval = m[INDEX(numentries,i,i)];
06699 for (j=i+1; j<numentries; j++) {
06700 const BigReal myval = m[INDEX(numentries,j,i)];
06701 const BigReal factor = myval / baseval;
06702
06703 for (int k=i; k<numentries; k++) {
06704 const BigReal subval = m[INDEX(numentries,i,k)];
06705 m[INDEX(numentries,j,k)] -= (factor * subval);
06706 }
06707
06708 b[j] -= (factor * b[i]);
06709
06710 }
06711 }
06712
06713 printf(" In upper diagonal form, equation is:\n");
06714 for (i=0; i<numentries; i++) {
06715 printf(" ( ");
06716 for (j=0; j<numentries; j++) {
06717 printf(" %6.3f,", m[INDEX(numentries, i, j)]);
06718 }
06719 printf(" ) ( D%-3i ) = ( %6.3f )\n", i, b[i]);
06720 }
06721
06722
06723 for (i=numentries-1; i>=0; i--) {
06724
06725
06726 for (j=i+1; j<numentries; j++) {
06727 b[i] -= ( m[INDEX(numentries,i,j)] * x[j] );
06728 }
06729
06730 x[i] = b[i] / m[INDEX(numentries,i,i)];
06731
06732 }
06733
06734 printf(" Solution vector is:\n\t(");
06735 for (i=0; i<numentries; i++) {
06736 printf(" %6.3f ", x[i]);
06737 }
06738 printf(" ) \n");
06739
06740
06741
06742
06743 distbin = 0;
06744 int entriesperseg = (int) ceil(spacing / table_spacing);
06745 int table_prefix = 2 * typeindex * (int) (mynearbyint(maxdist / table_spacing) + 1);
06746
06747 for (i=0; i<numentries-1; i++) {
06748 BigReal A,B,C,D;
06749 currdist = dists[i];
06750
06751 printf("Interpolating on interval %i\n", i);
06752
06753
06754 A = enervalues[i];
06755 B = x[i];
06756 C = 3 * (enervalues[i+1] - enervalues[i]) - (2 * x[i]) - x[i+1];
06757 D = 2 * (enervalues[i] - enervalues[i+1]) + x[i] + x[i+1];
06758
06759 printf("Coefficients for this interval: %f %f %f %f\n", A, B, C, D);
06760
06761
06762 for (j=0; j<entriesperseg; j++) {
06763 const BigReal mydist = currdist + (j * table_spacing);
06764 const BigReal mydistfrac = (float) j / (entriesperseg - 1);
06765 distbin = (int) mynearbyint(mydist / table_spacing);
06766 if (distbin >= (int) mynearbyint(maxdist / table_spacing)) break;
06767 BigReal energy;
06768 BigReal force;
06769
06770 energy = A + (B * mydistfrac) + (C * mydistfrac * mydistfrac) + (D * mydistfrac * mydistfrac * mydistfrac);
06771 force = B + (2 * C * mydistfrac) + (3 * D * mydistfrac * mydistfrac);
06772
06773 force *= (1.0 / spacing);
06774
06775 printf("Adding energy/force entry %f / %f in bins %i / %i for distance %f (%f)\n", energy, force, (table_prefix + 2 * distbin), (table_prefix + 2 * distbin + 1), mydist, mydistfrac);
06776 table_ener[table_prefix + 2 * distbin] = energy;
06777 table_ener[table_prefix + 2 * distbin + 1] = force;
06778 distbin++;
06779 }
06780 if (currdist >= maxdist) break;
06781 }
06782
06783
06784 distbin = (int) mynearbyint(maxdist / table_spacing);
06785 printf("Adding energy/force entry %f / %f in bins %i / %i\n", enervalues[numentries - 1], 0.0, (table_prefix + 2 * distbin), (table_prefix + 2 * distbin + 1));
06786 table_ener[table_prefix + 2 * distbin] = enervalues[numentries - 1];
06787 table_ener[table_prefix + 2 * distbin + 1] = 0.0;
06788 distbin++;
06789
06790
06791
06792 delete m;
06793 delete x;
06794 delete b;
06795 distbin--;
06796 printf("Testing: %i vs %i (from %f / %f)\n", distbin, (int) (mynearbyint(maxdist / table_spacing)), maxdist, table_spacing);
06797 if (distbin != (int) (mynearbyint(maxdist / table_spacing))) return 1;
06798 return 0;
06799 }
06800
06801
06802
06803
06804
06805
06806
06807
06808
06809
06810
06811
06812
06813
06814
06815
06816
06817
06818
06819
06820
06821 int Parameters::read_energy_type(FILE* enertable, const int typeindex, BigReal* table_ener, const float table_spacing, const float maxdist) {
06822
06823 char tableline[120];
06824
06825
06826 BigReal readdist;
06827 BigReal readener;
06828 BigReal readforce;
06829 BigReal lastdist;
06830 BigReal lastener;
06831 BigReal lastforce;
06832 readdist = -1.0;
06833 readener = 0.0;
06834 readforce = 0.0;
06835
06836
06837 float currdist;
06838 int distbin;
06839 currdist = -1.0;
06840 distbin = -1;
06841
06842 while(fgets(tableline,120,enertable) && distbin <= (int) (mynearbyint(maxdist / table_spacing) + 1)) {
06843 printf("At distance %f + %f vs. %f\n", currdist, table_spacing, maxdist);
06844 if (strncmp(tableline,"#",1)==0) {
06845 continue;
06846 }
06847 if (strncmp(tableline,"TYPE",4)==0) {
06848 break;
06849 }
06850
06851
06852 lastdist = readdist;
06853 lastener = readener;
06854 lastforce = readforce;
06855