From ddeb0cd31d8bbb46da400ea267e90752c7196c8f Mon Sep 17 00:00:00 2001
From: "Kurt A. O'Hearn" <ohearnk@msu.edu>
Date: Thu, 22 Mar 2018 18:51:58 -0400
Subject: [PATCH] Tools: draft basic SQLite functionality for Python driver.

---
 tools/driver.py | 197 ++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 191 insertions(+), 6 deletions(-)

diff --git a/tools/driver.py b/tools/driver.py
index 59a8c4a8..93163dea 100644
--- a/tools/driver.py
+++ b/tools/driver.py
@@ -1,6 +1,9 @@
 #!/bin/python3
 
-from ctypes import *
+from ctypes import c_int, c_double, c_char, c_char_p, c_void_p, \
+        Structure, Union, POINTER, CFUNCTYPE, cdll
+import sqlite3 as sq3
+from os import path
 
 
 class BondOrderData(Structure):
@@ -220,7 +223,6 @@ class SimulationData(Structure):
             ("ext_press", c_double * 3),
             ("kin_press", c_double),
             ("tot_press", c_double * 3),
-            ("tot_press", c_double * 3),
             ("timing", ReaxTiming),
             ]
 
@@ -236,6 +238,141 @@ class ReaxAtom(Structure):
             ]
 
 
+def create_db(name='spuremd.db'):
+    conn = sq3.connect(name)
+
+    conn.executescript("""
+        CREATE TABLE simulation(
+            id integer,
+            date text,
+            name text,
+            ensemble_type integer,
+            steps integer,
+            time_step integer,
+            restart_format integer,
+            random_velocity integer,
+            reposition_atoms integer,
+            peroidic_boundary integer,
+            geo_format integer,
+            restrict_bonds integer,
+            tabulate_long_range integer,
+            reneighbor integer,
+            vlist_cutoff real,
+            neighbor_cutoff real,
+            three_body_cutoff real,
+            hydrogen_bond_cutoff real,
+            bond_graph_cutoff real,
+            charge_method integer,
+            cm_q_net real,
+            cm_solver_type integer,
+            cm_solver_max_iters integer,
+            cm_solver_restart integer,
+            cm_solver_q_err real,
+            cm_domain_sparsity real,
+            cm_solver_pre_comp_type integer,
+            cm_solver_pre_comp_refactor integer,
+            cm_solver_pre_comp_droptol real,
+            cm_solver_pre_comp_sweeps integer,
+            cm_solver_pre_comp_sai_thres real,
+            cm_solver_pre_app_type integer,
+            cm_solver_pre_app_jacobi_iters integer,
+            temp_init real,
+            temp_final real,
+            temp_mass real,
+            temp_mode integer,
+            temp_rate real,
+            temp_freq integer,
+            pressure real,
+            pressure_mass real,
+            compress integer,
+            pressure_mode integer,
+            remove_center_of_mass integer,
+            debug_level integer,
+            write_freq integer,
+            traj_compress integer,
+            traj_format integer,
+            traj_title text,
+            atom_info integer,
+            atom_velocities integer,
+            atom_forces integer,
+            bond_info integer,
+            angle_info integer,
+            test_forces integer,
+            molecule_analysis integer,
+            freq_molecule_analysis integer,
+            ignore integer,
+            dipole_analysis integer,
+            freq_dipole_analysis integer,
+            diffusion_coefficient integer,
+            freq_diffusion_coefficient integer,
+            restrict_type integer,
+            PRIMARY KEY (id)
+        );
+
+        CREATE TABLE system_properties(
+            id integer,
+            step integer,
+            total_energy real,
+            potential_energy real,
+            kinetic_energy real,
+            temperature real,
+            volume real,
+            pressure real,
+            PRIMARY KEY (id, step)
+        );
+
+        CREATE TABLE potential(
+            id integer,
+            step integer,
+            bond_energy real,
+            atom_energy real,
+            lone_pair_energy real,
+            angle_energy real,
+            coa_energy real,
+            hydrogen_bond_energy real,
+            torsion_energy real,
+            conjugation_energy real,
+            van_der_waals_energy real,
+            coulombic_energy real,
+            polarization_energy real,
+            PRIMARY KEY (id, step)
+        );
+
+        CREATE TABLE trajectory(
+            id integer,
+            step integer,
+            atom_id integer,
+            position_x real,
+            position_y real,
+            position_z real,
+            charge real,
+            PRIMARY KEY (id, step, atom_id)
+        );
+
+        CREATE TABLE performance(
+            id integer,
+            step integer,
+            time_total real,
+            time_nbrs real,
+            time_init real,
+            time_bonded real,
+            time_nonbonded real,
+            time_cm real,
+            time_cm_sort real,
+            cm_solver_iters integer,
+            time_cm_pre_comp real,
+            time_cm_pre_app real,
+            time_cm_solver_spmv real,
+            time_cm_solver_vec_ops real,
+            time_cm_solver_orthog real,
+            time_cm_solver_tri_solve real,
+            PRIMARY KEY (id, step)
+        );
+    """)
+
+    conn.close()
+
+
 if __name__ == '__main__':
     lib = cdll.LoadLibrary("libspuremd.so.1")
 
@@ -258,10 +395,6 @@ if __name__ == '__main__':
     CALLBACKFUNC = CFUNCTYPE(None, POINTER(ReaxAtom),
             POINTER(SimulationData), POINTER(ReaxList))
 
-    def get_simulation_step_results(atoms, data, lists):
-        print("{0:24.15f} {1:24.15f} {2:24.15f}".format(
-            data[0].E_Tot, data[0].E_Kin, data[0].E_Pot))
-
     setup_callback = lib.setup_callback
     setup_callback.restype = c_int
 
@@ -269,6 +402,57 @@ if __name__ == '__main__':
     set_output_enabled.argtypes = [c_void_p, c_int]
     set_output_enabled.restype = c_int
 
+    db_file = "spuremd.db"
+
+    if not path.isfile(db_file):
+        create_db(db_file)
+
+    conn = sq3.connect(db_file)
+    record_potential = True
+    record_trajectory = False
+    record_performance = True
+
+    def get_simulation_step_results(atoms, data, lists):
+        print("{0:24.15f} {1:24.15f} {2:24.15f}".format(
+            data[0].E_Tot, data[0].E_Kin, data[0].E_Pot))
+
+        if data[0].step == 0:
+            #TODO: insert data into simulation table
+            pass
+
+        with conn:
+            conn.execute("INSERT INTO system_properties VALUES (?,?,?,?,?,?,?,?)",
+                    (0, data[0].step, data[0].E_Tot, data[0].E_Pot, data[0].E_Kin,
+                        data[0].therm.T, 0.0, data[0].iso_bar.P))
+            # MISSING: ID, system->box.volume
+
+        if record_potential:
+            with conn:
+                conn.execute("INSERT INTO potential VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)",
+                        (0, data[0].step, data[0].E_BE, data[0].E_Ov + data[0].E_Un,
+                            data[0].E_Lp, data[0].E_Ang + data[0].E_Pen, data[0].E_Coa,
+                            data[0].E_HB, data[0].E_Tor, data[0].E_Con, data[0].E_vdW,
+                            data[0].E_Ele, data[0].E_Pol))
+
+        if record_trajectory:
+            with conn:
+                for i in range(6540):
+                    conn.execute("INSERT INTO trajectory VALUES (?,?,?,?,?,?,?)",
+                            (0, data[0].step, i, atoms[i].x[0], atoms[i].x[1],
+                                atoms[i].x[2], atoms[i].q))
+
+        if record_performance:
+            with conn:
+                conn.execute("INSERT INTO performance VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
+                        (0, data[0].step, data[0].timing.total, data[0].timing.nbrs, data[0].timing.init_forces,
+                            data[0].timing.bonded, data[0].timing.nonb, data[0].timing.cm,
+                            data[0].timing.cm_sort_mat_rows, data[0].timing.cm_solver_iters,
+                            data[0].timing.cm_solver_pre_comp,
+                            data[0].timing.cm_solver_pre_app, data[0].timing.cm_solver_spmv,
+                            data[0].timing.cm_solver_vector_ops, data[0].timing.cm_solver_orthog,
+                            data[0].timing.cm_solver_tri_solve))
+
+
     handle = setup(b"data/benchmarks/water/water_6540.pdb",
             b"data/benchmarks/water/ffield.water",
             b"environ/param.gpu.water")
@@ -288,4 +472,5 @@ if __name__ == '__main__':
         print("{0:9d} {1:24.15f} {2:24.15f} {3:24.15f} {4:24.15f}".format(
             i + 1, atoms[i].x[0], atoms[i].x[1], atoms[i].x[2], atoms[i].q))
 
+    conn.close()
     cleanup(handle)
-- 
GitLab