예제 #1
0
def workflow_derivative_couplings(workflow_settings: Dict):
    """
    Compute the derivative couplings from an MD trajectory.

    :param workflow_settings: Arguments to compute the oscillators see:
    `data/schemas/derivative_couplings.json
    :returns: None
    """
    # Arguments to compute the orbitals and configure the workflow. see:
    # `data/schemas/general_settings.json
    config = workflow_settings['general_settings']

    # Dictionary containing the general configuration
    config.update(initialize(**config))

    # compute the molecular orbitals
    mo_paths_hdf5 = calculate_mos(**config)

    # Overlap matrix at two different times
    promised_overlaps = calculate_overlap(
        config['project_name'], config['path_hdf5'], config['dictCGFs'],
        config['geometries'], mo_paths_hdf5,
        config['hdf5_trans_mtx'], config['enumerate_from'],
        workflow_settings['overlaps_deph'], nHOMO=workflow_settings['nHOMO'],
        couplings_range=workflow_settings['couplings_range'])

    # Create a function that returns a proxime array of couplings
    schedule_couplings = schedule(lazy_couplings)

    # Calculate Non-Adiabatic Coupling
    promised_crossing_and_couplings = schedule_couplings(
        promised_overlaps, config['path_hdf5'], config['project_name'],
        config['enumerate_from'], workflow_settings['nHOMO'],
        workflow_settings['dt'], workflow_settings['tracking'],
        workflow_settings['write_overlaps'],
        algorithm=workflow_settings['algorithm'])

    # Write the results in PYXAID format
    work_dir = config['work_dir']
    path_hamiltonians = join(work_dir, 'hamiltonians')
    if not os.path.exists(path_hamiltonians):
        os.makedirs(path_hamiltonians)

    # Inplace scheduling of write_hamiltonians function.
    # Equivalent to add @schedule on top of the function
    schedule_write_ham = schedule(write_hamiltonians)

    # Number of matrix computed
    nPoints = len(config['geometries']) - 2

    # Write Hamilotians in PYXAID format
    promise_files = schedule_write_ham(
        config['path_hdf5'], mo_paths_hdf5, promised_crossing_and_couplings,
        nPoints, path_dir_results=path_hamiltonians,
        enumerate_from=config['enumerate_from'], nHOMO=workflow_settings['nHOMO'],
        couplings_range=workflow_settings['couplings_range'])

    run(promise_files, folder=work_dir)

    remove_folders(config['folders'])
def workflow_stddft(config: dict) -> None:
    """
    Compute the excited states using simplified TDDFT

    :param workflow_settings: Arguments to compute the oscillators see:
    `data/schemas/absorption_spectrum.json
    :returns: None
    """
    # Dictionary containing the general configuration
    config.update(initialize(config))

    # Single Point calculations settings using CP2K
    mo_paths_hdf5, energy_paths_hdf5 = unpack(calculate_mos(config), 2)

    # Read structures
    molecules_au = [
        change_mol_units(parse_string_xyz(gs))
        for i, gs in enumerate(config.geometries) if (i % config.stride) == 0
    ]

    # Noodles promised call
    scheduleTDDFT = schedule(compute_excited_states_tddft)

    results = gather(*[
        scheduleTDDFT(config, mo_paths_hdf5[i],
                      DictConfig({
                          'i': i * config.stride,
                          'mol': mol
                      })) for i, mol in enumerate(molecules_au)
    ])

    return run(gather(results, energy_paths_hdf5), folder=config['workdir'])
def workflow_stddft(config: dict) -> None:
    """
    Compute the excited states using simplified TDDFT

    :param workflow_settings: Arguments to compute the oscillators see:
    `data/schemas/absorption_spectrum.json
    :returns: None
    """
    # Dictionary containing the general configuration
    config.update(initialize(config))

    # Single Point calculations settings using CP2K
    mo_paths_hdf5, energy_paths_hdf5 = unpack(calculate_mos(config), 2)

    # Read structures
    molecules_au = [change_mol_units(parse_string_xyz(gs))
                    for i, gs in enumerate(config.geometries)
                    if (i % config.stride) == 0]

    # Noodles promised call
    scheduleTDDFT = schedule(compute_excited_states_tddft)

    results = gather(
       *[scheduleTDDFT(config, mo_paths_hdf5[i], DictConfig(
           {'i': i * config.stride, 'mol': mol}))
         for i, mol in enumerate(molecules_au)])

    return run(gather(results, energy_paths_hdf5), folder=config['workdir'])
예제 #4
0
def workflow_oscillator_strength(workflow_settings: Dict):
    """
    Compute the oscillator strength.

    :param workflow_settings: Arguments to compute the oscillators see:
    `data/schemas/absorption_spectrum.json
    :returns: None
    """
    # Arguments to compute the orbitals and configure the workflow. see:
    # `data/schemas/general_settings.json
    config = workflow_settings['general_settings']

    # Dictionary containing the general configuration
    config.update(initialize(**config))

    # Point calculations Using CP2K
    mo_paths_hdf5 = calculate_mos(**config)

    # geometries in atomic units
    molecules_au = [change_mol_units(parse_string_xyz(gs))
                    for gs in config['geometries']]

    # Construct initial and final states ranges
    transition_args = [workflow_settings[key] for key in
                       ['initial_states', 'final_states', 'nHOMO']]
    initial_states, final_states = build_transitions(*transition_args)

    # Make a promise object the function the compute the Oscillator Strenghts
    scheduleOscillator = schedule(calc_oscillator_strenghts)

    oscillators = gather(
        *[scheduleOscillator(
            i, mol,  mo_paths_hdf5, initial_states, final_states,
            config) for i, mol in enumerate(molecules_au)
          if i % workflow_settings['calculate_oscillator_every'] == 0])

    energies, promised_cross_section = create_promised_cross_section(
        oscillators, workflow_settings['broadening'], workflow_settings['energy_range'],
        workflow_settings['convolution'], workflow_settings['calculate_oscillator_every'])

    cross_section, data = run(
        gather(promised_cross_section, oscillators), folder=config['work_dir'])

    return store_data(data, energies, cross_section)
def workflow_derivative_couplings(config: dict) -> list:
    """
    Compute the derivative couplings from an MD trajectory.

    :param workflow_settings: Arguments to compute the oscillators see:
    `nac/workflows/schemas.py
    :returns: None
    """
    # Dictionary containing the general configuration
    config.update(initialize(config))

    logger.info("starting couplings calculation!")

    # compute the molecular orbitals
    mo_paths_hdf5, energy_paths_hdf5 = unpack(calculate_mos(config), 2)

    # mo_paths_hdf5 = run(calculate_mos(config), folder=config.workdir)

    # Overlap matrix at two different times
    promised_overlaps = calculate_overlap(config, mo_paths_hdf5)

    # Calculate Non-Adiabatic Coupling
    promised_crossing_and_couplings = lazy_couplings(config, promised_overlaps)

    # Write the results in PYXAID format
    config.path_hamiltonians = create_path_hamiltonians(config.workdir)

    # Inplace scheduling of write_hamiltonians function.
    # Equivalent to add @schedule on top of the function
    schedule_write_ham = schedule(write_hamiltonians)

    # Number of matrix computed
    config["nPoints"] = len(config.geometries) - 2

    # Write Hamilotians in PYXAID format
    promise_files = schedule_write_ham(
        config, promised_crossing_and_couplings, mo_paths_hdf5)

    results = run(
        gather(promise_files, energy_paths_hdf5), folder=config.workdir, always_cache=False)

    remove_folders(config.folders)

    return results
def workflow_derivative_couplings(config: dict) -> list:
    """
    Compute the derivative couplings from an MD trajectory.

    :param workflow_settings: Arguments to compute the oscillators see:
    `nac/workflows/schemas.py
    :returns: None
    """
    # Dictionary containing the general configuration
    config.update(initialize(config))

    logger.info("starting!")

    # compute the molecular orbitals
    mo_paths_hdf5, energy_paths_hdf5 = unpack(calculate_mos(config), 2)

    # mo_paths_hdf5 = run(calculate_mos(config), folder=config.workdir)

    # Overlap matrix at two different times
    promised_overlaps = calculate_overlap(config, mo_paths_hdf5)

    # Calculate Non-Adiabatic Coupling
    promised_crossing_and_couplings = lazy_couplings(config, promised_overlaps)

    # Write the results in PYXAID format
    config.path_hamiltonians = create_path_hamiltonians(config.workdir)

    # Inplace scheduling of write_hamiltonians function.
    # Equivalent to add @schedule on top of the function
    schedule_write_ham = schedule(write_hamiltonians)

    # Number of matrix computed
    config["nPoints"] = len(config.geometries) - 2

    # Write Hamilotians in PYXAID format
    promise_files = schedule_write_ham(
        config, promised_crossing_and_couplings, mo_paths_hdf5)

    results = run(gather(promise_files, energy_paths_hdf5), folder=config.workdir)

    remove_folders(config.folders)

    return results
def workflow_single_points(config: dict) -> list:
    """
    Single point calculations for a given trajectory

    :param workflow_settings: Arguments to run the single points calculations see:
    `nac/workflows/schemas.py
    """
    # Dictionary containing the general configuration
    config.update(initialize(config))

    logger.info("starting!")

    # compute the molecular orbitals
    # Unpack
    mo_paths_hdf5 = calculate_mos(config)
    # Pack
    results = run(mo_paths_hdf5, folder=config.workdir)

    return results
def workflow_single_points(config: dict) -> list:
    """
    Single point calculations for a given trajectory

    :param workflow_settings: Arguments to run the single points calculations see:
    `nac/workflows/schemas.py
    """
    # Dictionary containing the general configuration
    config.update(initialize(config))

    logger.info("starting!")

    # compute the molecular orbitals
    # Unpack
    mo_paths_hdf5 = calculate_mos(config)
    # Pack
    results = run(mo_paths_hdf5, folder=config.workdir)

    return results
예제 #9
0
def calculate_couplings_and_oscillators():
    """
    Compute a couple of couplings with the Levine algorithm
    using precalculated MOs.
    """
    initial_config = initialize(project_name,
                                path_traj_xyz,
                                basisname=basisname,
                                path_basis=None,
                                path_potential=None,
                                enumerate_from=0,
                                calculate_guesses='first',
                                path_hdf5=path_test_hdf5,
                                scratch_path=scratch_path)

    generate_pyxaid_hamiltonians('cp2k',
                                 project_name,
                                 cp2k_main,
                                 guess_args=cp2k_guess,
                                 nHOMO=50,
                                 couplings_range=(50, 30),
                                 **initial_config)

    data = workflow_oscillator_strength(
        'cp2k',
        project_name,
        cp2k_main,
        guess_args=cp2k_guess,
        nHOMO=50,
        couplings_range=(50, 30),
        initial_states=[50],
        energy_range=(0, 5),  # eV
        final_states=[[52]],
        **initial_config)

    return data
예제 #10
0
def workflow_electron_transfer(workflow_settings: Dict):
    """
    Use a MD trajectory to calculate the Electron transfer rate.

    :param workflow_settings: Arguments to compute the oscillators see:
    `data/schemas/electron_transfer.json
    :returns: None
    """
    # Arguments to compute the orbitals and configure the workflow. see:
    # `data/schemas/general_settings.json
    config = workflow_settings['general_settings']

    # Dictionary containing the general configuration
    config.update(initialize(**config))

    # Point calculations Using CP2K
    mo_paths_hdf5 = calculate_mos(**config)

    # geometries in atomic units
    molecules_au = [
        change_mol_units(parse_string_xyz(gs)) for gs in config['geometries']
    ]

    # Time-dependent coefficients
    path_time_coeffs = workflow_settings['path_time_coeffs']
    time_depend_coeffs = read_time_dependent_coeffs(path_time_coeffs)
    msg = "Reading time_dependent coefficients from: {}".format(
        path_time_coeffs)
    logger.info(msg)

    # compute_overlaps_ET
    scheduled_overlaps = schedule(compute_overlaps_ET)
    fragment_overlaps = scheduled_overlaps(
        config['project_name'], molecules_au, config['basis_name'],
        config['path_hdf5'], config['dictCGFs'], mo_paths_hdf5,
        workflow_settings['fragment_indices'], config['enumerate_from'],
        config['package_name'])

    # Delta time in a.u.
    dt = workflow_settings['dt']
    dt_au = dt * femtosec2au

    # Indices relation between the PYXAID active space and the orbitals
    # stored in the HDF5
    args_map_index = [
        workflow_settings[key] for key in
        ['orbitals_range', 'pyxaid_HOMO', 'pyxaid_Nmin', 'pyxaid_Nmax']
    ]
    map_index_pyxaid_hdf5 = create_map_index_pyxaid(*args_map_index)

    # Number of points in the pyxaid trajectory:
    # shape: (initial_conditions, n_points, n_states)
    n_points = len(config['geometries']) - 2

    # Read the swap between Molecular orbitals obtained from a previous
    # Coupling calculation
    swaps = read_swaps(['path_hdf5'], ['project_name'])

    # Electron transfer rate for each frame of the Molecular dynamics
    scheduled_photoexcitation = schedule(compute_photoexcitation)
    etrs = scheduled_photoexcitation(config['path_hdf5'], time_depend_coeffs,
                                     fragment_overlaps, map_index_pyxaid_hdf5,
                                     swaps, n_points, ['pyxaid_iconds'], dt_au)

    # Execute the workflow
    electronTransferRates, path_overlaps = run(gather(etrs, fragment_overlaps),
                                               folder=config['work_dir'])

    for i, mtx in enumerate(electronTransferRates):
        write_ETR(mtx, dt, i)

    write_overlap_densities(config['path_hdf5'], path_overlaps, swaps, dt)