From 130d31b53e0d3bf60d3a819aa2107fc6975cd5ce Mon Sep 17 00:00:00 2001 From: Rollin King Date: Wed, 26 Jun 2019 11:33:14 -0400 Subject: [PATCH 1/6] first pass to initiate pull request for a function to align for dipole moment derivatives --- qcelemental/models/align.py | 21 +++++++ qcelemental/molutil/test_align.py | 92 +++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) diff --git a/qcelemental/models/align.py b/qcelemental/models/align.py index 96c71bbc..205009b4 100644 --- a/qcelemental/models/align.py +++ b/qcelemental/models/align.py @@ -126,6 +126,27 @@ def align_hessian(self, hess) -> NDArray: alhess = blockwise_contract(alhess) return alhess + def align_vector_gradient(self, mu_x, mu_y, mu_z): + """Align the nuclear gradients of vector components (e.g. dipole derivatives).""" + # Input data is assumed to be organized into separate x, y, z vector components. + # Organize derivatives for each atom into 3x3 and transform it. + nat = mu_x.shape[0] // 3 + al_mu_x = np.zeros( (nat, 3) ) + al_mu_y = np.zeros( (nat, 3) ) + al_mu_z = np.zeros( (nat, 3) ) + + DERatom = np.zeros( (3,3) ) + for at in range(nat): + Deratom.fill(0) + DERatom[0,:] = mu_x[at,:] + DERatom[1,:] = mu_y[at,:] + DERatom[2,:] = mu_z[at,:] + DERatom[:] = np.dot( self.rotation.T , np.dot(DIPDERatom, self.rotation) ) + al_mu_x[at][:] = DERatom[0,:] + al_mu_y[at][:] = DERatom[1,:] + al_mu_z[at][:] = DERatom[2,:] + return (al_mu_x, al_mu_y, al_muz) + def align_system(self, geom, mass, elem, elez, uniq, *, reverse: bool = False): """For AlignmentRecipe `ar`, apply its translation, rotation, and atom map.""" diff --git a/qcelemental/molutil/test_align.py b/qcelemental/molutil/test_align.py index ece1f064..baafddcc 100644 --- a/qcelemental/molutil/test_align.py +++ b/qcelemental/molutil/test_align.py @@ -442,3 +442,95 @@ def test_hessian_align(): p2chess = mill.align_hessian(p4_hooh_hess_native) assert compare_values(c4_hooh_hess, p2chess, atol=1.e-4) + +def test_vector_gradient_align(): + # from Psi4 test test_hessian_vs_cfour[HOOH_TS-H_analytic] + + rmill = """ +---------------------------------------- + AlignmentMill +---------------------------------------- +Mirror: False +Atom Map: [0 1 2 3] +Shift: [0.00000000e+00 0.00000000e+00 1.32217718e-10] +Rotation: +[[ 9.99999870e-01 -5.08999836e-04 -0.00000000e+00] + [ 5.08999836e-04 9.99999870e-01 0.00000000e+00] + [ 0.00000000e+00 -0.00000000e+00 1.00000000e+00]] +---------------------------------------- +""" + + p4_hooh_xyz = """ + units au + H 1.8327917647 -1.5752960165 -0.0000055594 + O 1.3171390326 0.1388012713 0.0000003503 + O -1.3171390326 -0.1388012713 0.0000003503 + H -1.8327917647 1.5752960165 -0.0000055594 + """ + + c4_hooh_xyz = """ + H 1.83198970 -1.57622870 -0.00000556 + O 1.31720951 0.13813083 0.00000035 + O -1.31720951 -0.13813083 0.00000035 + H -1.83198970 1.57622870 -0.00000556 + units au""" + + # From C4 DIPDER file, analytic + c4_hooh_dipder_x = np.array([ + [ 0.2780463810, -0.0627423838, -0.0000001663], + [ 0.2780463810, -0.0627423838, 0.0000001663], + [-0.2780463810, 0.0627423838, 0.0000007872], + [-0.2780463810, 0.0627423838, -0.0000007872]]) + c4_hooh_dipder_y = np.array([ + [-0.0452364698, 0.2701572972, -0.0000004246], + [-0.0452364698, 0.2701572972, 0.0000004246], + [ 0.0452364698, -0.2701572972, 0.0000007936], + [ 0.0452364698, -0.2701572972, -0.0000007936]]) + c4_hooh_dipder_z = np.array([ + [-0.0000001575, -0.0000004725, 0.4019549601], + [ 0.0000001575, 0.0000004725, 0.4019549601], + [-0.0000000523, 0.0000008401, -0.4019549601], + [ 0.0000000523, -0.0000008401, -0.4019549601]]) + + # Generated from fixing orientation/com in psi4. Then using + # a 5-point finite differences of nuclear gradients computed + # with an applied electric field to produce a file17.dat. + p4_hooh_dipdir_x_native = np.array( + [ 0.2781013514, -0.0627383175, -0.0000001660], + [-0.2781013514, 0.0627383175, 0.0000007867], + [-0.2781013514, 0.0627383175, -0.0000007867], + [ 0.2781013514, -0.0627383175, 0.0000001660]]) + p4_hooh_dipdir_y_native = np.array( + [-0.0452324587, 0.2701024305, -0.0000004247], + [ 0.0452324587, -0.2701024305, 0.0000007939], + [ 0.0452324587, -0.2701024305, -0.0000007939], + [-0.0452324587, 0.2701024305, 0.0000004247]]) + p4_hooh_dipdir_z_native = np.array( + [-0.0000001572, -0.0000004726, 0.4019549470], + [-0.0000000527, 0.0000008401, -0.4019549470], + [ 0.0000000527, -0.0000008401, -0.4019549470], + [ 0.0000001572, 0.0000004726, 0.4019549470]]) + + p4mol = qcel.models.Molecule.from_data(p4_hooh_xyz) + c4mol = qcel.models.Molecule.from_data(c4_hooh_xyz) + aqmol, data = p4mol.align(c4mol, atoms_map=True, mols_align=True, verbose=4) + mill = data['mill'] + #assert compare([0, 1, 2, 3], mill.atommap) + #assert compare_values([ + #[ 9.99999870e-01, -5.08999836e-04, -0.00000000e+00], + #[ 5.08999836e-04, 9.99999870e-01, 0.00000000e+00], + #[ 0.00000000e+00, -0.00000000e+00, 1.00000000e+00]], + #mill.rotation, + #atol=1.e-6) + + p2cgeom = mill.align_coordinates(p4mol.geometry) + assert compare_values(c4mol.geometry, p2cgeom, atol=1.e-6) + + # Still need to account for atom renumbering ! + p2c_dipdir_x, p2c_dipdir_y, p2c_dipdir_z = mill.align_vector_gradient( + p4_hooh_dipdir_x_native, p4_hooh_dipdir_y_native, p4_hooh_dipdir_z_native) + + assert compare_values(c4_hooh_dipdir_x, p2c_dipdir_x, atol=1.e-6) + assert compare_values(c4_hooh_dipdir_y, p2c_dipdir_y, atol=1.e-6) + assert compare_values(c4_hooh_dipdir_z, p2c_dipdir_z, atol=1.e-6) + From d008c3f9394e269315c6191ff3a8d090169557f1 Mon Sep 17 00:00:00 2001 From: Rollin King Date: Wed, 26 Jun 2019 11:33:14 -0400 Subject: [PATCH 2/6] first pass to initiate pull request for a function to align for dipole moment derivatives --- qcelemental/models/align.py | 21 +++++++ qcelemental/molutil/test_align.py | 92 +++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) diff --git a/qcelemental/models/align.py b/qcelemental/models/align.py index 96c71bbc..205009b4 100644 --- a/qcelemental/models/align.py +++ b/qcelemental/models/align.py @@ -126,6 +126,27 @@ def align_hessian(self, hess) -> NDArray: alhess = blockwise_contract(alhess) return alhess + def align_vector_gradient(self, mu_x, mu_y, mu_z): + """Align the nuclear gradients of vector components (e.g. dipole derivatives).""" + # Input data is assumed to be organized into separate x, y, z vector components. + # Organize derivatives for each atom into 3x3 and transform it. + nat = mu_x.shape[0] // 3 + al_mu_x = np.zeros( (nat, 3) ) + al_mu_y = np.zeros( (nat, 3) ) + al_mu_z = np.zeros( (nat, 3) ) + + DERatom = np.zeros( (3,3) ) + for at in range(nat): + Deratom.fill(0) + DERatom[0,:] = mu_x[at,:] + DERatom[1,:] = mu_y[at,:] + DERatom[2,:] = mu_z[at,:] + DERatom[:] = np.dot( self.rotation.T , np.dot(DIPDERatom, self.rotation) ) + al_mu_x[at][:] = DERatom[0,:] + al_mu_y[at][:] = DERatom[1,:] + al_mu_z[at][:] = DERatom[2,:] + return (al_mu_x, al_mu_y, al_muz) + def align_system(self, geom, mass, elem, elez, uniq, *, reverse: bool = False): """For AlignmentRecipe `ar`, apply its translation, rotation, and atom map.""" diff --git a/qcelemental/molutil/test_align.py b/qcelemental/molutil/test_align.py index ece1f064..baafddcc 100644 --- a/qcelemental/molutil/test_align.py +++ b/qcelemental/molutil/test_align.py @@ -442,3 +442,95 @@ def test_hessian_align(): p2chess = mill.align_hessian(p4_hooh_hess_native) assert compare_values(c4_hooh_hess, p2chess, atol=1.e-4) + +def test_vector_gradient_align(): + # from Psi4 test test_hessian_vs_cfour[HOOH_TS-H_analytic] + + rmill = """ +---------------------------------------- + AlignmentMill +---------------------------------------- +Mirror: False +Atom Map: [0 1 2 3] +Shift: [0.00000000e+00 0.00000000e+00 1.32217718e-10] +Rotation: +[[ 9.99999870e-01 -5.08999836e-04 -0.00000000e+00] + [ 5.08999836e-04 9.99999870e-01 0.00000000e+00] + [ 0.00000000e+00 -0.00000000e+00 1.00000000e+00]] +---------------------------------------- +""" + + p4_hooh_xyz = """ + units au + H 1.8327917647 -1.5752960165 -0.0000055594 + O 1.3171390326 0.1388012713 0.0000003503 + O -1.3171390326 -0.1388012713 0.0000003503 + H -1.8327917647 1.5752960165 -0.0000055594 + """ + + c4_hooh_xyz = """ + H 1.83198970 -1.57622870 -0.00000556 + O 1.31720951 0.13813083 0.00000035 + O -1.31720951 -0.13813083 0.00000035 + H -1.83198970 1.57622870 -0.00000556 + units au""" + + # From C4 DIPDER file, analytic + c4_hooh_dipder_x = np.array([ + [ 0.2780463810, -0.0627423838, -0.0000001663], + [ 0.2780463810, -0.0627423838, 0.0000001663], + [-0.2780463810, 0.0627423838, 0.0000007872], + [-0.2780463810, 0.0627423838, -0.0000007872]]) + c4_hooh_dipder_y = np.array([ + [-0.0452364698, 0.2701572972, -0.0000004246], + [-0.0452364698, 0.2701572972, 0.0000004246], + [ 0.0452364698, -0.2701572972, 0.0000007936], + [ 0.0452364698, -0.2701572972, -0.0000007936]]) + c4_hooh_dipder_z = np.array([ + [-0.0000001575, -0.0000004725, 0.4019549601], + [ 0.0000001575, 0.0000004725, 0.4019549601], + [-0.0000000523, 0.0000008401, -0.4019549601], + [ 0.0000000523, -0.0000008401, -0.4019549601]]) + + # Generated from fixing orientation/com in psi4. Then using + # a 5-point finite differences of nuclear gradients computed + # with an applied electric field to produce a file17.dat. + p4_hooh_dipdir_x_native = np.array( + [ 0.2781013514, -0.0627383175, -0.0000001660], + [-0.2781013514, 0.0627383175, 0.0000007867], + [-0.2781013514, 0.0627383175, -0.0000007867], + [ 0.2781013514, -0.0627383175, 0.0000001660]]) + p4_hooh_dipdir_y_native = np.array( + [-0.0452324587, 0.2701024305, -0.0000004247], + [ 0.0452324587, -0.2701024305, 0.0000007939], + [ 0.0452324587, -0.2701024305, -0.0000007939], + [-0.0452324587, 0.2701024305, 0.0000004247]]) + p4_hooh_dipdir_z_native = np.array( + [-0.0000001572, -0.0000004726, 0.4019549470], + [-0.0000000527, 0.0000008401, -0.4019549470], + [ 0.0000000527, -0.0000008401, -0.4019549470], + [ 0.0000001572, 0.0000004726, 0.4019549470]]) + + p4mol = qcel.models.Molecule.from_data(p4_hooh_xyz) + c4mol = qcel.models.Molecule.from_data(c4_hooh_xyz) + aqmol, data = p4mol.align(c4mol, atoms_map=True, mols_align=True, verbose=4) + mill = data['mill'] + #assert compare([0, 1, 2, 3], mill.atommap) + #assert compare_values([ + #[ 9.99999870e-01, -5.08999836e-04, -0.00000000e+00], + #[ 5.08999836e-04, 9.99999870e-01, 0.00000000e+00], + #[ 0.00000000e+00, -0.00000000e+00, 1.00000000e+00]], + #mill.rotation, + #atol=1.e-6) + + p2cgeom = mill.align_coordinates(p4mol.geometry) + assert compare_values(c4mol.geometry, p2cgeom, atol=1.e-6) + + # Still need to account for atom renumbering ! + p2c_dipdir_x, p2c_dipdir_y, p2c_dipdir_z = mill.align_vector_gradient( + p4_hooh_dipdir_x_native, p4_hooh_dipdir_y_native, p4_hooh_dipdir_z_native) + + assert compare_values(c4_hooh_dipdir_x, p2c_dipdir_x, atol=1.e-6) + assert compare_values(c4_hooh_dipdir_y, p2c_dipdir_y, atol=1.e-6) + assert compare_values(c4_hooh_dipdir_z, p2c_dipdir_z, atol=1.e-6) + From d2d0f8369de464beb5633fc32727b5ebb0a1fde8 Mon Sep 17 00:00:00 2001 From: Rollin King Date: Wed, 26 Jun 2019 16:22:23 -0400 Subject: [PATCH 3/6] test case works, but atoms numbering in c4 is mysterious. --- qcelemental/models/align.py | 22 ++++++------- qcelemental/molutil/__init__.py | 2 ++ qcelemental/molutil/test_align.py | 52 ++++++++++--------------------- 3 files changed, 30 insertions(+), 46 deletions(-) diff --git a/qcelemental/models/align.py b/qcelemental/models/align.py index 205009b4..6a32f723 100644 --- a/qcelemental/models/align.py +++ b/qcelemental/models/align.py @@ -130,22 +130,22 @@ def align_vector_gradient(self, mu_x, mu_y, mu_z): """Align the nuclear gradients of vector components (e.g. dipole derivatives).""" # Input data is assumed to be organized into separate x, y, z vector components. # Organize derivatives for each atom into 3x3 and transform it. - nat = mu_x.shape[0] // 3 + nat = mu_x.shape[0] al_mu_x = np.zeros( (nat, 3) ) al_mu_y = np.zeros( (nat, 3) ) al_mu_z = np.zeros( (nat, 3) ) - DERatom = np.zeros( (3,3) ) + Datom = np.zeros( (3,3) ) # atom whose nuclear derivatives are taken for at in range(nat): - Deratom.fill(0) - DERatom[0,:] = mu_x[at,:] - DERatom[1,:] = mu_y[at,:] - DERatom[2,:] = mu_z[at,:] - DERatom[:] = np.dot( self.rotation.T , np.dot(DIPDERatom, self.rotation) ) - al_mu_x[at][:] = DERatom[0,:] - al_mu_y[at][:] = DERatom[1,:] - al_mu_z[at][:] = DERatom[2,:] - return (al_mu_x, al_mu_y, al_muz) + Datom.fill(0) + Datom[0,:] = mu_x[at,:] + Datom[1,:] = mu_y[at,:] + Datom[2,:] = mu_z[at,:] + Datom[:] = np.dot( self.rotation.T , np.dot(Datom, self.rotation) ) + al_mu_x[self.atommap[at]][:] = Datom[0,:] + al_mu_y[self.atommap[at]][:] = Datom[1,:] + al_mu_z[self.atommap[at]][:] = Datom[2,:] + return (al_mu_x, al_mu_y, al_mu_z) def align_system(self, geom, mass, elem, elez, uniq, *, reverse: bool = False): """For AlignmentRecipe `ar`, apply its translation, rotation, and atom map.""" diff --git a/qcelemental/molutil/__init__.py b/qcelemental/molutil/__init__.py index 2bdfaa64..42c20586 100644 --- a/qcelemental/molutil/__init__.py +++ b/qcelemental/molutil/__init__.py @@ -1 +1,3 @@ from .align import B787, kabsch_align, compute_scramble +from .test_align import test_hessian_align, test_vector_gradient_align + diff --git a/qcelemental/molutil/test_align.py b/qcelemental/molutil/test_align.py index baafddcc..5fb49e28 100644 --- a/qcelemental/molutil/test_align.py +++ b/qcelemental/molutil/test_align.py @@ -444,22 +444,6 @@ def test_hessian_align(): assert compare_values(c4_hooh_hess, p2chess, atol=1.e-4) def test_vector_gradient_align(): - # from Psi4 test test_hessian_vs_cfour[HOOH_TS-H_analytic] - - rmill = """ ----------------------------------------- - AlignmentMill ----------------------------------------- -Mirror: False -Atom Map: [0 1 2 3] -Shift: [0.00000000e+00 0.00000000e+00 1.32217718e-10] -Rotation: -[[ 9.99999870e-01 -5.08999836e-04 -0.00000000e+00] - [ 5.08999836e-04 9.99999870e-01 0.00000000e+00] - [ 0.00000000e+00 -0.00000000e+00 1.00000000e+00]] ----------------------------------------- -""" - p4_hooh_xyz = """ units au H 1.8327917647 -1.5752960165 -0.0000055594 @@ -469,10 +453,14 @@ def test_vector_gradient_align(): """ c4_hooh_xyz = """ + # H 1.83198970 -1.57622870 -0.00000556 + # O 1.31720951 0.13813083 0.00000035 + # O -1.31720951 -0.13813083 0.00000035 + # H -1.83198970 1.57622870 -0.00000556 H 1.83198970 -1.57622870 -0.00000556 - O 1.31720951 0.13813083 0.00000035 - O -1.31720951 -0.13813083 0.00000035 H -1.83198970 1.57622870 -0.00000556 + O -1.31720951 -0.13813083 0.00000035 + O 1.31720951 0.13813083 0.00000035 units au""" # From C4 DIPDER file, analytic @@ -495,17 +483,17 @@ def test_vector_gradient_align(): # Generated from fixing orientation/com in psi4. Then using # a 5-point finite differences of nuclear gradients computed # with an applied electric field to produce a file17.dat. - p4_hooh_dipdir_x_native = np.array( + p4_hooh_dipder_x = np.array([ [ 0.2781013514, -0.0627383175, -0.0000001660], [-0.2781013514, 0.0627383175, 0.0000007867], [-0.2781013514, 0.0627383175, -0.0000007867], [ 0.2781013514, -0.0627383175, 0.0000001660]]) - p4_hooh_dipdir_y_native = np.array( + p4_hooh_dipder_y = np.array([ [-0.0452324587, 0.2701024305, -0.0000004247], [ 0.0452324587, -0.2701024305, 0.0000007939], [ 0.0452324587, -0.2701024305, -0.0000007939], [-0.0452324587, 0.2701024305, 0.0000004247]]) - p4_hooh_dipdir_z_native = np.array( + p4_hooh_dipder_z = np.array([ [-0.0000001572, -0.0000004726, 0.4019549470], [-0.0000000527, 0.0000008401, -0.4019549470], [ 0.0000000527, -0.0000008401, -0.4019549470], @@ -513,24 +501,18 @@ def test_vector_gradient_align(): p4mol = qcel.models.Molecule.from_data(p4_hooh_xyz) c4mol = qcel.models.Molecule.from_data(c4_hooh_xyz) - aqmol, data = p4mol.align(c4mol, atoms_map=True, mols_align=True, verbose=4) + aqmol, data = p4mol.align(c4mol, atoms_map=False, mols_align=True, verbose=4) mill = data['mill'] - #assert compare([0, 1, 2, 3], mill.atommap) - #assert compare_values([ - #[ 9.99999870e-01, -5.08999836e-04, -0.00000000e+00], - #[ 5.08999836e-04, 9.99999870e-01, 0.00000000e+00], - #[ 0.00000000e+00, -0.00000000e+00, 1.00000000e+00]], - #mill.rotation, - #atol=1.e-6) + + assert compare([0, 3, 2, 1], mill.atommap) p2cgeom = mill.align_coordinates(p4mol.geometry) assert compare_values(c4mol.geometry, p2cgeom, atol=1.e-6) - # Still need to account for atom renumbering ! - p2c_dipdir_x, p2c_dipdir_y, p2c_dipdir_z = mill.align_vector_gradient( - p4_hooh_dipdir_x_native, p4_hooh_dipdir_y_native, p4_hooh_dipdir_z_native) + p2c_dipder_x, p2c_dipder_y, p2c_dipder_z = mill.align_vector_gradient( + p4_hooh_dipder_x, p4_hooh_dipder_y, p4_hooh_dipder_z) - assert compare_values(c4_hooh_dipdir_x, p2c_dipdir_x, atol=1.e-6) - assert compare_values(c4_hooh_dipdir_y, p2c_dipdir_y, atol=1.e-6) - assert compare_values(c4_hooh_dipdir_z, p2c_dipdir_z, atol=1.e-6) + assert compare_values(c4_hooh_dipder_x, p2c_dipder_x, atol=1.e-5) + assert compare_values(c4_hooh_dipder_y, p2c_dipder_y, atol=1.e-5) + assert compare_values(c4_hooh_dipder_z, p2c_dipder_z, atol=1.e-5) From 03848aaaa4edf7465836140817214570d2e3ec8b Mon Sep 17 00:00:00 2001 From: Rollin King Date: Thu, 27 Jun 2019 14:29:31 -0400 Subject: [PATCH 4/6] Reorder atoms correctly. Use GRD geometry and note that. --- qcelemental/models/align.py | 12 ++++++------ qcelemental/molutil/test_align.py | 20 ++++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/qcelemental/models/align.py b/qcelemental/models/align.py index 6a32f723..82003b8a 100644 --- a/qcelemental/models/align.py +++ b/qcelemental/models/align.py @@ -138,13 +138,13 @@ def align_vector_gradient(self, mu_x, mu_y, mu_z): Datom = np.zeros( (3,3) ) # atom whose nuclear derivatives are taken for at in range(nat): Datom.fill(0) - Datom[0,:] = mu_x[at,:] - Datom[1,:] = mu_y[at,:] - Datom[2,:] = mu_z[at,:] + Datom[0,:] = mu_x[self.atommap[at],:] + Datom[1,:] = mu_y[self.atommap[at],:] + Datom[2,:] = mu_z[self.atommap[at],:] Datom[:] = np.dot( self.rotation.T , np.dot(Datom, self.rotation) ) - al_mu_x[self.atommap[at]][:] = Datom[0,:] - al_mu_y[self.atommap[at]][:] = Datom[1,:] - al_mu_z[self.atommap[at]][:] = Datom[2,:] + al_mu_x[at][:] = Datom[0,:] + al_mu_y[at][:] = Datom[1,:] + al_mu_z[at][:] = Datom[2,:] return (al_mu_x, al_mu_y, al_mu_z) def align_system(self, geom, mass, elem, elez, uniq, *, reverse: bool = False): diff --git a/qcelemental/molutil/test_align.py b/qcelemental/molutil/test_align.py index 5fb49e28..76df4d7c 100644 --- a/qcelemental/molutil/test_align.py +++ b/qcelemental/molutil/test_align.py @@ -443,7 +443,9 @@ def test_hessian_align(): p2chess = mill.align_hessian(p4_hooh_hess_native) assert compare_values(c4_hooh_hess, p2chess, atol=1.e-4) +@using_networkx def test_vector_gradient_align(): + # HOOH TS (optimized to be very nearly planar) p4_hooh_xyz = """ units au H 1.8327917647 -1.5752960165 -0.0000055594 @@ -452,16 +454,14 @@ def test_vector_gradient_align(): H -1.8327917647 1.5752960165 -0.0000055594 """ + # from C4 GRD file, produced by p4_hooh_xyz in ZMAT c4_hooh_xyz = """ - # H 1.83198970 -1.57622870 -0.00000556 - # O 1.31720951 0.13813083 0.00000035 - # O -1.31720951 -0.13813083 0.00000035 - # H -1.83198970 1.57622870 -0.00000556 - H 1.83198970 -1.57622870 -0.00000556 - H -1.83198970 1.57622870 -0.00000556 - O -1.31720951 -0.13813083 0.00000035 - O 1.31720951 0.13813083 0.00000035 - units au""" + units au + H 1.8319897007 -1.5762287045 -0.0000055594 + H -1.8319897007 1.5762287045 -0.0000055594 + O 1.3172095119 0.1381308288 0.0000003503 + O -1.3172095119 -0.1381308288 0.0000003503 + """ # From C4 DIPDER file, analytic c4_hooh_dipder_x = np.array([ @@ -504,7 +504,7 @@ def test_vector_gradient_align(): aqmol, data = p4mol.align(c4mol, atoms_map=False, mols_align=True, verbose=4) mill = data['mill'] - assert compare([0, 3, 2, 1], mill.atommap) + assert compare([0, 3, 1, 2], mill.atommap) p2cgeom = mill.align_coordinates(p4mol.geometry) assert compare_values(c4mol.geometry, p2cgeom, atol=1.e-6) From d4fbedeaa4394633518902e4393693e0433b1324 Mon Sep 17 00:00:00 2001 From: Rollin King Date: Fri, 19 Jul 2019 11:33:24 -0400 Subject: [PATCH 5/6] changed arguments in and out to be organized by (3, 3*Natom) --- qcelemental/models/align.py | 25 +++++++-------- qcelemental/molutil/test_align.py | 53 ++++++++++++++++--------------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/qcelemental/models/align.py b/qcelemental/models/align.py index 82003b8a..f4fb4326 100644 --- a/qcelemental/models/align.py +++ b/qcelemental/models/align.py @@ -126,26 +126,25 @@ def align_hessian(self, hess) -> NDArray: alhess = blockwise_contract(alhess) return alhess - def align_vector_gradient(self, mu_x, mu_y, mu_z): + def align_vector_gradient(self, mu_derivatives): """Align the nuclear gradients of vector components (e.g. dipole derivatives).""" - # Input data is assumed to be organized into separate x, y, z vector components. + # Input data is assumed to be organized into outermost x, y, z vector components. # Organize derivatives for each atom into 3x3 and transform it. - nat = mu_x.shape[0] - al_mu_x = np.zeros( (nat, 3) ) - al_mu_y = np.zeros( (nat, 3) ) - al_mu_z = np.zeros( (nat, 3) ) + mu_x, mu_y, mu_z = mu_derivatives + nat = mu_x.shape[0] // 3 + al_mu = np.zeros( (3,3*nat) ) Datom = np.zeros( (3,3) ) # atom whose nuclear derivatives are taken for at in range(nat): Datom.fill(0) - Datom[0,:] = mu_x[self.atommap[at],:] - Datom[1,:] = mu_y[self.atommap[at],:] - Datom[2,:] = mu_z[self.atommap[at],:] + Datom[0,:] = mu_x[3*self.atommap[at]:3*self.atommap[at]+3] + Datom[1,:] = mu_y[3*self.atommap[at]:3*self.atommap[at]+3] + Datom[2,:] = mu_z[3*self.atommap[at]:3*self.atommap[at]+3] Datom[:] = np.dot( self.rotation.T , np.dot(Datom, self.rotation) ) - al_mu_x[at][:] = Datom[0,:] - al_mu_y[at][:] = Datom[1,:] - al_mu_z[at][:] = Datom[2,:] - return (al_mu_x, al_mu_y, al_mu_z) + al_mu[0, 3*at : 3*at+3] = Datom[0,:] + al_mu[1, 3*at : 3*at+3] = Datom[1,:] + al_mu[2, 3*at : 3*at+3] = Datom[2,:] + return al_mu def align_system(self, geom, mass, elem, elez, uniq, *, reverse: bool = False): """For AlignmentRecipe `ar`, apply its translation, rotation, and atom map.""" diff --git a/qcelemental/molutil/test_align.py b/qcelemental/molutil/test_align.py index 76df4d7c..708975ce 100644 --- a/qcelemental/molutil/test_align.py +++ b/qcelemental/molutil/test_align.py @@ -465,39 +465,41 @@ def test_vector_gradient_align(): # From C4 DIPDER file, analytic c4_hooh_dipder_x = np.array([ - [ 0.2780463810, -0.0627423838, -0.0000001663], - [ 0.2780463810, -0.0627423838, 0.0000001663], - [-0.2780463810, 0.0627423838, 0.0000007872], - [-0.2780463810, 0.0627423838, -0.0000007872]]) + 0.2780463810, -0.0627423838, -0.0000001663, + 0.2780463810, -0.0627423838, 0.0000001663, + -0.2780463810, 0.0627423838, 0.0000007872, + -0.2780463810, 0.0627423838, -0.0000007872]) c4_hooh_dipder_y = np.array([ - [-0.0452364698, 0.2701572972, -0.0000004246], - [-0.0452364698, 0.2701572972, 0.0000004246], - [ 0.0452364698, -0.2701572972, 0.0000007936], - [ 0.0452364698, -0.2701572972, -0.0000007936]]) + -0.0452364698, 0.2701572972, -0.0000004246, + -0.0452364698, 0.2701572972, 0.0000004246, + 0.0452364698, -0.2701572972, 0.0000007936, + 0.0452364698, -0.2701572972, -0.0000007936]) c4_hooh_dipder_z = np.array([ - [-0.0000001575, -0.0000004725, 0.4019549601], - [ 0.0000001575, 0.0000004725, 0.4019549601], - [-0.0000000523, 0.0000008401, -0.4019549601], - [ 0.0000000523, -0.0000008401, -0.4019549601]]) + -0.0000001575, -0.0000004725, 0.4019549601, + 0.0000001575, 0.0000004725, 0.4019549601, + -0.0000000523, 0.0000008401, -0.4019549601, + 0.0000000523, -0.0000008401, -0.4019549601]) # Generated from fixing orientation/com in psi4. Then using # a 5-point finite differences of nuclear gradients computed # with an applied electric field to produce a file17.dat. p4_hooh_dipder_x = np.array([ - [ 0.2781013514, -0.0627383175, -0.0000001660], - [-0.2781013514, 0.0627383175, 0.0000007867], - [-0.2781013514, 0.0627383175, -0.0000007867], - [ 0.2781013514, -0.0627383175, 0.0000001660]]) + 0.2781013514, -0.0627383175, -0.0000001660, + -0.2781013514, 0.0627383175, 0.0000007867, + -0.2781013514, 0.0627383175, -0.0000007867, + 0.2781013514, -0.0627383175, 0.0000001660]) p4_hooh_dipder_y = np.array([ - [-0.0452324587, 0.2701024305, -0.0000004247], - [ 0.0452324587, -0.2701024305, 0.0000007939], - [ 0.0452324587, -0.2701024305, -0.0000007939], - [-0.0452324587, 0.2701024305, 0.0000004247]]) + -0.0452324587, 0.2701024305, -0.0000004247, + 0.0452324587, -0.2701024305, 0.0000007939, + 0.0452324587, -0.2701024305, -0.0000007939, + -0.0452324587, 0.2701024305, 0.0000004247]) p4_hooh_dipder_z = np.array([ - [-0.0000001572, -0.0000004726, 0.4019549470], - [-0.0000000527, 0.0000008401, -0.4019549470], - [ 0.0000000527, -0.0000008401, -0.4019549470], - [ 0.0000001572, 0.0000004726, 0.4019549470]]) + -0.0000001572, -0.0000004726, 0.4019549470, + -0.0000000527, 0.0000008401, -0.4019549470, + 0.0000000527, -0.0000008401, -0.4019549470, + 0.0000001572, 0.0000004726, 0.4019549470]) + p4_hooh_dipder = np.concatenate((p4_hooh_dipder_x, p4_hooh_dipder_y, + p4_hooh_dipder_z)).reshape(3,-1) p4mol = qcel.models.Molecule.from_data(p4_hooh_xyz) c4mol = qcel.models.Molecule.from_data(c4_hooh_xyz) @@ -509,8 +511,7 @@ def test_vector_gradient_align(): p2cgeom = mill.align_coordinates(p4mol.geometry) assert compare_values(c4mol.geometry, p2cgeom, atol=1.e-6) - p2c_dipder_x, p2c_dipder_y, p2c_dipder_z = mill.align_vector_gradient( - p4_hooh_dipder_x, p4_hooh_dipder_y, p4_hooh_dipder_z) + p2c_dipder_x, p2c_dipder_y, p2c_dipder_z = mill.align_vector_gradient(p4_hooh_dipder) assert compare_values(c4_hooh_dipder_x, p2c_dipder_x, atol=1.e-5) assert compare_values(c4_hooh_dipder_y, p2c_dipder_y, atol=1.e-5) From 212aab754df4a5dcafc506544275ba3c84b06205 Mon Sep 17 00:00:00 2001 From: Rollin King Date: Fri, 19 Jul 2019 17:11:55 -0400 Subject: [PATCH 6/6] remove tests from module proper --- qcelemental/molutil/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/qcelemental/molutil/__init__.py b/qcelemental/molutil/__init__.py index 42c20586..6a16a0f6 100644 --- a/qcelemental/molutil/__init__.py +++ b/qcelemental/molutil/__init__.py @@ -1,3 +1,2 @@ from .align import B787, kabsch_align, compute_scramble -from .test_align import test_hessian_align, test_vector_gradient_align