Пример #1
0
def _has_scf_convergence_message(output_str):
    """ Assess whether the output file string contains the
        message signaling successful convergence of the SCF procedure.

        :param output_str: string of the program's output file
        :type output_str: str
        :rtype: bool
    """

    scf_str1 = (
        'Initial convergence to {} achieved.  Increase integral accuracy.' +
        app.LINE_FILL + app.NEWLINE + app.LINE_FILL + app.escape('SCF Done:')
    ).format(app.EXPONENTIAL_FLOAT_D)
    scf_str2 = app.escape('Rotation gradient small -- convergence achieved.')
    scf_str3 = app.escape('The problem occurs in Multi')
    scf_str4 = app.escape('The problem occurs in cipro')

    pattern = app.one_of_these([scf_str1, scf_str2, scf_str3, scf_str4])

    return apf.has_match(pattern, output_str, case=False)
Пример #2
0
def thermo_block(mech_str, remove_comments=True):
    """ Parses the thermo block out of the mechanism input file.

        :param mech_str: string of mechanism input file
        :type mech_str: str
        :param remove_comments: elect to remove comment liness from string
        :type remove_comments: bool
        :return block_str: string containing thermo block
        :rtype: string
    """

    block_str = _block(string=_clean_up(mech_str,
                                        remove_comments=remove_comments),
                       start_pattern=app.one_of_these([
                           'THERMO ALL', 'THERM ALL', 'THER ALL', 'THERMO',
                           'THERM', 'THER'
                       ]),
                       end_pattern='END')

    return block_str
Пример #3
0
def colliders(rxn_str):
    """ Parses the data string for a reaction in the reactions block
        for the line containing the names of several bath gases and
        their corresponding collider efficiencies

        :param rxn_str: raw Chemkin string for a single reaction
        :type rxn_str: str
        :return params: collider efficiencies for each bath gas
        :rtype: dict {spc1: eff1, spc2: ...}
    """

    bad_strings = ('DUP', 'LOW', 'TROE', 'CHEB', 'PLOG', CHEMKIN_ARROW)
    species_char = app.one_of_these([
        app.LETTER, app.DIGIT,
        app.escape('('),
        app.escape(')'), app.UNDERSCORE
    ])
    species_name = app.one_or_more(species_char)

    # Loop over the lines and search for string with collider facts
    if ('LOW' in rxn_str or 'TROE' in rxn_str or 'M=' in rxn_str
            or 'M =' in rxn_str):
        params = {}
        for line in rxn_str.splitlines():
            if not any(apf.has_match(string, line) for string in bad_strings):
                factor_pattern = (
                    app.capturing(species_name) + app.zero_or_more(app.SPACE) +
                    app.escape('/') + app.zero_or_more(app.SPACE) +
                    app.capturing(app.NUMBER) + app.zero_or_more(app.SPACE) +
                    app.escape('/') + app.zero_or_more(app.SPACE))
                baths = apf.all_captures(factor_pattern, line)
                if baths:
                    for bath in baths:
                        params[bath[0]] = float(bath[1])
        # If nothing was put into the dictionary, set it to None
        if not params:
            params = None
    else:
        params = None

    return params
Пример #4
0
def matrix_block_pattern(symbol_pattern=SYMBOL_PATTERN,
                         key_pattern=KEY_PATTERN,
                         variable_pattern=VARIABLE_PATTERN):
    """ captures the whole matrix block of a z-matrix
    """
    entry_pattern = _entry_pattern(variable_pattern)

    def _patterns(nentries):
        return [symbol_pattern] + nentries * [key_pattern, entry_pattern]

    line_patterns = [
        _LSTART + app.LINESPACES.join(_patterns(n)) + _LEND
        for n in range(0, 4)
    ]
    pattern = app.one_of_these([
        app.NEWLINE.join(line_patterns[:3]) +
        app.zero_or_more(app.NEWLINE + line_patterns[3]),
        app.NEWLINE.join(line_patterns[:2]),
        app.NEWLINE.join(line_patterns[:1]),
    ])
    return app.capturing(pattern)
Пример #5
0
def _ccsd_t_energy(output_str):
    """ Reads the CCSD(T)/UCCSD(T) energy from the output file string.
        Returns the energy in Hartrees.

        :param output_str: string of the program's output file
        :type output_str: str
        :rtype: float
    """

    ene = ar.energy.read(
        output_str,
        app.one_of_these([
            app.escape('!CCSD(T) total energy') + app.maybe(':'),
            app.escape('!RHF-UCCSD(T) energy'),
            app.LINESPACES.join([
                app.escape('!CCSD(T) STATE'),
                app.FLOAT,
                app.escape('Energy')]),
        ]))

    return ene
Пример #6
0
def data_strings(block_str):
    """ Parse all of the NASA polynomials given in the thermo block
        of the mechanism input file and stores them in a list.

        :param block_str: string for thermo block
        :type block_str: str
        :return thm_strs: strings containing NASA polynomials for all species
        :rtype: list(str)
    """

    headline_pattern = (
        app.LINE_START + app.not_followed_by(app.one_of_these(
            [app.DIGIT, app.PLUS, app.escape('=')])) +
        app.one_or_more(app.NONNEWLINE) +
        app.escape('1') + app.LINE_END
    )
    thm_strs = headlined_sections(
        string=block_str.strip(),
        headline_pattern=headline_pattern
    )

    return thm_strs
Пример #7
0
def hessian(output_str):
    """ Reads the molecular Hessian (in Cartesian coordinates) from
        the output file string. Returns the Hessian in atomic units.

        :param output_str: string of the program's output file
        :type output_str: str
        :rtype: tuple(tuple(float))
    """

    comp_ptt = app.UNSIGNED_INTEGER
    mat = ar.matrix.read(
        output_str,
        val_ptt=app.EXPONENTIAL_FLOAT_D,
        start_ptt=(app.escape('Force constants in Cartesian coordinates:') +
                   app.lpadded(app.NEWLINE)),
        block_start_ptt=(app.series(comp_ptt, app.LINESPACES) +
                         app.padded(app.NEWLINE)),
        line_start_ptt=comp_ptt,
        tril=True)

    if mat is not None:
        mat = [[_cast(apf.replace('d', 'e', dst, case=False)) for dst in row]
               for row in mat]

    if mat is None:
        comp_ptt = app.one_of_these(['X', 'Y', 'Z']) + app.UNSIGNED_INTEGER
        mat = ar.matrix.read(
            output_str,
            start_ptt=(app.escape('The second derivative matrix:') +
                       app.lpadded(app.NEWLINE)),
            block_start_ptt=(app.series(comp_ptt, app.LINESPACES) +
                             app.padded(app.NEWLINE)),
            line_start_ptt=comp_ptt,
            tril=True)

    if mat is not None:
        mat = tuple(map(tuple, mat))

    return mat
Пример #8
0
def collider_enhance_factors(rxn_dstr):
    """ Parses the data string for a reaction in the reactions block
        for the line containing the names of several bath gases and
        their corresponding collision enhancement factors.

        :param rxn_dstr: data string for species in reaction block
        :type rxn_dstr: str
        :return factors: Collision enhanncement factors for each bath gas
        :rtype: dict[bath name: enhancement factors]
    """

    first_str = _first_line_pattern(rct_ptt=SPECIES_NAMES_PATTERN,
                                    prd_ptt=SPECIES_NAMES_PATTERN,
                                    param_ptt=COEFF_PATTERN)
    bad_strings = ('DUP', 'LOW', 'TROE', 'CHEB', 'PLOG', first_str)

    species_char = app.one_of_these([
        app.LETTER, app.DIGIT,
        app.escape('('),
        app.escape(')'), app.UNDERSCORE
    ])
    species_name = app.one_or_more(species_char)

    # Loop over the lines and search for string with collider facts
    factors = {}
    if apf.has_match('LOW', rxn_dstr) or apf.has_match('TROE', rxn_dstr):
        for line in rxn_dstr.splitlines():
            if not any(apf.has_match(string, line) for string in bad_strings):
                factor_pattern = (app.capturing(species_name) +
                                  app.escape('/') + app.maybe(app.SPACE) +
                                  app.capturing(app.NUMBER) + app.escape('/'))
                baths = apf.all_captures(factor_pattern, line)
                if baths:
                    factors = {}
                    for bath in baths:
                        factors[bath[0]] = float(bath[1])

    return factors
Пример #9
0
def _lccsd_f12_energy(output_str):
    """ Reads the LCCSD-F12 energy from the output file string.
        Currently, the function only reads the energy of the F12b variant.

        For local, open-shell R/L seem interchangable.

        I think it works with just PNO variant? (because of search line)

        I think it is the same for closed- and open-shell systems.

        Returns the energy in Hartrees.

        :param output_str: string of the program's output file
        :type output_str: str
        :rtype: float
    """

    ptt = app.one_of_these([
        app.escape('!PNO-RCCSD-F12b total energy'),
        app.escape('!PNO-LCCSD-F12b total energy')])

    ene = ar.energy.read(output_str, ptt)
    return ene
Пример #10
0
def stereo_atoms(ich, iso=True, one_indexed=False):
    """ Parse the stereo atoms from the stereochemistry layer.

        :param ich: InChI string
        :type ich: str
        :param iso: Include isotope stereochemistry?
        :type iso: bool
        :param one_indexed: Return indices in one-indexing?
        :type one_indexed: bool
    """
    if len(split(ich)) > 1:
        raise NotImplementedError("Multicomponent InChIs not implemented."
                                  "Call inchi.split() first")

    atm_ptt = (app.capturing(app.UNSIGNED_INTEGER) +
               app.one_of_these(list(map(app.escape, '+-'))))

    ste_dct = stereo_sublayers(ich)
    iso_dct = isotope_sublayers(ich)

    tlyr = ''
    if 't' in ste_dct:
        tlyr += ste_dct['t']

    if iso and 't' in iso_dct:
        tlyr += ',' + iso_dct['t']

    atms = ()
    if tlyr:
        atms = ap_cast(apf.all_captures(atm_ptt, tlyr))

    if not one_indexed:
        atms = tuple(i - 1 for i in atms)
        atms = atms if atms is not None else ()

    return atms
Пример #11
0
def test_():
    """ test autoread.zmatrix
    """
    string = ('  Geometry (in Angstrom), charge = 0, multiplicity = 1:\n'
              '\n'
              '  O\n'
              '  O       1     R1\n'
              '  H       1     R2   2     A2\n'
              '  H       2     R2   1     A2   3     D3\n'
              '\n'
              '  A2    =  96.7725720000\n'
              '  D3    = 129.3669950000\n'
              '  R1    =  1.4470582953\n'
              '  R2    =  0.9760730000\n')

    syms, key_mat, name_mat, val_dct = autoread.zmatrix.read(
        string,
        start_ptt=(
            app.padded(app.escape('Geometry (in Angstrom),'), app.NONNEWLINE) +
            2 * app.padded(app.NEWLINE)))
    assert syms == ('O', 'O', 'H', 'H')
    assert key_mat == ((None, None, None), (1, None, None), (1, 2, None),
                       (2, 1, 3))
    assert name_mat == ((None, None, None), ('R1', None, None),
                        ('R2', 'A2', None), ('R2', 'A2', 'D3'))
    assert val_dct == {
        'A2': 96.772572,
        'D3': 129.366995,
        'R1': 1.4470582953,
        'R2': 0.976073
    }

    string = ('C \n'
              'O , 1 , R1 \n'
              'H , 1 , R2 , 2 , A2 \n'
              'H , 1 , R3 , 2 , A3 , 3 , D3 \n'
              'H , 1 , R4 , 2 , A4 , 3 , D4 \n'
              'H , 2 , R5 , 1 , A5 , 3 , D5 \n'
              '\n'
              'R1  = 2.67535  \n'
              'R2  = 2.06501   A2  = 109.528  \n'
              'R3  = 2.06501   A3  = 109.528   D3  = 120.808        \n'
              'R4  = 2.06458   A4  = 108.982   D4  = 240.404        \n'
              'R5  = 1.83748   A5  = 107.091   D5  = 299.596        \n')

    syms, key_mat, name_mat, val_dct = autoread.zmatrix.read(
        string,
        mat_entry_start_ptt=',',
        mat_entry_sep_ptt=',',
        setv_sep_ptt=app.padded(app.one_of_these(['', app.NEWLINE])))

    assert syms == ('C', 'O', 'H', 'H', 'H', 'H')
    assert key_mat == ((None, None, None), (1, None, None), (1, 2, None),
                       (1, 2, 3), (1, 2, 3), (2, 1, 3))
    assert name_mat == ((None, None, None), ('R1', None, None),
                        ('R2', 'A2', None), ('R3', 'A3', 'D3'),
                        ('R4', 'A4', 'D4'), ('R5', 'A5', 'D5'))
    assert val_dct == {
        'R1': 2.67535,
        'R2': 2.06501,
        'A2': 109.528,
        'R3': 2.06501,
        'A3': 109.528,
        'D3': 120.808,
        'R4': 2.06458,
        'A4': 108.982,
        'D4': 240.404,
        'R5': 1.83748,
        'A5': 107.091,
        'D5': 299.596
    }

    string = ('C \n'
              'X , 1 , R1 \n'
              'C , 1 , R2 , 2 , A2 \n'
              'H , 1 , R3 , 2 , A3 , 3 , D3 \n'
              'C , 3 , R4 , 1 , A4 , 2 , D4 \n'
              'H , 3 , R5 , 1 , A5 , 5 , D5 \n'
              'C , 5 , R6 , 3 , A6 , 1 , D6 \n'
              'H , 5 , R7 , 3 , A7 , 7 , D7 \n'
              'C , 7 , R8 , 5 , A8 , 3 , D8 \n'
              'H , 7 , R9 , 5 , A9 , 9 , D9 \n'
              'O , 9 , R10, 7 , A10, 5 , D10\n'
              'H , 9 , R11, 7 , A11, 11, D11\n'
              '\n'
              'R1  = 1       \n'
              'R2  = 2.45306  A2  = 90      \n'
              'R3  = 2.0156   A3  = 90       D3  = 180      \n'
              'R4  = 2.72923  A4  = 125.99   D4  = 0        \n'
              'R5  = 2.05621  A5  = 118.134  D5  = 180      \n'
              'R6  = 2.53427  A6  = 131.892  D6  = 0.004769 \n'
              'R7  = 2.06371  A7  = 112.345  D7  = 180      \n'
              'R8  = 2.7902   A8  = 128.119  D8  = 1.62e-05 \n'
              'R9  = 2.05471  A9  = 119.045  D9  = 180      \n'
              'R10 = 2.31772  A10 = 120.738  D10 = 180      \n'
              'R11 = 2.07277  A11 = 117.734  D11 = 180      \n')

    syms, key_mat, name_mat, val_dct = autoread.zmatrix.read(
        string,
        mat_entry_start_ptt=',',
        mat_entry_sep_ptt=',',
        setv_sep_ptt=app.padded(app.one_of_these(['', app.NEWLINE])))
Пример #12
0
def test__setval():
    """ test autoread.zmatrix.setval
    """
    string = ('    A2        =   96.7725720000\n'
              '    D3        =  129.3669950000\n'
              '    R1        =    1.4470582953\n'
              '    R2        =    0.9760730000\n')

    val_dct = autoread.zmatrix.setval.read(string)

    assert val_dct == {
        'A2': 96.772572,
        'D3': 129.366995,
        'R1': 1.4470582953,
        'R2': 0.976073
    }

    string = ('              ----------------------------\n'
              '              !   Optimized Parameters   !\n'
              '              ! (Angstroms and Degrees)  !\n'
              ' -------------                            -----\n'
              ' !  Name     Value   Derivative information   !\n'
              ' ----------------------------------------------\n'
              ' !   R1     1.4057   -DE/DX =    0.0          !\n'
              ' !   R2     0.9761   -DE/DX =    0.0628       !\n'
              ' !   A2    96.7726   -DE/DX =    0.0552       !\n'
              ' !   D3   129.367    -DE/DX =    0.0019       !\n'
              ' ----------------------------------------------\n'
              ' GradGradGradGradGradGradGradGradGradGradGradGrad\n')

    start_ptt = app.padded(app.NEWLINE).join([
        app.escape('!   Optimized Parameters   !'), app.LINE, app.LINE,
        app.LINE, app.LINE, ''
    ])

    val_dct = autoread.zmatrix.setval.read(
        string,
        start_ptt=start_ptt,
        entry_sep_ptt='',
        entry_start_ptt=app.escape('!'),
        sep_ptt=app.maybe(app.LINESPACES).join(
            [app.escape('-DE/DX ='), app.FLOAT,
             app.escape('!'), app.NEWLINE]))

    assert val_dct == {
        'R1': 1.4057,
        'R2': 0.9761,
        'A2': 96.7726,
        'D3': 129.367
    }

    string = ('R1  = 2.73454  \n'
              'R2  = 1.84451   A2  = 96.7726  \n'
              'R3  = 1.84451   A3  = 96.7726   D3  = 129.367        \n')

    val_dct = autoread.zmatrix.setval.read(string,
                                           sep_ptt=app.one_of_these(
                                               ['', app.NEWLINE]))

    assert val_dct == {
        'R1': 2.73454,
        'R2': 1.84451,
        'A2': 96.7726,
        'R3': 1.84451,
        'A3': 96.7726,
        'D3': 129.367
    }

    string = (' SETTING R1             =         1.37586100\n'
              ' SETTING R2             =         1.05835400\n'
              ' SETTING A2             =       108.86198100\n'
              ' SETTING R3             =         1.05835400\n'
              ' SETTING A3             =       108.86198100\n'
              ' SETTING D3             =       120.32113700\n'
              ' SETTING R4             =         1.05835400\n'
              ' SETTING A4             =       108.86198100\n'
              ' SETTING D4             =       234.91269600\n'
              ' SETTING R5             =         0.95251900\n'
              ' SETTING A5             =       103.13240300\n'
              ' SETTING D5             =       297.93805300\n'
              ' SETTING SPIN           =     0.00000000D+00\n'
              ' SETTING CHARGE         =     0.00000000D+00\n')

    val_dct = autoread.zmatrix.setval.read(
        string,
        entry_start_ptt='SETTING',
        val_ptt=app.one_of_these([app.EXPONENTIAL_FLOAT_D, app.NUMBER]),
        last=False,
        case=False)
    assert val_dct == {
        'R1': 1.375861,
        'R2': 1.058354,
        'A2': 108.861981,
        'R3': 1.058354,
        'A3': 108.861981,
        'D3': 120.321137,
        'R4': 1.058354,
        'A4': 108.861981,
        'D4': 234.912696,
        'R5': 0.952519,
        'A5': 103.132403,
        'D5': 297.938053,
        'SPIN': '0.00000000D+00',
        'CHARGE': '0.00000000D+00'
    }

    string = (' Optimized variables\n'
              ' R1=                  1.43218364 ANGSTROM\n'
              ' R2=                  1.09538054 ANGSTROM\n'
              ' A2=                112.03775543 DEGREE\n'
              ' R3=                  1.09538307 ANGSTROM\n'
              ' A3=                112.04463832 DEGREE\n'
              ' R4=                  1.09084803 ANGSTROM\n'
              ' A4=                108.31761858 DEGREE\n'
              ' D4=                240.16203078 DEGREE\n'
              ' D5=                299.84441753 DEGREE\n')

    val_dct = autoread.zmatrix.setval.read(
        string,
        start_ptt=app.padded('Optimized variables') + app.NEWLINE,
        entry_end_ptt=app.one_of_these(['ANGSTROM', 'DEGREE']),
        last=True,
        case=False)
    assert val_dct == {
        'R1': 1.43218364,
        'R2': 1.09538054,
        'A2': 112.03775543,
        'R3': 1.09538307,
        'A3': 112.04463832,
        'R4': 1.09084803,
        'A4': 108.31761858,
        'D4': 240.16203078,
        'D5': 299.84441753
    }
Пример #13
0
def opt_zmatrix(output_string):
    """ get optimized z-matrix geometry from output
    """
    # read the matrix from the beginning of the output
    syms, key_mat, name_mat = ar.zmatrix.matrix.read(
        output_string,
        start_ptt=app.maybe(app.SPACES).join(
            ['geometry', app.escape('='),
             app.escape('{'), '']),
        entry_start_ptt=app.maybe(','),
        entry_sep_ptt=',',
        last=False,
        case=False)

    # read the initial z-matrix values from the beginning out the output
    if len(syms) == 1:
        val_dct = {}
    else:
        val_dct = ar.zmatrix.setval.read(
            output_string,
            # entry_start_ptt=MOLPRO_ENTRY_START_PATTERN,
            entry_start_ptt='SETTING',
            name_ptt=(app.one_of_these(['R', 'A', 'D']) +
                      app.one_or_more(app.INTEGER)),
            val_ptt=(app.one_of_these([app.EXPONENTIAL_FLOAT_D, app.NUMBER])),
            last=True,
            case=False)

    names = sorted(set(numpy.ravel(name_mat)) - {None})
    caps_names = list(map(str.upper, names))
    name_dct = dict(zip(caps_names, names))
    assert set(caps_names) <= set(val_dct)
    val_dct = {
        name_dct[caps_name]: val_dct[caps_name]
        for caps_name in caps_names
    }

    # read optimized z-matrix values from the end of the output
    var_string = app.one_of_these(
        [app.padded('Optimized variables'),
         app.padded('Current variables')])
    opt_val_dct = ar.zmatrix.setval.read(output_string,
                                         start_ptt=var_string + app.NEWLINE,
                                         entry_end_ptt=app.one_of_these(
                                             ['ANGSTROM', 'DEGREE']),
                                         last=True,
                                         case=False)
    opt_val_dct = {
        name_dct[caps_name]: opt_val_dct[caps_name]
        for caps_name in opt_val_dct.keys()
    }
    assert set(opt_val_dct) <= set(val_dct)
    val_dct.update(opt_val_dct)

    # call the automol constructor
    zma = automol.zmatrix.from_data(syms,
                                    key_mat,
                                    name_mat,
                                    val_dct,
                                    one_indexed=True,
                                    angstrom=True,
                                    degree=True)
    return zma
Пример #14
0
""" molecular geometry and structure readers
"""
import numpy
import autoread as ar
import autoparse.pattern as app
import automol

MOLPRO_ENTRY_START_PATTERN = ('SETTING' + app.SPACES +
                              app.one_of_these(['R', 'A', 'D']) +
                              app.one_or_more(app.INTEGER))
# 'SETTING' + app.not_followed_by(app.padded('MOLPRO_ENERGY')),
# 'SETTING' + app.not_followed_by('MOLPRO_ENERGY'),
# 'SETTING' + app.not_followed_by(app.padded('SPIN')),
# 'SETTING' + app.not_followed_by(app.padded('CHARGE'))


def opt_geometry(output_string):
    """ get optimized geometry from output
    """
    ptt = app.padded(app.NEWLINE).join([
        app.escape('Current geometry (xyz format, in Angstrom)'), '',
        app.UNSIGNED_INTEGER,
        (app.one_or_more(app.NONNEWLINE) + app.SPACES + 'ENERGY=' + app.FLOAT),
        ''
    ])
    # app.padded(app.NEWLINE).join([
    #     app.escape('ATOMIC COORDINATES'),
    #     app.LINE, app.LINE, app.LINE, '']),

    syms, xyzs = ar.geom.read(output_string, start_ptt=ptt)
    # line_start_ptt=(app.LETTER + app.maybe(app.LETTER)))
Пример #15
0
def cheb(rxn_str):
    """ Parses the data string for a reaction in the reactions block
        for the lines containing the Chebyshevs fitting parameters,
        then reads the parameters from these lines.

        :param rxn_str: raw Chemkin string for a single reaction
        :type rxn_str: str
        :return params: Chebyshev fitting parameters
        :rtype: dict[param: value]
    """

    original_rxn_str = rxn_str
    rxn_str = apf.remove(COMMENTS_PATTERN, rxn_str)

    tcheb_pattern = ('TCHEB' + app.zero_or_more(app.SPACE) + app.escape('/') +
                     app.zero_or_more(app.SPACE) + app.capturing(app.NUMBER) +
                     app.one_or_more(app.SPACE) + app.capturing(app.NUMBER) +
                     app.zero_or_more(app.SPACE) + app.escape('/'))
    pcheb_pattern = ('PCHEB' + app.zero_or_more(app.SPACE) + app.escape('/') +
                     app.zero_or_more(app.SPACE) + app.capturing(app.NUMBER) +
                     app.one_or_more(app.SPACE) + app.capturing(app.NUMBER) +
                     app.zero_or_more(app.SPACE) + app.escape('/'))
    cheb_pattern = (app.not_preceded_by(app.one_of_these(['T', 'P'])) +
                    'CHEB' + app.zero_or_more(app.SPACE) + app.escape('/') +
                    app.capturing(app.one_or_more(app.WILDCARD2)) +
                    app.escape('/'))

    cheb_params_raw = apf.all_captures(cheb_pattern, rxn_str)

    if cheb_params_raw:
        params = {}
        # Get temp and pressure limits or use Chemkin defaults if non-existent
        cheb_temps = apf.first_capture(tcheb_pattern, rxn_str)
        cheb_pressures = apf.first_capture(pcheb_pattern, rxn_str)
        if cheb_temps is None:
            cheb_temps = ('300.00', '2500.00')
            print('No Chebyshev temperature limits specified' +
                  ' for the below reaction.' +
                  f' Assuming 300 and 2500 K. \n \n {original_rxn_str}\n')
        if cheb_pressures is None:
            cheb_pressures = ('0.001', '100.00')
            print('No Chebyshev pressure limits specified' +
                  ' for the below reaction.' +
                  f' Assuming 0.001 and 100 atm. \n \n {original_rxn_str}\n')

        # Get all the numbers from the CHEB parameters
        cheb_params = []
        for cheb_line in cheb_params_raw:
            cheb_params.extend(cheb_line.split())

        # Get alpha dimensions N and M, which are the first two CHEB entries
        cheb_n = int(float(cheb_params[0]))
        cheb_m = int(float(cheb_params[1]))

        # Start on third value (after N and M) and get all polynomial coeffs
        coeffs = []
        for idx, coeff in enumerate(cheb_params[2:]):
            # extra coefficients are allowed but ignored
            if idx + 1 > (cheb_n * cheb_m):
                break
            coeffs.append(coeff)
        assert len(coeffs) == (cheb_n * cheb_m), (
            f'For the below reaction, there should be {cheb_n*cheb_m}' +
            ' Chebyshev polynomial' +
            f' coefficients, but there are only {len(coeffs)}.' +
            f' \n \n {original_rxn_str}\n')
        alpha = np.array(list(map(float, coeffs)))

        params['tlim'] = tuple(float(val) for val in cheb_temps)
        params['plim'] = tuple(float(val) for val in cheb_pressures)
        params['alpha'] = alpha.reshape([cheb_n, cheb_m])

    else:
        params = None

    return params
Пример #16
0
def _charge_layer_pattern():
    q_slyr_ptt = _sublayer_pattern(key_ptt='q')
    p_slyr_ptt = _sublayer_pattern(key_ptt='p')
    ptt = (app.one_of_these([q_slyr_ptt, p_slyr_ptt]) +
           app.maybe(SLASH + p_slyr_ptt))
    return ptt
Пример #17
0
from phydat import phycon
from autoreact.params import RxnParams

# Various strings needed to parse the data sections of the Reaction block
CHEMKIN_ARROW = (app.maybe(app.escape('<')) + app.escape('=') +
                 app.maybe(app.escape('>')))
CHEMKIN_PLUS_EM = app.PLUS + 'M'
CHEMKIN_PAREN_PLUS_EM = app.escape('(') + app.PLUS + 'M' + app.escape(')')
CHEMKIN_PAREN_PLUS = app.escape('(') + app.PLUS
CHEMKIN_PAREN_CLOSE = app.escape(')')

SPECIES_NAME_PATTERN = (r'[^\s=+\-]' + app.zero_or_more(
    app.one_of_these([
        app.LETTER, app.DIGIT, r'[#,()\-_]',
        app.escape('*'),
        app.escape('(+)'),
        app.escape('['),
        app.escape(']')
    ])) + app.zero_or_more(app.PLUS))
SPECIES_NAMES_PATTERN = app.series(app.padded(SPECIES_NAME_PATTERN),
                                   app.padded(app.PLUS))

REACTION_PATTERN = (SPECIES_NAMES_PATTERN + app.padded(CHEMKIN_ARROW) +
                    SPECIES_NAMES_PATTERN)
COEFF_PATTERN = (app.NUMBER + app.LINESPACES + app.NUMBER + app.LINESPACES +
                 app.NUMBER)
COMMENTS_PATTERN = app.escape('!') + app.capturing(
    app.one_or_more(app.WILDCARD2))

BAD_STRS = ['inf', 'INF', 'nan']
Пример #18
0
""" energy parsers
"""
from autoparse import cast as _cast
import autoparse.find as apf
import autoparse.pattern as app

# VALUE_PATTERN = app.one_of_these([app.FLOAT])
VALUE_PATTERN = app.one_of_these([app.EXPONENTIAL_FLOAT_D, app.FLOAT])
SEP_PATTERN = app.LINESPACES


def read(string,
         start_ptt,
         val_ptt=VALUE_PATTERN,
         last=True,
         case=False):
    """ read energy from a string
    """
    ptt_ = pattern(start_ptt=start_ptt, val_ptt=app.capturing(val_ptt))

    ene_str = (apf.last_capture(ptt_, string, case=case) if last else
               apf.first_capture(ptt_, string, case=case))
    ene = _cast(ene_str.replace('D', 'E'))
    return ene


def pattern(start_ptt,
            val_ptt=VALUE_PATTERN):
    """ energy pattern
    """
    return start_ptt + app.lpadded(val_ptt)
Пример #19
0
def opt_zmatrix(output_str):
    """ Reads the optimized Z-Matrix from the output file string.
        Returns the Z-Matrix in Bohr and Radians.

        :param output_str: string of the program's output file
        :type output_str: str
        :rtype: automol molecular geometry data structure
    """

    # Reads the matrix from the beginning of the output
    symbs, key_mat, name_mat = ar.vmat.read(
        output_str,
        start_ptt=app.padded(app.NEWLINE).join(
            [app.escape('Symbolic Z-matrix:'), app.LINE, '']),
        symb_ptt=ar.par.Pattern.ATOM_SYMBOL + app.maybe(app.UNSIGNED_INTEGER),
        key_ptt=app.one_of_these([app.UNSIGNED_INTEGER, app.VARIABLE_NAME]),
        line_end_ptt=app.maybe(app.UNSIGNED_INTEGER),
        last=False)

    # Reads the values from the end of the output
    if all(x is not None for x in (symbs, key_mat, name_mat)):
        grad_val = app.one_of_these([app.FLOAT, 'nan', '-nan'])
        if len(symbs) == 1:
            val_mat = ((None, None, None), )
        else:
            val_dct = ar.setval.read(output_str,
                                     start_ptt=app.padded(app.NEWLINE).join([
                                         app.padded('Optimized Parameters',
                                                    app.NONNEWLINE), app.LINE,
                                         app.LINE, app.LINE, app.LINE, ''
                                     ]),
                                     entry_sep_ptt='',
                                     entry_start_ptt=app.escape('!'),
                                     sep_ptt=app.maybe(app.LINESPACES).join([
                                         app.escape('-DE/DX ='), grad_val,
                                         app.escape('!'), app.NEWLINE
                                     ]),
                                     last=True)
            val_mat = ar.setval.convert_dct_to_matrix(val_dct, name_mat)

        # Check for the pattern
        err_ptt = app.LINESPACES.join(
            [app.escape('-DE/DX ='),
             app.one_of_these(['nan', '-nan'])])
        if 'Optimized Parameters' in output_str:
            test_str = output_str.split('Optimized Parameters')[1]
            if apf.has_match(err_ptt, test_str):
                print('Warning: Bad gradient value (nan)',
                      'in "Optimized Parameters" list.')

        # For the case when variable names are used instead of integer keys:
        # (otherwise, does nothing)
        key_dct = dict(map(reversed, enumerate(symbs)))
        key_dct[None] = 0
        key_mat = [[
            key_dct[val] + 1 if not isinstance(val, numbers.Real) else val
            for val in row
        ] for row in key_mat]
        symb_ptt = app.STRING_START + app.capturing(ar.par.Pattern.ATOM_SYMBOL)
        symbs = [apf.first_capture(symb_ptt, symb) for symb in symbs]

        # Call the automol constructor
        zma = automol.zmat.from_data(symbs,
                                     key_mat,
                                     val_mat,
                                     name_mat,
                                     one_indexed=True,
                                     angstrom=True,
                                     degree=True)
    else:
        zma = None

    return zma
Пример #20
0
def test__matrix():
    """ test autoread.matrix
    """

    # Gradients
    start_ptt = (app.padded(app.NEWLINE).join([
        app.padded(app.escape('Forces (Hartrees/Bohr)'), app.NONNEWLINE),
        app.LINE, app.LINE, ''
    ]))

    mat = autoread.matrix.read(GRAD1_STR,
                               start_ptt=start_ptt,
                               line_start_ptt=app.LINESPACES.join(
                                   [app.UNSIGNED_INTEGER] * 2))
    assert numpy.allclose(mat, ((0.0, -0.0, -0.061240635),
                                (0.0, -0.021691602, 0.030622057),
                                (-0.0, 0.021691602, 0.030622057)))

    start_ptt = (app.padded(app.NEWLINE).join([
        app.escape('## Gradient (Symmetry 0) ##'), app.LINE, '', app.LINE, '',
        ''
    ]))

    mat = autoread.matrix.read(GRAD2_STR,
                               start_ptt=start_ptt,
                               line_start_ptt=app.UNSIGNED_INTEGER)
    assert numpy.allclose(mat, ((0.0, 0.0, 0.997), (0.0, -0.749, -0.488),
                                (-0.0, 0.749, -0.488)))

    # Hessians
    start_ptt = (app.escape('The second derivative matrix:') +
                 app.lpadded(app.NEWLINE))
    comp_ptt = app.one_of_these(['X', 'Y', 'Z']) + app.UNSIGNED_INTEGER
    block_start_ptt = (app.series(comp_ptt, app.LINESPACES) +
                       app.padded(app.NEWLINE))

    mat = autoread.matrix.read(HESS1_STR,
                               start_ptt=start_ptt,
                               block_start_ptt=block_start_ptt,
                               line_start_ptt=comp_ptt,
                               tril=True)
    assert numpy.allclose(
        mat,
        ((-0.21406, 0., 0., -0.06169, 0., 0., 0.27574, 0., 0.),
         (0., 2.05336, 0.12105, 0., -0.09598, 0.08316, 0., -1.95737, -0.20421),
         (0., 0.12105, 0.19177, 0., -0.05579, -0.38831, 0., -0.06525, 0.19654),
         (-0.06169, 0., 0., 0.0316, 0., 0., 0.03009, 0., 0.),
         (0., -0.09598, -0.05579, 0., 0.12501, -0.06487, 0., -0.02902,
          0.12066), (0., 0.08316, -0.38831, 0., -0.06487, 0.44623, 0.,
                     -0.01829, -0.05792),
         (0.27574, 0., 0., 0.03009, 0., 0., -0.30583, 0., 0.),
         (0., -1.95737, -0.06525, 0., -0.02902, -0.01829, 0., 1.9864, 0.08354),
         (0., -0.20421, 0.19654, 0., 0.12066, -0.05792, 0., 0.08354,
          -0.13862)))

    start_ptt = (app.padded(app.NEWLINE).join(
        [app.escape('## Hessian (Symmetry 0) ##'), app.LINE, '']))
    block_start_ptt = (app.padded(app.NEWLINE).join(
        ['', app.series(app.UNSIGNED_INTEGER, app.LINESPACES), '', '']))

    mat = autoread.matrix.read(HESS2_STR,
                               start_ptt=start_ptt,
                               block_start_ptt=block_start_ptt,
                               line_start_ptt=app.UNSIGNED_INTEGER)
    assert numpy.allclose(
        mat, ((0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
              (0.0, 0.959, 0.0, 0.0, -0.452, 0.519, 0.0, -0.477, -0.23),
              (0.0, 0.0, 0.371, 0.0, 0.222, -0.555, 0.0, -0.279, -0.128),
              (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
              (0.0, -0.479, 0.279, 0.0, 0.455, -0.256, 0.0, -0.017, 0.051),
              (0.0, 0.251, -0.185, 0.0, -0.247, 0.607, 0.0, -0.012, 0.09),
              (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
              (0.0, -0.479, -0.279, 0.0, -0.003, -0.263, 0.0, 0.494, 0.279),
              (0.0, -0.251, -0.185, 0.0, 0.025, 0.947, 0.0, 0.292, 0.137)))

    # Test finding nothing
    mat = autoread.matrix.read('',
                               start_ptt=start_ptt,
                               block_start_ptt=block_start_ptt,
                               line_start_ptt=app.UNSIGNED_INTEGER)
    assert mat is None
Пример #21
0
def opt_zmatrix(output_str):
    """ Reads the optimized Z-Matrix from the output file string.
        Returns the Z-Matrix in Bohr and Radians.

        :param output_str: string of the program's output file
        :type output_str: str
        :rtype: automol molecular geometry data structure
    """

    # Reads the matrix from the beginning of the output
    symbs, key_mat, name_mat = ar.vmat.read(
        output_str,
        start_ptt=app.maybe(app.SPACES).join([
            'geometry', app.escape('='), app.escape('{'), '']),
        entry_start_ptt=app.maybe(','),
        entry_sep_ptt=',',
        last=False,
        case=False)

    # Read the initial z-matrix values from the beginning out the output
    if all(x is not None for x in (symbs, key_mat, name_mat)):
        if len(symbs) == 1:
            val_dct = {}
        else:
            val_dct = ar.setval.read(
                output_str,
                # entry_start_ptt=MOLPRO_ENTRY_START_PATTERN,
                entry_start_ptt='SETTING',
                name_ptt=(
                    app.one_of_these(['R', 'A', 'D']) +
                    app.one_or_more(app.INTEGER)),
                val_ptt=(
                    app.one_of_these([app.EXPONENTIAL_FLOAT_D, app.NUMBER])),
                last=True,
                case=False)

        names = sorted(set(numpy.ravel(name_mat)) - {None})
        caps_names = list(map(str.upper, names))
        name_dct = dict(zip(caps_names, names))
        assert set(caps_names) <= set(val_dct)
        val_dct = {name_dct[caps_name]: val_dct[caps_name]
                   for caps_name in caps_names}

        # Read optimized z-matrix values from the end of the output
        var_string = app.one_of_these([
            app.padded('Optimized variables'),
            app.padded('Current variables')
        ])
        opt_val_dct = ar.setval.read(
            output_str,
            start_ptt=var_string + app.NEWLINE,
            entry_end_ptt=app.one_of_these(['ANGSTROM', 'DEGREE']),
            last=True,
            case=False)
        opt_val_dct = {name_dct[caps_name]: opt_val_dct[caps_name]
                       for caps_name in opt_val_dct.keys()}
        assert set(opt_val_dct) <= set(val_dct)
        val_dct.update(opt_val_dct)

        val_mat = ar.setval.convert_dct_to_matrix(val_dct, name_mat)

        # Call the automol constructor
        zma = automol.zmat.from_data(
            symbs, key_mat, val_mat, name_mat,
            one_indexed=True, angstrom=True, degree=True)
    else:
        zma = None

    return zma
Пример #22
0
def test__setval():
    """ test autoread.zmat.setval
    """

    val_dct = autoread.setval.read(ZMA_VAL1_STR)
    assert val_dct == {
        'A2': 96.772572,
        'D3': 129.366995,
        'R1': 1.4470582953,
        'R2': 0.976073
    }

    start_ptt = app.padded(app.NEWLINE).join([
        app.escape('!   Optimized Parameters   !'), app.LINE, app.LINE,
        app.LINE, app.LINE, ''
    ])

    val_dct = autoread.setval.read(ZMA_VAL2_STR,
                                   start_ptt=start_ptt,
                                   entry_sep_ptt='',
                                   entry_start_ptt=app.escape('!'),
                                   sep_ptt=app.maybe(app.LINESPACES).join([
                                       app.escape('-DE/DX ='), app.FLOAT,
                                       app.escape('!'), app.NEWLINE
                                   ]))
    assert val_dct == {
        'R1': 1.4057,
        'R2': 0.9761,
        'A2': 96.7726,
        'D3': 129.367
    }

    val_dct = autoread.setval.read(ZMA_VAL3_STR,
                                   sep_ptt=app.one_of_these(['', app.NEWLINE]))
    assert val_dct == {
        'R1': 2.73454,
        'R2': 1.84451,
        'A2': 96.7726,
        'R3': 1.84451,
        'A3': 96.7726,
        'D3': 129.367
    }

    val_dct = autoread.setval.read(ZMA_VAL4_STR,
                                   entry_start_ptt='SETTING',
                                   val_ptt=app.one_of_these(
                                       [app.EXPONENTIAL_FLOAT_D, app.NUMBER]),
                                   last=False,
                                   case=False)
    assert val_dct == {
        'R1': 1.375861,
        'R2': 1.058354,
        'A2': 108.861981,
        'R3': 1.058354,
        'A3': 108.861981,
        'D3': 120.321137,
        'R4': 1.058354,
        'A4': 108.861981,
        'D4': 234.912696,
        'R5': 0.952519,
        'A5': 103.132403,
        'D5': 297.938053,
        'SPIN': '0.00000000D+00',
        'CHARGE': '0.00000000D+00'
    }

    val_dct = autoread.setval.read(
        ZMA_VAL5_STR,
        start_ptt=app.padded('Optimized variables') + app.NEWLINE,
        entry_end_ptt=app.one_of_these(['ANGSTROM', 'DEGREE']),
        last=True,
        case=False)
    assert val_dct == {
        'R1': 1.43218364,
        'R2': 1.09538054,
        'A2': 112.03775543,
        'R3': 1.09538307,
        'A3': 112.04463832,
        'R4': 1.09084803,
        'A4': 108.31761858,
        'D4': 240.16203078,
        'D5': 299.84441753
    }
Пример #23
0
def test_zmat():
    """ test autoread.zmat
    """
    def _val_mats_similar(val_mat, ref_val_mat):
        """ Check if two value matrices are the same
        """
        for i, row in enumerate(val_mat):
            for j, val in enumerate(row):
                ref_val = ref_val_mat[i][j]
                if val is None:
                    assert ref_val is None
                else:
                    assert numpy.isclose(val, ref_val)

    # Simple ZMA reads
    start_ptt = (
        app.padded(app.escape('Geometry (in Angstrom),'), app.NONNEWLINE) +
        2 * app.padded(app.NEWLINE))

    symbs, key_mat, name_mat, val_mat = autoread.zmat.read(ZMA1_STR,
                                                           start_ptt=start_ptt)
    assert symbs == ('O', 'O', 'H', 'H')
    assert key_mat == ((None, None, None), (1, None, None), (1, 2, None),
                       (2, 1, 3))
    assert name_mat == ((None, None, None), ('R1', None, None),
                        ('R2', 'A2', None), ('R2', 'A2', 'D3'))
    ref_val_mat = ((None, None, None), (1.4470582953, None, None),
                   (0.976073, 96.772572, None), (0.976073, 96.772572,
                                                 129.36699))
    _val_mats_similar(val_mat, ref_val_mat)

    symbs, key_mat, name_mat, val_mat = autoread.zmat.read(
        ZMA2_STR,
        mat_entry_start_ptt=',',
        mat_entry_sep_ptt=',',
        setv_sep_ptt=app.padded(app.one_of_these(['', app.NEWLINE])))
    assert symbs == ('C', 'O', 'H', 'H', 'H', 'H')
    assert key_mat == ((None, None, None), (1, None, None), (1, 2, None),
                       (1, 2, 3), (1, 2, 3), (2, 1, 3))
    assert name_mat == ((None, None, None), ('R1', None, None),
                        ('R2', 'A2', None), ('R3', 'A3', 'D3'),
                        ('R4', 'A4', 'D4'), ('R5', 'A5', 'D5'))
    ref_val_mat = ((None, None, None), (2.67535, None, None),
                   (2.06501, 109.528, None), (2.06501, 109.528, 120.808),
                   (2.06458, 108.982, 240.404), (1.83748, 107.091, 299.596))
    _val_mats_similar(val_mat, ref_val_mat)
    # assert val_dct == {
    #     'R1': 2.67535, 'R2': 2.06501, 'A2': 109.528, 'R3': 2.06501,
    #     'A3': 109.528, 'D3': 120.808, 'R4': 2.06458, 'A4': 108.982,
    #     'D4': 240.404, 'R5': 1.83748, 'A5': 107.091, 'D5': 299.596}

    symbs, key_mat, name_mat, val_mat = autoread.zmat.read(
        ZMA4_STR,
        mat_entry_start_ptt=',',
        mat_entry_sep_ptt=',',
        setv_sep_ptt=app.padded(app.one_of_these(['', app.NEWLINE])),
        last=False)
    assert symbs == ('C', )
    assert key_mat == ((None, None, None), )
    assert name_mat == ((None, None, None), )
    assert val_mat == ((None, None, None), )

    # Check last functionality
    symbs, key_mat, name_mat, val_mat = autoread.zmat.read(
        ZMA2_STR + '\n\n' + ZMA3_STR,
        mat_entry_start_ptt=',',
        mat_entry_sep_ptt=',',
        setv_sep_ptt=app.padded(app.one_of_these(['', app.NEWLINE])),
        last=False)
    assert symbs == ('C', 'O', 'H', 'H', 'H', 'H')
    assert key_mat == ((None, None, None), (1, None, None), (1, 2, None),
                       (1, 2, 3), (1, 2, 3), (2, 1, 3))
    assert name_mat == ((None, None, None), ('R1', None, None),
                        ('R2', 'A2', None), ('R3', 'A3', 'D3'),
                        ('R4', 'A4', 'D4'), ('R5', 'A5', 'D5'))
    ref_val_mat = ((None, None, None), (2.67535, None, None),
                   (2.06501, 109.528, None), (2.06501, 109.528, 120.808),
                   (2.06458, 108.982, 240.404), (1.83748, 107.091, 299.596))
    _val_mats_similar(val_mat, ref_val_mat)
Пример #24
0
def _main_layer_pattern():
    c_slyr_ptt = _sublayer_pattern(key_ptt='c')
    h_slyr_ptt = _sublayer_pattern(key_ptt='h')
    ptt = (app.one_of_these([c_slyr_ptt, h_slyr_ptt]) +
           app.maybe(SLASH + h_slyr_ptt))
    return ptt
Пример #25
0
def _has_scf_convergence_message(output_string):
    """ does this output string have a convergence success message?
    """
    scf_str1 = 'Energy and wave function converged'
    pattern = app.one_of_these([scf_str1])
    return apf.has_match(pattern, output_string, case=True)
Пример #26
0
def options_matrix_optimization(script_str,
                                prefix,
                                geom,
                                chg,
                                mul,
                                method,
                                basis,
                                prog,
                                errors=(),
                                options_mat=(),
                                feedback=False,
                                frozen_coordinates=(),
                                freeze_dummy_atoms=True,
                                **kwargs):
    """ try several sets of options to generate an output file

    :returns: the input string and the output string
    :rtype: (str, str)
    """
    assert len(errors) == len(options_mat)

    subrun_fs = autofile.fs.subrun(prefix)
    max_macro_idx, _ = max(subrun_fs[-1].existing(), default=(-1, -1))
    macro_idx = max_macro_idx + 1
    micro_idx = 0
    read_geom_ = (elstruct.reader.opt_zmatrix_(prog)
                  if automol.zmatrix.is_valid(geom) else
                  elstruct.reader.opt_geometry_(prog))

    if freeze_dummy_atoms and automol.zmatrix.is_valid(geom):
        frozen_coordinates = (tuple(frozen_coordinates) +
                              automol.zmatrix.dummy_coordinate_names(geom))

    kwargs_ = dict(kwargs)
    while True:
        subrun_fs[-1].create([macro_idx, micro_idx])
        path = subrun_fs[-1].path([macro_idx, micro_idx])

        with warnings.catch_warnings():
            warnings.simplefilter('ignore')
            inp_str, out_str = elstruct.run.direct(
                elstruct.writer.optimization,
                script_str,
                path,
                geom=geom,
                charge=chg,
                mult=mul,
                method=method,
                basis=basis,
                prog=prog,
                frozen_coordinates=frozen_coordinates,
                **kwargs_)

        error_vals = [
            elstruct.reader.has_error_message(prog, error, out_str)
            for error in errors
        ]

        # Kill the while loop if we Molpro error signaling a hopeless point
        # When an MCSCF WF calculation fails to converge at some step in opt
        # it is not clear how to save the optimization, so we give up on opt
        fail_pattern = app.one_of_these([
            app.escape('The problem occurs in Multi'),
            app.escape('The problem occurs in cipro')
        ])
        if apf.has_match(fail_pattern, out_str, case=False):
Пример #27
0
def opt_zmatrix(output_str):
    """ Reads the optimized Z-Matrix from the output file string.
        Returns the Z-Matrix in Bohr and Radians.

        :param output_str: string of the program's output file
        :type output_str: str
        :rtype: automol molecular geometry data structure
    """

    # complicated string patterns for the initial matrix read
    mat_ptt = app.padded(app.NEWLINE).join([
        app.LINESPACES.join(
            [app.escape('Input from ZMAT file'),
             app.escape('*')]), app.LINE, app.LINE, ''
    ])

    nam_ptt = (app.LETTER + app.one_or_more(
        app.one_of_these([app.LETTER, app.UNDERSCORE, app.DIGIT])) +
               app.maybe(app.escape('*')))

    # read the matrix from the beginning of the output
    symbs, key_mat, name_mat = ar.vmat.read(
        output_str,
        start_ptt=mat_ptt,
        symb_ptt=ar.par.Pattern.ATOM_SYMBOL + app.maybe(app.UNSIGNED_INTEGER),
        key_ptt=app.one_of_these([app.UNSIGNED_INTEGER, app.VARIABLE_NAME]),
        name_ptt=nam_ptt,
        last=False)

    # Remove any asterisks(*) from the entries in the name matrix
    if all(x is not None for x in (symbs, key_mat, name_mat)):
        name_mat = tuple([[
            name.replace('*', '') if name is not None else None
            for name in name_row
        ] for name_row in name_mat])

        # complicated string patterns for the value dictionary read
        start_ptt = app.padded(app.NEWLINE).join(
            [app.padded('Final ZMATnew file', app.NONNEWLINE)] +
            [app.LINE for i in range(len(symbs) + 3)] + [''])

        # read the values from the end of the output
        if len(symbs) == 1:
            # val_dct = {}
            val_mat = ((None, None, None), )
        else:
            val_dct = ar.setval.read(output_str,
                                     start_ptt=start_ptt,
                                     entry_sep_ptt='=',
                                     last=True)
            val_mat = ar.setval.convert_dct_to_matrix(val_dct, name_mat)

        # for the case when variable names are used instead of integer keys:
        # (otherwise, does nothing)
        key_dct = dict(map(reversed, enumerate(symbs)))
        key_dct[None] = 0
        key_mat = [[
            key_dct[val] + 1 if not isinstance(val, numbers.Real) else val
            for val in row
        ] for row in key_mat]
        symb_ptt = app.STRING_START + app.capturing(ar.par.Pattern.ATOM_SYMBOL)
        symbs = [apf.first_capture(symb_ptt, symb) for symb in symbs]

        # call the automol constructor
        zma = automol.zmat.from_data(symbs,
                                     key_mat,
                                     val_mat,
                                     name_mat,
                                     one_indexed=True,
                                     angstrom=True,
                                     degree=True)
    else:
        zma = None

    return zma
Пример #28
0
def chebyshev_parameters(rxn_dstr, a_units='moles'):
    """ Parses the data string for a reaction in the reactions block
        for the lines containing the Chebyshevs fitting parameters,
        then reads the parameters from these lines.

        :param rxn_dstr: data string for species in reaction block
        :type rxn_dstr: str
        :return params: Chebyshev fitting parameters
        :rtype: dict[param: value]
    """
    original_rxn_dstr = rxn_dstr
    rxn_dstr = apf.remove(COMMENTS_PATTERN, rxn_dstr)

    tcheb_pattern = ('TCHEB' + app.zero_or_more(app.SPACE) + app.escape('/') +
                     app.zero_or_more(app.SPACE) + app.capturing(app.NUMBER) +
                     app.one_or_more(app.SPACE) + app.capturing(app.NUMBER) +
                     app.zero_or_more(app.SPACE) + app.escape('/'))
    pcheb_pattern = ('PCHEB' + app.zero_or_more(app.SPACE) + app.escape('/') +
                     app.zero_or_more(app.SPACE) + app.capturing(app.NUMBER) +
                     app.one_or_more(app.SPACE) + app.capturing(app.NUMBER) +
                     app.zero_or_more(app.SPACE) + app.escape('/'))
    cheb_pattern = (app.not_preceded_by(app.one_of_these(['T', 'P'])) +
                    'CHEB' + app.zero_or_more(app.SPACE) + app.escape('/') +
                    app.capturing(app.one_or_more(app.WILDCARD2)) +
                    app.escape('/'))

    cheb_params_raw = apf.all_captures(cheb_pattern, rxn_dstr)

    if cheb_params_raw:
        params = {}
        # Get the temp and pressure limits; add the Chemkin default values if they don't exist
        cheb_temps = apf.first_capture(tcheb_pattern, rxn_dstr)
        cheb_pressures = apf.first_capture(pcheb_pattern, rxn_dstr)
        if cheb_temps is None:
            cheb_temps = ('300.00', '2500.00')
            print(
                f'No Chebyshev temperature limits specified for the below reaction. Assuming 300 and 2500 K. \n \n {original_rxn_dstr}\n'
            )
        if cheb_pressures is None:
            cheb_pressures = ('0.001', '100.00')
            print(
                f'No Chebyshev pressure limits specified for the below reaction. Assuming 0.001 and 100 atm. \n \n {original_rxn_dstr}\n'
            )

        # Get all the numbers from the CHEB parameters
        cheb_params = []
        for cheb_line in cheb_params_raw:
            cheb_params.extend(cheb_line.split())

        # Get the cheb array dimensions N and M, which are the first two entries of the CHEB params
        cheb_n = int(
            math.floor(float(cheb_params[0]))
        )  # rounds down to match the Chemkin parser, although it should be an integer already
        cheb_m = int(math.floor(float(cheb_params[1])))

        # Start on the third value (after N and M) and get all the polynomial coefficients
        coeffs = []
        for idx, coeff in enumerate(cheb_params[2:]):
            if idx + 1 > (
                    cheb_n * cheb_m
            ):  # there are allowed to be extra coefficients, but just ignore them
                break
            coeffs.append(coeff)
        assert len(coeffs) == (cheb_n * cheb_m), (
            f'For the below reaction, there should be {cheb_n*cheb_m} Chebyshev polynomial coefficients, but there are only {len(coeffs)}. \n \n {original_rxn_dstr}\n'
        )
        alpha = numpy.array(list(map(float, coeffs)))

        params['t_limits'] = [float(val) for val in cheb_temps]
        params['p_limits'] = [float(val) for val in cheb_pressures]
        params['alpha_elm'] = alpha.reshape([cheb_n, cheb_m])
        params['a_units'] = a_units

    else:
        params = None

    return params
Пример #29
0
def test__matrix():
    """ test autoread.matrix
    """
    # gaussian gradient
    string = (' ***** Axes restored to original set *****\n'
              ' ------------------------------------------------------------\n'
              ' Center   Atomic              Forces (Hartrees/Bohr)\n'
              ' Number   Number         X              Y              Z\n'
              ' ------------------------------------------------------------\n'
              '    1       8       0.000000000   -0.000000000   -0.061240635\n'
              '    2       1       0.000000000   -0.021691602    0.030622057\n'
              '    3       1      -0.000000000    0.021691602    0.030622057\n'
              ' ------------------------------------------------------------\n'
              ' Cartesian Forces:  Max     0.061240635 RMS     0.027012111\n')

    mat = autoread.matrix.read(
        string,
        start_ptt=app.padded(app.NEWLINE).join([
            app.padded(app.escape('Forces (Hartrees/Bohr)'), app.NONNEWLINE),
            app.LINE, app.LINE, ''
        ]),
        line_start_ptt=app.LINESPACES.join([app.UNSIGNED_INTEGER] * 2))

    assert numpy.allclose(mat, ((0.0, -0.0, -0.061240635),
                                (0.0, -0.021691602, 0.030622057),
                                (-0.0, 0.021691602, 0.030622057)))

    # gaussian hessian
    string = (' The second derivative matrix:\n'
              '             X1    Y1    Z1    X2    Y2\n'
              '      X1   -0.21406\n'
              '      Y1   -0.00000  2.05336\n'
              '      Z1   -0.00000  0.12105  0.19177\n'
              '      X2   -0.06169 -0.00000  0.00000  0.03160\n'
              '      Y2    0.00000 -0.09598 -0.05579 -0.00000  0.12501\n'
              '      Z2    0.00000  0.08316 -0.38831 -0.00000 -0.06487\n'
              '      X3    0.27574  0.00000  0.00000  0.03009 -0.00000\n'
              '      Y3    0.00000 -1.95737 -0.06525  0.00000 -0.02902\n'
              '      Z3    0.00000 -0.20421  0.19654 -0.00000  0.12066\n'
              '             Z2    X3    Y3    Z3\n'
              '      Z2    0.44623\n'
              '      X3    0.00000 -0.30583\n'
              '      Y3   -0.01829 -0.00000  1.98640\n'
              '      Z3   -0.05792 -0.00000  0.08354 -0.13862\n'
              ' ITU= 0\n'
              '   Eigenvalues ---  0.06664  0.66895  3.25121\n')

    comp_ptt = app.one_of_these(['X', 'Y', 'Z']) + app.UNSIGNED_INTEGER
    mat = autoread.matrix.read(
        string,
        start_ptt=(app.escape('The second derivative matrix:') +
                   app.lpadded(app.NEWLINE)),
        block_start_ptt=(app.series(comp_ptt, app.LINESPACES) +
                         app.padded(app.NEWLINE)),
        line_start_ptt=comp_ptt,
        tril=True)

    assert numpy.allclose(
        mat,
        ((-0.21406, 0., 0., -0.06169, 0., 0., 0.27574, 0., 0.),
         (0., 2.05336, 0.12105, 0., -0.09598, 0.08316, 0., -1.95737, -0.20421),
         (0., 0.12105, 0.19177, 0., -0.05579, -0.38831, 0., -0.06525, 0.19654),
         (-0.06169, 0., 0., 0.0316, 0., 0., 0.03009, 0., 0.),
         (0., -0.09598, -0.05579, 0., 0.12501, -0.06487, 0., -0.02902,
          0.12066), (0., 0.08316, -0.38831, 0., -0.06487, 0.44623, 0.,
                     -0.01829, -0.05792),
         (0.27574, 0., 0., 0.03009, 0., 0., -0.30583, 0., 0.),
         (0., -1.95737, -0.06525, 0., -0.02902, -0.01829, 0., 1.9864, 0.08354),
         (0., -0.20421, 0.19654, 0., 0.12066, -0.05792, 0., 0.08354,
          -0.13862)))

    # psi4 gradient
    string = ('  ## Gradient (Symmetry 0) ##\n'
              '  Irrep: 1 Size: 3 x 3\n'
              '\n'
              '            1         2         3\n'
              '\n'
              '    1     0.000     0.000     0.997\n'
              '    2     0.000    -0.749    -0.488\n'
              '    3    -0.000     0.749    -0.488\n')

    mat = autoread.matrix.read(string,
                               start_ptt=app.padded(app.NEWLINE).join([
                                   app.escape('## Gradient (Symmetry 0) ##'),
                                   app.LINE, '', app.LINE, '', ''
                               ]),
                               line_start_ptt=app.UNSIGNED_INTEGER)

    assert numpy.allclose(mat, ((0.0, 0.0, 0.997), (0.0, -0.749, -0.488),
                                (-0.0, 0.749, -0.488)))

    # psi4 hessian
    string = ('-------------------------------------------\n'
              ' ## Hessian (Symmetry 0) ##\n'
              ' Irrep: 1 Size: 9 x 9\n'
              '\n'
              '       1     2     3     4     5 \n'
              '\n'
              '  1   0.000   0.000   0.000   0.000   0.000\n'
              '  2   0.000   0.959   0.000   0.000  -0.452\n'
              '  3   0.000   0.000   0.371   0.000   0.222\n'
              '  4   0.000   0.000   0.000   0.000   0.000\n'
              '  5   0.000  -0.479   0.279   0.000   0.455\n'
              '  6   0.000   0.251  -0.185   0.000  -0.247\n'
              '  7   0.000   0.000   0.000   0.000   0.000\n'
              '  8   0.000  -0.479  -0.279   0.000  -0.003\n'
              '  9   0.000  -0.251  -0.185   0.000   0.025\n'
              '\n'
              '       6     7     8     9\n'
              '\n'
              '  1   0.000   0.000   0.000   0.000\n'
              '  2   0.519   0.000  -0.477  -0.230\n'
              '  3  -0.555   0.000  -0.279  -0.128\n'
              '  4   0.000   0.000   0.000   0.000\n'
              '  5  -0.256   0.000  -0.017   0.051\n'
              '  6   0.607   0.000  -0.012   0.090\n'
              '  7   0.000   0.000   0.000   0.000\n'
              '  8  -0.263   0.000   0.494   0.279\n'
              '  9   0.947   0.000   0.292   0.137\n')

    mat = autoread.matrix.read(string,
                               start_ptt=app.padded(app.NEWLINE).join([
                                   app.escape('## Hessian (Symmetry 0) ##'),
                                   app.LINE, ''
                               ]),
                               block_start_ptt=app.padded(app.NEWLINE).join([
                                   '',
                                   app.series(app.UNSIGNED_INTEGER,
                                              app.LINESPACES), '', ''
                               ]),
                               line_start_ptt=app.UNSIGNED_INTEGER)

    assert numpy.allclose(
        mat, ((0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
              (0.0, 0.959, 0.0, 0.0, -0.452, 0.519, 0.0, -0.477, -0.23),
              (0.0, 0.0, 0.371, 0.0, 0.222, -0.555, 0.0, -0.279, -0.128),
              (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
              (0.0, -0.479, 0.279, 0.0, 0.455, -0.256, 0.0, -0.017, 0.051),
              (0.0, 0.251, -0.185, 0.0, -0.247, 0.607, 0.0, -0.012, 0.09),
              (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
              (0.0, -0.479, -0.279, 0.0, -0.003, -0.263, 0.0, 0.494, 0.279),
              (0.0, -0.251, -0.185, 0.0, 0.025, 0.947, 0.0, 0.292, 0.137)))
Пример #30
0
def options_matrix_optimization(script_str, prefix,
                                geo, chg, mul, method, basis, prog,
                                errors=(), options_mat=(), feedback=False,
                                frozen_coordinates=(),
                                freeze_dummy_atoms=True,
                                **kwargs):
    """ try several sets of options to generate an output file

        :param script_str: BASH submission script for electronic structure job
        :type script_str: str
        :param prefix:
        :type prefix:
        :param geo: molecular geometry or Z-Matrix
        :type geo:
        :param chg: electric charge
        :type chg: int
        :param mul: spin-multiplicity
        :type mul: int
        :param method: name of the electronic structure method
        :type method: str
        :param basis: name of the basis set
        :type basis: str
        :param prog: name of the electronic structure program
        :type prog: str
        :param errors: list of error message types to search output for
        :type errors: tuple(str)
        :param options_mat: varopis options to run job with
        :type options_mat: tuple(dict[str: str])
        :param feedback: update geom with job from previous sequence
        :type feedback: bool
        :param frozen_coordinates: Z-matrix coordinate names to freeze in opts
        :type frozen_coordinates: tuple(str)
        :param freeze_dummy_atoms: freeze any coords defined by dummy atoms
        :type freeze_dummy_atoms: bool
        :param kwargs:
        :type:
        :returns: the input string and the output string
        :rtype: (str, str)
    """
    assert len(errors) == len(options_mat)

    subrun_fs = autofile.fs.subrun(prefix)
    max_macro_idx, _ = max(subrun_fs[-1].existing(), default=(-1, -1))
    macro_idx = max_macro_idx + 1
    if macro_idx == 26:
        macro_idx = 0
    micro_idx = 0

    if freeze_dummy_atoms and automol.zmat.is_valid(geo):
        frozen_coordinates = (tuple(frozen_coordinates) +
                              automol.zmat.dummy_coordinate_names(geo))

    kwargs_ = dict(kwargs)

    # Initialize loop geo
    step_geo = geo
    while True:
        subrun_fs[-1].create([macro_idx, micro_idx])
        path = subrun_fs[-1].path([macro_idx, micro_idx])

        with warnings.catch_warnings():
            warnings.simplefilter('ignore')
            inp_str, out_str = elstruct.run.direct(
                elstruct.writer.optimization, script_str, path,
                geo=step_geo, charge=chg, mult=mul, method=method,
                basis=basis, prog=prog, frozen_coordinates=frozen_coordinates,
                **kwargs_)

        error_vals = [elstruct.reader.has_error_message(prog, error, out_str)
                      for error in errors]

        # Kill the while loop if we Molpro error signaling a hopeless point
        # When an MCSCF WF calculation fails to converge at some step in opt
        # it is not clear how to save the optimization, so we give up on opt
        fail_pattern = app.one_of_these([
            app.escape('The problem occurs in Multi'),
            app.escape('The problem occurs in cipro')
        ])
        if apf.has_match(fail_pattern, out_str, case=False):