Example #1
0
def qd_opt(mol: Molecule,
           jobs: Tuple[Optional[Type[Job]], ...],
           settings: Tuple[Optional[Settings], ...],
           use_ff: bool = False) -> None:
    """Perform an optimization of the quantum dot.

    Performs an inplace update of **mol**.

    Parameters
    ----------
    mol : |plams.Molecule|_
        The to-be optimized molecule.

    job_recipe : |plams.Settings|_
        A Settings instance containing all jon settings.
        Expects 4 keys: ``"job1"``, ``"job2"``, ``"s1"``, ``"s2"``.

    forcefield : bool
        If ``True``, perform the job with CP2K with a user-specified forcefield.

    """
    # Prepare the job settings
    if use_ff:
        qd_opt_ff(mol, jobs, settings)
        return None

    # Expand arguments
    job1, job2 = jobs
    s1, s2 = settings

    # Extra options for AMSJob
    if job1 is AMSJob:
        s1 = Settings(s1)
        s1.input.ams.constraints.atom = mol.properties.indices
    if job2 is AMSJob:
        s2 = Settings(s2)
        s2.input.ams.constraints.atom = mol.properties.indices

    # Run the first job and fix broken angles
    mol.job_geometry_opt(job1, s1, name='QD_opt_part1')
    fix_carboxyl(mol)
    fix_h(mol)
    mol.round_coords()

    # Run the second job
    if job2 is not None:
        mol.job_geometry_opt(job2, s2, name='QD_opt_part2')
        mol.round_coords()
    return None
Example #2
0
def _preoptimize(mol: Molecule) -> None:
    """Perform a constrained geometry optimization of **mol** with AMS UFF."""
    s = get_template('qd.yaml')['UFF']
    s.input.ams.constraints.atom = mol.properties.indices
    s.input.ams.GeometryOptimization.coordinatetype = 'Cartesian'
    mol.job_geometry_opt(AMSJob, s, name='E_XYn_preopt')
Example #3
0
def get_bde_dE(tot: Molecule,
               lig: Molecule,
               core: Iterable[Molecule],
               job: Type[Job],
               s: Settings,
               forcefield: bool = False) -> np.ndarray:
    """Calculate the bond dissociation energy: dE = dE(mopac) + (dG(uff) - dE(uff)).

    Parameters
    ----------
    tot : |plams.Molecule|_
        The complete intact quantum dot.

    lig : |plams.Molecule|_
        A ligand dissociated from the surface of the quantum dot

    core : |list|_ [|plams.Molecule|_]
        A list with one or more quantum dots (*i.e.* **tot**) with **lig** removed.

    job : |plams.Job|_
        A :class:`.Job` subclass.

    s : |plams.Settings|_
        The settings for **job**.

    """
    # Optimize XYn
    len_core = len(core)
    if job is AMSJob:
        s_cp = Settings(s)
        s_cp.input.ams.GeometryOptimization.coordinatetype = 'Cartesian'
        lig.job_geometry_opt(job, s_cp, name='E_XYn_opt')
    elif forcefield:
        qd_opt_ff(lig, Settings({'job1': Cp2kJob, 's1': s}), name='E_XYn_opt')
    else:
        lig.job_geometry_opt(job, s, name='E_XYn_opt')

    E_lig = lig.properties.energy.E
    if E_lig in (None, np.nan):
        logger.error(
            'The BDE XYn geometry optimization failed, skipping further jobs')
        return np.full(len_core, np.nan)

    # Perform a single point on the full quantum dot
    if forcefield:
        qd_opt_ff(tot, Settings({'job1': Cp2kJob, 's1': s}), name='E_QD_opt')
    else:
        tot.job_single_point(job, s, name='E_QD_sp')

    E_tot = tot.properties.energy.E
    if E_tot in (None, np.nan):
        logger.error(
            'The BDE quantum dot single point failed, skipping further jobs')
        return np.full(len_core, np.nan)

    # Perform a single point on the quantum dot(s) - XYn
    for mol in core:
        if forcefield:
            qd_opt_ff(mol,
                      Settings({
                          'job1': Cp2kJob,
                          's1': s
                      }),
                      name='E_QD-XYn_opt')
        else:
            mol.job_single_point(job, s, name='E_QD-XYn_sp')
    E_core = np.fromiter([mol.properties.energy.E for mol in core],
                         count=len_core,
                         dtype=float)

    # Calculate and return dE
    dE = (E_lig + E_core) - E_tot
    return dE