PageRenderTime 57ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/src/read_data.cpp

http://github.com/browndeer/lammps-ocl
C++ | 1378 lines | 1049 code | 215 blank | 114 comment | 642 complexity | 8c651b6dd05149fd6eae81d8a4cb4364 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.0
  1. /* ----------------------------------------------------------------------
  2. LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
  3. http://lammps.sandia.gov, Sandia National Laboratories
  4. Steve Plimpton, sjplimp@sandia.gov
  5. Copyright (2003) Sandia Corporation. Under the terms of Contract
  6. DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
  7. certain rights in this software. This software is distributed under
  8. the GNU General Public License.
  9. See the README file in the top-level LAMMPS directory.
  10. ------------------------------------------------------------------------- */
  11. #include "lmptype.h"
  12. #include "math.h"
  13. #include "mpi.h"
  14. #include "string.h"
  15. #include "stdlib.h"
  16. #include "read_data.h"
  17. #include "atom.h"
  18. #include "atom_vec.h"
  19. #include "comm.h"
  20. #include "update.h"
  21. #include "force.h"
  22. #include "pair.h"
  23. #include "domain.h"
  24. #include "bond.h"
  25. #include "angle.h"
  26. #include "dihedral.h"
  27. #include "improper.h"
  28. #include "error.h"
  29. #include "memory.h"
  30. #include "special.h"
  31. using namespace LAMMPS_NS;
  32. #define MAXLINE 256
  33. #define LB_FACTOR 1.1
  34. #define CHUNK 1024
  35. #define DELTA 4 // must be 2 or larger
  36. #define NSECTIONS 22 // change when add to header::section_keywords
  37. #define MIN(a,b) ((a) < (b) ? (a) : (b))
  38. #define MAX(a,b) ((a) > (b) ? (a) : (b))
  39. /* ---------------------------------------------------------------------- */
  40. ReadData::ReadData(LAMMPS *lmp) : Pointers(lmp)
  41. {
  42. MPI_Comm_rank(world,&me);
  43. line = new char[MAXLINE];
  44. keyword = new char[MAXLINE];
  45. buffer = new char[CHUNK*MAXLINE];
  46. narg = maxarg = 0;
  47. arg = NULL;
  48. }
  49. /* ---------------------------------------------------------------------- */
  50. ReadData::~ReadData()
  51. {
  52. delete [] line;
  53. delete [] keyword;
  54. delete [] buffer;
  55. memory->sfree(arg);
  56. }
  57. /* ---------------------------------------------------------------------- */
  58. void ReadData::command(int narg, char **arg)
  59. {
  60. if (narg != 1) error->all("Illegal read_data command");
  61. if (domain->box_exist)
  62. error->all("Cannot read_data after simulation box is defined");
  63. if (domain->dimension == 2 && domain->zperiodic == 0)
  64. error->all("Cannot run 2d simulation with nonperiodic Z dimension");
  65. // scan data file to determine max topology needed per atom
  66. // allocate initial topology arrays
  67. if (atom->molecular) {
  68. if (me == 0) {
  69. if (screen) fprintf(screen,"Scanning data file ...\n");
  70. open(arg[0]);
  71. header(0);
  72. scan(atom->bond_per_atom,atom->angle_per_atom,
  73. atom->dihedral_per_atom,atom->improper_per_atom);
  74. if (compressed) pclose(fp);
  75. else fclose(fp);
  76. atom->bond_per_atom += atom->extra_bond_per_atom;
  77. }
  78. MPI_Bcast(&atom->bond_per_atom,1,MPI_INT,0,world);
  79. MPI_Bcast(&atom->angle_per_atom,1,MPI_INT,0,world);
  80. MPI_Bcast(&atom->dihedral_per_atom,1,MPI_INT,0,world);
  81. MPI_Bcast(&atom->improper_per_atom,1,MPI_INT,0,world);
  82. } else
  83. atom->bond_per_atom = atom->angle_per_atom =
  84. atom->dihedral_per_atom = atom->improper_per_atom = 0;
  85. // read header info
  86. if (me == 0) {
  87. if (screen) fprintf(screen,"Reading data file ...\n");
  88. open(arg[0]);
  89. }
  90. header(1);
  91. domain->box_exist = 1;
  92. // problem setup using info from header
  93. update->ntimestep = 0;
  94. int n;
  95. if (comm->nprocs == 1) n = static_cast<int> (atom->natoms);
  96. else n = static_cast<int> (LB_FACTOR * atom->natoms / comm->nprocs);
  97. atom->allocate_type_arrays();
  98. atom->avec->grow(n);
  99. n = atom->nmax;
  100. domain->print_box(" ");
  101. domain->set_initial_box();
  102. domain->set_global_box();
  103. comm->set_procs();
  104. domain->set_local_box();
  105. // read rest of file in free format
  106. // if add a section keyword, add to header::section_keywords and NSECTIONS
  107. int atomflag = 0;
  108. while (strlen(keyword)) {
  109. if (strcmp(keyword,"Atoms") == 0) {
  110. atoms();
  111. atomflag = 1;
  112. } else if (strcmp(keyword,"Velocities") == 0) {
  113. if (atomflag == 0) error->all("Must read Atoms before Velocities");
  114. velocities();
  115. } else if (strcmp(keyword,"Bonds") == 0) {
  116. if (atom->avec->bonds_allow == 0)
  117. error->all("Invalid data file section: Bonds");
  118. if (atomflag == 0) error->all("Must read Atoms before Bonds");
  119. bonds();
  120. } else if (strcmp(keyword,"Angles") == 0) {
  121. if (atom->avec->angles_allow == 0)
  122. error->all("Invalid data file section: Angles");
  123. if (atomflag == 0) error->all("Must read Atoms before Angles");
  124. angles();
  125. } else if (strcmp(keyword,"Dihedrals") == 0) {
  126. if (atom->avec->dihedrals_allow == 0)
  127. error->all("Invalid data file section: Dihedrals");
  128. if (atomflag == 0) error->all("Must read Atoms before Dihedrals");
  129. dihedrals();
  130. } else if (strcmp(keyword,"Impropers") == 0) {
  131. if (atom->avec->impropers_allow == 0)
  132. error->all("Invalid data file section: Impropers");
  133. if (atomflag == 0) error->all("Must read Atoms before Impropers");
  134. impropers();
  135. } else if (strcmp(keyword,"Masses") == 0) {
  136. mass();
  137. } else if (strcmp(keyword,"Shapes") == 0) {
  138. shape();
  139. } else if (strcmp(keyword,"Dipoles") == 0) {
  140. dipole();
  141. } else if (strcmp(keyword,"Pair Coeffs") == 0) {
  142. if (force->pair == NULL)
  143. error->all("Must define pair_style before Pair Coeffs");
  144. paircoeffs();
  145. } else if (strcmp(keyword,"Bond Coeffs") == 0) {
  146. if (atom->avec->bonds_allow == 0)
  147. error->all("Invalid data file section: Bond Coeffs");
  148. if (force->bond == NULL)
  149. error->all("Must define bond_style before Bond Coeffs");
  150. bondcoeffs();
  151. } else if (strcmp(keyword,"Angle Coeffs") == 0) {
  152. if (atom->avec->angles_allow == 0)
  153. error->all("Invalid data file section: Angle Coeffs");
  154. if (force->angle == NULL)
  155. error->all("Must define angle_style before Angle Coeffs");
  156. anglecoeffs(0);
  157. } else if (strcmp(keyword,"Dihedral Coeffs") == 0) {
  158. if (atom->avec->dihedrals_allow == 0)
  159. error->all("Invalid data file section: Dihedral Coeffs");
  160. if (force->dihedral == NULL)
  161. error->all("Must define dihedral_style before Dihedral Coeffs");
  162. dihedralcoeffs(0);
  163. } else if (strcmp(keyword,"Improper Coeffs") == 0) {
  164. if (atom->avec->impropers_allow == 0)
  165. error->all("Invalid data file section: Improper Coeffs");
  166. if (force->improper == NULL)
  167. error->all("Must define improper_style before Improper Coeffs");
  168. impropercoeffs(0);
  169. } else if (strcmp(keyword,"BondBond Coeffs") == 0) {
  170. if (atom->avec->angles_allow == 0)
  171. error->all("Invalid data file section: BondBond Coeffs");
  172. if (force->angle == NULL)
  173. error->all("Must define angle_style before BondBond Coeffs");
  174. anglecoeffs(1);
  175. } else if (strcmp(keyword,"BondAngle Coeffs") == 0) {
  176. if (atom->avec->angles_allow == 0)
  177. error->all("Invalid data file section: BondAngle Coeffs");
  178. if (force->angle == NULL)
  179. error->all("Must define angle_style before BondAngle Coeffs");
  180. anglecoeffs(2);
  181. } else if (strcmp(keyword,"MiddleBondTorsion Coeffs") == 0) {
  182. if (atom->avec->dihedrals_allow == 0)
  183. error->all("Invalid data file section: MiddleBondTorsion Coeffs");
  184. if (force->dihedral == NULL)
  185. error->all("Must define dihedral_style before MiddleBondTorsion Coeffs");
  186. dihedralcoeffs(1);
  187. } else if (strcmp(keyword,"EndBondTorsion Coeffs") == 0) {
  188. if (atom->avec->dihedrals_allow == 0)
  189. error->all("Invalid data file section: EndBondTorsion Coeffs");
  190. if (force->dihedral == NULL)
  191. error->all("Must define dihedral_style before EndBondTorsion Coeffs");
  192. dihedralcoeffs(2);
  193. } else if (strcmp(keyword,"AngleTorsion Coeffs") == 0) {
  194. if (atom->avec->dihedrals_allow == 0)
  195. error->all("Invalid data file section: AngleTorsion Coeffs");
  196. if (force->dihedral == NULL)
  197. error->all("Must define dihedral_style before AngleTorsion Coeffs");
  198. dihedralcoeffs(3);
  199. } else if (strcmp(keyword,"AngleAngleTorsion Coeffs") == 0) {
  200. if (atom->avec->dihedrals_allow == 0)
  201. error->all("Invalid data file section: AngleAngleTorsion Coeffs");
  202. if (force->dihedral == NULL)
  203. error->all("Must define dihedral_style before AngleAngleTorsion Coeffs");
  204. dihedralcoeffs(4);
  205. } else if (strcmp(keyword,"BondBond13 Coeffs") == 0) {
  206. if (atom->avec->dihedrals_allow == 0)
  207. error->all("Invalid data file section: BondBond13 Coeffs");
  208. if (force->dihedral == NULL)
  209. error->all("Must define dihedral_style before BondBond13 Coeffs");
  210. dihedralcoeffs(5);
  211. } else if (strcmp(keyword,"AngleAngle Coeffs") == 0) {
  212. if (atom->avec->impropers_allow == 0)
  213. error->all("Invalid data file section: AngleAngle Coeffs");
  214. if (force->improper == NULL)
  215. error->all("Must define improper_style before AngleAngle Coeffs");
  216. impropercoeffs(1);
  217. } else {
  218. char str[128];
  219. sprintf(str,"Unknown identifier in data file: %s",keyword);
  220. error->all(str);
  221. }
  222. parse_keyword(0,1);
  223. }
  224. // close file
  225. if (me == 0) {
  226. if (compressed) pclose(fp);
  227. else fclose(fp);
  228. }
  229. // error if natoms > 0 yet no atoms were read
  230. if (atom->natoms > 0 && atomflag == 0) error->all("No atoms in data file");
  231. // create bond topology now that system is defined
  232. if (atom->molecular) {
  233. Special special(lmp);
  234. special.build();
  235. }
  236. }
  237. /* ----------------------------------------------------------------------
  238. read free-format header of data file
  239. if flag = 0, only called by proc 0
  240. if flag = 1, called by all procs so bcast lines as read them
  241. 1st line and blank lines are skipped
  242. non-blank lines are checked for header keywords and leading value is read
  243. header ends with EOF or non-blank line containing no header keyword
  244. if EOF, line is set to blank line
  245. else line has first keyword line for rest of file
  246. ------------------------------------------------------------------------- */
  247. void ReadData::header(int flag)
  248. {
  249. int n;
  250. char *ptr;
  251. char *section_keywords[NSECTIONS] =
  252. {"Atoms","Velocities","Bonds","Angles","Dihedrals","Impropers",
  253. "Masses","Shapes","Dipoles",
  254. "Pair Coeffs","Bond Coeffs","Angle Coeffs",
  255. "Dihedral Coeffs","Improper Coeffs",
  256. "BondBond Coeffs","BondAngle Coeffs","MiddleBondTorsion Coeffs",
  257. "EndBondTorsion Coeffs","AngleTorsion Coeffs",
  258. "AngleAngleTorsion Coeffs","BondBond13 Coeffs","AngleAngle Coeffs"};
  259. // skip 1st line of file
  260. if (me == 0) {
  261. char *eof = fgets(line,MAXLINE,fp);
  262. if (eof == NULL) error->one("Unexpected end of data file");
  263. }
  264. while (1) {
  265. // read a line and bcast length if flag is set
  266. if (me == 0) {
  267. if (fgets(line,MAXLINE,fp) == NULL) n = 0;
  268. else n = strlen(line) + 1;
  269. }
  270. if (flag) MPI_Bcast(&n,1,MPI_INT,0,world);
  271. // if n = 0 then end-of-file so return with blank line
  272. if (n == 0) {
  273. line[0] = '\0';
  274. return;
  275. }
  276. // bcast line if flag is set
  277. if (flag) MPI_Bcast(line,n,MPI_CHAR,0,world);
  278. // trim anything from '#' onward
  279. // if line is blank, continue
  280. if (ptr = strchr(line,'#')) *ptr = '\0';
  281. if (strspn(line," \t\n\r") == strlen(line)) continue;
  282. // search line for header keyword and set corresponding variable
  283. if (strstr(line,"atoms")) sscanf(line,BIGINT_FORMAT,&atom->natoms);
  284. else if (strstr(line,"bonds")) sscanf(line,BIGINT_FORMAT,&atom->nbonds);
  285. else if (strstr(line,"angles")) sscanf(line,BIGINT_FORMAT,&atom->nangles);
  286. else if (strstr(line,"dihedrals")) sscanf(line,BIGINT_FORMAT,
  287. &atom->ndihedrals);
  288. else if (strstr(line,"impropers")) sscanf(line,BIGINT_FORMAT,
  289. &atom->nimpropers);
  290. else if (strstr(line,"atom types")) sscanf(line,"%d",&atom->ntypes);
  291. else if (strstr(line,"bond types")) sscanf(line,"%d",&atom->nbondtypes);
  292. else if (strstr(line,"angle types")) sscanf(line,"%d",&atom->nangletypes);
  293. else if (strstr(line,"dihedral types"))
  294. sscanf(line,"%d",&atom->ndihedraltypes);
  295. else if (strstr(line,"improper types"))
  296. sscanf(line,"%d",&atom->nimpropertypes);
  297. else if (strstr(line,"extra bond per atom"))
  298. sscanf(line,"%d",&atom->extra_bond_per_atom);
  299. else if (strstr(line,"xlo xhi"))
  300. sscanf(line,"%lg %lg",&domain->boxlo[0],&domain->boxhi[0]);
  301. else if (strstr(line,"ylo yhi"))
  302. sscanf(line,"%lg %lg",&domain->boxlo[1],&domain->boxhi[1]);
  303. else if (strstr(line,"zlo zhi"))
  304. sscanf(line,"%lg %lg",&domain->boxlo[2],&domain->boxhi[2]);
  305. else if (strstr(line,"xy xz yz")) {
  306. domain->triclinic = 1;
  307. sscanf(line,"%lg %lg %lg",&domain->xy,&domain->xz,&domain->yz);
  308. } else break;
  309. }
  310. // error check on total system size
  311. if (atom->natoms < 0 || atom->natoms > MAXBIGINT ||
  312. atom->nbonds < 0 || atom->nbonds > MAXBIGINT ||
  313. atom->nangles < 0 || atom->nangles > MAXBIGINT ||
  314. atom->ndihedrals < 0 || atom->ndihedrals > MAXBIGINT ||
  315. atom->nimpropers < 0 || atom->nimpropers > MAXBIGINT) {
  316. if (flag == 0) error->one("System in data file is too big");
  317. else error->all("System in data file is too big");
  318. }
  319. // check that exiting string is a valid section keyword
  320. parse_keyword(1,flag);
  321. for (n = 0; n < NSECTIONS; n++)
  322. if (strcmp(keyword,section_keywords[n]) == 0) break;
  323. if (n == NSECTIONS) {
  324. char str[128];
  325. sprintf(str,"Unknown identifier in data file: %s",keyword);
  326. error->all(str);
  327. }
  328. // error check on consistency of header values
  329. if ((atom->nbonds || atom->nbondtypes) &&
  330. atom->avec->bonds_allow == 0)
  331. error->one("No bonds allowed with this atom style");
  332. if ((atom->nangles || atom->nangletypes) &&
  333. atom->avec->angles_allow == 0)
  334. error->one("No angles allowed with this atom style");
  335. if ((atom->ndihedrals || atom->ndihedraltypes) &&
  336. atom->avec->dihedrals_allow == 0)
  337. error->one("No dihedrals allowed with this atom style");
  338. if ((atom->nimpropers || atom->nimpropertypes) &&
  339. atom->avec->impropers_allow == 0)
  340. error->one("No impropers allowed with this atom style");
  341. if (atom->nbonds > 0 && atom->nbondtypes <= 0)
  342. error->one("Bonds defined but no bond types");
  343. if (atom->nangles > 0 && atom->nangletypes <= 0)
  344. error->one("Angles defined but no angle types");
  345. if (atom->ndihedrals > 0 && atom->ndihedraltypes <= 0)
  346. error->one("Dihedrals defined but no dihedral types");
  347. if (atom->nimpropers > 0 && atom->nimpropertypes <= 0)
  348. error->one("Impropers defined but no improper types");
  349. }
  350. /* ----------------------------------------------------------------------
  351. read all atoms
  352. ------------------------------------------------------------------------- */
  353. void ReadData::atoms()
  354. {
  355. int i,m,nchunk;
  356. bigint nread = 0;
  357. bigint natoms = atom->natoms;
  358. while (nread < natoms) {
  359. if (natoms-nread > CHUNK) nchunk = CHUNK;
  360. else nchunk = natoms-nread;
  361. if (me == 0) {
  362. char *eof;
  363. m = 0;
  364. for (i = 0; i < nchunk; i++) {
  365. eof = fgets(&buffer[m],MAXLINE,fp);
  366. if (eof == NULL) error->one("Unexpected end of data file");
  367. m += strlen(&buffer[m]);
  368. }
  369. buffer[m++] = '\n';
  370. }
  371. MPI_Bcast(&m,1,MPI_INT,0,world);
  372. MPI_Bcast(buffer,m,MPI_CHAR,0,world);
  373. atom->data_atoms(nchunk,buffer);
  374. nread += nchunk;
  375. }
  376. // check that all atoms were assigned correctly
  377. bigint tmp = atom->nlocal;
  378. MPI_Allreduce(&tmp,&natoms,1,MPI_LMP_BIGINT,MPI_SUM,world);
  379. if (me == 0) {
  380. if (screen) fprintf(screen," " BIGINT_FORMAT " atoms\n",natoms);
  381. if (logfile) fprintf(logfile," " BIGINT_FORMAT " atoms\n",natoms);
  382. }
  383. if (natoms != atom->natoms) error->all("Did not assign all atoms correctly");
  384. // if any atom ID < 0, error
  385. // if all atom IDs = 0, tag_enable = 0
  386. // if any atom ID > 0, error if any atom ID == 0
  387. // not checking if atom IDs > natoms or are unique
  388. int nlocal = atom->nlocal;
  389. int *tag = atom->tag;
  390. int flag = 0;
  391. for (int i = 0; i < nlocal; i++)
  392. if (tag[i] < 0) flag = 1;
  393. int flag_all;
  394. MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world);
  395. if (flag_all)
  396. error->all("Invalid atom ID in Atoms section of data file");
  397. flag = 0;
  398. for (int i = 0; i < nlocal; i++)
  399. if (tag[i] > 0) flag = 1;
  400. MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_MAX,world);
  401. if (flag_all == 0) atom->tag_enable = 0;
  402. if (atom->tag_enable) {
  403. flag = 0;
  404. for (int i = 0; i < nlocal; i++)
  405. if (tag[i] == 0) flag = 1;
  406. MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world);
  407. if (flag_all)
  408. error->all("Invalid atom ID in Atoms section of data file");
  409. }
  410. // create global mapping
  411. if (atom->map_style) {
  412. atom->map_init();
  413. atom->map_set();
  414. }
  415. }
  416. /* ----------------------------------------------------------------------
  417. read all velocities
  418. to find atoms, must build atom map if not a molecular system
  419. ------------------------------------------------------------------------- */
  420. void ReadData::velocities()
  421. {
  422. int i,m,nchunk;
  423. int mapflag = 0;
  424. if (atom->map_style == 0) {
  425. mapflag = 1;
  426. atom->map_style = 1;
  427. atom->map_init();
  428. atom->map_set();
  429. }
  430. bigint nread = 0;
  431. bigint natoms = atom->natoms;
  432. while (nread < natoms) {
  433. if (natoms-nread > CHUNK) nchunk = CHUNK;
  434. else nchunk = natoms-nread;
  435. if (me == 0) {
  436. char *eof;
  437. m = 0;
  438. for (i = 0; i < nchunk; i++) {
  439. eof = fgets(&buffer[m],MAXLINE,fp);
  440. if (eof == NULL) error->one("Unexpected end of data file");
  441. m += strlen(&buffer[m]);
  442. }
  443. buffer[m++] = '\n';
  444. }
  445. MPI_Bcast(&m,1,MPI_INT,0,world);
  446. MPI_Bcast(buffer,m,MPI_CHAR,0,world);
  447. atom->data_vels(nchunk,buffer);
  448. nread += nchunk;
  449. }
  450. if (mapflag) {
  451. atom->map_delete();
  452. atom->map_style = 0;
  453. }
  454. if (me == 0) {
  455. if (screen) fprintf(screen," " BIGINT_FORMAT " velocities\n",natoms);
  456. if (logfile) fprintf(logfile," " BIGINT_FORMAT " velocities\n",natoms);
  457. }
  458. }
  459. /* ---------------------------------------------------------------------- */
  460. void ReadData::bonds()
  461. {
  462. int i,m,nchunk;
  463. bigint nread = 0;
  464. bigint nbonds = atom->nbonds;
  465. while (nread < nbonds) {
  466. nchunk = MIN(nbonds-nread,CHUNK);
  467. if (me == 0) {
  468. char *eof;
  469. m = 0;
  470. for (i = 0; i < nchunk; i++) {
  471. eof = fgets(&buffer[m],MAXLINE,fp);
  472. if (eof == NULL) error->one("Unexpected end of data file");
  473. m += strlen(&buffer[m]);
  474. }
  475. buffer[m++] = '\n';
  476. }
  477. MPI_Bcast(&m,1,MPI_INT,0,world);
  478. MPI_Bcast(buffer,m,MPI_CHAR,0,world);
  479. atom->data_bonds(nchunk,buffer);
  480. nread += nchunk;
  481. }
  482. // check that bonds were assigned correctly
  483. int nlocal = atom->nlocal;
  484. bigint sum;
  485. bigint n = 0;
  486. for (i = 0; i < nlocal; i++) n += atom->num_bond[i];
  487. MPI_Allreduce(&n,&sum,1,MPI_LMP_BIGINT,MPI_SUM,world);
  488. int factor = 1;
  489. if (!force->newton_bond) factor = 2;
  490. if (me == 0) {
  491. if (screen) fprintf(screen," " BIGINT_FORMAT " bonds\n",sum/factor);
  492. if (logfile) fprintf(logfile," " BIGINT_FORMAT " bonds\n",sum/factor);
  493. }
  494. if (sum != factor*atom->nbonds) error->all("Bonds assigned incorrectly");
  495. }
  496. /* ---------------------------------------------------------------------- */
  497. void ReadData::angles()
  498. {
  499. int i,m,nchunk;
  500. bigint nread = 0;
  501. bigint nangles = atom->nangles;
  502. while (nread < nangles) {
  503. nchunk = MIN(nangles-nread,CHUNK);
  504. if (me == 0) {
  505. char *eof;
  506. m = 0;
  507. for (i = 0; i < nchunk; i++) {
  508. eof = fgets(&buffer[m],MAXLINE,fp);
  509. if (eof == NULL) error->one("Unexpected end of data file");
  510. m += strlen(&buffer[m]);
  511. }
  512. buffer[m++] = '\n';
  513. }
  514. MPI_Bcast(&m,1,MPI_INT,0,world);
  515. MPI_Bcast(buffer,m,MPI_CHAR,0,world);
  516. atom->data_angles(nchunk,buffer);
  517. nread += nchunk;
  518. }
  519. // check that ang
  520. int nlocal = atom->nlocal;
  521. bigint sum;
  522. bigint n = 0;
  523. for (i = 0; i < nlocal; i++) n += atom->num_angle[i];
  524. MPI_Allreduce(&n,&sum,1,MPI_LMP_BIGINT,MPI_SUM,world);
  525. int factor = 1;
  526. if (!force->newton_bond) factor = 3;
  527. if (me == 0) {
  528. if (screen) fprintf(screen," " BIGINT_FORMAT " angles\n",sum/factor);
  529. if (logfile) fprintf(logfile," " BIGINT_FORMAT " angles\n",sum/factor);
  530. }
  531. if (sum != factor*atom->nangles) error->all("Angles assigned incorrectly");
  532. }
  533. /* ---------------------------------------------------------------------- */
  534. void ReadData::dihedrals()
  535. {
  536. int i,m,nchunk;
  537. bigint nread = 0;
  538. bigint ndihedrals = atom->ndihedrals;
  539. while (nread < ndihedrals) {
  540. nchunk = MIN(ndihedrals-nread,CHUNK);
  541. if (me == 0) {
  542. char *eof;
  543. m = 0;
  544. for (i = 0; i < nchunk; i++) {
  545. eof = fgets(&buffer[m],MAXLINE,fp);
  546. if (eof == NULL) error->one("Unexpected end of data file");
  547. m += strlen(&buffer[m]);
  548. }
  549. buffer[m++] = '\n';
  550. }
  551. MPI_Bcast(&m,1,MPI_INT,0,world);
  552. MPI_Bcast(buffer,m,MPI_CHAR,0,world);
  553. atom->data_dihedrals(nchunk,buffer);
  554. nread += nchunk;
  555. }
  556. // check that dihedrals were assigned correctly
  557. int nlocal = atom->nlocal;
  558. bigint sum;
  559. bigint n = 0;
  560. for (i = 0; i < nlocal; i++) n += atom->num_dihedral[i];
  561. MPI_Allreduce(&n,&sum,1,MPI_LMP_BIGINT,MPI_SUM,world);
  562. int factor = 1;
  563. if (!force->newton_bond) factor = 4;
  564. if (me == 0) {
  565. if (screen) fprintf(screen," " BIGINT_FORMAT " dihedrals\n",sum/factor);
  566. if (logfile) fprintf(logfile," " BIGINT_FORMAT " dihedrals\n",sum/factor);
  567. }
  568. if (sum != factor*atom->ndihedrals)
  569. error->all("Dihedrals assigned incorrectly");
  570. }
  571. /* ---------------------------------------------------------------------- */
  572. void ReadData::impropers()
  573. {
  574. int i,m,nchunk;
  575. bigint nread = 0;
  576. bigint nimpropers = atom->nimpropers;
  577. while (nread < nimpropers) {
  578. nchunk = MIN(nimpropers-nread,CHUNK);
  579. if (me == 0) {
  580. char *eof;
  581. m = 0;
  582. for (i = 0; i < nchunk; i++) {
  583. eof = fgets(&buffer[m],MAXLINE,fp);
  584. if (eof == NULL) error->one("Unexpected end of data file");
  585. m += strlen(&buffer[m]);
  586. }
  587. buffer[m++] = '\n';
  588. }
  589. MPI_Bcast(&m,1,MPI_INT,0,world);
  590. MPI_Bcast(buffer,m,MPI_CHAR,0,world);
  591. atom->data_impropers(nchunk,buffer);
  592. nread += nchunk;
  593. }
  594. // check that impropers were assigned correctly
  595. int nlocal = atom->nlocal;
  596. bigint sum;
  597. bigint n = 0;
  598. for (i = 0; i < nlocal; i++) n += atom->num_improper[i];
  599. MPI_Allreduce(&n,&sum,1,MPI_LMP_BIGINT,MPI_SUM,world);
  600. int factor = 1;
  601. if (!force->newton_bond) factor = 4;
  602. if (me == 0) {
  603. if (screen) fprintf(screen," " BIGINT_FORMAT " impropers\n",sum/factor);
  604. if (logfile) fprintf(logfile," " BIGINT_FORMAT " impropers\n",sum/factor);
  605. }
  606. if (sum != factor*atom->nimpropers)
  607. error->all("Impropers assigned incorrectly");
  608. }
  609. /* ---------------------------------------------------------------------- */
  610. void ReadData::mass()
  611. {
  612. int i,m;
  613. char *buf = new char[atom->ntypes*MAXLINE];
  614. char *original = buf;
  615. if (me == 0) {
  616. char *eof;
  617. m = 0;
  618. for (i = 0; i < atom->ntypes; i++) {
  619. eof = fgets(&buf[m],MAXLINE,fp);
  620. if (eof == NULL) error->one("Unexpected end of data file");
  621. m += strlen(&buf[m]);
  622. buf[m-1] = '\0';
  623. }
  624. }
  625. MPI_Bcast(&m,1,MPI_INT,0,world);
  626. MPI_Bcast(buf,m,MPI_CHAR,0,world);
  627. for (i = 0; i < atom->ntypes; i++) {
  628. atom->set_mass(buf);
  629. buf += strlen(buf) + 1;
  630. }
  631. delete [] original;
  632. }
  633. /* ---------------------------------------------------------------------- */
  634. void ReadData::shape()
  635. {
  636. int i,m;
  637. char *buf = new char[atom->ntypes*MAXLINE];
  638. char *original = buf;
  639. if (me == 0) {
  640. char *eof;
  641. m = 0;
  642. for (i = 0; i < atom->ntypes; i++) {
  643. eof = fgets(&buf[m],MAXLINE,fp);
  644. if (eof == NULL) error->one("Unexpected end of data file");
  645. m += strlen(&buf[m]);
  646. buf[m-1] = '\0';
  647. }
  648. }
  649. MPI_Bcast(&m,1,MPI_INT,0,world);
  650. MPI_Bcast(buf,m,MPI_CHAR,0,world);
  651. for (i = 0; i < atom->ntypes; i++) {
  652. atom->set_shape(buf);
  653. buf += strlen(buf) + 1;
  654. }
  655. delete [] original;
  656. }
  657. /* ---------------------------------------------------------------------- */
  658. void ReadData::dipole()
  659. {
  660. int i,m;
  661. char *buf = new char[atom->ntypes*MAXLINE];
  662. char *original = buf;
  663. if (me == 0) {
  664. char *eof;
  665. m = 0;
  666. for (i = 0; i < atom->ntypes; i++) {
  667. eof = fgets(&buf[m],MAXLINE,fp);
  668. if (eof == NULL) error->one("Unexpected end of data file");
  669. m += strlen(&buf[m]);
  670. buf[m-1] = '\0';
  671. }
  672. }
  673. MPI_Bcast(&m,1,MPI_INT,0,world);
  674. MPI_Bcast(buf,m,MPI_CHAR,0,world);
  675. for (i = 0; i < atom->ntypes; i++) {
  676. atom->set_dipole(buf);
  677. buf += strlen(buf) + 1;
  678. }
  679. delete [] original;
  680. }
  681. /* ---------------------------------------------------------------------- */
  682. void ReadData::paircoeffs()
  683. {
  684. int i,m;
  685. char *buf = new char[atom->ntypes*MAXLINE];
  686. char *original = buf;
  687. if (me == 0) {
  688. char *eof;
  689. m = 0;
  690. for (i = 0; i < atom->ntypes; i++) {
  691. eof = fgets(&buf[m],MAXLINE,fp);
  692. if (eof == NULL) error->one("Unexpected end of data file");
  693. m += strlen(&buf[m]);
  694. buf[m-1] = '\0';
  695. }
  696. }
  697. MPI_Bcast(&m,1,MPI_INT,0,world);
  698. MPI_Bcast(buf,m,MPI_CHAR,0,world);
  699. for (i = 0; i < atom->ntypes; i++) {
  700. m = strlen(buf) + 1;
  701. parse_coeffs(buf,NULL,1);
  702. force->pair->coeff(narg,arg);
  703. buf += m;
  704. }
  705. delete [] original;
  706. }
  707. /* ---------------------------------------------------------------------- */
  708. void ReadData::bondcoeffs()
  709. {
  710. int i,m;
  711. char *buf = new char[atom->nbondtypes*MAXLINE];
  712. char *original = buf;
  713. if (me == 0) {
  714. char *eof;
  715. m = 0;
  716. for (i = 0; i < atom->nbondtypes; i++) {
  717. eof = fgets(&buf[m],MAXLINE,fp);
  718. if (eof == NULL) error->one("Unexpected end of data file");
  719. m += strlen(&buf[m]);
  720. buf[m-1] = '\0';
  721. }
  722. }
  723. MPI_Bcast(&m,1,MPI_INT,0,world);
  724. MPI_Bcast(buf,m,MPI_CHAR,0,world);
  725. for (i = 0; i < atom->nbondtypes; i++) {
  726. m = strlen(buf) + 1;
  727. parse_coeffs(buf,NULL,0);
  728. force->bond->coeff(narg,arg);
  729. buf += m;
  730. }
  731. delete [] original;
  732. }
  733. /* ---------------------------------------------------------------------- */
  734. void ReadData::anglecoeffs(int which)
  735. {
  736. int i,m;
  737. char *buf = new char[atom->nangletypes*MAXLINE];
  738. char *original = buf;
  739. if (me == 0) {
  740. char *eof;
  741. m = 0;
  742. for (i = 0; i < atom->nangletypes; i++) {
  743. eof = fgets(&buf[m],MAXLINE,fp);
  744. if (eof == NULL) error->one("Unexpected end of data file");
  745. m += strlen(&buf[m]);
  746. buf[m-1] = '\0';
  747. }
  748. }
  749. MPI_Bcast(&m,1,MPI_INT,0,world);
  750. MPI_Bcast(buf,m,MPI_CHAR,0,world);
  751. for (i = 0; i < atom->nangletypes; i++) {
  752. m = strlen(buf) + 1;
  753. if (which == 0) parse_coeffs(buf,NULL,0);
  754. else if (which == 1) parse_coeffs(buf,"bb",0);
  755. else if (which == 2) parse_coeffs(buf,"ba",0);
  756. force->angle->coeff(narg,arg);
  757. buf += m;
  758. }
  759. delete [] original;
  760. }
  761. /* ---------------------------------------------------------------------- */
  762. void ReadData::dihedralcoeffs(int which)
  763. {
  764. int i,m;
  765. char *buf = new char[atom->ndihedraltypes*MAXLINE];
  766. char *original = buf;
  767. if (me == 0) {
  768. char *eof;
  769. m = 0;
  770. for (i = 0; i < atom->ndihedraltypes; i++) {
  771. eof = fgets(&buf[m],MAXLINE,fp);
  772. if (eof == NULL) error->one("Unexpected end of data file");
  773. m += strlen(&buf[m]);
  774. buf[m-1] = '\0';
  775. }
  776. }
  777. MPI_Bcast(&m,1,MPI_INT,0,world);
  778. MPI_Bcast(buf,m,MPI_CHAR,0,world);
  779. for (i = 0; i < atom->ndihedraltypes; i++) {
  780. m = strlen(buf) + 1;
  781. if (which == 0) parse_coeffs(buf,NULL,0);
  782. else if (which == 1) parse_coeffs(buf,"mbt",0);
  783. else if (which == 2) parse_coeffs(buf,"ebt",0);
  784. else if (which == 3) parse_coeffs(buf,"at",0);
  785. else if (which == 4) parse_coeffs(buf,"aat",0);
  786. else if (which == 5) parse_coeffs(buf,"bb13",0);
  787. force->dihedral->coeff(narg,arg);
  788. buf += m;
  789. }
  790. delete [] original;
  791. }
  792. /* ---------------------------------------------------------------------- */
  793. void ReadData::impropercoeffs(int which)
  794. {
  795. int i,m;
  796. char *buf = new char[atom->nimpropertypes*MAXLINE];
  797. char *original = buf;
  798. if (me == 0) {
  799. char *eof;
  800. m = 0;
  801. for (i = 0; i < atom->nimpropertypes; i++) {
  802. eof = fgets(&buf[m],MAXLINE,fp);
  803. if (eof == NULL) error->one("Unexpected end of data file");
  804. m += strlen(&buf[m]);
  805. buf[m-1] = '\0';
  806. }
  807. }
  808. MPI_Bcast(&m,1,MPI_INT,0,world);
  809. MPI_Bcast(buf,m,MPI_CHAR,0,world);
  810. for (i = 0; i < atom->nimpropertypes; i++) {
  811. m = strlen(buf) + 1;
  812. if (which == 0) parse_coeffs(buf,NULL,0);
  813. else if (which == 1) parse_coeffs(buf,"aa",0);
  814. force->improper->coeff(narg,arg);
  815. buf += m;
  816. }
  817. delete [] original;
  818. }
  819. /* ----------------------------------------------------------------------
  820. proc 0 scans the data file for topology maximums
  821. ------------------------------------------------------------------------- */
  822. void ReadData::scan(int &bond_per_atom, int &angle_per_atom,
  823. int &dihedral_per_atom, int &improper_per_atom)
  824. {
  825. int i,tmp1,tmp2,atom1,atom2,atom3,atom4;
  826. char *eof;
  827. if (atom->natoms > MAXSMALLINT)
  828. error->all("Molecular data file has too many atoms");
  829. int natoms = static_cast<int> (atom->natoms);
  830. bond_per_atom = angle_per_atom = dihedral_per_atom = improper_per_atom = 0;
  831. // allocate topology counting vector
  832. // initially, array length = 1 to natoms
  833. // will grow via reallocate() if atom IDs > natoms
  834. int cmax = natoms + 1;
  835. int *count;
  836. memory->create(count,cmax,"read_data:count");
  837. while (strlen(keyword)) {
  838. if (strcmp(keyword,"Masses") == 0) skip_lines(atom->ntypes);
  839. else if (strcmp(keyword,"Dipoles") == 0) skip_lines(atom->ntypes);
  840. else if (strcmp(keyword,"Atoms") == 0) skip_lines(natoms);
  841. else if (strcmp(keyword,"Velocities") == 0) skip_lines(natoms);
  842. else if (strcmp(keyword,"Pair Coeffs") == 0) {
  843. if (force->pair == NULL)
  844. error->all("Must define pair_style before Pair Coeffs");
  845. skip_lines(atom->ntypes);
  846. } else if (strcmp(keyword,"Bond Coeffs") == 0) {
  847. if (atom->avec->bonds_allow == 0)
  848. error->all("Invalid data file section: Bond Coeffs");
  849. if (force->bond == NULL)
  850. error->all("Must define bond_style before Bond Coeffs");
  851. skip_lines(atom->nbondtypes);
  852. } else if (strcmp(keyword,"Angle Coeffs") == 0) {
  853. if (atom->avec->angles_allow == 0)
  854. error->all("Invalid data file section: Angle Coeffs");
  855. if (force->angle == NULL)
  856. error->all("Must define angle_style before Angle Coeffs");
  857. skip_lines(atom->nangletypes);
  858. } else if (strcmp(keyword,"Dihedral Coeffs") == 0) {
  859. skip_lines(atom->ndihedraltypes);
  860. if (atom->avec->dihedrals_allow == 0)
  861. error->all("Invalid data file section: Dihedral Coeffs");
  862. if (force->dihedral == NULL)
  863. error->all("Must define dihedral_style before Dihedral Coeffs");
  864. } else if (strcmp(keyword,"Improper Coeffs") == 0) {
  865. if (atom->avec->impropers_allow == 0)
  866. error->all("Invalid data file section: Improper Coeffs");
  867. if (force->improper == NULL)
  868. error->all("Must define improper_style before Improper Coeffs");
  869. skip_lines(atom->nimpropertypes);
  870. } else if (strcmp(keyword,"BondBond Coeffs") == 0) {
  871. if (atom->avec->angles_allow == 0)
  872. error->all("Invalid data file section: BondBond Coeffs");
  873. if (force->angle == NULL)
  874. error->all("Must define angle_style before BondBond Coeffs");
  875. skip_lines(atom->nangletypes);
  876. } else if (strcmp(keyword,"BondAngle Coeffs") == 0) {
  877. if (atom->avec->angles_allow == 0)
  878. error->all("Invalid data file section: BondAngle Coeffs");
  879. if (force->angle == NULL)
  880. error->all("Must define angle_style before BondAngle Coeffs");
  881. skip_lines(atom->nangletypes);
  882. } else if (strcmp(keyword,"MiddleBondTorsion Coeffs") == 0) {
  883. if (atom->avec->dihedrals_allow == 0)
  884. error->all("Invalid data file section: MiddleBondTorsion Coeffs");
  885. if (force->dihedral == NULL)
  886. error->all("Must define dihedral_style before MiddleBondTorsion Coeffs");
  887. skip_lines(atom->ndihedraltypes);
  888. } else if (strcmp(keyword,"EndBondTorsion Coeffs") == 0) {
  889. if (atom->avec->dihedrals_allow == 0)
  890. error->all("Invalid data file section: EndBondTorsion Coeffs");
  891. if (force->dihedral == NULL)
  892. error->all("Must define dihedral_style before EndBondTorsion Coeffs");
  893. skip_lines(atom->ndihedraltypes);
  894. } else if (strcmp(keyword,"AngleTorsion Coeffs") == 0) {
  895. if (atom->avec->dihedrals_allow == 0)
  896. error->all("Invalid data file section: AngleTorsion Coeffs");
  897. if (force->dihedral == NULL)
  898. error->all("Must define dihedral_style before AngleTorsion Coeffs");
  899. skip_lines(atom->ndihedraltypes);
  900. } else if (strcmp(keyword,"AngleAngleTorsion Coeffs") == 0) {
  901. if (atom->avec->dihedrals_allow == 0)
  902. error->all("Invalid data file section: AngleAngleTorsion Coeffs");
  903. if (force->dihedral == NULL)
  904. error->all("Must define dihedral_style before AngleAngleTorsion Coeffs");
  905. skip_lines(atom->ndihedraltypes);
  906. } else if (strcmp(keyword,"BondBond13 Coeffs") == 0) {
  907. if (atom->avec->dihedrals_allow == 0)
  908. error->all("Invalid data file section: BondBond13 Coeffs");
  909. if (force->dihedral == NULL)
  910. error->all("Must define dihedral_style before BondBond13 Coeffs");
  911. skip_lines(atom->ndihedraltypes);
  912. } else if (strcmp(keyword,"AngleAngle Coeffs") == 0) {
  913. if (atom->avec->impropers_allow == 0)
  914. error->all("Invalid data file section: AngleAngle Coeffs");
  915. if (force->improper == NULL)
  916. error->all("Must define improper_style before AngleAngle Coeffs");
  917. skip_lines(atom->nimpropertypes);
  918. } else if (strcmp(keyword,"Bonds") == 0) {
  919. for (i = 1; i < cmax; i++) count[i] = 0;
  920. if (force->newton_bond)
  921. for (i = 0; i < atom->nbonds; i++) {
  922. eof = fgets(line,MAXLINE,fp);
  923. if (eof == NULL) error->one("Unexpected end of data file");
  924. sscanf(line,"%d %d %d %d",&tmp1,&tmp2,&atom1,&atom2);
  925. if (atom1 >= cmax) cmax = reallocate(&count,cmax,atom1);
  926. count[atom1]++;
  927. }
  928. else
  929. for (i = 0; i < atom->nbonds; i++) {
  930. eof = fgets(line,MAXLINE,fp);
  931. if (eof == NULL) error->one("Unexpected end of data file");
  932. sscanf(line,"%d %d %d %d",&tmp1,&tmp2,&atom1,&atom2);
  933. int amax = MAX(atom1,atom2);
  934. if (amax >= cmax) cmax = reallocate(&count,cmax,amax);
  935. count[atom1]++;
  936. count[atom2]++;
  937. }
  938. for (i = 1; i < cmax; i++) bond_per_atom = MAX(bond_per_atom,count[i]);
  939. if (screen) fprintf(screen," %d = max bonds/atom\n",bond_per_atom);
  940. if (logfile) fprintf(logfile," %d = max bonds/atom\n",bond_per_atom);
  941. } else if (strcmp(keyword,"Angles") == 0) {
  942. for (i = 1; i < cmax; i++) count[i] = 0;
  943. if (force->newton_bond)
  944. for (i = 0; i < atom->nangles; i++) {
  945. eof = fgets(line,MAXLINE,fp);
  946. if (eof == NULL) error->one("Unexpected end of data file");
  947. sscanf(line,"%d %d %d %d %d",&tmp1,&tmp2,&atom1,&atom2,&atom3);
  948. if (atom2 >= cmax) cmax = reallocate(&count,cmax,atom2);
  949. count[atom2]++;
  950. }
  951. else
  952. for (i = 0; i < atom->nangles; i++) {
  953. eof = fgets(line,MAXLINE,fp);
  954. if (eof == NULL) error->one("Unexpected end of data file");
  955. sscanf(line,"%d %d %d %d %d",&tmp1,&tmp2,&atom1,&atom2,&atom3);
  956. int amax = MAX(atom1,atom2);
  957. amax = MAX(amax,atom3);
  958. if (amax >= cmax) cmax = reallocate(&count,cmax,amax);
  959. count[atom1]++;
  960. count[atom2]++;
  961. count[atom3]++;
  962. }
  963. for (i = 1; i < cmax; i++) angle_per_atom = MAX(angle_per_atom,count[i]);
  964. if (screen) fprintf(screen," %d = max angles/atom\n",angle_per_atom);
  965. if (logfile) fprintf(logfile," %d = max angles/atom\n",angle_per_atom);
  966. } else if (strcmp(keyword,"Dihedrals") == 0) {
  967. for (i = 1; i < cmax; i++) count[i] = 0;
  968. if (force->newton_bond)
  969. for (i = 0; i < atom->ndihedrals; i++) {
  970. eof = fgets(line,MAXLINE,fp);
  971. if (eof == NULL) error->one("Unexpected end of data file");
  972. sscanf(line,"%d %d %d %d %d %d",
  973. &tmp1,&tmp2,&atom1,&atom2,&atom3,&atom4);
  974. if (atom2 >= cmax) cmax = reallocate(&count,cmax,atom2);
  975. count[atom2]++;
  976. }
  977. else
  978. for (i = 0; i < atom->ndihedrals; i++) {
  979. eof = fgets(line,MAXLINE,fp);
  980. if (eof == NULL) error->one("Unexpected end of data file");
  981. sscanf(line,"%d %d %d %d %d %d",
  982. &tmp1,&tmp2,&atom1,&atom2,&atom3,&atom4);
  983. int amax = MAX(atom1,atom2);
  984. amax = MAX(amax,atom3);
  985. amax = MAX(amax,atom4);
  986. if (amax >= cmax) cmax = reallocate(&count,cmax,amax);
  987. count[atom1]++;
  988. count[atom2]++;
  989. count[atom3]++;
  990. count[atom4]++;
  991. }
  992. for (i = 1; i < cmax; i++)
  993. dihedral_per_atom = MAX(dihedral_per_atom,count[i]);
  994. if (screen)
  995. fprintf(screen," %d = max dihedrals/atom\n",dihedral_per_atom);
  996. if (logfile)
  997. fprintf(logfile," %d = max dihedrals/atom\n",dihedral_per_atom);
  998. } else if (strcmp(keyword,"Impropers") == 0) {
  999. for (i = 1; i < cmax; i++) count[i] = 0;
  1000. if (force->newton_bond)
  1001. for (i = 0; i < atom->nimpropers; i++) {
  1002. eof = fgets(line,MAXLINE,fp);
  1003. if (eof == NULL) error->one("Unexpected end of data file");
  1004. sscanf(line,"%d %d %d %d %d %d",
  1005. &tmp1,&tmp2,&atom1,&atom2,&atom3,&atom4);
  1006. if (atom2 >= cmax) cmax = reallocate(&count,cmax,atom2);
  1007. count[atom2]++;
  1008. }
  1009. else
  1010. for (i = 0; i < atom->nimpropers; i++) {
  1011. eof = fgets(line,MAXLINE,fp);
  1012. if (eof == NULL) error->one("Unexpected end of data file");
  1013. sscanf(line,"%d %d %d %d %d %d",
  1014. &tmp1,&tmp2,&atom1,&atom2,&atom3,&atom4);
  1015. int amax = MAX(atom1,atom2);
  1016. amax = MAX(amax,atom3);
  1017. amax = MAX(amax,atom4);
  1018. if (amax >= cmax) cmax = reallocate(&count,cmax,amax);
  1019. count[atom1]++;
  1020. count[atom2]++;
  1021. count[atom3]++;
  1022. count[atom4]++;
  1023. }
  1024. for (i = 1; i < cmax; i++)
  1025. improper_per_atom = MAX(improper_per_atom,count[i]);
  1026. if (screen)
  1027. fprintf(screen," %d = max impropers/atom\n",improper_per_atom);
  1028. if (logfile)
  1029. fprintf(logfile," %d = max impropers/atom\n",improper_per_atom);
  1030. } else {
  1031. char str[128];
  1032. sprintf(str,"Unknown identifier in data file: %s",keyword);
  1033. error->one(str);
  1034. }
  1035. parse_keyword(0,0);
  1036. }
  1037. // free topology counting vector
  1038. memory->destroy(count);
  1039. // error check that topology was specified in file
  1040. if ((atom->nbonds && !bond_per_atom) ||
  1041. (atom->nangles && !angle_per_atom) ||
  1042. (atom->ndihedrals && !dihedral_per_atom) ||
  1043. (atom->nimpropers && !improper_per_atom))
  1044. error->one("Needed topology not in data file");
  1045. }
  1046. /* ----------------------------------------------------------------------
  1047. reallocate the count vector from cmax to amax+1 and return new length
  1048. zero new locations
  1049. ------------------------------------------------------------------------- */
  1050. int ReadData::reallocate(int **pcount, int cmax, int amax)
  1051. {
  1052. int *count = *pcount;
  1053. memory->grow(count,amax+1,"read_data:count");
  1054. for (int i = cmax; i <= amax; i++) count[i] = 0;
  1055. *pcount = count;
  1056. return amax+1;
  1057. }
  1058. /* ----------------------------------------------------------------------
  1059. proc 0 opens data file
  1060. test if gzipped
  1061. ------------------------------------------------------------------------- */
  1062. void ReadData::open(char *file)
  1063. {
  1064. compressed = 0;
  1065. char *suffix = file + strlen(file) - 3;
  1066. if (suffix > file && strcmp(suffix,".gz") == 0) compressed = 1;
  1067. if (!compressed) fp = fopen(file,"r");
  1068. else {
  1069. #ifdef LAMMPS_GZIP
  1070. char gunzip[128];
  1071. sprintf(gunzip,"gunzip -c %s",file);
  1072. fp = popen(gunzip,"r");
  1073. #else
  1074. error->one("Cannot open gzipped file");
  1075. #endif
  1076. }
  1077. if (fp == NULL) {
  1078. char str[128];
  1079. sprintf(str,"Cannot open file %s",file);
  1080. error->one(str);
  1081. }
  1082. }
  1083. /* ----------------------------------------------------------------------
  1084. grab next keyword
  1085. read lines until one is non-blank
  1086. keyword is all text on line w/out leading & trailing white space
  1087. read one additional line (assumed blank)
  1088. if any read hits EOF, set keyword to empty
  1089. if first = 1, line variable holds non-blank line that ended header
  1090. if flag = 0, only proc 0 is calling so no bcast
  1091. else flag = 1, bcast keyword line to all procs
  1092. ------------------------------------------------------------------------- */
  1093. void ReadData::parse_keyword(int first, int flag)
  1094. {
  1095. int eof = 0;
  1096. // proc 0 reads upto non-blank line plus 1 following line
  1097. // eof is set to 1 if any read hits end-of-file
  1098. if (me == 0) {
  1099. if (!first) {
  1100. if (fgets(line,MAXLINE,fp) == NULL) eof = 1;
  1101. }
  1102. while (eof == 0 && strspn(line," \t\n\r") == strlen(line)) {
  1103. if (fgets(line,MAXLINE,fp) == NULL) eof = 1;
  1104. }
  1105. if (fgets(buffer,MAXLINE,fp) == NULL) eof = 1;
  1106. }
  1107. // if eof, set keyword empty and return
  1108. if (flag) MPI_Bcast(&eof,1,MPI_INT,0,world);
  1109. if (eof) {
  1110. keyword[0] = '\0';
  1111. return;
  1112. }
  1113. // bcast keyword line to all procs
  1114. if (flag) {
  1115. int n;
  1116. if (me == 0) n = strlen(line) + 1;
  1117. MPI_Bcast(&n,1,MPI_INT,0,world);
  1118. MPI_Bcast(line,n,MPI_CHAR,0,world);
  1119. }
  1120. // copy non-whitespace portion of line into keyword
  1121. int start = strspn(line," \t\n\r");
  1122. int stop = strlen(line) - 1;
  1123. while (line[stop] == ' ' || line[stop] == '\t'
  1124. || line[stop] == '\n' || line[stop] == '\r') stop--;
  1125. line[stop+1] = '\0';
  1126. strcpy(keyword,&line[start]);
  1127. }
  1128. /* ----------------------------------------------------------------------
  1129. proc 0 reads N lines from file
  1130. ------------------------------------------------------------------------- */
  1131. void ReadData::skip_lines(int n)
  1132. {
  1133. char *eof;
  1134. for (int i = 0; i < n; i++) eof = fgets(line,MAXLINE,fp);
  1135. if (eof == NULL) error->one("Unexpected end of data file");
  1136. }
  1137. /* ----------------------------------------------------------------------
  1138. parse a line of coeffs into words, storing them in narg,arg
  1139. trim anything from '#' onward
  1140. word strings remain in line, are not copied
  1141. if addstr != NULL, add addstr as 2nd arg for class2 angle/dihedral/improper
  1142. if dupflag, duplicate 1st word, so pair_coeff "2" becomes "2 2"
  1143. ------------------------------------------------------------------------- */
  1144. void ReadData::parse_coeffs(char *line, char *addstr, int dupflag)
  1145. {
  1146. char *ptr;
  1147. if (ptr = strchr(line,'#')) *ptr = '\0';
  1148. narg = 0;
  1149. char *word = strtok(line," \t\n\r\f");
  1150. while (word) {
  1151. if (narg == maxarg) {
  1152. maxarg += DELTA;
  1153. arg = (char **)
  1154. memory->srealloc(arg,maxarg*sizeof(char *),"read_data:arg");
  1155. }
  1156. arg[narg++] = word;
  1157. if (addstr && narg == 1) arg[narg++] = addstr;
  1158. if (dupflag && narg == 1) arg[narg++] = word;
  1159. word = strtok(NULL," \t\n\r\f");
  1160. }
  1161. }