示例#1
0
def compute_elec_struct(self,zbackprop):
    if not zbackprop:
        cbackprop = ""
    else:
        cbackprop = "backprop_"    

    istate = self.get_istate()
    nstates = self.get_numstates()

    # initialize electronic_phases if not present
    if not hasattr(self,'electronic_phases'):
        self.electronic_phases = np.ones(nstates)
    if not hasattr(self,'backprop_electronic_phases'):
        self.backprop_electronic_phases = np.ones(nstates)

    exec("pos = self.get_" + cbackprop + "positions()")
    pos_list = pos.tolist()
        
    TC = TCProtobufClient(host='localhost', port=54321)

    base_options = self.get_tc_options()

    base_options["castarget"] = istate

    TC.update_options(**base_options)

    TC.connect()

    # Check if the server is available
    avail = TC.is_available()
    #print "TCPB Server available: {}".format(avail)

    # Write CI vectors and orbitals for initial guess and overlaps
    cwd = os.getcwd()
    # Gradient calculation

    # here we call TC once for energies and once for the gradient
    # will eventually be replaced by a more efficient interface
    options = {}
    results = TC.compute_job_sync("energy", pos_list, "bohr", **options)
    #print results

    e = np.zeros(nstates)
    e[0] = results['energy']

    results = TC.compute_job_sync("gradient", pos_list, "bohr", **options)
    #print results

    f = np.zeros((nstates,self.numdims))
    #print "results['gradient'] ", results['gradient']
    #print "results['gradient'].flatten() ", results['gradient'].flatten()
    f[self.istate,:] = -1.0 * results['gradient'].flatten()

    exec("self.set_" + cbackprop + "energies(e)")

    exec("self.set_" + cbackprop + "forces(f)")
示例#2
0
    def compute(self, input_model: "AtomicInput", config: "TaskConfig" = None) -> "AtomicResult":
        """
        Submit AtomicInput to TeraChem running in "server mode"
        """
        self.found(raise_error=True)

        from tcpb.tcpb import TCProtobufClient

        with TCProtobufClient(host=os.getenv("TERACHEM_PBS_HOST"), port=int(os.getenv("TERACHEM_PBS_PORT"))) as client:
            return client.compute(input_model)
示例#3
0
def compute_electronic_overlap(self, pos1, civec1, orbs1, pos2, civec2, orbs2):
    orbout1 = os.path.join(cwd, "c0.1")
    orbs1.tofile(orbout1)
    orbout2 = os.path.join(cwd, "c0.2")
    orbs2.tofile(orbout2)

    civecout1 = os.path.join(cwd, "civec.1")
    civec1.tofile(civecout1)
    civecout2 = os.path.join(cwd, "civec.2")
    civec2.tofile(civecout2)

    TC = TCProtobufClient(host='localhost', port=self.tc_port)
    options = self.get_tc_options()
    #     TC.update_options(**base_options)
    TC.connect()
    # Check if the server is available
    avail = TC.is_available()

    options["geom2"] = (0.529177 * pos2).tolist()
    options["cvec1file"] = civecfilename
    options["cvec2file"] = civecout
    options["orb1afile"] = orbout2
    options["orb2afile"] = orbout

    results2 = TC.compute_job_sync("ci_vec_overlap", pos1.tolist(), "bohr",
                                   **options)

    S = results2['ci_overlap']

    return S
示例#4
0
    def found(raise_error: bool = False) -> bool:
        """Whether TeraChemPBS harness is ready for operation.
        Parameters
        ----------
        raise_error: bool
            Passed on to control negative return between False and ModuleNotFoundError raised.
        Returns
        -------
        bool
            If tcpb package is found and server available, returns True.
            If raise_error is False and tcpb package missing and/or server us unavailable, returns False.
            If raise_error is True and tcpb package missing and/or server us unavailable, the error message is raised.
        """
        tcpb_pkg_available = which_import(
            "tcpb",
            return_bool=True,
            raise_error=raise_error,
            raise_msg="TeraChem protobuf client package (tcpb) not found. Please install tcpb>=0.7.0.",
        )
        if not tcpb_pkg_available:
            return False

        from tcpb.exceptions import ServerError
        from tcpb.tcpb import TCProtobufClient

        try:
            with TCProtobufClient(
                host=os.getenv("TERACHEM_PBS_HOST"), port=int(os.getenv("TERACHEM_PBS_PORT"))
            ) as client:
                return client.is_available()
        except TypeError as e:
            # TERACHEM_PBS_HOST/PORT environment variables unset
            msg = "Environment variables 'TERACHEM_PBS_HOST' and 'TERACHEM_PBS_PORT' must be set!"
            logger.error(msg)
            if raise_error:
                raise ValueError(msg) from e
        except ServerError as e:
            msg = (
                f"Unable to connect to TeraChem server at "
                f"{os.getenv('TERACHEM_PBS_HOST')}:{os.getenv('TERACHEM_PBS_PORT')}"
            )
            logger.error(msg)
            if raise_error:
                raise OSError(msg) from e
        return False
示例#5
0
def compute_elec_struct(self, zbackprop):
    """Subroutine that calls electronic structure calculation in Terachem
    through tcpb interface. This version is compatible with tcpb-0.5.0
    When running multiple job on the same server we need to make sure we use
    different ports for Terachem server. Every trajectory or centroid
    has a port variable, which is passed along to children.
    Needs to be provided at input in start file as a traj_param"""

    if not zbackprop:
        cbackprop = ""
    else:
        cbackprop = "backprop_"

    istate = self.get_istate()
    nstates = self.get_numstates()

    # initialize electronic_phases if not present
    if not hasattr(self, 'electronic_phases'):
        self.electronic_phases = np.ones(nstates)
    if not hasattr(self, 'backprop_electronic_phases'):
        self.backprop_electronic_phases = np.ones(nstates)

    exec("pos = self.get_" + cbackprop + "positions()")
    pos_list = pos.tolist()

    TC = TCProtobufClient(host='localhost', port=self.tc_port)

    base_options = self.get_tc_options()

    options = base_options

    options["castarget"] = istate

    #     TC.update_options(**base_options)

    TC.connect()

    # Check if the server is available
    avail = TC.is_available()
    #     print "TCPB Server available: {}".format(avail)

    # Write CI vectors and orbitals for initial guess and overlaps
    cwd = os.getcwd()
    if hasattr(self, 'civecs'):
        civecout = os.path.join(cwd, "CIvecs.Singlet.old")
        orbout = os.path.join(cwd, "c0.old")
        orbout_t = os.path.join(cwd, "c0_t.old")
        eval("self.get_" + cbackprop + "civecs()").tofile(civecout)
        eval("self.get_" + cbackprop + "orbs()").tofile(orbout)
        n = int(math.floor(math.sqrt(self.get_norbs())))
        ((np.resize(eval("self.get_" + cbackprop + "orbs()"),
                    (n, n)).T).flatten()).tofile(orbout_t)
        #         print "old civecs", eval("self.get_" + cbackprop + "civecs()")
        #         print "old orbs", eval("self.get_" + cbackprop + "orbs()")
        zolaps = True
        if ("casscf" in self.tc_options):
            if (self.tc_options["casscf"] == "yes"):
                options["caswritevecs"] = "yes"
                options["casguess"] = orbout_t
            else:
                options["caswritevecs"] = "yes"
                options["guess"] = orbout
        else:
            options["caswritevecs"] = "yes"
            options["guess"] = orbout
    else:
        zolaps = False
        options["caswritevecs"] = "yes"

    # Gradient calculation

    # here we call TC once for energies and once for the gradient
    # will eventually be replaced by a more efficient interface
    results = TC.compute_job_sync("energy", pos_list, "bohr", **options)
    #     print results

    e = np.zeros(nstates)
    e = results['energy']
    #    e[:] = results['energy'][:]

    results = TC.compute_job_sync("gradient", pos_list, "bohr", **options)
    #     print results

    civecfilename = os.path.join(results['job_scr_dir'], "CIvecs.Singlet.dat")
    exec("self.set_" + cbackprop + "civecs(np.fromfile(civecfilename))")
    #     print "new civecs", self.civecs

    #     orbfilename = os.path.join(results['job_scr_dir'], "c0")
    orbfilename = results['orbfile']
    exec("self.set_" + cbackprop +
         "orbs((np.fromfile(orbfilename)).flatten())")

    self.set_norbs(self.get_orbs().size)

    # BGL transpose hack is temporary
    n = int(math.floor(math.sqrt(self.get_norbs())))
    clastchar = orbfilename.strip()[-1]
    #     print "n", n
    #     print "clastchar", clastchar
    if clastchar != '0':
        tmporbs = eval("self.get_" + cbackprop + "orbs()")
        exec("self.set_" + cbackprop +
             "orbs(((tmporbs.reshape((n,n))).T).flatten())")
    # end transpose hack

#     print "new orbs", eval("self.get_" + cbackprop + "orbs()")
    orbout2 = os.path.join(cwd, "c0.new")
    eval("self.get_" + cbackprop + "orbs()").tofile(orbout2)

    self.set_ncivecs(self.get_civecs().size)

    f = np.zeros((nstates, self.numdims))
    #     print "results['gradient'] ", results['gradient']
    #     print "results['gradient'].flatten() ", results['gradient'].flatten()
    f[self.istate, :] = -1.0 * results['gradient'].flatten()

    exec("self.set_" + cbackprop + "energies(e)")
    exec("self.set_" + cbackprop + "forces(f)")

    # if False:
    if zolaps:
        exec("pos2 = self.get_" + cbackprop +
             "prev_wf_positions_in_angstrom()")
        #         print 'pos2.tolist()', pos2.tolist()
        #         print 'civecfilename', civecfilename
        #         print 'civecout', civecout
        #         print 'orbfilename', orbfilename
        #         print 'orbout2', orbout2
        #         print 'orbout', orbout
        options = base_options

        options["geom2"] = pos2.tolist()
        options["cvec1file"] = civecfilename
        options["cvec2file"] = civecout
        options["orb1afile"] = orbout2
        options["orb2afile"] = orbout

        #         print 'pos_list', pos_list
        results2 = TC.compute_job_sync("ci_vec_overlap", pos_list, "bohr",
                                       **options)
        #         print "results2", results2
        S = results2['ci_overlap']
        #         print "S before phasing ", S

        # phasing electronic overlaps
        for jstate in range(nstates):
            S[:, jstate] *= eval("self.get_" + cbackprop +
                                 "electronic_phases()[jstate]")
            S[jstate, :] *= eval("self.get_" + cbackprop +
                                 "electronic_phases()[jstate]")

        for jstate in range(nstates):
            if S[jstate, jstate] < 0.0:
                ep = eval("self.get_" + cbackprop + "electronic_phases()")
                ep[jstate] *= -1.0
                exec("self.set_" + cbackprop + "electronic_phases(ep)")
                # I'm not sure if this line is right, but it seems to be working
                S[jstate, :] *= -1.0

#         print "S", S
        exec("self.set_" + cbackprop + "S_elec_flat(S.flatten())")

        W = np.zeros((2, 2))
        W[0, 0] = S[istate, istate]

        tdc = np.zeros(nstates)

        for jstate in range(nstates):
            if istate == jstate:
                tdc[jstate] = 0.0
            else:
                W[1, 0] = S[jstate, istate]
                W[0, 1] = S[istate, jstate]
                W[1, 1] = S[jstate, jstate]
                tdc[jstate] = self.compute_tdc(W)


#                 print "tdc", tdc[jstate]

#         tmp=self.compute_tdc(W)
#         tdc = np.zeros(self.numstates)
#         if self.istate == 1:
#             jstate = 0
#         else:
#             jstate = 1
#             tdc[jstate] = tmp
#
#         print "tdc2 ", tdc
        exec("self.set_" + cbackprop + "timederivcoups(tdc)")
    else:
        exec("self.set_" + cbackprop +
             "timederivcoups(np.zeros(self.numstates))")

    exec("self.set_" + cbackprop + "prev_wf_positions(pos)")
示例#6
0
def test_atomic_input_to_job_input_cisco_casci_similarity(ethylene):
    """
    Test that the new atomic_input_to_job_input function produces the same protobuf
    messages that Stefan's old method created
    """
    # Dicts of options used according to Stefan's old methodology
    old_methodoloy_options = {
        "method": "hf",
        "basis": "6-31g**",
        "atoms": ethylene["atoms"],
    }
    keywords = {
        # base options
        "charge": 0,
        "spinmult": 1,
        "closed_shell": True,
        "restricted": True,
        "precision": "double",
        "convthre": 1e-8,
        "threall": 1e-20,
        # cisno options
        "cisno": "yes",
        "cisnostates": 2,
        "cisnumstates": 2,
        "closed": 7,
        "active": 2,
        "cassinglets": 2,
        "dcimaxiter": 100,
    }

    # Construct Geometry in bohr
    geom_angstrom = qcel.Datum("geometry", "angstrom",
                               np.array(ethylene["geometry"]))
    geom_bohr = _round(geom_angstrom.to_units("bohr"))

    # Construct Molecule object
    m_ethylene = Molecule.from_data({
        "symbols":
        ethylene["atoms"],
        "geometry":
        geom_bohr,
        "molecular_multiplicity":
        keywords["spinmult"],
        "molecular_charge":
        keywords["charge"],
    })

    # Construct AtomicInput
    atomic_input = AtomicInput(
        molecule=m_ethylene,
        driver="energy",
        model={
            "method": "hf",
            "basis": "6-31g**"
        },
        keywords=keywords,
    )

    # Create protobof JobInput using Stefan's old approach
    client = TCProtobufClient("host", 11111)
    stefan_style = client._create_job_input_msg(
        "energy", geom_bohr, "bohr", **{
            **old_methodoloy_options,
            **keywords
        })
    # Create protobuf JobInput using AtomicInput object
    job_input = atomic_input_to_job_input(atomic_input)
    assert job_input == stefan_style