source: utils/Python/compute_pair_bondlength.py.in@ 5169d1b

Candidate_v1.7.1 stable v1.7.1
Last change on this file since 5169d1b was 802a9d, checked in by Frederik Heber <frederik.heber@…>, 6 weeks ago

Adds scripts to generate a bond table.

  • one python script for the computation and a bash script to call it. With this split, we can easily parallelize the computations to make use of JobMarket's multiple workers.
  • Property mode set to 100755
File size: 5.0 KB
Line 
1#!@PYTHON@
2
3# Compoute bond distance
4#
5# For a given set of elements we go through all pairs and compute the bond length after
6# an optimization with a fixed number of steps.
7
8
9import re, os, os.path, sys, operator
10import pyMoleCuilder as mol
11from numpy.linalg import norm
12
13import argparse, sys
14
15STEPS = 50
16
17mol.CommandVerbose('1')
18
19parser = argparse.ArgumentParser()
20parser.add_argument("--basis-set", type=str, default="6-31G", \
21 help="Sets the basis set with mpqc for the CLHF ab-initio computations")
22parser.add_argument("elements", nargs=2, \
23 help="The pair of elements, e.g., Li H")
24parser.add_argument("--output-prefix", type=str, default="", required=True, \
25 help="Prefix for output filenames of created pairs")
26parser.add_argument("--server-address", type=str, default="", required=True, \
27 help="Hostname of the molecuilder_server")
28parser.add_argument("--server-port", type=str, default="", required=True, \
29 help="Port of the molecuilder_server")
30parser.add_argument('--version', '-V', action="store_true", \
31 help='Gives version information')
32
33params, _ = parser.parse_known_args()
34
35if params.version:
36 # give version and exit
37 print(sys.argv[0]+" -- version 0.1")
38 sys.exit(0)
39
40elem1 = params.elements[0]
41elem2 = params.elements[1]
42
43def createPair(elem1, elem2):
44 # we put them in a default distance of 1.5A
45 mol.AtomAdd(domain_position = "9.25,10,10", add_atom = elem1)
46 mol.SelectionAllMolecules() # enforce adding to present molecule
47 mol.AtomAdd(domain_position = "10.75,10,10", add_atom = elem2)
48 mol.SelectionAllAtoms()
49 mol.BondAdd()
50 mol.AtomSaturate(use_outer_shell = "1")
51 mol.SelectionClearAllMolecules()
52
53def optimizeGeometry(elem1, elem2):
54 prefix = "BondFragment-"+elem1+"_"+elem2
55 mol.FragmentationClearFragmentationResults()
56 mol.PotentialClearHomologies()
57 # create the keyset filen
58 mol.SelectionAllAtoms()
59 mol.SelectionNotAtomByElement("H")
60 with open("./BondFragmentKeySets.dat", "w") as f:
61 for i in range(mol.getSelectedAtomCount()):
62 f.write(str(i)+" ");
63 f.write("\n");
64 mol.SelectionAllAtoms()
65 mol.wait()
66 for step in range(STEPS):
67 mol.WorldOutputAs(output_as=params.output_prefix + "-" + elem1 + "_" + elem2 + ".in", force_overwrite="1")
68 # parse the full molecule as one single fragment job
69 mol.FragmentationAddSelectedAtomsAsFragment(
70 add_selected_atoms_as_fragment=params.output_prefix + "-" + elem1 + "_" + elem2,
71 output_types=""
72 )
73 status = mol.wait()
74 mol.FragmentationFragmentationAutomation(
75 DoLongrange="0",
76 server_address=str(params.server_address),
77 server_port=str(params.server_port)
78 )
79 status = mol.wait()
80 if not status:
81 print("Fragmentation computation failed, STOPPING.", flush=True)
82 return False
83 mol.FragmentationAnalyseFragmentationResults(
84 fragment_prefix=prefix
85 )
86 mol.wait()
87 mol.WorldStepWorldTime("1")
88 mol.wait()
89 mol.MoleculeForceAnnealing(
90 use_bondgraph="1"
91 )
92 mol.FragmentationClearFragmentationResults()
93 return True
94
95def extractNonHydrogenBondLength(elem1, elem2):
96 name="length-" + elem1 + "_" + elem2
97 mol.SelectionClearAllAtoms()
98 if elem1 != "H":
99 mol.SelectionAtomByElement(elem1)
100 else:
101 mol.SelectionAtomByName(elem1+"1")
102 if elem2 != "H":
103 mol.SelectionAtomByElement(elem2)
104 else:
105 mol.SelectionAtomByName(elem2+"2")
106 mol.GeometryDistanceToVector(distance_to_vector=name)
107 mol.wait()
108 return norm(mol.get_geometryobject(name), 2)
109
110# original list of element for pairing
111elements=["H", "He", "Li", "Be", "B", "C", "N", "O", "F", "Ne", "Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar", "K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe"]
112
113# list with elements excluded where force calculation did not work: noble gases, Mn,Fe with H need fine-tuning with smaller step width
114elements=["H", "Li", "Be", "B", "C", "N", "O", "F", "Na", "Mg", "Al", "Si", "P", "S", "Cl", "K", "Ca", "Sc", "Ti", "Mn", "Sc", "Ti", "V", "Cr", "Mn", "Fe"]
115dysfunctional_pairs=[ "Sc_Ti" ]
116
117# list for testing the code
118#elements=["H"]
119
120mol.ParserSetTremoloAtomdata("Id type x=3 F=3 neighbors=4")
121mol.ParserSetParserParameters(set_parser_parameters="mpqc", parser_parameters="theory=CLHF;basis=" + params.basis_set + ";")
122
123element_pair = elem1+"_"+elem2
124if element_pair in dysfunctional_pairs:
125 print("The combination " + element_pair + " cannot be computed, SKIPPING.", flush=True)
126 length = "SKIPPED"
127else:
128 createPair(elem1, elem2)
129 mol.wait()
130 status = optimizeGeometry(elem1, elem2)
131 if status:
132 length = extractNonHydrogenBondLength(elem1, elem2)
133 mol.wait()
134 else:
135 length = "SKIPPED"
136print("DISTANCE: " + elem1 + " " + elem2 + ": " + str(length), flush=True)
137
138mol.SelectionAllAtoms()
139mol.WorldOutputAs(output_as=params.output_prefix + "-" + elem1 + "_" + elem2 + ".data", force_overwrite="1")
140mol.wait()
Note: See TracBrowser for help on using the repository browser.