{"action":"created","comment":{"url":"https://api.github.com/repos/psi4/psi4/pulls/comments/203921398","pull_request_review_id":138907528,"id":203921398,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIwMzkyMTM5OA==","diff_hunk":"@@ -0,0 +1,766 @@\n+#\n+# @BEGIN LICENSE\n+#\n+# Psi4: an open-source quantum chemistry software package\n+#\n+# Copyright (c) 2007-2018 The Psi4 Developers.\n+#\n+# The copyrights for code used from other parties are included in\n+# the corresponding files.\n+#\n+# This file is part of Psi4.\n+#\n+# Psi4 is free software; you can redistribute it and/or modify\n+# it under the terms of the GNU Lesser General Public License as published by\n+# the Free Software Foundation, version 3.\n+#\n+# Psi4 is distributed in the hope that it will be useful,\n+# but WITHOUT ANY WARRANTY; without even the implied warranty of\n+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+# GNU Lesser General Public License for more details.\n+#\n+# You should have received a copy of the GNU Lesser General Public License along\n+# with Psi4; if not, write to the Free Software Foundation, Inc.,\n+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n+#\n+# @END LICENSE\n+#\n+\n+\"\"\"\n+The SCF iteration functions\n+\"\"\"\n+\n+import numpy as np\n+\n+from psi4.driver import p4util\n+from psi4.driver import constants\n+from psi4.driver.p4util.exceptions import ConvergenceError, ValidationError\n+from psi4 import core\n+\n+from .efp import get_qm_atoms_opts, modify_Fock_permanent, modify_Fock_induced\n+\n+#import logging\n+#logger = logging.getLogger(\"scf.scf_iterator\")\n+#logger.setLevel(logging.DEBUG)\n+\n+# Q: I expect more local settings of options for part of SCF.\n+#    For convcrit, do we want:\n+#   (A) easy to grep\n+#    with p4util.OptionsStateCM(['SCF', 'E_CONVERGENCE'], ['SCF', 'D_CONVERGENCE']):\n+#        core.set_local_option('SCF', 'E_CONVERGENCE', 1.e-5)\n+#        core.set_local_option('SCF', 'D_CONVERGENCE', 1.e-4)\n+#        self.iterations()\n+#\n+#   or (B) functional. options never touched\n+#    self.iterations(e_conv=1.e-5, d_conv=1.e-4)\n+\n+\n+def scf_compute_energy(self):\n+    \"\"\"Base class Wavefunction requires this function. Here it is\n+    simply a wrapper around initialize(), iterations(), finalize_energy(). It\n+    returns the SCF energy computed by finalize_energy().\n+\n+    \"\"\"\n+    if core.get_option('SCF', 'DF_SCF_GUESS') and (core.get_global_option('SCF_TYPE') == 'DIRECT'):\n+        # speed up DIRECT algorithm (recomputes full (non-DF) integrals\n+        #   each iter) by first converging via fast DF iterations, then\n+        #   fully converging in fewer slow DIRECT iterations. aka Andy trick 2.0\n+        core.print_out(\"  Starting with a DF guess...\\n\\n\")\n+        with p4util.OptionsStateCM(['SCF_TYPE']):\n+            core.set_global_option('SCF_TYPE', 'DF')\n+            self.initialize()\n+            try:\n+                self.iterations()\n+            except ConvergenceError:\n+                raise ConvergenceError(\"\"\"SCF DF preiterations\"\"\", self.iteration_)\n+        core.print_out(\"\\n  DF guess converged.\\n\\n\")\n+\n+        # reset the DIIS & JK objects in prep for DIRECT\n+        if self.initialized_diis_manager_:\n+            self.diis_manager().reset_subspace()\n+        self.integrals()\n+    else:\n+        self.initialize()\n+\n+    try:\n+        self.iterations()\n+    except ConvergenceError as e:\n+        if core.get_option(\"SCF\", \"FAIL_ON_MAXITER\"):\n+            core.print_out(\"  Failed to converge.\\n\")\n+            # energy = 0.0\n+            # A P::e fn to either throw or protest upon nonconvergence\n+            # die_if_not_converged()\n+            raise e\n+        else:\n+            core.print_out(\"  Energy did not converge, but proceeding anyway.\\n\\n\")\n+    else:\n+        core.print_out(\"  Energy converged.\\n\\n\")\n+\n+    scf_energy = self.finalize_energy()\n+    return scf_energy\n+\n+\n+def scf_initialize(self):\n+    \"\"\"Specialized initialization, compute integrals and does everything to prepare for iterations\"\"\"\n+\n+    self.iteration_ = 0\n+    efp_enabled = hasattr(self.molecule(), 'EFP')\n+\n+    if core.get_option('SCF', \"PRINT\") > 0:\n+        core.print_out(\"  ==> Pre-Iterations <==\\n\\n\")\n+        self.print_preiterations()\n+\n+    if efp_enabled:\n+        # EFP: Set QM system, options, and callback. Display efp geom in [A]\n+        efpobj = self.molecule().EFP\n+        core.print_out(efpobj.banner())\n+        core.print_out(efpobj.geometry_summary(units_to_bohr=constants.bohr2angstroms))\n+\n+        efpptc, efpcoords, efpopts = get_qm_atoms_opts(self.molecule())\n+        efpobj.set_point_charges(efpptc, efpcoords)\n+        efpobj.set_opts(efpopts, label='psi', append='psi')\n+\n+        efpobj.set_electron_density_field_fn(field_fn)\n+\n+    if self.attempt_number_ == 1:\n+        mints = core.MintsHelper(self.basisset())\n+        if core.get_global_option('RELATIVISTIC') in ['X2C', 'DKH']:\n+            mints.set_rel_basisset(self.get_basisset('BASIS_RELATIVISTIC'))\n+\n+        mints.one_electron_integrals()\n+        self.integrals()\n+\n+        core.timer_on(\"HF: Form core H\")\n+        self.form_H()\n+        core.timer_off(\"HF: Form core H\")\n+\n+        if efp_enabled:\n+            # EFP: Add in permanent moment contribution and cache\n+            core.timer_on(\"HF: Form Vefp\")\n+            verbose = core.get_option('SCF', \"PRINT\")\n+            Vefp = modify_Fock_permanent(self.molecule(), mints, verbose=verbose-1)\n+            Vefp = core.Matrix.from_array(Vefp)\n+            self.H().add(Vefp)\n+            Horig = self.H().clone()\n+            self.Horig = Horig\n+            core.print_out(\"  QM/EFP: iterating Total Energy including QM/EFP Induction\\n\")\n+            core.timer_off(\"HF: Form Vefp\")\n+\n+        core.timer_on(\"HF: Form S/X\")\n+        self.form_Shalf()\n+        core.timer_off(\"HF: Form S/X\")\n+\n+        core.timer_on(\"HF: Guess\")\n+        self.guess()\n+        core.timer_off(\"HF: Guess\")\n+\n+    else:\n+        # We're reading the orbitals from the previous set of iterations.\n+        self.form_D()\n+        self.set_energies(\"Total Energy\", self.compute_initial_E())\n+\n+\n+\n+def scf_iterate(self, e_conv=None, d_conv=None):\n+\n+    is_dfjk = core.get_global_option('SCF_TYPE').endswith('DF')\n+    verbose = core.get_option('SCF', \"PRINT\")\n+    reference = core.get_option('SCF', \"REFERENCE\")\n+\n+    # self.member_data_ signals are non-local, used internally by c-side fns\n+    self.diis_enabled_ = _validate_diis()\n+    self.MOM_excited_ = _validate_MOM()\n+    self.diis_start_ = core.get_option('SCF', 'DIIS_START')\n+    damping_enabled = _validate_damping()\n+    soscf_enabled = _validate_soscf()\n+    frac_enabled = _validate_frac()\n+    efp_enabled = hasattr(self.molecule(), 'EFP')\n+\n+    if self.iteration_ < 2:\n+        core.print_out(\"  ==> Iterations <==\\n\\n\")\n+        core.print_out(\"%s                        Total Energy        Delta E     RMS |[F,P]|\\n\\n\" % (\"   \"\n+                                                                                                      if is_dfjk else \"\"))\n+\n+    # SCF iterations!\n+    SCFE_old = 0.0\n+    SCFE = 0.0\n+    Drms = 0.0\n+    while True:\n+        self.iteration_ += 1\n+\n+        diis_performed = False\n+        soscf_performed = False\n+        self.frac_performed_ = False\n+        #self.MOM_performed_ = False  # redundant from common_init()\n+\n+        self.save_density_and_energy()\n+\n+        if efp_enabled:\n+            # EFP: Add efp contribution to Fock matrix\n+            self.H().copy(self.Horig)\n+            global mints\n+            mints = core.MintsHelper(self.basisset())\n+            Vefp = modify_Fock_induced(self.molecule().EFP, mints, verbose=verbose-1)\n+            Vefp = core.Matrix.from_array(Vefp)\n+            self.H().add(Vefp)\n+\n+        SCFE = 0.0\n+        self.clear_external_potentials()\n+\n+        core.timer_on(\"HF: Form G\")\n+        self.form_G()\n+        core.timer_off(\"HF: Form G\")\n+\n+        # reset fractional SAD occupation\n+        if (self.iteration_ == 0) and self.reset_occ_:\n+            self.reset_occupation()\n+\n+        upcm = 0.0\n+        if core.get_option('SCF', 'PCM'):\n+            calc_type = core.PCM.CalcType.Total\n+            if core.get_option(\"PCM\", \"PCM_SCF_TYPE\") == \"SEPARATE\":\n+                calc_type = core.PCM.CalcType.NucAndEle\n+            Dt = self.Da().clone()\n+            Dt.add(self.Db())\n+            upcm, Vpcm = self.get_PCM().compute_PCM_terms(Dt, calc_type)\n+            SCFE += upcm\n+            self.push_back_external_potential(Vpcm)\n+        self.set_variable(\"PCM POLARIZATION ENERGY\", upcm)\n+        self.set_energies(\"PCM Polarization\", upcm)\n+\n+        core.timer_on(\"HF: Form F\")\n+        self.form_F()\n+        core.timer_off(\"HF: Form F\")\n+\n+        if verbose > 3:\n+            self.Fa().print_out()\n+            self.Fb().print_out()\n+\n+        SCFE += self.compute_E()\n+        if efp_enabled:\n+            global efp_Dt\n+\n+            # EFP: Add efp contribution to energy\n+            efp_Dt = self.Da().clone()\n+            efp_Dt.add(self.Db())\n+            efp_wfn_dependent_energy = self.molecule().EFP.get_wavefunction_dependent_energy()\n+            SCFE += efp_wfn_dependent_energy\n+\n+        self.set_energies(\"Total Energy\", SCFE)\n+        Ediff = SCFE - SCFE_old\n+        SCFE_old = SCFE\n+\n+        status = []\n+\n+        # We either do SOSCF or DIIS\n+        if (soscf_enabled and (self.iteration_ > 3) and (Drms < core.get_option('SCF', 'SOSCF_START_CONVERGENCE'))):\n+\n+            Drms = self.compute_orbital_gradient(False, core.get_option('SCF', 'DIIS_MAX_VECS'))\n+            diis_performed = False\n+            if self.functional().needs_xc():\n+                base_name = \"SOKS, nmicro=\"\n+            else:\n+                base_name = \"SOSCF, nmicro=\"\n+\n+            if not _converged(Ediff, Drms, e_conv=e_conv, d_conv=d_conv):\n+                nmicro = self.soscf_update(\n+                    core.get_option('SCF', 'SOSCF_CONV'),\n+                    core.get_option('SCF', 'SOSCF_MIN_ITER'),\n+                    core.get_option('SCF', 'SOSCF_MAX_ITER'), core.get_option('SCF', 'SOSCF_PRINT'))\n+                if nmicro > 0:\n+                    # if zero, the soscf call bounced for some reason\n+                    self.find_occupation()\n+                    status.append(base_name + str(nmicro))\n+                    soscf_performed = True  # Stops DIIS\n+                else:\n+                    if verbose > 0:\n+                        core.print_out(\"Did not take a SOSCF step, using normal convergence methods\\n\")\n+                    soscf_performed = False  # Back to DIIS\n+\n+            else:\n+                # need to ensure orthogonal orbitals and set epsilon\n+                status.append(base_name + \"conv\")\n+                core.timer_on(\"HF: Form C\")\n+                self.form_C()\n+                core.timer_off(\"HF: Form C\")\n+                soscf_performed = True  # Stops DIIS\n+\n+        if not soscf_performed:\n+            # Normal convergence procedures if we do not do SOSCF\n+\n+            core.timer_on(\"HF: DIIS\")\n+            diis_performed = False\n+            add_to_diis_subspace = False\n+\n+            if self.diis_enabled_ and self.iteration_ >= self.diis_start_:\n+                add_to_diis_subspace = True\n+\n+            Drms = self.compute_orbital_gradient(add_to_diis_subspace, core.get_option('SCF', 'DIIS_MAX_VECS'))\n+\n+            if (self.diis_enabled_\n+                    and self.iteration_ >= self.diis_start_ + core.get_option('SCF', 'DIIS_MIN_VECS') - 1):\n+                diis_performed = self.diis()\n+\n+            if diis_performed:\n+                status.append(\"DIIS\")\n+\n+            core.timer_off(\"HF: DIIS\")\n+\n+            if verbose > 4 and diis_performed:\n+                core.print_out(\"  After DIIS:\\n\")\n+                self.Fa().print_out()\n+                self.Fb().print_out()\n+\n+            # frac, MOM invoked here from Wfn::HF::find_occupation\n+            core.timer_on(\"HF: Form C\")\n+            self.form_C()\n+            core.timer_off(\"HF: Form C\")\n+\n+        if self.MOM_performed_:\n+            status.append(\"MOM\")\n+\n+        if self.frac_performed_:\n+            status.append(\"FRAC\")\n+\n+        core.timer_on(\"HF: Form D\")\n+        self.form_D()\n+        core.timer_off(\"HF: Form D\")\n+\n+        core.set_variable(\"SCF ITERATION ENERGY\", SCFE)\n+\n+        # After we've built the new D, damp the update\n+        if (damping_enabled and self.iteration_ > 1 and Drms > core.get_option('SCF', 'DAMPING_CONVERGENCE')):\n+            damping_percentage = core.get_option('SCF', \"DAMPING_PERCENTAGE\")\n+            self.damping_update(damping_percentage * 0.01)\n+            status.append(\"DAMP={}%\".format(round(damping_percentage)))\n+\n+        if verbose > 3:\n+            self.Ca().print_out()\n+            self.Cb().print_out()\n+            self.Da().print_out()\n+            self.Db().print_out()\n+\n+        # Print out the iteration\n+        core.print_out(\"   @%s%s iter %3d: %20.14f   %12.5e   %-11.5e %s\\n\" %\n+                       (\"DF-\" if is_dfjk else \"\", reference, self.iteration_, SCFE, Ediff, Drms, '/'.join(status)))\n+\n+        # if a an excited MOM is requested but not started, don't stop yet\n+        if self.MOM_excited_ and not self.MOM_performed_:\n+            continue\n+\n+        # if a fractional occupation is requested but not started, don't stop yet\n+        if frac_enabled and not self.frac_performed_:\n+            continue\n+\n+        # Call any postiteration callbacks\n+\n+        if _converged(Ediff, Drms, e_conv=e_conv, d_conv=d_conv):\n+            break\n+        if self.iteration_ >= core.get_option('SCF', 'MAXITER'):\n+            raise ConvergenceError(\"\"\"SCF iterations\"\"\", self.iteration_)\n+\n+\n+def scf_finalize_energy(self):\n+    \"\"\"Performs stability analysis and calls back SCF with new guess\n+    if needed, Returns the SCF energy. This function should be called\n+    once orbitals are ready for energy/property computations, usually\n+    after iterations() is called.\n+\n+    \"\"\"\n+\n+    # post-scf vv10 correlation\n+    if core.get_option('SCF', \"DFT_VV10_POSTSCF\"):\n+        self.functional().set_lock(False)\n+        self.functional().set_do_vv10(True)\n+        self.functional().set_lock(True)\n+        core.print_out(\"  ==> calculating VV10 correction on post-scf density <==\\n\\n\")\n+        SCFE = 0.0\n+        self.form_V()\n+        SCFE += self.compute_E()\n+        self.set_energies(\"Total Energy\", SCFE)\n+\n+    # Perform wavefunction stability analysis before doing\n+    # anything on a wavefunction that may not be truly converged.\n+    if core.get_option('SCF', 'STABILITY_ANALYSIS') != \"NONE\":\n+        # We need the integral file, make sure it is written and\n+        # compute it if needed\n+        if core.get_option('SCF', 'REFERENCE') != \"UHF\":\n+            psio = core.IO.shared_object()\n+            #psio.open(constants.PSIF_SO_TEI, 1)  # PSIO_OPEN_OLD\n+            #try:\n+            #    psio.tocscan(constants.PSIF_SO_TEI, \"IWL Buffers\")\n+            #except TypeError:\n+            #    # \"IWL Buffers\" actually found but psio_tocentry can't be returned to Py\n+            #    psio.close(constants.PSIF_SO_TEI, 1)\n+            #else:\n+            #    # tocscan returned None\n+            #    psio.close(constants.PSIF_SO_TEI, 1)\n+\n+            # logic above foiled by psio_tocentry not returning None<--nullptr in pb11 2.2.1\n+            #   so forcibly recomputing for now until stability revamp\n+            core.print_out(\"    SO Integrals not on disk. Computing...\")\n+            mints = core.MintsHelper(self.basisset())\n+            mints.integrals()\n+            core.print_out(\"done.\\n\")\n+\n+            # Q: Not worth exporting all the layers of psio, right?\n+\n+        follow = self.stability_analysis()\n+\n+        while follow and self.attempt_number_ <= core.get_option('SCF', 'MAX_ATTEMPTS'):\n+            self.attempt_number_ += 1\n+            core.print_out(\"    Running SCF again with the rotated orbitals.\\n\")\n+\n+            if self.initialized_diis_manager_:\n+                self.diis_manager().reset_subspace()\n+            # reading the rotated orbitals in before starting iterations\n+            self.form_D()\n+            self.set_energies(\"Total Energy\", self.compute_initial_E())\n+            self.iterations()\n+            follow = self.stability_analysis()\n+\n+        if follow and self.attempt_number_ > core.get_option('SCF', 'MAX_ATTEMPTS'):\n+            core.print_out(\"    There's still a negative eigenvalue. Try modifying FOLLOW_STEP_SCALE\\n\")\n+            core.print_out(\"    or increasing MAX_ATTEMPTS (not available for PK integrals).\\n\")\n+\n+    # At this point, we are not doing any more SCF cycles\n+    #   and we can compute and print final quantities.\n+\n+    if hasattr(self.molecule(), 'EFP'):\n+        efpobj = self.molecule().EFP\n+\n+        efpobj.compute()  # do_gradient=do_gradient)\n+        efpene = efpobj.get_energy(label='psi')\n+        efp_wfn_independent_energy = efpene['total'] - efpene['ind']\n+        self.set_energies(\"EFP\", efpene['total'])\n+\n+        SCFE = self.get_energies(\"Total Energy\")\n+        SCFE += efp_wfn_independent_energy\n+        self.set_energies(\"Total Energy\", SCFE)\n+        core.print_out(efpobj.energy_summary(scfefp=SCFE, label='psi'))\n+\n+        core.set_variable('EFP ELST ENERGY', efpene['electrostatic'] + efpene['charge_penetration'] + efpene['electrostatic_point_charges'])\n+        core.set_variable('EFP IND ENERGY', efpene['polarization'])\n+        core.set_variable('EFP DISP ENERGY', efpene['dispersion'])\n+        core.set_variable('EFP EXCH ENERGY', efpene['exchange_repulsion'])\n+        core.set_variable('EFP TOTAL ENERGY', efpene['total'])\n+        core.set_variable('CURRENT ENERGY', efpene['total'])\n+\n+    core.print_out(\"\\n  ==> Post-Iterations <==\\n\\n\")\n+\n+    self.check_phases()\n+    self.compute_spin_contamination()\n+    self.frac_renormalize()\n+    reference = core.get_option(\"SCF\", \"REFERENCE\")\n+\n+    energy = self.get_energies(\"Total Energy\")\n+\n+#    fail_on_maxiter = core.get_option(\"SCF\", \"FAIL_ON_MAXITER\")\n+#    if converged or not fail_on_maxiter:\n+#\n+#        if print_lvl > 0:\n+#            self.print_orbitals()\n+#\n+#        if converged:\n+#            core.print_out(\"  Energy converged.\\n\\n\")\n+#        else:\n+#            core.print_out(\"  Energy did not converge, but proceeding anyway.\\n\\n\")\n+\n+    if core.get_option('SCF', 'PRINT') > 0:\n+        self.print_orbitals()\n+\n+    is_dfjk = core.get_global_option('SCF_TYPE').endswith('DF')\n+    core.print_out(\"  @%s%s Final Energy: %20.14f\" % ('DF-' if is_dfjk else '', reference, energy))\n+    # if (perturb_h_) {\n+    #     core.print_out(\" with %f %f %f perturbation\" %\n+    #                    (dipole_field_strength_[0], dipole_field_strength_[1], dipole_field_strength_[2]))\n+    # }\n+    core.print_out(\"\\n\\n\")\n+    self.print_energies()\n+\n+    self.clear_external_potentials()\n+    if core.get_option('SCF', 'PCM'):\n+        calc_type = core.PCM.CalcType.Total\n+        if core.get_option(\"PCM\", \"PCM_SCF_TYPE\") == \"SEPARATE\":\n+            calc_type = core.PCM.CalcType.NucAndEle\n+        Dt = self.Da().clone()\n+        Dt.add(self.Db())\n+        _, Vpcm = self.get_PCM().compute_PCM_terms(Dt, calc_type)\n+        self.push_back_external_potential(Vpcm)\n+\n+    # recompute the Fock matrices as they are modified during the SCF\n+    #   iteration and might need to be dumped to checkpoint later\n+    self.form_F()","path":"psi4/driver/procrouting/scf_proc/scf_iterator.py","position":493,"original_position":493,"commit_id":"93920db69b1cd5a60de466d1408cf0f99d83d0c0","original_commit_id":"93920db69b1cd5a60de466d1408cf0f99d83d0c0","user":{"login":"dgasmith","id":1769841,"node_id":"MDQ6VXNlcjE3Njk4NDE=","avatar_url":"https://avatars2.githubusercontent.com/u/1769841?v=4","gravatar_id":"","url":"https://api.github.com/users/dgasmith","html_url":"https://github.com/dgasmith","followers_url":"https://api.github.com/users/dgasmith/followers","following_url":"https://api.github.com/users/dgasmith/following{/other_user}","gists_url":"https://api.github.com/users/dgasmith/gists{/gist_id}","starred_url":"https://api.github.com/users/dgasmith/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dgasmith/subscriptions","organizations_url":"https://api.github.com/users/dgasmith/orgs","repos_url":"https://api.github.com/users/dgasmith/repos","events_url":"https://api.github.com/users/dgasmith/events{/privacy}","received_events_url":"https://api.github.com/users/dgasmith/received_events","type":"User","site_admin":false},"body":"Is this normal? Seems like a needed JK build. The Fock matrix should be fine I think?","created_at":"2018-07-20T02:03:13Z","updated_at":"2018-07-20T02:25:13Z","html_url":"https://github.com/psi4/psi4/pull/953#discussion_r203921398","pull_request_url":"https://api.github.com/repos/psi4/psi4/pulls/953","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/psi4/psi4/pulls/comments/203921398"},"html":{"href":"https://github.com/psi4/psi4/pull/953#discussion_r203921398"},"pull_request":{"href":"https://api.github.com/repos/psi4/psi4/pulls/953"}}},"pull_request":{"url":"https://api.github.com/repos/psi4/psi4/pulls/953","id":180756879,"node_id":"MDExOlB1bGxSZXF1ZXN0MTgwNzU2ODc5","html_url":"https://github.com/psi4/psi4/pull/953","diff_url":"https://github.com/psi4/psi4/pull/953.diff","patch_url":"https://github.com/psi4/psi4/pull/953.patch","issue_url":"https://api.github.com/repos/psi4/psi4/issues/953","number":953,"state":"open","locked":false,"title":"Py-side SCF, PCM, EFP, Mol parsing 2","user":{"login":"loriab","id":2314730,"node_id":"MDQ6VXNlcjIzMTQ3MzA=","avatar_url":"https://avatars0.githubusercontent.com/u/2314730?v=4","gravatar_id":"","url":"https://api.github.com/users/loriab","html_url":"https://github.com/loriab","followers_url":"https://api.github.com/users/loriab/followers","following_url":"https://api.github.com/users/loriab/following{/other_user}","gists_url":"https://api.github.com/users/loriab/gists{/gist_id}","starred_url":"https://api.github.com/users/loriab/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/loriab/subscriptions","organizations_url":"https://api.github.com/users/loriab/orgs","repos_url":"https://api.github.com/users/loriab/repos","events_url":"https://api.github.com/users/loriab/events{/privacy}","received_events_url":"https://api.github.com/users/loriab/received_events","type":"User","site_admin":false},"body":"## Description\r\n~This replaces #919, which I don't want to overwrite just yet b/c it has history and some review comments. This is up-to-date wrt master (10 Apr) and has had a recent pyvib2 rebased through (9 Apr). All tests pass. This is **not** ready to look at b/c it still includes #834 . When that makes it into master, I'll rebase it through again and then~ this PR should only include fully-working py-side scf and mol parsing (`create_molecule_from_string` is gone in this code). This is my last sequence PR before splitting away qcdb. I suggest it form the start of `v1.3` .\r\n\r\n~Since originally posted (+27k/–10k), this PR has had #834 subtracted from it (now +13k/–7k). It is built atop #965, so I wouldn't review until that gets pulled in and subtracted from this. What does need answering soonish is whether for 1.2/1.3 purposes, the remaining commits of this PR should be separated further.~\r\n\r\n~Now this has had #965 rebased through, it should be stable for a good while. It now has size (+9k/–6k). There doesn't seem much interest in promoting the below to 1.2, so no need for further subdivision.~\r\n\r\nThis has now had **v1.2 rebased through** so I sincerely hope it's been kneaded for the last time.\r\n\r\n## Todos: Py-side SCF/PCM/EFP (1.3)\r\n* **Developer Interest**\r\n  - [x] SCF iterations moved py-side\r\n  - [x] includes control of MOM, DIIS, damping, soscf, frac, efp\r\n  - [x] SCF finalize, stability, post-iterations, printing moved py-side\r\n  - [x] Rework a good bit of Wfn::HF::common_init() to minimize the convergence helper controllers that are c-side\r\n  - [x] A couple export/def bugs fixed in Wfn::HF and more fns exported and moved to public in class\r\n  - [x] PCMSolver interface reworked for py-side\r\n  - [x] libefp EFP object moved from c-side `P::e.EFP` to a py-side attached EFP attribute on the `psi4.core.Molecule` object.\r\n  - [x] Psi4 forgot about the c-side EFP object in bin, lib, globals, exports (still in options)\r\n  - [x] EFP/EFP calcs moved purely py-side\r\n  - [x] SCF/EFP calcs carry out operations on the EFP object py-side\r\n  - [x] efp_torque no longer in `P::e` but `EFP TORQUE` in `P::e:arrays`\r\n\r\n## Todos: Py-side Mol Parsing (could be split out for 1.2)\r\n* **User Interest**\r\n  - [x] `molecule {...}` will take xyz (element symbol _or_ atomic number) or psi4 formats.\r\n  - [x] overall chgmult now specifiable through `1 3\\n--` before any fragments.\r\n  - [x] can specify atomic number, mass number, mass, ghosting, extra-label in mol spec.\r\n* **Developer Interest**\r\n  - [x] `*.Molecule` forgot `charge_specified` and `multiplicity_specified` attributes. They were only used once in deciding mult defaulting in the SCF and that logic is now handled at mol parsing time.\r\n  - [x] `*.Molecule` forgot `create_molecule_from_string()` and good riddance. Also `*.Molecule` `init_with_xyz` (all the format variations can be handled by plain `from_string`. There's an optional `dtype` if you want to be specific.\r\n  - [x] Remove singlet/doublet defaulting logic in `Wavefunction::common_init()`, as this is taken care of by mol init\r\n  - [x] In keywords (`read_options`), `EFP_POL`, `QMEFP_POL`, `EFP_POL_DAMPING`, all `POL` --> `IND`.\r\n  - [x] Main `molutil.set_geometry()` that all psithon and psiapi calls use to process user molecule switch from c-side parsing to `qcdb.molparse.from_string()` parsing. This fn handles QM mol, EFP frag, and PubChem contents.\r\n  - [x] `libefp` accessed through `PylibEFP` and `-DENABLE_libefp=ON` activates both\r\n  - [x] `psi4.core.Molecule.molecule_from_string(string)` constructor calls py-side parsing. Can override string contents with `fix_com`, `fix_orientation`, `fix_symmetry` args. `string` can have QM mol, EFP frag, and pubchem contents.\r\n\r\n## Questions\r\n- [ ] @robertodr, feel free to elaborate PCMSolver changes\r\n- [x] ~**Everyone** the previous PR #965 gets both Mol classes to a point where they _can_ be instantiated by py-side parsing (or arrays, or dict). Do we want the second set of changes above where inputparser is calling py-side parsing into 1.2? It will require PylibEFP. SCF/EFP will remain c-side.~\r\n\r\n## Checklist\r\n- [x] Tests added for any new features\r\n- [x] [All or relevant fraction of full tests run](http://psicode.org/psi4manual/master/build_planning.html#how-to-run-a-subset-of-tests)\r\n- [ ] symmetrize pubchem inputs, see https://github.com/psi4/psi4/pull/965#issuecomment-382854005\r\n- [ ] max_attempts for instability following isn't through\r\n\r\n## Status\r\n- [x] Ready for review\r\n- [ ] Ready for merge\r\n","created_at":"2018-04-10T23:48:39Z","updated_at":"2018-07-20T02:25:13Z","closed_at":null,"merged_at":null,"merge_commit_sha":"3e514e25bc9c5391a816e9eb5f65232c2bff7e00","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":{"url":"https://api.github.com/repos/psi4/psi4/milestones/4","html_url":"https://github.com/psi4/psi4/milestone/4","labels_url":"https://api.github.com/repos/psi4/psi4/milestones/4/labels","id":3242981,"node_id":"MDk6TWlsZXN0b25lMzI0Mjk4MQ==","number":4,"title":"Psi4 1.3","description":"last before driver split","creator":{"login":"dgasmith","id":1769841,"node_id":"MDQ6VXNlcjE3Njk4NDE=","avatar_url":"https://avatars2.githubusercontent.com/u/1769841?v=4","gravatar_id":"","url":"https://api.github.com/users/dgasmith","html_url":"https://github.com/dgasmith","followers_url":"https://api.github.com/users/dgasmith/followers","following_url":"https://api.github.com/users/dgasmith/following{/other_user}","gists_url":"https://api.github.com/users/dgasmith/gists{/gist_id}","starred_url":"https://api.github.com/users/dgasmith/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dgasmith/subscriptions","organizations_url":"https://api.github.com/users/dgasmith/orgs","repos_url":"https://api.github.com/users/dgasmith/repos","events_url":"https://api.github.com/users/dgasmith/events{/privacy}","received_events_url":"https://api.github.com/users/dgasmith/received_events","type":"User","site_admin":false},"open_issues":37,"closed_issues":7,"state":"open","created_at":"2018-04-04T18:33:03Z","updated_at":"2018-07-18T14:15:40Z","due_on":"2018-11-01T07:00:00Z","closed_at":null},"commits_url":"https://api.github.com/repos/psi4/psi4/pulls/953/commits","review_comments_url":"https://api.github.com/repos/psi4/psi4/pulls/953/comments","review_comment_url":"https://api.github.com/repos/psi4/psi4/pulls/comments{/number}","comments_url":"https://api.github.com/repos/psi4/psi4/issues/953/comments","statuses_url":"https://api.github.com/repos/psi4/psi4/statuses/93920db69b1cd5a60de466d1408cf0f99d83d0c0","head":{"label":"loriab:scfitertopy444","ref":"scfitertopy444","sha":"93920db69b1cd5a60de466d1408cf0f99d83d0c0","user":{"login":"loriab","id":2314730,"node_id":"MDQ6VXNlcjIzMTQ3MzA=","avatar_url":"https://avatars0.githubusercontent.com/u/2314730?v=4","gravatar_id":"","url":"https://api.github.com/users/loriab","html_url":"https://github.com/loriab","followers_url":"https://api.github.com/users/loriab/followers","following_url":"https://api.github.com/users/loriab/following{/other_user}","gists_url":"https://api.github.com/users/loriab/gists{/gist_id}","starred_url":"https://api.github.com/users/loriab/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/loriab/subscriptions","organizations_url":"https://api.github.com/users/loriab/orgs","repos_url":"https://api.github.com/users/loriab/repos","events_url":"https://api.github.com/users/loriab/events{/privacy}","received_events_url":"https://api.github.com/users/loriab/received_events","type":"User","site_admin":false},"repo":{"id":71407205,"node_id":"MDEwOlJlcG9zaXRvcnk3MTQwNzIwNQ==","name":"psi4","full_name":"loriab/psi4","owner":{"login":"loriab","id":2314730,"node_id":"MDQ6VXNlcjIzMTQ3MzA=","avatar_url":"https://avatars0.githubusercontent.com/u/2314730?v=4","gravatar_id":"","url":"https://api.github.com/users/loriab","html_url":"https://github.com/loriab","followers_url":"https://api.github.com/users/loriab/followers","following_url":"https://api.github.com/users/loriab/following{/other_user}","gists_url":"https://api.github.com/users/loriab/gists{/gist_id}","starred_url":"https://api.github.com/users/loriab/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/loriab/subscriptions","organizations_url":"https://api.github.com/users/loriab/orgs","repos_url":"https://api.github.com/users/loriab/repos","events_url":"https://api.github.com/users/loriab/events{/privacy}","received_events_url":"https://api.github.com/users/loriab/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/loriab/psi4","description":"Open-Source Quantum Chemistry – an electronic structure package in C++ driven by Python","fork":true,"url":"https://api.github.com/repos/loriab/psi4","forks_url":"https://api.github.com/repos/loriab/psi4/forks","keys_url":"https://api.github.com/repos/loriab/psi4/keys{/key_id}","collaborators_url":"https://api.github.com/repos/loriab/psi4/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/loriab/psi4/teams","hooks_url":"https://api.github.com/repos/loriab/psi4/hooks","issue_events_url":"https://api.github.com/repos/loriab/psi4/issues/events{/number}","events_url":"https://api.github.com/repos/loriab/psi4/events","assignees_url":"https://api.github.com/repos/loriab/psi4/assignees{/user}","branches_url":"https://api.github.com/repos/loriab/psi4/branches{/branch}","tags_url":"https://api.github.com/repos/loriab/psi4/tags","blobs_url":"https://api.github.com/repos/loriab/psi4/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/loriab/psi4/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/loriab/psi4/git/refs{/sha}","trees_url":"https://api.github.com/repos/loriab/psi4/git/trees{/sha}","statuses_url":"https://api.github.com/repos/loriab/psi4/statuses/{sha}","languages_url":"https://api.github.com/repos/loriab/psi4/languages","stargazers_url":"https://api.github.com/repos/loriab/psi4/stargazers","contributors_url":"https://api.github.com/repos/loriab/psi4/contributors","subscribers_url":"https://api.github.com/repos/loriab/psi4/subscribers","subscription_url":"https://api.github.com/repos/loriab/psi4/subscription","commits_url":"https://api.github.com/repos/loriab/psi4/commits{/sha}","git_commits_url":"https://api.github.com/repos/loriab/psi4/git/commits{/sha}","comments_url":"https://api.github.com/repos/loriab/psi4/comments{/number}","issue_comment_url":"https://api.github.com/repos/loriab/psi4/issues/comments{/number}","contents_url":"https://api.github.com/repos/loriab/psi4/contents/{+path}","compare_url":"https://api.github.com/repos/loriab/psi4/compare/{base}...{head}","merges_url":"https://api.github.com/repos/loriab/psi4/merges","archive_url":"https://api.github.com/repos/loriab/psi4/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/loriab/psi4/downloads","issues_url":"https://api.github.com/repos/loriab/psi4/issues{/number}","pulls_url":"https://api.github.com/repos/loriab/psi4/pulls{/number}","milestones_url":"https://api.github.com/repos/loriab/psi4/milestones{/number}","notifications_url":"https://api.github.com/repos/loriab/psi4/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/loriab/psi4/labels{/name}","releases_url":"https://api.github.com/repos/loriab/psi4/releases{/id}","deployments_url":"https://api.github.com/repos/loriab/psi4/deployments","created_at":"2016-10-19T23:17:18Z","updated_at":"2018-07-04T07:11:41Z","pushed_at":"2018-07-20T00:08:06Z","git_url":"git://github.com/loriab/psi4.git","ssh_url":"git@github.com:loriab/psi4.git","clone_url":"https://github.com/loriab/psi4.git","svn_url":"https://github.com/loriab/psi4","homepage":"http://psicode.org","size":85417,"stargazers_count":0,"watchers_count":0,"language":"C++","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"lgpl-3.0","name":"GNU Lesser General Public License v3.0","spdx_id":"LGPL-3.0","url":"https://api.github.com/licenses/lgpl-3.0","node_id":"MDc6TGljZW5zZTEy"},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"psi4:master","ref":"master","sha":"571029c94e0e742ef19fa7dcd34983f5e9354c38","user":{"login":"psi4","id":2636883,"node_id":"MDEyOk9yZ2FuaXphdGlvbjI2MzY4ODM=","avatar_url":"https://avatars1.githubusercontent.com/u/2636883?v=4","gravatar_id":"","url":"https://api.github.com/users/psi4","html_url":"https://github.com/psi4","followers_url":"https://api.github.com/users/psi4/followers","following_url":"https://api.github.com/users/psi4/following{/other_user}","gists_url":"https://api.github.com/users/psi4/gists{/gist_id}","starred_url":"https://api.github.com/users/psi4/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/psi4/subscriptions","organizations_url":"https://api.github.com/users/psi4/orgs","repos_url":"https://api.github.com/users/psi4/repos","events_url":"https://api.github.com/users/psi4/events{/privacy}","received_events_url":"https://api.github.com/users/psi4/received_events","type":"Organization","site_admin":false},"repo":{"id":9174469,"node_id":"MDEwOlJlcG9zaXRvcnk5MTc0NDY5","name":"psi4","full_name":"psi4/psi4","owner":{"login":"psi4","id":2636883,"node_id":"MDEyOk9yZ2FuaXphdGlvbjI2MzY4ODM=","avatar_url":"https://avatars1.githubusercontent.com/u/2636883?v=4","gravatar_id":"","url":"https://api.github.com/users/psi4","html_url":"https://github.com/psi4","followers_url":"https://api.github.com/users/psi4/followers","following_url":"https://api.github.com/users/psi4/following{/other_user}","gists_url":"https://api.github.com/users/psi4/gists{/gist_id}","starred_url":"https://api.github.com/users/psi4/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/psi4/subscriptions","organizations_url":"https://api.github.com/users/psi4/orgs","repos_url":"https://api.github.com/users/psi4/repos","events_url":"https://api.github.com/users/psi4/events{/privacy}","received_events_url":"https://api.github.com/users/psi4/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/psi4/psi4","description":"Open-Source Quantum Chemistry – an electronic structure package in C++ driven by Python","fork":false,"url":"https://api.github.com/repos/psi4/psi4","forks_url":"https://api.github.com/repos/psi4/psi4/forks","keys_url":"https://api.github.com/repos/psi4/psi4/keys{/key_id}","collaborators_url":"https://api.github.com/repos/psi4/psi4/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/psi4/psi4/teams","hooks_url":"https://api.github.com/repos/psi4/psi4/hooks","issue_events_url":"https://api.github.com/repos/psi4/psi4/issues/events{/number}","events_url":"https://api.github.com/repos/psi4/psi4/events","assignees_url":"https://api.github.com/repos/psi4/psi4/assignees{/user}","branches_url":"https://api.github.com/repos/psi4/psi4/branches{/branch}","tags_url":"https://api.github.com/repos/psi4/psi4/tags","blobs_url":"https://api.github.com/repos/psi4/psi4/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/psi4/psi4/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/psi4/psi4/git/refs{/sha}","trees_url":"https://api.github.com/repos/psi4/psi4/git/trees{/sha}","statuses_url":"https://api.github.com/repos/psi4/psi4/statuses/{sha}","languages_url":"https://api.github.com/repos/psi4/psi4/languages","stargazers_url":"https://api.github.com/repos/psi4/psi4/stargazers","contributors_url":"https://api.github.com/repos/psi4/psi4/contributors","subscribers_url":"https://api.github.com/repos/psi4/psi4/subscribers","subscription_url":"https://api.github.com/repos/psi4/psi4/subscription","commits_url":"https://api.github.com/repos/psi4/psi4/commits{/sha}","git_commits_url":"https://api.github.com/repos/psi4/psi4/git/commits{/sha}","comments_url":"https://api.github.com/repos/psi4/psi4/comments{/number}","issue_comment_url":"https://api.github.com/repos/psi4/psi4/issues/comments{/number}","contents_url":"https://api.github.com/repos/psi4/psi4/contents/{+path}","compare_url":"https://api.github.com/repos/psi4/psi4/compare/{base}...{head}","merges_url":"https://api.github.com/repos/psi4/psi4/merges","archive_url":"https://api.github.com/repos/psi4/psi4/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/psi4/psi4/downloads","issues_url":"https://api.github.com/repos/psi4/psi4/issues{/number}","pulls_url":"https://api.github.com/repos/psi4/psi4/pulls{/number}","milestones_url":"https://api.github.com/repos/psi4/psi4/milestones{/number}","notifications_url":"https://api.github.com/repos/psi4/psi4/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/psi4/psi4/labels{/name}","releases_url":"https://api.github.com/repos/psi4/psi4/releases{/id}","deployments_url":"https://api.github.com/repos/psi4/psi4/deployments","created_at":"2013-04-02T16:21:04Z","updated_at":"2018-07-20T01:47:11Z","pushed_at":"2018-07-20T01:47:04Z","git_url":"git://github.com/psi4/psi4.git","ssh_url":"git@github.com:psi4/psi4.git","clone_url":"https://github.com/psi4/psi4.git","svn_url":"https://github.com/psi4/psi4","homepage":"http://psicode.org","size":84472,"stargazers_count":226,"watchers_count":226,"language":"C++","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":182,"mirror_url":null,"archived":false,"open_issues_count":87,"license":{"key":"lgpl-3.0","name":"GNU Lesser General Public License v3.0","spdx_id":"LGPL-3.0","url":"https://api.github.com/licenses/lgpl-3.0","node_id":"MDc6TGljZW5zZTEy"},"forks":182,"open_issues":87,"watchers":226,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/psi4/psi4/pulls/953"},"html":{"href":"https://github.com/psi4/psi4/pull/953"},"issue":{"href":"https://api.github.com/repos/psi4/psi4/issues/953"},"comments":{"href":"https://api.github.com/repos/psi4/psi4/issues/953/comments"},"review_comments":{"href":"https://api.github.com/repos/psi4/psi4/pulls/953/comments"},"review_comment":{"href":"https://api.github.com/repos/psi4/psi4/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/psi4/psi4/pulls/953/commits"},"statuses":{"href":"https://api.github.com/repos/psi4/psi4/statuses/93920db69b1cd5a60de466d1408cf0f99d83d0c0"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"dgasmith"}}