def qcdb_post_parse_output(self, input_model: AtomicInput, output_model: "AtomicResult") -> "AtomicResult": dqcvars = PreservingDict(copy.deepcopy(output_model.extras["qcvars"])) for k in list(dqcvars.keys()): if k in ["DETCI AVG DVEC NORM", "MCSCF TOTAL ENERGY"]: dqcvars.pop(k) qcvars.build_out(dqcvars) calcinfo = qcvars.certify_and_datumize( dqcvars, plump=True, nat=len(output_model.molecule.symbols)) output_model.extras["qcdb:qcvars"] = calcinfo return output_model
def qcdb_post_parse_output(self, input_model: AtomicInput, output_model: "AtomicResult") -> "AtomicResult": progvars = PreservingDict(copy.deepcopy(output_model.extras["qcvars"])) ropts = input_model.extras["qcdb:options"] # badly placed # if "MP2 OPPOSITE-SPIN CORRELATION ENERGY" in progvars and "MP2 SAME-SPIN CORRELATION ENERGY" in progvars: # oss_opt = ropts.scroll['QCDB']['MP2_OS_SCALE'] # sss_opt = ropts.scroll['QCDB']['MP2_SS_SCALE'] # custom_scsmp2_corl = \ # Decimal(oss_opt.value) * progvars["MP2 OPPOSITE-SPIN CORRELATION ENERGY"] + \ # Decimal(sss_opt.value) * progvars["MP2 SAME-SPIN CORRELATION ENERGY"] # if "MP2 SINGLES ENERGY" in progvars: # custom_scsmp2_corl += progvars["MP2 SINGLES ENERGY"] # progvars["CUSTOM SCS-MP2 CORRELATION ENERGY"] = custom_scsmp2_corl # # if "CCSD OPPOSITE-SPIN CORRELATION ENERGY" in progvars and "CCSD SAME-SPIN CORRELATION ENERGY" in progvars: # oss_opt = ropts.scroll['QCDB']['CCSD_OS_SCALE'] # sss_opt = ropts.scroll['QCDB']['CCSD_SS_SCALE'] # custom_scsmp2_corl = \ # Decimal(oss_opt.value) * progvars["CCSD OPPOSITE-SPIN CORRELATION ENERGY"] + \ # Decimal(sss_opt.value) * progvars["CCSD SAME-SPIN CORRELATION ENERGY"] # # TODO check on validity of CCSD SINGLES ENERGY # if "CCSD SINGLES ENERGY" in progvars: # custom_scsccsd_corl += progvars["CCSD SINGLES ENERGY"] # progvars["CUSTOM SCS-CCSD CORRELATION ENERGY"] = custom_scsccsd_corl qcvars.build_out(progvars) calcinfo = qcvars.certify_and_datumize( progvars, plump=True, nat=len(output_model.molecule.symbols)) output_model.extras["qcdb:qcvars"] = calcinfo return output_model
def qcdb_post_parse_output(self, input_model: 'ResultInput', output_model: 'Result') -> 'Result': dqcvars = PreservingDict(copy.deepcopy(output_model.extras['qcvars'])) # badly placed # Cfour's SCS-MP2 is non adjustible and only valid for UHF # ROMP2 doesn't print SS & OS if "MP2 OPPOSITE-SPIN CORRELATION ENERGY" in dqcvars and "MP2 SAME-SPIN CORRELATION ENERGY" in dqcvars: oss_opt = input_model.extras['qcdb:options'].scroll['QCDB'][ 'MP2_OS_SCALE'] sss_opt = input_model.extras['qcdb:options'].scroll['QCDB'][ 'MP2_SS_SCALE'] custom_scsmp2_corl = \ Decimal(oss_opt.value) * dqcvars["MP2 OPPOSITE-SPIN CORRELATION ENERGY"] + \ Decimal(sss_opt.value) * dqcvars["MP2 SAME-SPIN CORRELATION ENERGY"] if "MP2 SINGLES ENERGY" in dqcvars: custom_scsmp2_corl += dqcvars["MP2 SINGLES ENERGY"] dqcvars["CUSTOM SCS-MP2 CORRELATION ENERGY"] = custom_scsmp2_corl qcvars.build_out(dqcvars) calcinfo = qcvars.certify(dqcvars, plump=True, nat=len(output_model.molecule.symbols)) output_model.extras['qcdb:qcvars'] = calcinfo return output_model
def qcdb_post_parse_output(self, input_model: AtomicInput, output_model: "AtomicResult") -> "AtomicResult": dqcvars = PreservingDict(copy.deepcopy(output_model.extras["qcvars"])) # badly placed # Cfour's SCS-MP2 is non adjustible and only valid for UHF # ROMP2 doesn't print SS & OS # if "MP2 OPPOSITE-SPIN CORRELATION ENERGY" in dqcvars and "MP2 SAME-SPIN CORRELATION ENERGY" in dqcvars: # oss_opt = input_model.extras['qcdb:options'].scroll['QCDB']['MP2_OS_SCALE'] # sss_opt = input_model.extras['qcdb:options'].scroll['QCDB']['MP2_SS_SCALE'] # custom_scsmp2_corl = \ # Decimal(oss_opt.value) * dqcvars["MP2 OPPOSITE-SPIN CORRELATION ENERGY"] + \ # Decimal(sss_opt.value) * dqcvars["MP2 SAME-SPIN CORRELATION ENERGY"] # if "MP2 SINGLES ENERGY" in dqcvars: # custom_scsmp2_corl += dqcvars["MP2 SINGLES ENERGY"] # dqcvars["CUSTOM SCS-MP2 CORRELATION ENERGY"] = custom_scsmp2_corl try: qcvars.build_out(dqcvars) except ValueError: raise InputError( error_stamp(output_model.native_files["input"], output_model.stdout, output_model.stderr)) calcinfo = qcvars.certify_and_datumize( dqcvars, plump=True, nat=len(output_model.molecule.symbols)) output_model.extras["qcdb:qcvars"] = calcinfo return output_model
def qcdb_post_parse_output(self, input_model: AtomicInput, output_model: "AtomicResult") -> "AtomicResult": dqcvars = PreservingDict(copy.deepcopy(output_model.extras["qcvars"])) qcvars.build_out(dqcvars) calcinfo = qcvars.certify_and_datumize( dqcvars, plump=True, nat=len(output_model.molecule.symbols)) output_model.extras["qcdb:qcvars"] = calcinfo return output_model
def qcdb_post_parse_output(self, input_model: 'ResultInput', output_model: 'Result') -> 'Result': dqcvars = PreservingDict(copy.deepcopy(output_model.extras['qcvars'])) qcvars.build_out(dqcvars) calcinfo = qcvars.certify(dqcvars, plump=True, nat=len(output_model.molecule.symbols)) output_model.extras['qcdb:qcvars'] = calcinfo return output_model
def dftd3_harvest(jobrec, dftd3rec): """Processes raw results from read-only `dftd3rec` into QCAspect fields in returned `jobrec`.""" try: jobrec["molecule"]["real"] jobrec["do_gradient"] except KeyError as err: raise KeyError("Required fields missing from ({})".format( jobrec.keys())) from err try: dftd3rec["stdout"] if jobrec["do_gradient"] is True: dftd3rec["dftd3_gradient"] except KeyError as err: raise KeyError("Required fields missing from ({})".format( dftd3rec.keys())) from err # parse energy output (could go further and break into E6, E8, E10 and Cn coeff) for ln in dftd3rec["stdout"].splitlines(): if re.search("DFTD3 V", ln): version = ln.replace("DFTD3", "").replace("|", "").strip().lower() elif re.match(" Edisp /kcal,au", ln): # ene = float(ln.split()[3]) ene = Decimal(ln.split()[3]) elif re.match(" normal termination of dftd3", ln): break else: raise Dftd3Error( "Unsuccessful run. Possibly -D variant not available in dftd3 version." ) # parse gradient output if "dftd3_gradient" in dftd3rec: real = np.array(jobrec["molecule"]["real"]) fnat = real.shape[0] rnat = np.sum(real) srealgrad = dftd3rec["dftd3_gradient"].replace("D", "E") realgrad = np.fromstring(srealgrad, count=3 * rnat, sep=" ").reshape( (-1, 3)) ireal = np.argwhere(real).reshape((-1)) fullgrad = np.zeros((fnat, 3)) fullgrad[ireal, :] = realgrad # TODO if dftd3rec['do_gradient']: raise Dftd3Error # QCAspect = collections.namedtuple('QCAspect', 'lbl unit data comment') # calcinfo = [] # calcinfo.append(QCAspect('DISPERSION CORRECTION ENERGY', '[Eh]', ene, '')) # calcinfo.append( # QCAspect('DISPERSION CORRECTION GRADIENT', '[Eh/a0]', fullgrad, '')) # calcinfo = {info.lbl: info for info in calcinfo} # pprint.pprint(jobrec) # import sys # sys.exit() formal = { "d2p4": "d2", "d2gr": "d2", "d3zero": "d3", "d3bj": "d3(bj)", "d3mzero": "d3m", "d3mbj": "d3m(bj)" } dash = formal[jobrec["dashlevel"]] if jobrec["functional"] == "": qcvkey = " ".join(["custom", dash]).upper() else: fctl = jobrec["functional"] if fctl.endswith("-d"): fctl = fctl[:-2] elif fctl == "lcwpbe": fctl = "wpbe" qcvkey = "-".join([fctl, dash]).upper() dftd3var = {} dftd3var["DISPERSION CORRECTION ENERGY"] = ene dftd3var["{} DISPERSION CORRECTION ENERGY".format(qcvkey)] = ene if "dftd3_gradient" in dftd3rec: dftd3var["DISPERSION CORRECTION GRADIENT"] = fullgrad dftd3var["{} DISPERSION CORRECTION GRADIENT".format(qcvkey)] = fullgrad progvars = PreservingDict(dftd3var) qcvars.build_out(progvars) calcinfo = qcvars.certify_and_datumize(progvars) # amalgamate output text = dftd3rec["stdout"] text += "\n <<< DFTD3 {} {} Results >>>".format( "", "") # name.lower(), calledby.capitalize())) # banner() text += print_variables(calcinfo) jobrec["raw_output"] = text jobrec["qcvars"] = calcinfo prov = {} prov["creator"] = "DFTD3" prov["routine"] = sys._getframe().f_code.co_name prov["version"] = version jobrec["provenance"].append(prov) return jobrec