| 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 |
|
|---|
| 9 | import re, os, os.path, sys, operator
|
|---|
| 10 | import pyMoleCuilder as mol
|
|---|
| 11 | from numpy.linalg import norm
|
|---|
| 12 |
|
|---|
| 13 | import argparse, sys
|
|---|
| 14 |
|
|---|
| 15 | STEPS = 50
|
|---|
| 16 |
|
|---|
| 17 | mol.CommandVerbose('1')
|
|---|
| 18 |
|
|---|
| 19 | parser = argparse.ArgumentParser()
|
|---|
| 20 | parser.add_argument("--basis-set", type=str, default="6-31G", \
|
|---|
| 21 | help="Sets the basis set with mpqc for the CLHF ab-initio computations")
|
|---|
| 22 | parser.add_argument("elements", nargs=2, \
|
|---|
| 23 | help="The pair of elements, e.g., Li H")
|
|---|
| 24 | parser.add_argument("--output-prefix", type=str, default="", required=True, \
|
|---|
| 25 | help="Prefix for output filenames of created pairs")
|
|---|
| 26 | parser.add_argument("--server-address", type=str, default="", required=True, \
|
|---|
| 27 | help="Hostname of the molecuilder_server")
|
|---|
| 28 | parser.add_argument("--server-port", type=str, default="", required=True, \
|
|---|
| 29 | help="Port of the molecuilder_server")
|
|---|
| 30 | parser.add_argument('--version', '-V', action="store_true", \
|
|---|
| 31 | help='Gives version information')
|
|---|
| 32 |
|
|---|
| 33 | params, _ = parser.parse_known_args()
|
|---|
| 34 |
|
|---|
| 35 | if params.version:
|
|---|
| 36 | # give version and exit
|
|---|
| 37 | print(sys.argv[0]+" -- version 0.1")
|
|---|
| 38 | sys.exit(0)
|
|---|
| 39 |
|
|---|
| 40 | elem1 = params.elements[0]
|
|---|
| 41 | elem2 = params.elements[1]
|
|---|
| 42 |
|
|---|
| 43 | def 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 |
|
|---|
| 53 | def 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 |
|
|---|
| 95 | def 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
|
|---|
| 111 | elements=["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
|
|---|
| 114 | elements=["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"]
|
|---|
| 115 | dysfunctional_pairs=[ "Sc_Ti" ]
|
|---|
| 116 |
|
|---|
| 117 | # list for testing the code
|
|---|
| 118 | #elements=["H"]
|
|---|
| 119 |
|
|---|
| 120 | mol.ParserSetTremoloAtomdata("Id type x=3 F=3 neighbors=4")
|
|---|
| 121 | mol.ParserSetParserParameters(set_parser_parameters="mpqc", parser_parameters="theory=CLHF;basis=" + params.basis_set + ";")
|
|---|
| 122 |
|
|---|
| 123 | element_pair = elem1+"_"+elem2
|
|---|
| 124 | if element_pair in dysfunctional_pairs:
|
|---|
| 125 | print("The combination " + element_pair + " cannot be computed, SKIPPING.", flush=True)
|
|---|
| 126 | length = "SKIPPED"
|
|---|
| 127 | else:
|
|---|
| 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"
|
|---|
| 136 | print("DISTANCE: " + elem1 + " " + elem2 + ": " + str(length), flush=True)
|
|---|
| 137 |
|
|---|
| 138 | mol.SelectionAllAtoms()
|
|---|
| 139 | mol.WorldOutputAs(output_as=params.output_prefix + "-" + elem1 + "_" + elem2 + ".data", force_overwrite="1")
|
|---|
| 140 | mol.wait()
|
|---|