|
| 1 | +#!/usr/bin/env python |
| 2 | +''' |
| 3 | +An example of using COSMO-RS functionality. |
| 4 | +''' |
| 5 | + |
| 6 | +#%% Imports |
| 7 | + |
| 8 | +import io |
| 9 | + |
| 10 | +import numpy as np |
| 11 | +import matplotlib.pyplot as plt |
| 12 | + |
| 13 | +from pyscf import gto, dft |
| 14 | +from pyscf.solvent import pcm |
| 15 | +from pyscf.solvent.cosmors import get_sas_volume |
| 16 | +from pyscf.solvent.cosmors import write_cosmo_file |
| 17 | +from pyscf.solvent.cosmors import get_cosmors_parameters |
| 18 | + |
| 19 | + |
| 20 | +#%% Set parameters |
| 21 | + |
| 22 | +# get molecule |
| 23 | +coords = ''' |
| 24 | +C 0.000000 0.000000 -0.542500 |
| 25 | +O 0.000000 0.000000 0.677500 |
| 26 | +H 0.000000 0.9353074360871938 -1.082500 |
| 27 | +H 0.000000 -0.9353074360871938 -1.082500 |
| 28 | +''' |
| 29 | +mol = gto.M(atom=coords, basis='6-31G*', verbose=1) |
| 30 | + |
| 31 | +# configure PCM |
| 32 | +cm = pcm.PCM(mol) |
| 33 | +cm.eps = float('inf') # f_epsilon = 1 is required for COSMO-RS |
| 34 | +cm.method = 'C-PCM' # or COSMO, IEF-PCM, SS(V)PE, see https://manual.q-chem.com/5.4/topic_pcm-em.html |
| 35 | +cm.lebedev_order = 29 # lebedev grids on the cavity surface, lebedev_order=29 <--> # of grids = 302 |
| 36 | + |
| 37 | + |
| 38 | +#%% COSMO-files |
| 39 | + |
| 40 | +# run DFT SCF (any level of theory is OK, though DFT is optimal) |
| 41 | +mf = dft.RKS(mol, xc='b3lyp') |
| 42 | +mf = mf.PCM(cm) |
| 43 | +mf.kernel() |
| 44 | + |
| 45 | +# generate COSMO-file |
| 46 | +with io.StringIO() as outp: # with open('formaldehyde.cosmo', 'w') as outf: |
| 47 | + write_cosmo_file(outp, mf) |
| 48 | + print(outp.getvalue()) |
| 49 | + |
| 50 | + |
| 51 | +# if PCM DFT were computed with fepsilon < 1 <=> eps != inf the ValueError will be raised |
| 52 | +# use ignore_low_feps=True to overrule it, but please be sure you know what you're doing |
| 53 | + |
| 54 | +# run DFT SCF |
| 55 | +cm = pcm.PCM(mol) |
| 56 | +cm.eps = 32.613 # methanol |
| 57 | +mf = dft.RKS(mol, xc='b3lyp') |
| 58 | +mf = mf.PCM(cm) |
| 59 | +mf.kernel() |
| 60 | + |
| 61 | +# try to get COSMO-file |
| 62 | +with io.StringIO() as outp: |
| 63 | + try: |
| 64 | + write_cosmo_file(outp, mf) |
| 65 | + print(outp.getvalue()) |
| 66 | + except ValueError as e: |
| 67 | + print(e) |
| 68 | + |
| 69 | +# overruling |
| 70 | +with io.StringIO() as outp: |
| 71 | + write_cosmo_file(outp, mf, ignore_low_feps=True) |
| 72 | + print(outp.getvalue()) |
| 73 | + |
| 74 | + |
| 75 | +# The molecular volume is computed for the solvent-accessible surface generated |
| 76 | +# within pcm.PCM object. Please note that r_sol is assumed to be equal to zero, |
| 77 | +# so that SAS is a union of vdW spheres. |
| 78 | +# Increasing integration step increases accuracy of integration, but for most COSMO-RS |
| 79 | +# modelling and ML step=0.2 should be enough: |
| 80 | + |
| 81 | +# compute volumes with different step values |
| 82 | +steps = [1.0, 0.5, 0.2, 0.1, 0.05, 0.02, 0.01] |
| 83 | +Vs = [get_sas_volume(mf.with_solvent.surface, step) for step in steps] |
| 84 | +# plot |
| 85 | +ax = plt.gca() |
| 86 | +ax.plot(Vs) |
| 87 | +ax.set_xticks(range(len(steps))) |
| 88 | +_ = ax.set_xticklabels(steps) |
| 89 | +plt.show() |
| 90 | + |
| 91 | + |
| 92 | +#%% Sigma-profiles |
| 93 | + |
| 94 | +# compute SCF PCM |
| 95 | +cm = pcm.PCM(mol) |
| 96 | +cm.eps = float('inf') |
| 97 | +mf = dft.RKS(mol, xc='b3lyp') |
| 98 | +mf = mf.PCM(cm) |
| 99 | +mf.kernel() |
| 100 | + |
| 101 | +# compute sigma-profile and related parameters |
| 102 | +params = get_cosmors_parameters(mf) |
| 103 | +print(params) |
| 104 | +plt.plot(params['Screening charge, e/A**2'], |
| 105 | + params['Screening charge density, A**2']) |
| 106 | +plt.show() |
| 107 | + |
| 108 | +# custom sigma grid |
| 109 | +sigmas_grid = np.linspace(-0.025, 0.025, 101) |
| 110 | +params = get_cosmors_parameters(mf, sigmas_grid) |
| 111 | +plt.plot(params['Screening charge, e/A**2'], |
| 112 | + params['Screening charge density, A**2']) |
| 113 | +plt.show() |
| 114 | + |
| 115 | + |
0 commit comments