Ejemplo n.º 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'])
Ejemplo n.º 2
0
def example_FDE_fragments():
    # For the purpose of the example, define xyz files here:
    xyz1 = io.StringIO('''3

    O         0.00000000000000     -2.29819386240000      1.63037963360000
    H        -0.76925379540000     -2.28223123190000      2.22684542850000
    H         0.76925379540000     -2.28223123190000      2.22684542850000''')

    xyz2 = io.StringIO('''3

    O         0.00000000000000      2.29819386240000      1.63037963360000
    H        -0.76925379540000      2.28223123190000      2.22684542850000
    H         0.76925379540000      2.28223123190000      2.22684542850000''')

    xyz3 = io.StringIO('''3

    O         0.00000000000000      0.00000000000000     -0.26192472620000
    H         0.00000000000000      0.77162768440000      0.34261631290000
    H         0.00000000000000     -0.77162768440000      0.34261631290000''')

    # Read the Molecule from file
    m_h2o_1 = Molecule()
    m_h2o_1.readxyz(xyz1, 1)
    m_h2o_2 = Molecule()
    m_h2o_2.readxyz(xyz2, 1)
    m_mol = Molecule()
    m_mol.readxyz(xyz3, 1)

    settings = Settings()
    settings.basis = 'SZ'
    settings.specific.adf.nosymfit = ''

    # Prepare first water fragment
    r_h2o_1 = adf(templates.singlepoint.overlay(settings), m_h2o_1, job_name="h2o_1")

    # Prepare second water fragment
    r_h2o_2 = adf(templates.singlepoint.overlay(settings), m_h2o_2, job_name="h2o_2")

    frags = gather(schedule(Fragment)(r_h2o_1, m_h2o_1, isfrozen=True),
                   schedule(Fragment)(r_h2o_2, m_h2o_2, isfrozen=True),
                   Fragment(None, m_mol))

    job_fde = adf_fragmentsjob(templates.singlepoint. overlay(settings), frags,
                               job_name="test_fde_fragments")

    # Perform FDE job and get dipole
    # This gets the dipole moment of the active subsystem only
    dipole_fde = run(job_fde.dipole)

    print('FDE dipole:', dipole_fde)

    return dipole_fde
Ejemplo n.º 3
0
def run_workflow_couplings(config: DictConfig) -> PromisedObject:
    """Run the derivative coupling workflow using `config`."""
    # compute the molecular orbitals
    logger.info("starting couplings calculation!")
    mo_paths_hdf5, energy_paths_hdf5 = unpack(calculate_mos(config), 2)

    # 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, config.orbitals_type)

    # 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)

    return gather(promise_files, energy_paths_hdf5)
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'])
Ejemplo n.º 6
0
def test_xenon_42_multi():
    A = add(1, 1)
    B = sub(3, A)

    multiples = [mul(add(i, B), A) for i in range(6)]
    C = schedule(sum)(gather_all(multiples))

    machine = Machine(
        scheduler_adaptor='slurm',
        location='ssh://fs0.das5.cs.vu.nl/home/jhidding',
        credential=xenon.CertificateCredential(
            username='******', certfile='/home/johannes/.ssh/id_rsa'),
        jobs_properties={
            'xenon.adaptors.schedulers.ssh.strictHostKeyChecking': 'false'
        })
    worker_config = XenonJobConfig(
        prefix=Path('/home/jhidding/.local/share/workon/mcfly'),
        working_dir='/home/jhidding/',
        time_out=1000000000000,
        verbose=False)  # , options=['-C', 'TitanX', '--gres=gpu:1'])

    result = run_xenon(C,
                       machine=machine,
                       worker_config=worker_config,
                       n_processes=2)

    print("The answer is:", result)
Ejemplo n.º 7
0
def single_stage_r2c(cfg, n1, direction='f', **args):
    k1_p = indent_code(
        generate_codelet(cfg,
                         "r2c" + direction,
                         n=n1,
                         name="r2c{}_{}".format(direction, n1),
                         opencl=True,
                         **args))
    return noodles.schedule("\n\n".join)(noodles.gather(
        macros_to_code(macros), k1_p))
Ejemplo n.º 8
0
def adf3fde_cycle(frags, caps, adf3fde_settings, fragment_settings, job_name='fde'):
    new_frags = []
    for i, frag in enumerate(frags):
        frag.isfrozen = False
        new_frags.append(schedule(Fragment)(adf_fragmentsjob(
            adf3fde_settings, frags, caps, fragment_settings,
            job_name=job_name + '_' + str(i)), frag.mol, pack_tape=True))
        frag.isfrozen = True

    return gather(*new_frags)
Ejemplo n.º 9
0
def adf3fde(frags, caps, settings, fde_settings, fragment_settings, cycles=1):
    adf3fde_settings = templates.singlepoint
    adf3fde_settings.specific.adf.allow = "partialsuperfrags"
    if settings:
        adf3fde_settings = settings.overlay(adf3fde_settings)
    adf3fde_settings.specific.adf.fde = fde_settings

    for i in range(cycles):
        frags = adf3fde_cycle(
            frags, caps, adf3fde_settings, fragment_settings, job_name='fde_' + str(i))
    return schedule(ADF3FDE_Result)(frags, caps)
Ejemplo n.º 10
0
def test_xenon_42_simple(xenon_server):
    A = add(1, 1)
    B = sub(3, A)

    multiples = [mul(add(i, B), A) for i in range(6)]
    C = schedule(sum)(gather_all(multiples))

    machine = Machine()
    worker_config = XenonJobConfig(verbose=True)

    result = run_xenon_simple(C, machine=machine, worker_config=worker_config)

    assert (result == 42)
Ejemplo n.º 11
0
def adf3fde(frags, caps, settings, fde_settings, fragment_settings, cycles=1):
    adf3fde_settings = templates.singlepoint
    adf3fde_settings.specific.adf.allow = "partialsuperfrags"
    if settings:
        adf3fde_settings = settings.overlay(adf3fde_settings)
    adf3fde_settings.specific.adf.fde = fde_settings

    for i in range(cycles):
        frags = adf3fde_cycle(frags,
                              caps,
                              adf3fde_settings,
                              fragment_settings,
                              job_name='fde_' + str(i))
    return schedule(ADF3FDE_Result)(frags, caps)
Ejemplo n.º 12
0
def test_xenon_42_multi(xenon_server):
    A = add(1, 1)
    B = sub(3, A)

    multiples = [mul(add(i, B), A) for i in range(6)]
    C = schedule(sum)(gather_all(multiples))

    machine = Machine()
    worker_config = XenonJobConfig(queue_name='multi', verbose=True)

    result = run_xenon(C,
                       machine=machine,
                       worker_config=worker_config,
                       n_processes=2)

    assert (result == 42)
Ejemplo n.º 13
0
def multi_stage_hc2hc(cfg, n1, n2, **args):
    k1_p = indent_code(
        generate_codelet(cfg,
                         "r2cf",
                         n=n1,
                         name="notw{}".format(n1),
                         opencl=True,
                         **args))
    k = indent_code(
        generate_codelet(cfg,
                         "hc2hc",
                         n=n2,
                         name="twiddle{}".format(n2),
                         opencl=True,
                         **args))
    return noodles.schedule("\n\n".join)(noodles.gather(
        macros_to_code(macros), indent_code(twiddle_const(n1, n2)), k1_p, k))
Ejemplo n.º 14
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
Ejemplo n.º 17
0
def create_promised_cross_section(oscillators: List, broadening: float,
                                  energy_range: Tuple, convolution: str,
                                  calculate_oscillator_every: int):
    """
    Create the function call that schedule the computation of the
    photoabsorption cross section
    """
    # Energy grid in  hartrees
    initial_energy = energy_range[0]
    final_energy = energy_range[1]
    npoints = 10 * (final_energy - initial_energy) // broadening
    energies = np.linspace(initial_energy, final_energy, npoints)

    # Compute the cross section
    schedule_cross_section = schedule(compute_cross_section_grid)

    return energies, schedule_cross_section(oscillators, convolution, energies,
                                            broadening,
                                            calculate_oscillator_every)
Ejemplo n.º 18
0
def adf3fde_cycle(frags,
                  caps,
                  adf3fde_settings,
                  fragment_settings,
                  job_name='fde'):
    new_frags = []
    for i, frag in enumerate(frags):
        frag.isfrozen = False
        new_frags.append(
            schedule(Fragment)(adf_fragmentsjob(adf3fde_settings,
                                                frags,
                                                caps,
                                                fragment_settings,
                                                job_name=job_name + '_' +
                                                str(i)),
                               frag.mol,
                               pack_tape=True))
        frag.isfrozen = True

    return gather(*new_frags)
Ejemplo n.º 19
0
def two_stage_kernel(cfg, n1, n2):
    k1_p = indent_code(
        generate_codelet(cfg,
                         "notw_complex",
                         n=n1,
                         name="notw{}".format(n1),
                         opencl=True))
    k2_p = indent_code(
        generate_codelet(cfg,
                         "twiddle_complex",
                         n=n2,
                         name="twiddle{}".format(n2),
                         opencl=True))
    k3 = two_stage_template.format(n=n1 * n2,
                                   n1=n1,
                                   n2=n2,
                                   n1s=2 * n1,
                                   n2s=2 * n2)
    return noodles.schedule("\n\n".join)(noodles.gather(
        macros_to_code(macros), indent_code(twiddle_const(n1, n2)), k1_p, k2_p,
        k3))
Ejemplo n.º 20
0
def run_partialcharges(results: Results,
                       options: Options,
                       promise: PromisedObject = None) -> dict:
    """
    Compute partial charges
    """
    opts = edit_calculator_options(options,
                                   ['esp2multipole', 'partialcharges'])

    if promise is not None:
        path_partialcharges = options.path_optionfiles / "partialcharges.xml"
        sections_to_edit = {"partialcharges": {"input": promise}}
        opts['partialcharges'] = schedule(edit_xml_file)(
            path_partialcharges, 'options', lift(sections_to_edit))

    logger.info("Running CHELPG fit")
    args = create_promise_command("xtp_tools -e partialcharges -o {}",
                                  opts['partialcharges'])

    return call_xtp_cmd(args,
                        options.scratch_dir / 'partialcharges',
                        expected_output={})
Ejemplo n.º 21
0
def run_workflow_stddft(config: DictConfig) -> PromisedObject:
    """Compute the excited states using simplified TDDFT using `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 gather(results, energy_paths_hdf5)
Ejemplo n.º 22
0
def run_iqm(results: Results, options: Options, state: PromisedObject) -> dict:
    """Run the eqm jobs."""
    # Copy option files
    src = ["mbgft.xml", "xtpdft.xml"]
    dst = ["mbgft_pair.xml", "xtpdft_pair.xml"]
    copy_option_files(options.path_optionfiles, src, dst)

    results['job_opts_iqm'] = edit_calculator_options(
        options, ['iqm', 'xtpdft_pair', 'mbgft_pair'])

    # replace optionfiles with its absolute path
    sections_to_edit = {
        '': {
            'replace_regex_recursively':
            ('OPTIONFILES', to_posix(options.path_optionfiles))
        }
    }

    edited_iqm_file = schedule(edit_xml_file)(results['job_opts_iqm']['iqm'],
                                              'iqm', sections_to_edit)

    # write into state
    cmd_iqm_write = create_promise_command(
        "xtp_parallel -e iqm -o {} -f {} -s 0 -j write", edited_iqm_file,
        state)

    results['job_setup_iqm'] = call_xtp_cmd(
        cmd_iqm_write,
        options.scratch_dir / 'iqm',
        expected_output={'iqm_jobs': "iqm.jobs"})

    # Select the number of jobs to run based on the input provided by the user
    results['job_select_iqm_jobs'] = edit_jobs_file(
        results['job_setup_iqm']['iqm_jobs'], options.iqm_jobs)

    return distribute_iqm_jobs(results, options, state)
Ejemplo n.º 23
0
def workflow_oscillator_strength(
        package_name: str,
        project_name: str,
        package_args: Dict,
        guess_args: Dict = None,
        geometries: List = None,
        dictCGFs: Dict = None,
        enumerate_from: int = 0,
        calc_new_wf_guess_on_points: str = None,
        path_hdf5: str = None,
        package_config: Dict = None,
        work_dir: str = None,
        initial_states: Any = None,
        final_states: Any = None,
        traj_folders: List = None,
        hdf5_trans_mtx: str = None,
        nHOMO: int = None,
        couplings_range: Tuple = None,
        calculate_oscillator_every: int = 50,
        convolution: str = 'gaussian',
        broadening: float = 0.1,  # eV
        energy_range: Tuple = None,  # eV
        geometry_units='angstrom',
        **kwargs):
    """
    Compute the oscillator strength

    :param package_name: Name of the package to run the QM simulations.
    :param project_name: Folder name where the computations
    are going to be stored.
    :param geometry:string containing the molecular geometry.
    :param package_args: Specific settings for the package
    :param guess_args: Specific settings for guess calculate with `package`.
    :type package_args: dict
    :param initial_states: List of the initial Electronic states.
    :type initial_states: [Int]
    :param final_states: List containing the sets of possible electronic
    states.
    :type final_states: [[Int]]
    :param calc_new_wf_guess_on_points: Points where the guess wave functions
    are calculated.
    :param package_config: Parameters required by the Package.
    :param  convolution: gaussian | lorentzian
    :param calculate_oscillator_every: step to compute the oscillator strengths
    :returns: None
    """
    # Start logging event
    file_log = '{}.log'.format(project_name)
    logging.basicConfig(filename=file_log,
                        level=logging.DEBUG,
                        format='%(levelname)s:%(message)s  %(asctime)s\n',
                        datefmt='%m/%d/%Y %I:%M:%S %p')

    # Point calculations Using CP2K
    mo_paths_hdf5 = calculate_mos(package_name,
                                  geometries,
                                  project_name,
                                  path_hdf5,
                                  traj_folders,
                                  package_args,
                                  guess_args,
                                  calc_new_wf_guess_on_points,
                                  enumerate_from,
                                  package_config=package_config)

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

    # Construct initial and final states ranges
    initial_states, final_states = build_transitions(initial_states,
                                                     final_states, nHOMO)

    # Schedule the function the compute the Oscillator Strenghts
    scheduleOscillator = schedule(calcOscillatorStrenghts)

    oscillators = gather(*[
        scheduleOscillator(i,
                           project_name,
                           mo_paths_hdf5,
                           dictCGFs,
                           mol,
                           path_hdf5,
                           hdf5_trans_mtx=hdf5_trans_mtx,
                           initial_states=initial_states,
                           final_states=final_states)
        for i, mol in enumerate(molecules_au)
        if i % calculate_oscillator_every == 0
    ])

    energies, promised_cross_section = create_promised_cross_section(
        oscillators, broadening, energy_range, convolution,
        calculate_oscillator_every)

    cross_section, data = run(gather(promised_cross_section, oscillators),
                              folder=work_dir)

    # Transform the energy to nm^-1
    energies_nm = energies * 1240

    # Save cross section
    np.savetxt(
        'cross_section_cm.txt',
        np.stack((energies, energies_nm, cross_section, cross_section * 1e16),
                 axis=1),
        header=
        'Energy[eV] Energy[nm^-1] photoabsorption_cross_section[cm^2] photoabsorption_cross_section[^2]'
    )

    # molar extinction coefficients (e in M-1 cm-1)
    nA = physical_constants['Avogadro constant'][0]
    cte = np.log(10) * 1e3 / nA
    extinction_coefficients = cross_section / cte
    np.savetxt(
        'molar_extinction_coefficients.txt',
        np.stack((energies, energies_nm, extinction_coefficients), axis=1),
        header='Energy[eV] Energy[nm^-1] Extinction_coefficients[M^-1 cm^-1]')

    print("Data: ", data)
    print("Calculation Done")

    # Write data in human readable format
    write_information(data)

    return data
Ejemplo n.º 24
0
def generate_pyxaid_hamiltonians(package_name: str,
                                 project_name: str,
                                 package_args: Dict,
                                 guess_args: Dict = None,
                                 geometries: List = None,
                                 dictCGFs: Dict = None,
                                 calc_new_wf_guess_on_points: str = None,
                                 path_hdf5: str = None,
                                 enumerate_from: int = 0,
                                 package_config: Dict = None,
                                 dt: float = 1,
                                 traj_folders: List = None,
                                 work_dir: str = None,
                                 basisname: str = None,
                                 hdf5_trans_mtx: str = None,
                                 nHOMO: int = None,
                                 couplings_range: Tuple = None,
                                 algorithm='levine',
                                 ignore_warnings=False,
                                 tracking=True) -> None:
    """
    Use a md trajectory to generate the hamiltonian components to run PYXAID
    nonadiabatic molecular dynamics.

    :param package_name: Name of the package to run the QM simulations.
    :param project_name: Folder name where the computations
    are going to be stored.
    :param package_args: Specific Settings for the package that will compute
    the MOs.
    :param geometries: List of string cotaining the molecular geometries
    numerical results.
    :paramter dictCGFS: Dictionary from Atomic Label to basis set
    :param calc_new_wf_guess_on_points: Calculate a guess wave function either
    in the first point or on each point of the trajectory.
    :param path_hdf5: path to the HDF5 file were the data is going to be stored.
    :param enumerate_from: Number from where to start enumerating the folders
    create for each point in the MD.
    :param hdf5_trans_mtx: Path into the HDF5 file where the transformation
    matrix (from Cartesian to sphericals) is stored.
    :param dt: Time used in the dynamics (femtoseconds)
    :param package_config: Parameters required by the Package.
    :type package_config: Dict
    :param nHOMO: index of the H**O orbital.
    :param couplings_range: Range of MO use to compute the nonadiabatic
    coupling matrix.

    :returns: None
    """
    # Start logging event
    file_log = '{}.log'.format(project_name)
    logging.basicConfig(filename=file_log,
                        level=logging.DEBUG,
                        format='%(levelname)s:%(message)s  %(asctime)s\n',
                        datefmt='%m/%d/%Y %I:%M:%S %p')

    # Log initial config information
    log_config(work_dir, path_hdf5, algorithm)

    # prepare Cp2k Jobs
    # Point calculations Using CP2K
    mo_paths_hdf5 = calculate_mos(package_name,
                                  geometries,
                                  project_name,
                                  path_hdf5,
                                  traj_folders,
                                  package_args,
                                  guess_args,
                                  calc_new_wf_guess_on_points,
                                  enumerate_from,
                                  package_config=package_config,
                                  ignore_warnings=ignore_warnings)

    # Overlap matrix at two different times
    promised_overlaps = calculate_overlap(project_name,
                                          path_hdf5,
                                          dictCGFs,
                                          geometries,
                                          mo_paths_hdf5,
                                          hdf5_trans_mtx,
                                          enumerate_from,
                                          nHOMO=nHOMO,
                                          couplings_range=couplings_range)

    # Calculate Non-Adiabatic Coupling
    schedule_couplings = schedule(lazy_couplings)
    promised_crossing_and_couplings = schedule_couplings(promised_overlaps,
                                                         path_hdf5,
                                                         project_name,
                                                         enumerate_from,
                                                         nHOMO,
                                                         dt,
                                                         tracking,
                                                         algorithm=algorithm)

    # Write the results in PYXAID format
    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(geometries) - 2

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

    run(promise_files, folder=work_dir)

    remove_folders(traj_folders)
Ejemplo n.º 25
0
 def __getitem__(self, val):
     if isinstance(val, PromisedObject):
         return schedule(self.state[val])
     else:
         return self.state[val]
Ejemplo n.º 26
0
def zip_with():
    arr = np.random.normal(size=100)
    ys = patterns.map(lambda x: np.pi * x, arr)
    rs = patterns.zip_with(x_sin_pix, arr, ys)

    return schedule(np.allclose)(rs, arr * np.sin(np.pi * arr))
Ejemplo n.º 27
0
def calculate_ETR(
        package_name: str, project_name: str, package_args: Dict,
        path_time_coeffs: str=None, geometries: List=None,
        initial_conditions: List=None, path_hdf5: str=None,
        basis_name: str=None,
        enumerate_from: int=0, package_config: Dict=None,
        calc_new_wf_guess_on_points: str=None, guess_args: Dict=None,
        work_dir: str=None, traj_folders: List=None,
        dictCGFs: Dict=None, orbitals_range: Tuple=None,
        pyxaid_HOMO: int=None, pyxaid_Nmin: int=None, pyxaid_Nmax: int=None,
        fragment_indices: None=List, dt: float=1, **kwargs):
    """
    Use a md trajectory to calculate the Electron transfer rate.

    :param package_name: Name of the package to run the QM simulations.
    :param project_name: Folder name where the computations
    are going to be stored.
    :param package_args: Specific settings for the package.
    :param path_hdf5: Path to the HDF5 file that contains the
    numerical results.
    :param geometries: List of string cotaining the molecular geometries.
    :paramter dictCGFS: Dictionary from Atomic Label to basis set
    :type     dictCGFS: Dict String [CGF],
              CGF = ([Primitives], AngularMomentum),
              Primitive = (Coefficient, Exponent)
    :param calc_new_wf_guess_on_points: number of Computations that used a
                                        previous calculation as guess for the
                                        wave function.
    :param nHOMO: index of the H**O orbital.
    :param couplings_range: Range of MO use to compute the nonadiabatic
    :param pyxaid_range: range of HOMOs and LUMOs used by pyxaid.
    :param enumerate_from: Number from where to start enumerating the folders
                           create for each point in the MD.
    :param traj_folders: List of paths to where the CP2K MOs are printed.
     :param package_config: Parameters required by the Package.
    :param fragment_indices: indices of atoms belonging to a fragment.
    :param dt: integration time used in the molecular dynamics.
    :returns: None
    """
    # Start logging event
    file_log = '{}.log'.format(project_name)
    logging.basicConfig(filename=file_log, level=logging.DEBUG,
                        format='%(levelname)s:%(message)s  %(asctime)s\n',
                        datefmt='%m/%d/%Y %I:%M:%S %p')

    # prepare Cp2k Job point calculations Using CP2K
    mo_paths_hdf5 = calculate_mos(
        package_name, geometries, project_name, path_hdf5, traj_folders,
        package_args, guess_args, calc_new_wf_guess_on_points,
        enumerate_from, package_config=package_config)

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

    # Time-dependent coefficients
    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(
        project_name, molecules_au, basis_name, path_hdf5, dictCGFs,
        mo_paths_hdf5, fragment_indices, enumerate_from, package_name)

    # Delta time in a.u.
    dt_au = dt * femtosec2au

    # Indices relation between the PYXAID active space and the orbitals
    # stored in the HDF5
    map_index_pyxaid_hdf5 = create_map_index_pyxaid(
        orbitals_range, pyxaid_HOMO, pyxaid_Nmin, pyxaid_Nmax)

    # Number of ETR points calculated with the MD trajectory
    n_points = len(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(
        path_hdf5, time_depend_coeffs, fragment_overlaps,
        map_index_pyxaid_hdf5, swaps, n_points, dt_au)

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

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

    write_overlap_densities(path_hdf5, path_overlaps, dt)
Ejemplo n.º 28
0
def calculate_overlap(project_name: str,
                      path_hdf5: str,
                      dictCGFs: Dict,
                      geometries: List,
                      mo_paths_hdf5: List,
                      hdf5_trans_mtx: str,
                      enumerate_from: int,
                      overlaps_deph: bool,
                      nHOMO: int = None,
                      couplings_range: Tuple = None,
                      units: str = 'angstrom') -> List:
    """
    Calculate the Overlap matrices before computing the non-adiabatic
    coupling using 3 consecutive set of MOs in a molecular dynamic.

    :param path_hdf5: Path to the HDF5 file that contains the
    numerical results.
    :type path_hdf5: String
    :paramter dictCGFS: Dictionary from Atomic Label to basis set
    :type     dictCGFS: Dict String [CGF],
              CGF = ([Primitives], AngularMomentum),
              Primitive = (Coefficient, Exponent)
    :param geometries: list of molecular geometries
    :param mo_paths: Path to the MO coefficients and energies in the
    HDF5 file.
    :param hdf5_trans_mtx: path to the transformation matrix in the HDF5 file.
    :param enumerate_from: Number from where to start enumerating the folders
    create for each point in the MD
    :type enumerate_from: Int
    :param nHOMO: index of the H**O orbital in the HDF5
    :param couplings_range: range of Molecular orbitals used to compute the
    coupling.
    :returns: paths to the Overlap matrices inside the HDF5.
    """
    nPoints = len(geometries) - 1

    # Inplace scheduling of calculate_overlap function
    # Equivalent to add @schedule on top of the function
    schedule_overlaps = schedule(lazy_overlaps)

    # Compute the Overlaps
    paths_overlaps = []
    for i in range(nPoints):

        # Extract molecules to compute couplings
        if overlaps_deph:
            molecules = tuple(
                map(lambda idx: parse_string_xyz(geometries[idx]), [0, i + 1]))
        else:
            molecules = tuple(
                map(lambda idx: parse_string_xyz(geometries[idx]), [i, i + 1]))

        # If units are Angtrom convert then to a.u.
        if 'angstrom' in units.lower():
            molecules = tuple(map(change_mol_units, molecules))

        # Compute the coupling
        overlaps = schedule_overlaps(i,
                                     project_name,
                                     path_hdf5,
                                     dictCGFs,
                                     molecules,
                                     mo_paths_hdf5,
                                     hdf5_trans_mtx=hdf5_trans_mtx,
                                     enumerate_from=enumerate_from,
                                     nHOMO=nHOMO,
                                     couplings_range=couplings_range)

        paths_overlaps.append(overlaps)

    # Gather all the promised paths
    return gather(*paths_overlaps)
Ejemplo n.º 29
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)
Ejemplo n.º 30
0
def fold_and_map():
    arr = np.random.normal(size=100)
    xs = patterns.fold(aux_sum, 0, arr)
    ys = patterns.map(lambda x: x**2, xs)

    return schedule(np.allclose)(ys, np.cumsum(arr)**2)
Ejemplo n.º 31
0
    print(
        "Next, as many threads as there are logical cores, taken from multiprocessing.cpu_count()."
    )
    start_mt = time.time()
    my_q = queue.Queue()
    for i in range_of_values:
        my_q.put(i)
    procs = [
        threading.Thread(target=worker, args=(my_q, )) for i in range(ncpus)
    ]
    for ps in procs:
        ps.start()
    for ps in procs:
        ps.join()
    end_mt = time.time()
    print()

    print("Now Noodles with as many threads as there are logical cores.")
    start_noodles = time.time()
    result = run_parallel(gather(*(schedule(sumPrimes_noodles)(x)
                                   for x in range_of_values)),
                          n_threads=ncpus)
    for item in result:
        print(item)
    end_noodles = time.time()
    print()

    print("A single thread takes {0:.2f} seconds".format(end_st - start_st))
    print("Multithreading takes {0:.2f} seconds".format(end_mt - start_mt))
    print("Noodles takes {0:.2f} seconds".format(end_noodles - start_noodles))
Ejemplo n.º 32
0
def fun_ethylene(scratch_path):
    """
    Test Ethylene singlw
    """
    project_name = 'ethylene'

    # create Settings for the Cp2K Jobs
    s = Settings()
    s.basis = "DZVP-MOLOPT-SR-GTH"
    s.potential = "GTH-PBE"
    s.cell_parameters = [12.74] * 3
    dft = s.specific.cp2k.force_eval.dft
    dft.scf.added_mos = 20
    dft.scf.eps_scf = 1e-4

    dft['print']['ao_matrices']['overlap'] = ''
    dft['print']['ao_matrices']['filename'] = join(scratch_path, 'overlap.out')

    # Copy the basis and potential to a tmp file
    shutil.copy('test/test_files/BASIS_MOLOPT', scratch_path)
    shutil.copy('test/test_files/GTH_POTENTIALS', scratch_path)
    # Cp2k configuration files
    basiscp2k = join(scratch_path, 'BASIS_MOLOPT')
    potcp2k = join(scratch_path, 'GTH_POTENTIALS')
    cp2k_config = {"basis": basiscp2k, "potential": potcp2k}

    # HDF5 path
    path_hdf5 = join(scratch_path, 'ethylene.hdf5')

    # all_geometries type :: [String]
    path_xyz = 'test/test_files/ethylene.xyz'
    geometries = split_file_geometries(path_xyz)

    # Input/Output Files
    file_xyz = join(scratch_path, 'coordinates.xyz')
    file_inp = join(scratch_path, 'ethylene.inp')
    file_out = join(scratch_path, 'ethylene.out')
    file_MO = join(scratch_path, 'mo_coeffs.out')

    files = JobFiles(file_xyz, file_inp, file_out, file_MO)

    schedule_job = schedule(prepare_job_cp2k)

    promise = schedule_job(geometries[0],
                           files,
                           s,
                           scratch_path,
                           project_name=project_name,
                           hdf5_file=path_hdf5,
                           wfn_restart_job=None,
                           store_in_hdf5=True,
                           nHOMOS=25,
                           nLUMOS=25,
                           package_config=cp2k_config)

    cp2k_result = run(promise)

    path_properties = cp2k_result.orbitals

    with h5py.File(path_hdf5) as f5:
        assert (all(p in f5 for p in path_properties))
Ejemplo n.º 33
0
zeta = 0.5
f = harmonic_oscillator(omega_0, zeta)
t = np.linspace(0.0, 15.0, 4)
# ~\~ end
# ~\~ begin <<lit/paranoodles.md|noodlify>>[2]
h = 0.01


@noodles.schedule
def fine(x, t_0, t_1):
    return iterate_solution(forward_euler(f), h)(x, t_0, t_1)


# ~\~ end
# ~\~ begin <<lit/paranoodles.md|noodlify>>[3]
y_euler = noodles.gather(*tabulate(noodles.schedule(fine), [1.0, 0.0], t))


# ~\~ end
# ~\~ begin <<lit/paranoodles.md|noodlify>>[4]
def paint(node, name):
    if name == "coarse":
        node.attr["fillcolor"] = "#cccccc"
    elif name == "fine":
        node.attr["fillcolor"] = "#88ff88"
    else:
        node.attr["fillcolor"] = "#ffffff"


draw_workflow('seq-graph.svg', noodles.get_workflow(y_euler), paint)
Ejemplo n.º 34
0
def test_unwrap():
    assert f == unwrap(schedule(f))
    assert f == unwrap(f)