OpenMD 3.2
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
waterBoxer
1#!@Python3_EXECUTABLE@
2
3__author__ = "Chris Fennell and Dan Gezelter"
4__copyright__ = "Copyright (c) 2004-present The University of Notre Dame. All Rights Reserved."
5__license__ = "OpenMD"
6
7import sys
8import os
9import math
10import random
11import argparse
12from argparse import RawDescriptionHelpFormatter
13
14def usage():
15 print(__doc__)
16
17# function to calculate the arccosine
18def acos(rad):
19 return math.atan2(math.sqrt(1 - rad * rad), rad)
20
21# Function to open the output file
22def open_output_file(fileName):
23 f = open(fileName, 'w')
24 if os.path.exists(fileName):
25 return f
26 else:
27 sys.exit("Error: can't open file {}\n".format(fileName))
28
29# Function to find the cutoff
30def find_cutoff(cutoff, boxx, boxy, boxz):
31 bm = min(boxx, boxy, boxz)
32 boxLength2 = 0.5 * bm
33 if boxLength2 <= cutoff:
34 cutoff = int(boxLength2)
35
36# Functions to print the water model types
37def print_cl(outfile):
38 outfile.write("""
39molecule{
40 name = "Cl-";
41 atom[0]{
42 type = "Cl-";
43 position(0.0, 0.0, 0.0);
44 }
45}""")
46
47def print_na(outfile):
48 outfile.write("""
49molecule{
50 name = "Na+";
51 atom[0]{
52 type = "Na+";
53 position(0.0, 0.0, 0.0);
54 }
55}""")
56
57def print_ssd_e(outfile):
58 outfile.write("""
59molecule{
60 name = "SSD_E";
61 atom[0]{
62 type = "SSD_E";
63 position( 0.0, 0.0, 0.0 );
64 orientation( 0.0, 0.0, 0.0 );
65 }
66}""")
67
68def print_ssd_rf(outfile):
69 outfile.write("""
70molecule{
71 name = "SSD_RF";
72 atom[0]{
73 type = "SSD_RF";
74 position( 0.0, 0.0, 0.0 );
75 orientation( 0.0, 0.0, 0.0 );
76 }
77}""")
78
79def print_ssd(outfile):
80 outfile.write("""
81molecule{
82 name = "SSD";
83 atom[0]{
84 type = "SSD";
85 position( 0.0, 0.0, 0.0 );
86 orientation( 0.0, 0.0, 0.0 );
87 }
88}""")
89
90def print_ssdq(outfile):
91 outfile.write("""
92molecule{
93 name = "SSDQ";
94 atom[0]{
95 type = "SSDQ";
96 position( 0.0, 0.0, 0.0 );
97 orientation( 0.0, 0.0, 0.0 );
98 }
99}""")
100
101def print_ssdqo(outfile):
102 outfile.write("""
103molecule{
104 name = "SSDQO";
105 atom[0]{
106 type = "SSDQO";
107 position( 0.0, 0.0, 0.0 );
108 orientation( 0.0, 0.0, 0.0 );
109 }
110}""")
111
112def print_ssd1(outfile):
113 outfile.write("""
114molecule{
115 name = "SSD1";
116 atom[0]{
117 type = "SSD1";
118 position( 0.0, 0.0, 0.0 );
119 orientation( 0.0, 0.0, 0.0 );
120 }
121}""")
122
123def print_tip3p(outfile):
124 outfile.write("""
125molecule{
126 name = "TIP3P";
127 atom[0]{
128 type = "O_TIP3P";
129 position( 0.0, 0.0, -0.06556 );
130 }
131 atom[1]{
132 type = "H_TIP3P";
133 position( 0.0, 0.75695, 0.52032 );
134 }
135 atom[2]{
136 type = "H_TIP3P";
137 position( 0.0, -0.75695, 0.52032 );
138 }
139 rigidBody[0]{
140 members(0, 1, 2);
141 }
142}""")
143
144def print_tip4p(outfile):
145 outfile.write("""
146molecule{
147 name = "TIP4P";
148 atom[0]{
149 type = "O_TIP4P";
150 position( 0.0, 0.0, -0.06556 );
151 }
152 atom[1]{
153 type = "H_TIP4P";
154 position( 0.0, 0.75695, 0.52032 );
155 }
156 atom[2]{
157 type = "H_TIP4P";
158 position( 0.0, -0.75695, 0.52032 );
159 }
160 atom[3]{
161 type = "EP_TIP4P";
162 position( 0.0, 0.0, 0.08444 );
163 }
164 rigidBody[0]{
165 members(0, 1, 2, 3);
166 }
167}""")
168
169def print_tip4p_ice(outfile):
170 outfile.write("""
171molecule{
172 name = "TIP4P-Ice";
173 atom[0]{
174 type = "O_TIP4P-Ice";
175 position( 0.0, 0.0, -0.06556 );
176 }
177 atom[1]{
178 type = "H_TIP4P-Ice";
179 position( 0.0, 0.75695, 0.52032 );
180 }
181 atom[2]{
182 type = "H_TIP4P-Ice";
183 position( 0.0, -0.75695, 0.52032 );
184 }
185 atom[3]{
186 type = "EP_TIP4P-Ice";
187 position( 0.0, 0.0, 0.09214 );
188 }
189 rigidBody[0]{
190 members(0, 1, 2, 3);
191 }
192}""")
193
194def print_tip4p_2005(outfile):
195 outfile.write("""
196molecule{
197 name = "TIP4P-2005";
198 atom[0]{
199 type = "O_TIP4P-2005";
200 position( 0.0, 0.0, -0.06556 );
201 }
202 atom[1]{
203 type = "H_TIP4P-2005";
204 position( 0.0, 0.75695, 0.52032 );
205 }
206 atom[2]{
207 type = "H_TIP4P-2005";
208 position( 0.0, -0.75695, 0.52032 );
209 }
210 atom[3]{
211 type = "EP_TIP4P-2005";
212 position( 0.0, 0.0, 0.08904 );
213 }
214 rigidBody[0]{
215 members(0, 1, 2, 3);
216 }
217}""")
218
219def print_tip4pew(outfile):
220 outfile.write("""
221molecule{
222 name = "TIP4P-Ew";
223 atom[0]{
224 type = "O_TIP4P-Ew";
225 position( 0.0, 0.0, -0.06556 );
226 }
227 atom[1]{
228 type = "H_TIP4P-Ew";
229 position( 0.0, 0.75695, 0.52032 );
230 }
231 atom[2]{
232 type = "H_TIP4P-Ew";
233 position( 0.0, -0.75695, 0.52032 );
234 }
235 atom[3]{
236 type = "EP_TIP4P-Ew";
237 position( 0.0, 0.0, 0.05944 );
238 }
239 rigidBody[0]{
240 members(0, 1, 2, 3);
241 }
242}""")
243
244def print_tip5p(outfile):
245 outfile.write("""
246molecule{
247 name = "TIP5P";
248 atom[0]{
249 type = "O_TIP5P";
250 position( 0.0, 0.0, -0.06556 );
251 }
252 atom[1]{
253 type = "H_TIP5P";
254 position( 0.0, 0.75695, 0.52032 );
255 }
256 atom[2]{
257 type = "H_TIP5P";
258 position( 0.0, -0.75695, 0.52032 );
259 }
260 atom[3]{
261 type = "EP_TIP5P";
262 position( 0.57154, 0.0, -0.46971 );
263 }
264 atom[4]{
265 type = "EP_TIP5P";
266 position( -0.57154, 0.0, -0.46971 );
267 }
268 rigidBody[0]{
269 members(0, 1, 2, 3, 4);
270 }
271}""")
272
273def print_tip5pe(outfile):
274 outfile.write("""
275molecule{
276 name = "TIP5P-E";
277 atom[0]{
278 type = "O_TIP5P-E";
279 position( 0.0, 0.0, -0.06556 );
280 }
281 atom[1]{
282 type = "H_TIP5P";
283 position( 0.0, 0.75695, 0.52032 );
284 }
285 atom[2]{
286 type = "H_TIP5P";
287 position( 0.0, -0.75695, 0.52032 );
288 }
289 atom[3]{
290 type = "EP_TIP5P";
291 position( 0.57154, 0.0, -0.46971 );
292 }
293 atom[4]{
294 type = "EP_TIP5P";
295 position( -0.57154, 0.0, -0.46971 );
296 }
297 rigidBody[0]{
298 members(0, 1, 2, 3, 4);
299 }
300}""")
301
302def print_spce(outfile):
303 outfile.write("""
304molecule{
305 name = "SPCE";
306 atom[0]{
307 type = "O_SPCE";
308 position( 0.0, 0.0, -0.06461 );
309 }
310 atom[1]{
311 type = "H_SPCE";
312 position( 0.0, 0.81649, 0.51275 );
313 }
314 atom[2]{
315 type = "H_SPCE";
316 position( 0.0, -0.81649, 0.51275 );
317 }
318 rigidBody[0]{
319 members(0, 1, 2);
320 }
321}""")
322
323def print_spc(outfile):
324 outfile.write("""
325molecule{
326 name = "SPC";
327 atom[0]{
328 type = "O_SPC";
329 position( 0.0, 0.0, -0.06461 );
330 }
331 atom[1]{
332 type = "H_SPC";
333 position( 0.0, 0.81649, 0.51275 );
334 }
335 atom[2]{
336 type = "H_SPC";
337 position( 0.0, -0.81649, 0.51275 );
338 }
339 rigidBody[0]{
340 members(0, 1, 2);
341 }
342}""")
343
344def print_spc_hw(outfile):
345 outfile.write("""
346molecule{
347 name = "SPC-HW";
348 atom[0]{
349 type = "O_SPC-HW";
350 position( 0.0, 0.0, -0.06461 );
351 }
352 atom[1]{
353 type = "D_SPC-HW";
354 position( 0.0, 0.81649, 0.51275 );
355 }
356 atom[2]{
357 type = "D_SPC-HW";
358 position( 0.0, -0.81649, 0.51275 );
359 }
360 rigidBody[0]{
361 members(0, 1, 2);
362 }
363}""")
364
365def print_ne6(outfile):
366 outfile.write("""
367molecule{
368 name = "NE6";
369 atom[0]{
370 type = "O_NE6";
371 position( 0.0, 0.0, 0.0 );
372 }
373 atom[1]{
374 type = "H_NE6";
375 position( 0.0, 0.576029, 0.79283665 );
376 }
377 atom[2]{
378 type = "H_NE6";
379 position( 0.0, -0.576029, 0.79283665 );
380 }
381 atom[3]{
382 type = "EP_NE6";
383 position( 0.0, 0.23, 0.0 );
384 }
385 atom[4]{
386 type = "LP_NE6";
387 position( 0.732813007, -0.50364843, 0.0 );
388 }
389 atom[5]{
390 type = "LP_NE6";
391 position( -0.732813007, -0.50364843, 0.0 );
392 }
393 rigidBody[0]{
394 members(0, 1, 2, 3, 4, 5);
395 }
396}""")
397
398def print_tip3p_fb(outfile):
399 outfile.write("""
400molecule{
401 name = "TIP3P-FB";
402 atom[0]{
403 type = "O_TIP3P-FB";
404 position( 0.0, 0.0, -0.066424 );
405 }
406 atom[1]{
407 type = "H_TIP3P-FB";
408 position( 0.0, 0.819341, 0.527225 );
409 }
410 atom[2]{
411 type = "H_TIP3P-FB";
412 position( 0.0, -0.819341, 0.527225 );
413 }
414 rigidBody[0]{
415 members(0, 1, 2);
416 }
417}""")
418
419def print_tip4p_fb(outfile):
420 outfile.write("""
421molecule{
422 name = "TIP4P-FB";
423 atom[0]{
424 type = "O_TIP4P-FB";
425 position( 0.0, 0.0, -0.0655549 );
426 }
427 atom[1]{
428 type = "H_TIP4P-FB";
429 position( 0.0, 0.75695, 0.520327 );
430 }
431 atom[2]{
432 type = "H_TIP4P-FB";
433 position( 0.0, -0.75695, 0.520327 );
434 }
435 atom[3]{
436 type = "EP_TIP4P-FB";
437 position( 0.0, 0.0, 0.0397151 );
438 }
439 rigidBody[0]{
440 members(0, 1, 2, 3);
441 }
442}""")
443
444def print_opc(outfile):
445 outfile.write("""
446molecule{
447 name = "OPC";
448 atom[0]{
449 type = "O_OPC";
450 position( 0.0, 0.0, -0.0603651 );
451 }
452 atom[1]{
453 type = "H_OPC";
454 position( 0.0, 0.685582, 0.479134 );
455 }
456 atom[2]{
457 type = "H_OPC";
458 position( 0.0, -0.685582, 0.479134 );
459 }
460 atom[3]{
461 type = "EP_OPC";
462 position( 0.0, 0.0, 0.0990349 );
463 }
464 rigidBody[0]{
465 members(0, 1, 2, 3);
466 }
467}""")
468
469def print_opc3(outfile):
470 outfile.write("""
471molecule{
472 name = "OPC3";
473 atom[0]{
474 type = "O_OPC3";
475 position( 0.0, 0.0, -0.0632382 );
476 }
477 atom[1]{
478 type = "H_OPC3";
479 position( 0.0, 0.799262, 0.501939 );
480 }
481 atom[2]{
482 type = "H_OPC3";
483 position( 0.0, -0.799262, 0.501939 );
484 }
485 rigidBody[0]{
486 members(0, 1, 2);
487 }
488}""")
489
490def print_dpd(outfile):
491 outfile.write("""
492molecule{
493 name = "DPD";
494 atom[0]{
495 type = "DPD";
496 position( 0.0, 0.0, 0.0 );
497 }
498}""")
499
500def print_cg2(outfile):
501 outfile.write("""
502molecule{
503 name = "CG2";
504 atom[0]{
505 type = "CG2";
506 position( 0.0, 0.0, 0.0 );
507 }
508}""")
509
510# Function to print fake water model
511def print_fake_water(waterName, outfile):
512 outfile.write("\n\nmolecule{{\n name = \"{}\";\n atom[0]{{\n type = \"{}\";\n position(0.0, 0.0, 0.0);\n }}\n}}".format(waterName, waterName))
513
514# Function to print the water model
515def print_water_model(waterCase, outfile):
516 if waterCase == 0: print_cl(outfile)
517 elif waterCase == 1: print_na(outfile)
518 elif waterCase == 2: print_ssd_e(outfile)
519 elif waterCase == 3: print_ssd_rf(outfile)
520 elif waterCase == 4: print_ssd(outfile)
521 elif waterCase == 5: print_ssd1(outfile)
522 elif waterCase == 6: print_tip3p(outfile)
523 elif waterCase == 7: print_tip4p(outfile)
524 elif waterCase == 8: print_tip4pew(outfile)
525 elif waterCase == 9: print_tip5p(outfile)
526 elif waterCase == 10: print_tip5pe(outfile)
527 elif waterCase == 11: print_spce(outfile)
528 elif waterCase == 12: print_spc(outfile)
529 elif waterCase == 13: print_dpd(outfile)
530 elif waterCase == 14: print_cg2(outfile)
531 elif waterCase == 15: print_ssdq(outfile)
532 elif waterCase == 16: print_ssdqo(outfile)
533 elif waterCase == 17: print_tip4p_ice(outfile)
534 elif waterCase == 18: print_tip4p_2005(outfile)
535 elif waterCase == 19: print_spc_hw(outfile)
536 elif waterCase == 20: print_ne6(outfile)
537 elif waterCase == 21: print_tip3p_fb(outfile)
538 elif waterCase == 22: print_tip4p_fb(outfile)
539 elif waterCase == 23: print_opc(outfile)
540 elif waterCase == 24: print_opc3(outfile)
541
542# Function to validate the water model
543def validate_water(waterName):
544 water_models = {
545 'Cl-': 0, 'Na+': 1, 'SSD_E': 2, 'SSD_RF': 3, 'SSD': 4, 'SSD1': 5,
546 'TIP3P': 6, 'TIP4P': 7, 'TIP4P-Ew': 8, 'TIP5P': 9, 'TIP5P-E': 10,
547 'SPCE': 11, 'SPC': 12, 'DPD': 13, 'CG2': 14, 'SSDQ': 15, 'SSDQO': 16,
548 'TIP4P-Ice': 17, 'TIP4P-2005': 18, 'SPC-HW': 19, 'NE6': 20,
549 'TIP3P-FB': 21, 'TIP4P-FB': 22, 'OPC': 23, 'OPC3': 24
550 }
551 waterCase = water_models.get(waterName, -1)
552 invalidWater = False
553 if waterCase == -1:
554 invalidWater = True
555 return (waterCase, invalidWater)
556
557# Function to print the meta data
558def print_meta_data(outfile, doWaterInc, waterName, waterCase, invalidWater,
559 nMol, cutoff, alpha):
560 outfile.write(" <MetaData>\n")
561
562 if doWaterInc:
563 outfile.write('#include "water.inc"')
564 else:
565 print_water_model(waterCase, outfile)
566
567 if invalidWater:
568 print_fake_water(waterName, outfile)
569
570 outfile.write("\n\n")
571 outfile.write("component{\n")
572 outfile.write(" type = \"{}\";\n".format(waterName))
573 outfile.write(" nMol = {};\n".format(nMol))
574 outfile.write("}\n")
575 outfile.write("ensemble = \"NVT\";\n")
576 outfile.write("forceField = \"Water\";\n")
577 outfile.write("electrostaticSummationMethod = \"shifted_force\";\n")
578 outfile.write("electrostaticScreeningMethod = \"damped\";\n")
579 outfile.write("cutoffRadius = {};\n".format(cutoff))
580 outfile.write("dampingAlpha = {};\n".format(alpha))
581 outfile.write("\n")
582 outfile.write("targetTemp = 300;\n")
583 outfile.write("targetPressure = 1.0;\n")
584 outfile.write("\n")
585 outfile.write("tauThermostat = 1e3;\n")
586 outfile.write("tauBarostat = 1e4;\n")
587 outfile.write("\n")
588 outfile.write("dt = 2.0;\n")
589 outfile.write("runTime = 1e3;\n")
590 outfile.write("\n")
591 outfile.write("tempSet = \"true\";\n")
592 outfile.write("thermalTime = 10;\n")
593 outfile.write("sampleTime = 100;\n")
594 outfile.write("statusTime = 2;\n")
595 outfile.write(" </MetaData>\n")
596
597# Function to print the frame data
598def print_frame_data(outfile, boxx, boxy, boxz):
599 outfile.write(" <Snapshot>\n")
600 outfile.write(" <FrameData>\n")
601 outfile.write(" Time: 0\n")
602 outfile.write(" Hmat: {{{{ {}, 0, 0 }}, {{ 0, {}, 0 }}, {{ 0, 0, {} }}}}\n".format(boxx, boxy, boxz))
603 outfile.write(" </FrameData>\n")
604
605# Function to write the output file
606def write_output_file(outfile, nMol, xCorr, yCorr, zCorr, cutoff, alpha,
607 boxx, boxy, boxz, waterName, waterCase, invalidWater,
608 doRandomize, doWaterInc):
609 # Write out the header
610 outfile.write("<OpenMD version=2>\n")
611 find_cutoff(cutoff, boxx, boxy, boxz)
612 print_meta_data(outfile, doWaterInc, waterName, waterCase, invalidWater,
613 nMol, cutoff, alpha)
614 print_frame_data(outfile, boxx, boxy, boxz)
615 outfile.write(" <StuntDoubles>\n")
616
617 # Shift the box center to the origin and write out the coordinates
618 for i in range(nMol):
619 xCorr[i] -= 0.5 * boxx
620 yCorr[i] -= 0.5 * boxy
621 zCorr[i] -= 0.5 * boxz
622
623 q0 = 1.0
624 q1 = q2 = q3 = 0.0
625
626 if doRandomize:
627 cosTheta = 2.0 * random.random() - 1.0
628 theta = acos(cosTheta)
629 phi = 2.0 * math.pi * random.random()
630 psi = 2.0 * math.pi * random.random()
631
632 q0 = math.cos(0.5 * theta) * math.cos(0.5 * (phi + psi))
633 q1 = math.sin(0.5 * theta) * math.cos(0.5 * (phi - psi))
634 q2 = math.sin(0.5 * theta) * math.sin(0.5 * (phi - psi))
635 q3 = math.cos(0.5 * theta) * math.sin(0.5 * (phi + psi))
636
637 outfile.write("{}\tpq\t{} {} {} {} {} {} {}\n".format(i, xCorr[i], yCorr[i], zCorr[i], q0, q1, q2, q3))
638
639 outfile.write(" </StuntDoubles>\n")
640 outfile.write(" </Snapshot>\n")
641 outfile.write("</OpenMD>\n")
642
643def main(argv):
644
645 parser = argparse.ArgumentParser(
646 description='builds water boxes',
647 formatter_class=argparse.RawDescriptionHelpFormatter,
648 epilog=
649'''
650Note: you can only use values of x, y, or z that are smaller
651 than the derived box length for a given density and
652 number of molecules.
653
654Example:
655 waterBoxer -d 0.997 -x 20 -y 20 -z 20 -w TIP4P-Ice -o tip4pWater.omd
656''')
657 parser.add_argument("-d", "--density=", action="store", dest='density',
658 type=float, help="density in g/cm^3",
659 required=False, default=1.0)
660 parser.add_argument("-l", "--lattice=", choices=[0,1],
661 action="store", dest='lattice',
662 type=int, default=0, required=False,
663 help="0 - face centered cubic, 1 - simple cubic")
664 parser.add_argument("-c", "--rcut=", action="store", dest="rcut",
665 type=float, default=3.2, required=False,
666 help="default overlap cutoff in angstroms")
667 parser.add_argument("-o", "--output=", action="store", dest='fileName',
668 help="output file name", required=False,
669 default="freshWater.omd")
670 parser.add_argument("-w", "--water=", action="store", dest="waterName",
671 help="name of the water StuntDouble",
672 required=False, default="SPCE")
673 parser.add_argument("-x", "--boxx=", action="store", required=True,
674 dest='boxx', type=float,
675 help="dimension of the box along the x direction")
676 parser.add_argument("-y", "--boxy=", action="store", required=True,
677 dest='boxy', type=float,
678 help="dimension of the box along the y direction")
679 parser.add_argument("-z", "--boxz=", action="store", required=True,
680 dest='boxz', type=float,
681 help="dimension of the box along the z direction")
682 parser.add_argument("-r", "--randomize",
683 action=argparse.BooleanOptionalAction, default=False,
684 type=bool, dest='doRandomize',
685 help="randomize orientations")
686 parser.add_argument("-m", "--printInclude",
687 action=argparse.BooleanOptionalAction, default=False,
688 type=bool, dest='doWaterInc',
689 help="print out a water.inc file (file with all water models)")
690
691 if len(sys.argv) == 1:
692 parser.print_help()
693 sys.exit(2)
694 args = parser.parse_args()
695
696 density = args.density
697 lattice = args.lattice
698 rcut = args.rcut
699 fileName = args.fileName
700 waterName = args.waterName
701 boxx = args.boxx
702 boxy = args.boxy
703 boxz = args.boxz
704 doRandomize = args.doRandomize
705 doWaterInc = args.doWaterInc
706
707 tolerance = 1.0E-8
708 mass = 2.99151E-23 # mass of H2O in grams
709 cm3ToAng3 = 1E24 # convert cm^3 to angstroms^3
710 densityConvert = mass * cm3ToAng3
711 cutoff = 9
712 alpha = 0.18
713 invalidWater = False
714 waterCase = -1
715
716 if doWaterInc:
717 if fileName == 'water.inc':
718 sys.exit("Error: {} cannot be \"water.inc\"\n Please choose a different name\n".format(fileName))
719 if density <= 0:
720 usage()
721 sys.exit("Error: the value for '-d' ({}) is not a valid number\n Please choose a positive real # value\n".format(density))
722 if rcut <= 0:
723 usage()
724 sys.exit("Error: the value for '-c' ({}) is not a valid number\n Please choose a positive real # value\n".format(arg))
725 if lattice != 0 and lattice != 1:
726 usage()
727 sys.exit("Error: the '-l' value ({}) is not a valid number\n Please choose 0 or 1\n".format(arg))
728 if boxx <= 0:
729 usage()
730 sys.exit("Error: the value for '-x' ({}) is not a valid number\n Please choose a positive real # value\n".format(boxx))
731 if boxy <= 0:
732 usage()
733 sys.exit("Error: the value for '-y' ({}) is not a valid number\n Please choose a positive real # value\n".format(boxy))
734 if boxz <= 0:
735 usage()
736 sys.exit("Error: the value for '-z' ({}) is not a valid number\n Please choose a positive real # value\n".format(boxz))
737
738 outfile = open_output_file(fileName)
739
740 # Set magic lattice numbers
741 if lattice == 0:
742 a = (4 * 18.01 / (0.602 * density)) ** (1.0 / 3.0)
743 acut = rcut * math.sqrt(2.0)
744 if acut > a:
745 a = acut
746 newDensity = 4.0 * 18.01 / (0.602 * a ** 3)
747 print("using density of {} to match cutoff value ({})\n".format(newDensity, rcut))
748 elif lattice == 1:
749 a = (18.01 / (0.602 * density)) ** (1.0 / 3.0)
750 acut = rcut
751 if acut > a:
752 a = acut
753 newDensity = 18.01 / (0.602 * a ** 3)
754 print("using density of {} to match cutoff value ({})\n".format(newDensity, rcut))
755
756 nxFloat = boxx / a
757 nx = int(nxFloat + nxFloat / abs(nxFloat * 2))
758 nyFloat = boxy / a
759 ny = int(nyFloat + nyFloat / abs(nyFloat * 2))
760 nzFloat = boxz / a
761 nz = int(nzFloat + nzFloat / abs(nzFloat * 2))
762
763 anew = min(boxx / nx, boxy / ny, boxz / nz)
764
765 if anew < acut:
766 anew = acut
767
768 nxFloat = boxx / anew
769 nx = int(nxFloat + nxFloat / abs(nxFloat * 2))
770 nyFloat = boxy / anew
771 ny = int(nyFloat + nyFloat / abs(nyFloat * 2))
772 nzFloat = boxz / anew
773 nz = int(nzFloat + nzFloat / abs(nzFloat * 2))
774
775 if lattice == 0:
776 nMol = 4 * nx * ny * nz
777 else:
778 nMol = nx * ny * nz
779
780 newDensity = nMol * densityConvert / (boxx * boxy * boxz)
781
782 if abs(newDensity - density) > tolerance:
783 print("Resetting density to {} to make chosen box sides work out\n".format(newDensity))
784
785 cellLengthX = boxx / nx
786 cellLengthY = boxy / ny
787 cellLengthZ = boxz / nz
788
789 cell2X = cellLengthX * 0.5
790 cell2Y = cellLengthY * 0.5
791 cell2Z = cellLengthZ * 0.5
792
793 xCorr = []
794 yCorr = []
795 zCorr = []
796
797 if lattice == 0:
798 xref = [0.0, 0.0, cell2X, cell2X]
799 yref = [0.0, cell2Y, cell2Y, 0.0]
800 zref = [0.0, cell2Z, 0.0, cell2Z]
801
802 counter = 0
803 for z in range(nz):
804 for y in range(ny):
805 for x in range(nx):
806 for uc in range(4):
807 xCorr.append(xref[uc] + cellLengthX * x)
808 yCorr.append(yref[uc] + cellLengthY * y)
809 zCorr.append(zref[uc] + cellLengthZ * z)
810 counter += 4
811 elif lattice == 1:
812 xref = [cell2X]
813 yref = [cell2Y]
814 zref = [cell2Z]
815
816 counter = 0
817 for z in range(nz):
818 for y in range(ny):
819 for x in range(nx):
820 xCorr.append(xref[uc] + cellLengthX * x)
821 yCorr.append(yref[uc] + cellLengthY * y)
822 zCorr.append(zref[uc] + cellLengthZ * z)
823 counter += 1
824
825 (waterCase, invalidWater) = validate_water(waterName)
826 if invalidWater:
827 print("Warning: '{}' is not a recognized water model name.\n".format(waterName))
828 print(" Use the '-m' option to generate a 'water.inc' with the\n")
829 print(" recognized water model geometries.\n\n")
830 if waterName == 'DPD':
831 density *= 0.25
832 elif waterName == 'CG2':
833 density *= 0.5
834
835 write_output_file(outfile, nMol, xCorr, yCorr, zCorr, cutoff, alpha,
836 boxx, boxy, boxz, waterName, waterCase, invalidWater,
837 doRandomize, doWaterInc)
838 outfile.close()
839
840 print("The water box \"{}\" was generated.\n".format(fileName))
841
842 if doWaterInc:
843 try:
844 outfile = open("./water.inc", "w")
845 except:
846 sys.exit("Error: can't open file {}\n".format("water.inc"))
847
848 outfile.write("#ifndef _WATER_INC_\n#define _WATER_INC_\n")
849 print_cl(outfile)
850 print_na(outfile)
851 print_ssd_e(outfile)
852 print_ssd_rf(outfile)
853 print_ssd(outfile)
854 print_ssd1(outfile)
855 print_tip3p(outfile)
856 print_tip4p(outfile)
857 print_tip4pew(outfile)
858 print_tip5p(outfile)
859 print_tip5pe(outfile)
860 print_spce(outfile)
861 print_spc(outfile)
862 print_dpd(outfile)
863 print_cg2(outfile)
864 print_ssdq(outfile)
865 print_ssdqo(outfile)
866 print_tip4p_ice(outfile)
867 print_tip4p_2005(outfile)
868 print_spc_hw(outfile)
869 print_ne6(outfile)
870 print_tip3p_fb(outfile)
871 print_tip4p_fb(outfile)
872 print_opc(outfile)
873 print_opc3(outfile)
874 outfile.write("\n\n#endif")
875
876 print("The file \"water.inc\" was generated for inclusion in \"{}\"\n".format(fileName))
877
878 outfile.close()
879
880if __name__ == "__main__":
881 main(sys.argv[1:])