diff --git a/.gitignore b/.gitignore index d1a19546..d42d53c7 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ __pycache__ _gitmsg.saved.txt *.egg-info dist +.vscode/ diff --git a/AUTHORS.rst b/AUTHORS.rst index 100af573..810a30eb 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -15,4 +15,6 @@ contributed to this package : * Christof Köhler (University of Bremen) +* Alexander Maryewski (Karlsruhe Institute of Technology, Germany) + * Thomas Niehaus (University of Lyon, France) diff --git a/common/lib/accuracy.F90 b/common/lib/accuracy.F90 index 19ce9a94..2d2fc8bf 100644 --- a/common/lib/accuracy.F90 +++ b/common/lib/accuracy.F90 @@ -3,7 +3,7 @@ !! Not all routines use the string length specifications to set their character string lengths. module common_accuracy - use, intrinsic :: iso_fortran_env, only : real64 + use, intrinsic :: iso_fortran_env, only : real64, real128 implicit none private diff --git a/common/lib/gridgenerator.F90 b/common/lib/gridgenerator.F90 index bb320df4..ab9babc6 100644 --- a/common/lib/gridgenerator.F90 +++ b/common/lib/gridgenerator.F90 @@ -20,7 +20,7 @@ subroutine gengrid1_1(radQuad, rm, coordtrans, grid, weights) interface !> General interface for utilized coordinate transformation. - subroutine coordtrans(oldc, rm, newc, jacobi) + pure subroutine coordtrans(oldc, rm, newc, jacobi) use common_accuracy, only : dp !> old coordinate diff --git a/common/lib/partition.F90 b/common/lib/partition.F90 index ee2e6410..322a2d1c 100644 --- a/common/lib/partition.F90 +++ b/common/lib/partition.F90 @@ -32,7 +32,7 @@ pure function partitionFunc(r1, r2, dist, partparams) result(res) real(dp), intent(in) :: partparams(:) !! resulting value of the partition function, between [0,1] - real(dp) :: res + real(dp):: res end function partitionFunc diff --git a/common/lib/poisson.F90 b/common/lib/poisson.F90 index 3c17471e..c08bcc02 100644 --- a/common/lib/poisson.F90 +++ b/common/lib/poisson.F90 @@ -11,11 +11,10 @@ module common_poisson use common_accuracy, only : dp use common_constants, only : pi, pi_hlf - + use common_coordtrans, only : coordtrans_radial_becke1, coordtrans_radial_becke2 use common_quadratures, only : TQuadrature, TQuadrature2D, gauss_chebyshev_quadrature use common_quadratures, only : lebedev_laikov_quadrature use common_gridgenerator, only : gengrid1_1, gengrid1_3, gengrid2_3 - use common_coordtrans, only : coordtrans_radial_becke1, coordtrans_radial_becke2 use common_partition, only : partition_becke_homo use common_anglib, only : initGaunt use common_finitedifferences, only : makeHelmholzFDMatrix7P, makePoissonFDMatrix7P diff --git a/sktools/src/sktools/calculators/sktwocnt.py b/sktools/src/sktools/calculators/sktwocnt.py index 7ee5eeb7..6b25217e 100644 --- a/sktools/src/sktools/calculators/sktwocnt.py +++ b/sktools/src/sktools/calculators/sktwocnt.py @@ -11,7 +11,9 @@ SUPPORTED_FUNCTIONALS = {'lda' : 1, 'pbe' : 2, 'blyp' : 3, 'lcy-pbe' : 4, 'lcy-bnl' : 5, 'pbe0' : 6, 'b3lyp' : 7, - 'camy-b3lyp' : 8, 'camy-pbeh' : 9} + 'camy-b3lyp' : 8, 'camy-pbeh' : 9, 'tpss': 10, + 'scan': 11, 'r2scan': 12, 'r4scan': 13, 'task': 14, + 'task+cc': 15, 'ywb97m': 16} INPUT_FILE = "sktwocnt.in" STDOUT_FILE = "output" @@ -133,7 +135,7 @@ def _store_atomdata(self, workdir, atomdata, iatom): iatom) xcn = self._functional.type if xcn in ('lcy-bnl', 'lcy-pbe', 'pbe0', 'b3lyp', 'camy-b3lyp', - 'camy-pbeh'): + 'camy-pbeh', 'ywb97m'): atomfiles.dens_wavefuncs = self._store_dens_wavefuncs( workdir, atomdata.dens_wavefuncs, iatom) atomfiles.occshells = atomdata.occshells @@ -227,7 +229,7 @@ def _write_twocnt_gridinfo(self, fp): fp.write("{:f}\n".format(self._functional.alpha)) fp.write("{:s}\n".format(becke)) # CAM functionals - elif self._functional.type in ('camy-b3lyp', 'camy-pbeh'): + elif self._functional.type in ('camy-b3lyp', 'camy-pbeh', 'ywb97m'): becke = '2000 194 11 1.0' fp.write("{:f} {:f} {:f}\n".format(self._functional.omega, self._functional.alpha, @@ -243,7 +245,7 @@ def _write_twocnt_integration_parameters(self, fp): def _write_twocnt_atom_block(self, fp, atomfiles): if self._functional.type in ('lcy-bnl', 'lcy-pbe', 'pbe0', 'b3lyp', - 'camy-b3lyp', 'camy-pbeh'): + 'camy-b3lyp', 'camy-pbeh', 'ywb97m'): fp.write("{:d} {:d}\n".format(len(atomfiles.wavefuncs), len(atomfiles.dens_wavefuncs))) else: @@ -253,7 +255,7 @@ def _write_twocnt_atom_block(self, fp, atomfiles): fp.write("'{}' {:d}\n".format(wavefuncfile, ll)) if self._functional.type in ('lcy-bnl', 'lcy-pbe', 'pbe0', 'b3lyp', - 'camy-b3lyp', 'camy-pbeh'): + 'camy-b3lyp', 'camy-pbeh', 'ywb97m'): occdict = {} for xx in atomfiles.occshells: occdict[xx[0]] = xx[1] diff --git a/sktools/src/sktools/calculators/slateratom.py b/sktools/src/sktools/calculators/slateratom.py index 4fd25de3..a6683364 100644 --- a/sktools/src/sktools/calculators/slateratom.py +++ b/sktools/src/sktools/calculators/slateratom.py @@ -19,7 +19,11 @@ SUPPORTED_FUNCTIONALS = {'lda' : 2, 'pbe' : 3, 'blyp' : 4, 'lcy-pbe' : 5, 'lcy-bnl' : 6, 'pbe0' : 7, 'b3lyp' : 8, - 'camy-b3lyp' : 9, 'camy-pbeh' : 10} + 'camy-b3lyp' : 9, 'camy-pbeh' : 10, "tpss": 11, + 'scan': 12, 'r2scan': 13, 'r4scan': 14, 'task': 15, + 'task+cc': 16, 'ywb97m': 17} + +SUPPORTED_MIXERS = {1: 'simple', 2: 'broyden', 3: 'diis'} INPUT_FILE = "slateratom.in" STDOUT_FILE = "output" @@ -64,12 +68,15 @@ class SlaterAtomSettings(sc.ClassDict): Maximal power for every angular momentum. """ - def __init__(self, exponents, maxpowers, scftol, maxscfiter): + def __init__(self, exponents, maxpowers, scftol, maxscfiter, mixer_id, + mixing_parameter): super().__init__() self.exponents = exponents self.maxpowers = maxpowers self.scftol = scftol self.maxscfiter = maxscfiter + self.mixer = mixer_id + self.mixing_parameter = mixing_parameter @classmethod def fromhsd(cls, root, query): @@ -81,7 +88,12 @@ def fromhsd(cls, root, query): root, "scftolerance", converter=conv.float0, defvalue=1.0e-10) maxscfiter = query.getvalue( root, "maxscfiterations", converter=conv.int0, defvalue=120) - return cls(exponents, maxpowers, scftol, maxscfiter) + mixer_id = query.getvalue( + root, "mixer", converter=conv.int0, defvalue=2) + mixing_parameter = query.getvalue( + root, "mixingparameter", converter=conv.float0, defvalue=0.1) + return cls(exponents, maxpowers, scftol, maxscfiter, mixer_id, + mixing_parameter) def __eq__(self, other): if not isinstance(other, SlaterAtomSettings): @@ -168,16 +180,25 @@ def __init__(self, settings, atomconfig, functional, compressions): msg = "Slateratom: Maximum number of SCF iterations must be >=1" raise sc.SkgenException(msg) + if self._settings.mixer not in SUPPORTED_MIXERS.keys(): + msg = f"Slateratom: mixer {self._settings.mixer} not found" + raise sc.SkgenException(msg) + + if not 0.0 < self._settings.mixing_parameter <= 1.0: + msg = "Slateratom: mixing parameter must lie within the (0, 1] " \ + + "interval" + raise sc.SkgenException(msg) + if self.isXCFunctionalSupported(functional): xcfkey = functional.type self._functional = SUPPORTED_FUNCTIONALS[xcfkey] - if xcfkey in ('lcy-pbe', 'lcy-bnl', 'camy-b3lyp', 'camy-pbeh'): + if xcfkey in ('lcy-pbe', 'lcy-bnl', 'camy-b3lyp', 'camy-pbeh', 'ywb97m'): self._omega = functional.omega else: self._omega = None - if xcfkey in ('camy-b3lyp', 'camy-pbeh'): + if xcfkey in ('camy-b3lyp', 'camy-pbeh', 'ywb97m'): self._alpha = functional.alpha self._beta = functional.beta elif xcfkey == 'pbe0': @@ -294,7 +315,7 @@ def write(self, workdir): "2000 194 11 1.0 \t{:s} Becke integrator settings" .format(self._COMMENT)] # CAM functionals - elif xctype in ('camy-b3lyp', 'camy-pbeh'): + elif xctype in ('camy-b3lyp', 'camy-pbeh', 'ywb97m'): out += [ "{:g} {:g} {:g} \t{:s} ".format( self._omega, self._alpha, self._beta, self._COMMENT) + \ @@ -365,8 +386,9 @@ def write(self, workdir): out.append("{:s} \t\t{:s} write eigenvectors".format( self._LOGICALSTRS[False], self._COMMENT)) - out.append("{} {:g} \t\t\t{:s} broyden mixer, mixing factor".format( - 2, 0.1, self._COMMENT)) + out.append("{} {:g} \t\t{:s} mixer, mixing factor".format( + self._settings.mixer, self._settings.mixing_parameter, + self._COMMENT)) # Occupations for ll, occperl in enumerate(self._atomconfig.occupations): @@ -566,19 +588,15 @@ def get_density012(self): density : GridData Grid data with the density and its first and second derivatives. """ - fp = open(os.path.join(self._workdir, "dens.dat"), "r") - fp.readline() - fp.readline() - fp.readline() - fp.readline() - fp.readline() - ngrid = int(fp.readline()) - # noinspection PyNoneFunctionAssignment,PyTypeChecker - dens = np.fromfile(fp, dtype=float, count=ngrid * 7, sep=" ") - fp.close() - dens.shape = (ngrid, 7) - grid = oc.RadialGrid(dens[:,0], dens[:,1]) - density = dens[:,2:5] + + with open(os.path.join(self._workdir, "dens.dat"), 'r') as handle: + lines_ = [x.split() for x in handle.readlines()] + datarray = np.asarray(lines_[6:], dtype=float) + grid = oc.RadialGrid(datarray[:, 0], datarray[:, 1]) + density = datarray[:, 2:5] + if datarray.shape[1] == 8: + density = np.column_stack([density, datarray[:, 7]]) + return oc.GridData(grid, density) def get_wavefunction012(self, ss, nn, ll): diff --git a/sktools/src/sktools/xcfunctionals.py b/sktools/src/sktools/xcfunctionals.py index 47e53ec5..5fa63165 100644 --- a/sktools/src/sktools/xcfunctionals.py +++ b/sktools/src/sktools/xcfunctionals.py @@ -97,6 +97,46 @@ def fromhsd(cls, root, query): return myself +class XCYWB97M(sc.ClassDict): + '''Range-separated YwB97M xc-functional. + + Attributes + ---------- + omega (float): range-separation parameter + alpha (float): fraction of the global exact HF exchange + beta (float): determines (alpha + beta) fraction of long-range HF exchange + ''' + + @classmethod + def fromhsd(cls, root, query): + '''Creates instance from a HSD-node and with given query object.''' + omega, child = query.getvalue(root, 'omega', conv.float0, + returnchild=True) + if omega <= 0.0: + raise hsd.HSDInvalidTagValueException( + msg='Invalid rs-parameter {:f}'.format(omega), + node=child) + + alpha, child = query.getvalue(root, 'alpha', conv.float0, + returnchild=True) + + beta, child = query.getvalue(root, 'beta', conv.float0, + returnchild=True) + + if not alpha + beta > 0.0: + raise hsd.HSDInvalidTagValueException( + msg='Invalid CAM-parameter combination alpha={:f}, beta={:f}!\n' + .format(alpha, beta) + + 'Should satisfy alpha + beta > 0.0', node=child) + + myself = cls() + myself.type = 'ywb97m' + myself.omega = omega + myself.alpha = alpha + myself.beta = beta + return myself + + class XCCAMYPBEH(sc.ClassDict): '''Range-separated CAMY-PBEh xc-functional. @@ -189,6 +229,72 @@ def fromhsd(cls, root, query): return myself +class XCTPSS(sc.ClassDict): + """mGGA TPSS xc-functional.""" + + @classmethod + def fromhsd(cls, root, query): + """Creates instance from a HSD-node and with given query object.""" + myself = cls() + myself.type = "tpss" + return myself + + +class XCSCAN(sc.ClassDict): + """mGGA SCAN xc-functional.""" + + @classmethod + def fromhsd(cls, root, query): + """Creates instance from a HSD-node and with given query object.""" + myself = cls() + myself.type = "scan" + return myself + + +class XCR2SCAN(sc.ClassDict): + """mGGA r2SCAN xc-functional.""" + + @classmethod + def fromhsd(cls, root, query): + """Creates instance from a HSD-node and with given query object.""" + myself = cls() + myself.type = "r2scan" + return myself + + +class XCR4SCAN(sc.ClassDict): + """mGGA r4SCAN xc-functional.""" + + @classmethod + def fromhsd(cls, root, query): + """Creates instance from a HSD-node and with given query object.""" + myself = cls() + myself.type = "r4scan" + return myself + + +class XCTASK(sc.ClassDict): + """mGGA TASK xc-functional.""" + + @classmethod + def fromhsd(cls, root, query): + """Creates instance from a HSD-node and with given query object.""" + myself = cls() + myself.type = "task" + return myself + + +class XCTASK_CC(sc.ClassDict): + """mGGA TASK+CC xc-functional.""" + + @classmethod + def fromhsd(cls, root, query): + """Creates instance from a HSD-node and with given query object.""" + myself = cls() + myself.type = "task+cc" + return myself + + class XCLocal(sc.ClassDict): '''Local xc-functional.''' @@ -244,5 +350,12 @@ def fromhsd(cls, root, query): 'pbe0': XCPBE0, 'b3lyp': XCB3LYP, 'camy-b3lyp': XCCAMYB3LYP, - 'camy-pbeh': XCCAMYPBEH + 'camy-pbeh': XCCAMYPBEH, + 'tpss': XCTPSS, + 'scan': XCSCAN, + 'r2scan': XCR2SCAN, + 'r4scan': XCR4SCAN, + 'task': XCTASK, + 'task+cc': XCTASK_CC, + 'ywb97m': XCYWB97M } diff --git a/sktwocnt/lib/twocnt.F90 b/sktwocnt/lib/twocnt.F90 index 754efe74..293aa206 100644 --- a/sktwocnt/lib/twocnt.F90 +++ b/sktwocnt/lib/twocnt.F90 @@ -32,14 +32,19 @@ module twocnt #:if LIBXC_VERSION_MAJOR == 6 use xc_f03_lib_m, only : xc_f03_func_t, xc_f03_func_init, xc_f03_func_end, xc_f03_lda_vxc,& - & xc_f03_gga_vxc, XC_LDA_X, XC_LDA_X_YUKAWA, XC_LDA_C_PW, XC_GGA_X_PBE, XC_GGA_C_PBE,& - & XC_GGA_X_B88, XC_GGA_C_LYP, XC_GGA_X_SFAT_PBE, XC_HYB_GGA_XC_B3LYP,& - & XC_HYB_GGA_XC_CAMY_B3LYP, XC_UNPOLARIZED, xc_f03_func_set_ext_params + & xc_f03_gga_vxc, xc_f03_mgga_vxc, XC_LDA_X, XC_LDA_X_YUKAWA, XC_LDA_C_PW, XC_GGA_X_PBE,& + & XC_GGA_C_PBE, XC_GGA_X_B88, XC_GGA_C_LYP, XC_MGGA_X_SCAN, XC_MGGA_X_R4SCAN,& + & XC_MGGA_C_SCAN, XC_MGGA_X_TASK, XC_MGGA_X_R2SCAN, XC_MGGA_C_R2SCAN, XC_MGGA_X_TPSS,& + & XC_MGGA_C_TPSS, XC_MGGA_C_CC, XC_GGA_X_SFAT_PBE, XC_HYB_GGA_XC_B3LYP,& + & XC_HYB_GGA_XC_CAMY_B3LYP, XC_HYB_MGGA_XC_YWB97M, XC_UNPOLARIZED, xc_f03_func_set_ext_params #:elif LIBXC_VERSION_MAJOR == 7 use xc_f03_lib_m, only : xc_f03_func_t, xc_f03_func_init, xc_f03_func_end, xc_f03_lda_vxc,& - & xc_f03_gga_vxc, xc_f03_func_set_ext_params, XC_UNPOLARIZED - use xc_f03_funcs_m, only : XC_LDA_X, XC_LDA_X_YUKAWA, XC_LDA_C_PW, XC_GGA_X_PBE, XC_GGA_C_PBE,& - & XC_GGA_X_B88, XC_GGA_C_LYP, XC_GGA_X_SFAT_PBE, XC_HYB_GGA_XC_B3LYP, XC_HYB_GGA_XC_CAMY_B3LYP + & xc_f03_gga_vxc, xc_f03_mgga_vxc, xc_f03_func_set_ext_params, XC_UNPOLARIZED + use xc_f03_funcs_m, only : XC_LDA_X, XC_LDA_X_YUKAWA, XC_LDA_C_PW, XC_GGA_X_PBE,& + & XC_GGA_C_PBE, XC_GGA_X_B88, XC_GGA_C_LYP, XC_MGGA_X_SCAN, XC_MGGA_X_R4SCAN,& + & XC_MGGA_C_SCAN, XC_MGGA_X_TASK, XC_MGGA_X_R2SCAN, XC_MGGA_C_R2SCAN, XC_MGGA_X_TPSS,& + & XC_MGGA_C_TPSS, XC_MGGA_C_CC, XC_GGA_X_SFAT_PBE, XC_HYB_GGA_XC_B3LYP,& + & XC_HYB_GGA_XC_CAMY_B3LYP, XC_HYB_MGGA_XC_YWB97M #:endif implicit none @@ -76,8 +81,8 @@ module twocnt !> atomic potential on grid type(TGridorb2) :: pot - !> atomic density and 1st/2nd derivative on grid - type(TGridorb2) :: rho, drho, ddrho + !> atomic density, 1st/2nd derivative and kinetic energy density on grid + type(TGridorb2) :: rho, drho, ddrho, tau end type TAtomdata @@ -124,9 +129,10 @@ module twocnt !> scaling factor of Becke transformation real(dp) :: rm - !> xc-functional type + !! xc-functional type !! (1: LDA-PW91, 2: GGA-PBE96, 3: GGA-BLYP, 4: LCY-PBE96, 5: LCY-BNL, 6: PBE0, 7: B3LYP, - !! 8: CAMY-B3LYP, 9: CAMY-PBEh) + !! 8: CAMY-B3LYP, 9: CAMY-PBEh, 10: TPSS, 11: SCAN, 12: r2SCAN, 13: r4SCAN, 14: TASK, + !! 15: TASK+CC, 16: YWB97M) integer :: iXC !! true, if a global hybrid functional is requested @@ -138,6 +144,9 @@ module twocnt !! true, if a CAM functional is requested logical :: tCam + !! true, if a MGGA functional is requested + logical :: tMGGA + !> atomic properties of slateratom code, in the homonuclear case only atom1 is read type(TAtomdata) :: atom1, atom2 @@ -300,6 +309,26 @@ subroutine get_twocenter_integrals(env, inp, imap, skham, skover) call xc_f03_func_init(xcfunc_x, XC_GGA_X_PBE, XC_UNPOLARIZED) ! cpbe96 call xc_f03_func_init(xcfunc_c, XC_GGA_C_PBE, XC_UNPOLARIZED) + case(xcFunctional%MGGA_TPSS) + call xc_f03_func_init(xcfunc_x, XC_MGGA_X_TPSS, XC_UNPOLARIZED) + call xc_f03_func_init(xcfunc_c, XC_MGGA_C_TPSS, XC_UNPOLARIZED) + case(xcFunctional%MGGA_SCAN) + call xc_f03_func_init(xcfunc_x, XC_MGGA_X_SCAN, XC_UNPOLARIZED) + call xc_f03_func_init(xcfunc_c, XC_MGGA_C_SCAN, XC_UNPOLARIZED) + case(xcFunctional%MGGA_r2SCAN) + call xc_f03_func_init(xcfunc_x, XC_MGGA_X_R2SCAN, XC_UNPOLARIZED) + call xc_f03_func_init(xcfunc_c, XC_MGGA_C_R2SCAN, XC_UNPOLARIZED) + case(xcFunctional%MGGA_r4SCAN) + call xc_f03_func_init(xcfunc_x, XC_MGGA_X_R4SCAN, XC_UNPOLARIZED) + call xc_f03_func_init(xcfunc_c, XC_MGGA_C_R2SCAN, XC_UNPOLARIZED) + case(xcFunctional%MGGA_TASK) + call xc_f03_func_init(xcfunc_x, XC_MGGA_X_TASK, XC_UNPOLARIZED) + call xc_f03_func_init(xcfunc_c, XC_LDA_C_PW, XC_UNPOLARIZED) + case(xcFunctional%MGGA_TASK_CC) + call xc_f03_func_init(xcfunc_x, XC_MGGA_X_TASK, XC_UNPOLARIZED) + call xc_f03_func_init(xcfunc_c, XC_MGGA_C_CC, XC_UNPOLARIZED) + case(xcFunctional%CAMY_MGGA_wB97M) + call xc_f03_func_init(xcfunc_xc, XC_HYB_MGGA_XC_YWB97M, XC_UNPOLARIZED) end select if (inp%tLC .or. inp%tCam) then @@ -509,7 +538,8 @@ subroutine getskintegrals(beckeInt, radialHFQuadrature, nRad, nAng, atom1, atom2 !> xc-functional type !! (1: LDA-PW91, 2: GGA-PBE96, 3: GGA-BLYP, 4: LCY-PBE96, 5: LCY-BNL, 6: PBE0, 7: B3LYP, - !! 8: CAMY-B3LYP, 9: CAMY-PBEh) + !! 8: CAMY-B3LYP, 9: CAMY-PBEh, 10: TPSS, 11: SCAN, 12: r2SCAN, 13: r4SCAN, 14: TASK, + !! 15: TASK+CC, 16: YWB97M) integer, intent(in) :: iXC !> CAM alpha parameter @@ -551,8 +581,8 @@ subroutine getskintegrals(beckeInt, radialHFQuadrature, nRad, nAng, atom1, atom2 !! radial grid-orbital portion and 1st/2nd derivative for all basis functions of atom 2 real(dp), allocatable :: radval2(:,:), radval2p(:,:), radval2pp(:,:) - !! total potential and electron density of two atoms - real(dp), allocatable :: potval(:), densval(:) + !! total potential, electron density and kinetic energy density of two atoms + real(dp), allocatable :: potval(:), densval(:), tauval(:), taupotval(:) !! atomic 1st density derivatives of atom 1 real(dp), allocatable :: densval1p(:) @@ -572,7 +602,7 @@ subroutine getskintegrals(beckeInt, radialHFQuadrature, nRad, nAng, atom1, atom2 !! number of integration points integer :: nGrid - !> number of density grid points, compatible with libxc signature + !! number of density grid points, compatible with libxc signature integer(c_size_t) :: nGridLibxc !! orbital indices/angular momenta on the two atoms and interaction type @@ -581,10 +611,13 @@ subroutine getskintegrals(beckeInt, radialHFQuadrature, nRad, nAng, atom1, atom2 !! integral index integer :: ii + !! dummy laplacian + real(dp), allocatable :: lapl(:), vlapl(:) + !! libxc related objects real(dp), allocatable :: vxc(:), vx(:), vx_sr(:), vc(:) - real(dp), allocatable :: rhor(:), sigma(:), vxcsigma(:), vxsigma(:), vxsigma_sr(:), vcsigma(:) - real(dp), allocatable :: divvxc(:), divvx(:), divvc(:) + real(dp), allocatable :: rhor(:), sigma(:), tau(:), vxcsigma(:), vxsigma(:), vxsigma_sr(:) + real(dp), allocatable :: vcsigma(:), vxtau(:), vctau(:), vxctau(:), divvxc(:), divvx(:), divvc(:) r1 => grid1(:, 1) theta1 => grid1(:, 2) @@ -635,6 +668,27 @@ subroutine getskintegrals(beckeInt, radialHFQuadrature, nRad, nAng, atom1, atom2 ! care about correct 4pi normalization of density and compute sigma sigma = getLibxcSigma(densval1p, densval2p, dots) end if + + if (xcFunctional%isMGGA(iXC)) then + allocate(tauval(nGrid)) + tauval(:) = atom1%tau%getValue(r1) + atom2%tau%getValue(r2) + tau = getLibxcTau(tauval) + + if (iXC /= xcFunctional%CAMY_MGGA_wB97M) then + allocate(vxtau(nGrid), source=0.0_dp) + ! TASK has only LDA correlation + if (iXC /= xcFunctional%MGGA_TASK) then + allocate(vctau(nGrid), source=0.0_dp) + end if + ! wB97M is a one piece xc functional + else + allocate(vxctau(nGrid), source=0.0_dp) + end if + ! dummy Laplacian + allocate(lapl(nGrid)) + allocate(vlapl(nGrid)) + end if + if (tGlobalHybrid .or. tCam) then allocate(vxc(nGrid)) vxc(:) = 0.0_dp @@ -663,6 +717,29 @@ subroutine getskintegrals(beckeInt, radialHFQuadrature, nRad, nAng, atom1, atom2 call getDivergence(nRad, nAng, densval1p, densval2p, r1, r2, theta1, theta2, vxsigma, divvx) call getDivergence(nRad, nAng, densval1p, densval2p, r1, r2, theta1, theta2, vcsigma, divvc) potval = vx + vc + divvx + divvc + ! 10: MGGA-TPSS, 11: MGGA-SCAN, 12: MGGA-r2SCAN, 13: MGGA-r4SCAN 14: MGGA-TASK, + ! 15: MGGA-TASK+CC + case(xcFunctional%MGGA_TPSS, xcFunctional%MGGA_SCAN, xcFunctional%MGGA_r2SCAN,& + & xcFunctional%MGGA_r4SCAN, xcFunctional%MGGA_TASK, xcFunctional%MGGA_TASK_CC) + ! MGGA exchange + call xc_f03_mgga_vxc(xcfunc_x, nGridLibxc, rhor(1), sigma(1), lapl(1), tau(1), vx(1),& + & vxsigma(1), vlapl(1), vxtau(1)) + call getDivergence(nRad, nAng, densval1p, densval2p, r1, r2, theta1, theta2, vxsigma, divvx) + ! 11: MGGA-TPSS, 12: MGGA-SCAN, 13: MGGA-r2SCAN, 14: MGGA-TASK + if (iXC /= xcFunctional%MGGA_TASK) then + ! MGGA correlation + call xc_f03_mgga_vxc(xcfunc_c, nGridLibxc, rhor(1), sigma(1), lapl(1), tau(1), vc(1),& + & vcsigma(1), vlapl(1), vctau(1)) + call getDivergence(nRad, nAng, densval1p, densval2p, r1, r2, theta1, theta2, vcsigma,& + & divvc) + potval = vx + vc + divvx + divvc + taupotval = vxtau + vctau + else + ! LDA correlation for TASK + call xc_f03_lda_vxc(xcfunc_c, nGridLibxc, rhor(1), vc(1)) + potval = vx + vc + divvx + taupotval = vxtau + end if ! 5: LCY-BNL case(xcFunctional%LCY_BNL) call xc_f03_lda_vxc(xcfunc_x, nGridLibxc, rhor(1), vx(1)) @@ -701,7 +778,16 @@ subroutine getskintegrals(beckeInt, radialHFQuadrature, nRad, nAng, atom1, atom2 call getDivergence(nRad, nAng, densval1p, densval2p, r1, r2, theta1, theta2, vxcsigma,& & divvxc) potval = vxc + divvxc + ! 16: YwB97M + case(16) + ! semilocal part only + call xc_f03_mgga_vxc(xcfunc_xc, nGridLibxc, rhor(1), sigma(1), lapl(1), tau(1), vxc(1),& + & vxcsigma(1), vlapl(1), vxctau(1)) + call getDivergence(nRad, nAng, densval1p, densval2p, r1, r2, theta1, theta2, vxcsigma, divvxc) + potval = vxc + divvxc + taupotval = vxctau end select + ! add nuclear and coulomb potential to obtain the effective potential potval(:) = potval + atom1%pot%getValue(r1) + atom2%pot%getValue(r2) end if ifPotSup @@ -724,7 +810,7 @@ subroutine getskintegrals(beckeInt, radialHFQuadrature, nRad, nAng, atom1, atom2 ! calculate SK-quantities ! Hamiltonian integ1 = getHamiltonian(radval1(:, i1), radval2(:, i2), radval2p(:, i2), radval2pp(:, i2),& - & r2, l2, spherval1, spherval2, potval, weights) + & r2, l2, spherval1, spherval2, potval, weights, taupotval) ! overlap integral: \sum_{r,\Omega} R_1(r) Y_1(\Omega) R_2(r) Y_2(\Omega) weight integ2 = getOverlap(radval1(:, i1), radval2(:, i2), spherval1, spherval2, weights) ! total density: \int (|\phi_1|^2 + |\phi_2|^2) @@ -870,6 +956,21 @@ pure function getLibxcSigma(drho1, drho2, dots) result(sigma) end function getLibxcSigma + !> Calculates libXC renormalized kinetic energy density superposition of dimer. + pure function getLibxcTau(tau) result(rtau) + + !> superposition of atomic kinetic energy densities of atom 1 and atom 2 + real(dp), intent(in) :: tau(:) + + !> renormalized kinetic energy density + real(dp), allocatable :: rtau(:) + + ! renorm tau (incoming quantities are 4pi normed) + rtau = tau + + end function getLibxcTau + + !> Computes contribution div(v) to the xc-potential due to vsigma = deps/dsigma returned by libxc. !! div(v) = -2 div(vsigma grad(n)), evaluated in spherical coordinates r1, theta1 as: !! div(v) = -2 [(1/r1^2) d(r1^2 vsigma grad(n)_r1)/dr1 + @@ -1030,8 +1131,8 @@ end function getdensity !> Calculates Hamiltonian for a fixed orbital and interaction configuration. - pure function getHamiltonian(rad1, rad2, rad2p, rad2pp, r2, l2, spher1, spher2, pot, weights)& - & result(res) + pure function getHamiltonian(rad1, rad2, rad2p, rad2pp, r2, l2, spher1, spher2, pot, weights,& + & pot_tau) result(res) !> radial grid-orbital portion of atom 1 and atom 2 real(dp), intent(in) :: rad1(:), rad2(:) @@ -1054,15 +1155,29 @@ pure function getHamiltonian(rad1, rad2, rad2p, rad2pp, r2, l2, spher1, spher2, !> integration weights real(dp), intent(in) :: weights(:) + !> kinetic energy density on grid + real(dp), intent(in), allocatable :: pot_tau(:) + !! resulting Hamiltonian matrix element real(dp) :: res - res = sum((rad1 * spher1)& - & * (- 0.5_dp * rad2pp& - & - rad2p / r2& - & + 0.5_dp * l2 * (l2 + 1) * rad2 / r2**2& - & + pot * rad2)& - & * spher2 * weights) + ! TODO: wrong expression, fix + if (allocated(pot_tau)) then + res = sum((rad1 * spher1)& + & * ((- 0.5_dp * rad2pp& + & - rad2p / r2& + & + 0.5_dp * l2 * (l2 + 1) * rad2 / r2**2)& + & * (1.0_dp + pot_tau)& + & + pot * rad2)& + & * spher2 * weights) + else + res = sum((rad1 * spher1)& + & * (- 0.5_dp * rad2pp& + & - rad2p / r2& + & + 0.5_dp * l2 * (l2 + 1) * rad2 / r2**2& + & + pot * rad2)& + & * spher2 * weights) + end if end function getHamiltonian diff --git a/sktwocnt/lib/xcfunctionals.f90 b/sktwocnt/lib/xcfunctionals.f90 index b12325d5..2d424cc3 100644 --- a/sktwocnt/lib/xcfunctionals.f90 +++ b/sktwocnt/lib/xcfunctionals.f90 @@ -37,10 +37,32 @@ module xcfunctionals !> CAMY-PBEh integer :: CAMY_PBEh = 9 + !> TPSS + integer :: MGGA_TPSS = 10 + + !> SCAN + integer :: MGGA_SCAN = 11 + + !> r2SCAN + integer :: MGGA_r2SCAN = 12 + + !> r4SCAN + integer :: MGGA_r4SCAN = 13 + + !> TASK + integer :: MGGA_TASK = 14 + + !> TASK+CC + integer :: MGGA_TASK_CC = 15 + + !> CAMY-MGGA-WB97M + integer :: CAMY_MGGA_wB97M = 16 + contains procedure :: isLDA => TXcFunctionalsEnum_isLDA procedure :: isGGA => TXcFunctionalsEnum_isGGA + procedure :: isMGGA => TXcFunctionalsEnum_isMGGA procedure :: isGlobalHybrid => TXcFunctionalsEnum_isGlobalHybrid procedure :: isLongRangeCorrected => TXcFunctionalsEnum_isLongRangeCorrected procedure :: isCAMY => TXcFunctionalsEnum_isCAMY @@ -91,6 +113,28 @@ pure function TXcFunctionalsEnum_isGGA(this, xcnr) result(isGGA) end function TXcFunctionalsEnum_isGGA + pure function TXcFunctionalsEnum_isMGGA(this, xcnr) result(isMGGA) + + !> Class instance + class(TXcFunctionalsEnum), intent(in) :: this + + !> identifier of exchange-correlation type + integer, intent(in) :: xcnr + + !> True, if xc-functional index corresponds to a GGA functional + logical :: isMGGA + + isMGGA = .false. + + if (xcnr == this%MGGA_TPSS .or. xcnr == this%MGGA_SCAN .or. xcnr == this%MGGA_r2SCAN& + & .or. xcnr == this%MGGA_r4SCAN .or. xcnr == this%MGGA_TASK& + & .or. xcnr == this%MGGA_TASK_CC .or. xcnr == this%CAMY_MGGA_wB97M) then + isMGGA = .true. + end if + + end function TXcFunctionalsEnum_isMGGA + + pure function TXcFunctionalsEnum_isLongRangeCorrected(this, xcnr) result(isLongRangeCorrected) !> Class instance @@ -144,7 +188,8 @@ pure function TXcFunctionalsEnum_isCAMY(this, xcnr) result(isCamy) isCamy = .false. - if (xcnr == this%CAMY_B3LYP .or. xcnr == this%CAMY_PBEh) then + if (xcnr == this%CAMY_B3LYP .or. xcnr == this%CAMY_PBEh & + & .or. xcnr == this%CAMY_MGGA_wB97M) then isCamy = .true. end if @@ -164,7 +209,7 @@ pure function TXcFunctionalsEnum_isNotImplemented(this, xcnr) result(isNotImplem isNotImplemented = .false. - if (xcnr < 0 .or. xcnr > 9) then + if (xcnr < 0 .or. xcnr > 16) then isNotImplemented = .true. end if diff --git a/sktwocnt/prog/input.f90 b/sktwocnt/prog/input.f90 index bd8e9adc..b5a4f172 100644 --- a/sktwocnt/prog/input.f90 +++ b/sktwocnt/prog/input.f90 @@ -47,7 +47,8 @@ subroutine readInput(inp, fname) !! xc-functional type !! (1: LDA-PW91, 2: GGA-PBE96, 3: GGA-BLYP, 4: LCY-PBE96, 5: LCY-BNL, 6: PBE0, 7: B3LYP, - !! 8: CAMY-B3LYP, 9: CAMY-PBEh) + !! 8: CAMY-B3LYP, 9: CAMY-PBEh, 10: TPSS, 11: SCAN, 12: r2SCAN, 13: r4SCAN, 14: TASK, + !! 15: TASK+CC, 16: YWB97M) integer :: iXC !! potential data columns, summed up in order to receive the total atomic potential @@ -56,6 +57,7 @@ subroutine readInput(inp, fname) !! true, if radial grid-orbital 1st/2nd derivative shall be read logical :: tReadRadDerivs + inp%tMGGA = .false. inp%tLC = .false. inp%tCam = .false. inp%tGlobalHybrid = .false. @@ -82,35 +84,19 @@ subroutine readInput(inp, fname) & iline) end select - select case (iXC) - case(xcFunctional%LDA_PW91) - ! LDA-PW91 - case(xcFunctional%GGA_PBE96) - ! GGA-PBE96 - case(xcFunctional%GGA_BLYP) - ! GGA-BLYP - case(xcFunctional%LCY_PBE96) - ! LCY-PBE96 (purely long-range corrected) - inp%tLC = .true. - case(xcFunctional%LCY_BNL) - ! LCY-BNL (purely long-range corrected) - inp%tLC = .true. - case(xcFunctional%HYB_PBE0) - ! PBE0 (global hybrid) - inp%tGlobalHybrid = .true. - case(xcFunctional%HYB_B3LYP) - ! B3LYP (global hybrid) - inp%tGlobalHybrid = .true. - case(xcFunctional%CAMY_B3LYP) - ! CAMY-B3LYP (general CAM form) - inp%tCam = .true. - case(xcFunctional%CAMY_PBEh) - ! CAMY-PBEh (general CAM form) - inp%tCam = .true. - case default - call error_("Unknown exchange-correlation functional!", fname, line, iline) - end select inp%iXC = iXC + if (xcFunctional%isNotImplemented(iXC)) then + call error_("Unknown exchange-correlation functional!", fname, line, iline) + end if + inp%tLC = xcFunctional%isLongRangeCorrected(iXC) + inp%tGlobalHybrid = xcFunctional%isGlobalHybrid(iXC) + inp%tCam = xcFunctional%isCAMY(iXC) + inp%tMGGA = xcFunctional%isMGGA(iXC) + + if (inp%tMGGA .and. .not. inp%tDensitySuperpos) then + call error_("mGGA functionals are only supported in the density superposition mode!", fname,& + & line, iline) + end if if (inp%iXC == xcFunctional%HYB_B3LYP) then ! 20% fraction of HFX hard-coded at the moment @@ -172,10 +158,10 @@ subroutine readInput(inp, fname) tReadRadDerivs = .not. inp%tHetero call readatom_(fname, fp, iLine, potcomps, inp%tDensitySuperpos, tReadRadDerivs,& - & (inp%tGlobalHybrid .or. inp%tLC .or. inp%tCam), inp%atom1) + & (inp%tGlobalHybrid .or. inp%tLC .or. inp%tCam), inp%tMGGA, inp%atom1) if (inp%tHetero) then call readatom_(fname, fp, iLine, potcomps, inp%tDensitySuperpos, .true., (inp%tGlobalHybrid& - & .or. inp%tLC .or. inp%tCam), inp%atom2) + & .or. inp%tLC .or. inp%tCam), inp%tMGGA, inp%atom2) end if close(fp) @@ -185,7 +171,7 @@ end subroutine readInput !> Fills TAtomdata instance based on slateratom's output. subroutine readatom_(fname, fp, iLine, potcomps, tDensitySuperpos, tReadRadDerivs, tNonLocal,& - & atom) + & tMGGA, atom) !> filename character(len=*), intent(in) :: fname @@ -208,6 +194,9 @@ subroutine readatom_(fname, fp, iLine, potcomps, tDensitySuperpos, tReadRadDeriv !! true, there are non-local exchange contributions to calculate logical, intent(in) :: tNonLocal + !! true, if kinetic energy density (tau) needs to be read from density file + logical, intent(in) :: tMGGA + !> atomic properties instance type(TAtomdata), intent(out) :: atom @@ -302,7 +291,12 @@ subroutine readatom_(fname, fp, iLine, potcomps, tDensitySuperpos, tReadRadDeriv read(line, *, iostat=iErr) buffer call checkerror_(fname, line, iLine, iErr) if (tDensitySuperpos) then - call readdata_(buffer, [1, 3, 4, 5], data) + if (tMGGA) then + call readdata_(buffer, [1, 3, 4, 5, 6], data) + call TGridorb2_init(atom%tau, data(:, 1), data(:, 5)) + else + call readdata_(buffer, [1, 3, 4, 5], data) + end if call TGridorb2_init(atom%rho, data(:, 1), data(:, 2)) call TGridorb2_init(atom%drho, data(:, 1), data(:, 3)) call TGridorb2_init(atom%ddrho, data(:, 1), data(:, 4)) diff --git a/slateratom/lib/CMakeLists.txt b/slateratom/lib/CMakeLists.txt index 03df19ba..72e32c06 100644 --- a/slateratom/lib/CMakeLists.txt +++ b/slateratom/lib/CMakeLists.txt @@ -16,6 +16,7 @@ set(sources-f90 densitymatrix.f90 dft.f90 diagonalizations.f90 + diismixer.F90 globals.f90 hamiltonian.f90 integration.f90 @@ -23,6 +24,7 @@ set(sources-f90 mixer.f90 numerical_differentiation.f90 output.f90 + sap.f90 total_energy.f90 utilities.f90 zora_routines.f90) @@ -31,6 +33,7 @@ set(sources-fpp blasroutines.F90 broydenmixer.F90 confinement.F90 + diismixer.F90 input.F90 lapackroutines.F90 simplemixer.F90 diff --git a/slateratom/lib/density.f90 b/slateratom/lib/density.f90 index 1af7c7f1..89c9a7aa 100644 --- a/slateratom/lib/density.f90 +++ b/slateratom/lib/density.f90 @@ -2,6 +2,7 @@ module density use common_accuracy, only : dp + use common_constants, only : rec4pi use utilities, only : fak implicit none @@ -14,7 +15,7 @@ module density public :: basis_1st_times_basis_1st, basis_2nd_times_basis_2nd public :: basis_times_basis_times_r2, basis_times_basis_1st_times_r2,& & basis_times_basis_2nd_times_r2, basis_times_basis_1st_times_r,& - & basis_1st_times_basis_1st_times_r2 + & basis_1st_times_basis_1st_times_r2, tau_at_point contains @@ -222,6 +223,80 @@ pure function density_at_point_2nd(pp, max_l, num_alpha, poly_order, alpha, rr) end function density_at_point_2nd + !> Calculates kinetic energy density at a radial point in space analytically. + !! see Rev. Mod. Phys. 32, 186 (1960) eqn. 5. + pure function tau_at_point(pp, max_l, num_alpha, poly_order, alpha, rr) + + !> density matrix supervector + real(dp), intent(in) :: pp(0:,:,:) + + !> maximum angular momentum + integer, intent(in) :: max_l + + !> number of exponents in each shell + integer, intent(in) :: num_alpha(0:) + + !> highest polynomial order + l in each shell + integer, intent(in) :: poly_order(0:) + + !> basis exponents + real(dp), intent(in) :: alpha(0:,:) + + !> radial point in space, i.e. abcissa + real(dp), intent(in) :: rr + + !> resulting analytical kinetic energy density at a radial point in space + real(dp) :: tau_at_point + + !> auxiliary variables + integer :: ii, jj, kk, ll, mm, nn, oo, start + + tau_at_point = 0.0_dp + + do ii = 0, max_l + ll = 0 + do jj = 1, num_alpha(ii) + do kk = 1, poly_order(ii) + ll = ll + 1 + + ! set global index correctly + oo = ll - 1 + do mm = jj, num_alpha(ii) + + ! catch start index for polynomials, different depending on alpha block + start = 1 + if (mm == jj) start = kk + + do nn = start, poly_order(ii) + oo = oo + 1 + + if (ll == oo) then + tau_at_point = tau_at_point + pp(ii, ll, oo)& + & * (basis_1st_times_basis_1st(alpha(ii, jj), kk, alpha(ii, mm), nn, ii, rr)& + & + basis_times_basis(alpha(ii, jj), kk, alpha(ii, mm), nn, ii, rr)& + & * (ii * (ii + 1)) * (1 / rr**2)) + + end if + + if (ll /= oo) then + tau_at_point = tau_at_point + 2.0_dp * pp(ii, ll, oo)& + & * (basis_1st_times_basis_1st( alpha(ii, jj), kk, alpha(ii, mm), nn, ii, rr)& + & + basis_times_basis(alpha(ii, jj), kk, alpha(ii, mm), nn, ii, rr)& + & * (ii * (ii + 1)) * (1 / rr**2)) + end if + + end do + end do + end do + end do + end do + + ! normalize tau + tau_at_point = tau_at_point * 0.5_dp * rec4pi + + end function tau_at_point + + !> Calculates wavefunction at a radial point in space analytically. pure function wavefunction(cof, alpha, num_alpha, poly_order, ang, rr) @@ -876,12 +951,12 @@ pure function basis_times_basis_2nd_times_r2(alpha, poly1, beta, poly2, ll, rr) normalization2 = (2.0_dp * beta)**(nn) * sqrt(2.0_dp * beta) / sqrt(fak(2 * nn)) ! WARNING: without summing negative and positive contributions independently, - ! zora becomes completely unstable ! + ! zora becomes completely unstable! positive = real((nn - 1) * (nn - 2), dp) * rr**(mm + nn - 2) + beta**2 * rr**(mm + nn) negative = real(2 * (nn - 1), dp) * beta * rr**(nn + mm - 1) - basis_times_basis_2nd_times_r2 = normalization1 * normalization2& - & * (positive - negative) * exp(ab * rr) + basis_times_basis_2nd_times_r2 = normalization1 * normalization2 * (positive - negative)& + & * exp(ab * rr) if (abs(basis_times_basis_2nd_times_r2) < 1.0d-20) basis_times_basis_2nd_times_r2 = 0.0_dp @@ -938,7 +1013,6 @@ end function basis_times_basis_1st_times_r !> Evaluates product of 1st derivatives of basis functions and r^2. - !! beta and poly2 are the arguments of the 2nd basis. pure function basis_1st_times_basis_1st_times_r2(alpha, poly1, beta, poly2, ll, rr) !> basis exponent of 1st basis derivative @@ -962,27 +1036,8 @@ pure function basis_1st_times_basis_1st_times_r2(alpha, poly1, beta, poly2, ll, !> product of 1st derivatives of basis functions and r^2 real(dp) :: basis_1st_times_basis_1st_times_r2 - !> normalization pre-factors - real(dp) :: normalization1, normalization2 - - !> auxiliary variables - integer :: mm, nn - real(dp) :: ab, positive, negative - - mm = poly1 + ll - nn = poly2 + ll - ab = - (alpha + beta) - - normalization1 = (2.0_dp * alpha)**(mm) * sqrt(2.0_dp * alpha) / sqrt(fak(2 * mm)) - normalization2 = (2.0_dp * beta)**(nn) * sqrt(2.0_dp * beta) / sqrt(fak(2 * nn)) - - ! WARNING: without summing negative and positive contributions independently, - ! zora becomes completely unstable ! - positive = real((mm - 1) * (nn - 1), dp) * rr**(mm + nn - 2) + alpha * beta * rr**(mm + nn) - negative = (alpha * real(nn - 1, dp) + beta * real(mm - 1, dp)) * rr**(mm + nn - 1) - - basis_1st_times_basis_1st_times_r2 = normalization1 * normalization2& - & * (positive - negative) * exp(ab * rr) + basis_1st_times_basis_1st_times_r2 = & + & basis_1st_times_basis_1st(alpha, poly1, beta, poly2, ll, rr) * (rr ** 2) if (abs(basis_1st_times_basis_1st_times_r2) < 1.0d-20)& & basis_1st_times_basis_1st_times_r2 = 0.0_dp diff --git a/slateratom/lib/dft.f90 b/slateratom/lib/dft.f90 index cda52119..e9f0393a 100644 --- a/slateratom/lib/dft.f90 +++ b/slateratom/lib/dft.f90 @@ -6,14 +6,17 @@ module dft use common_constants, only : pi, rec4pi use xcfunctionals, only : xcFunctional, getExcVxc_LDA_PW91,& & getExcVxc_GGA_PBE96, getExcVxc_GGA_BLYP, getExcVxc_LCY_PBE96, getExcVxc_LCY_BNL,& - & getExcVxc_HYB_B3LYP, getExcVxc_HYB_PBE0, getExcVxc_CAMY_B3LYP, getExcVxc_CAMY_PBEh + & getExcVxc_HYB_B3LYP, getExcVxc_HYB_PBE0, getExcVxc_CAMY_B3LYP, getExcVxc_CAMY_PBEh, & + & getExcVxc_MGGA_TPSS, getExcVxc_MGGA_SCAN, getExcVxc_MGGA_r2SCAN, getExcVxc_MGGA_r4SCAN,& + & getExcVxc_MGGA_TASK, getExcVxc_MGGA_TASK_CC, getExcVxc_CAMY_MGGA_wB97M use density, only : basis, basis_times_basis_times_r2, density_at_point, density_at_point_1st,& - & density_at_point_2nd + & density_at_point_2nd, tau_at_point, basis_1st_times_basis_1st_times_r2,& + & basis_1st_times_basis_1st, basis_times_basis implicit none private - public :: dft_start_pot, density_grid, dft_exc_energy, dft_vxc_energy + public :: thomas_fermi_start_pot, density_grid, dft_exc_energy, dft_vxc_energy public :: dft_exc_matrixelement, xalpha public :: check_accuracy @@ -23,9 +26,9 @@ module dft !> Total potential to initialize a DFT calculation from Thomas-Fermi theory. This does not work as !! intended in the current code, since we do not have a numerical Coulomb-Potential. !! - !! Generalized Thomas-Fermi atomic potential as published by R. Latter, + !! Generalized Fermi atomic potential as published by R. Latter, !! Phys. Rev. 99, 510 (1955) eqn. 5/9 and implemented in Dirk Porezags scfatom. - pure subroutine dft_start_pot(abcissa, num_mesh_points, nuc, vxc) + pure subroutine thomas_fermi_start_pot(abcissa, num_mesh_points, nuc, vxc) !> numerical integration abcissas real(dp), intent(in) :: abcissa(:) @@ -59,13 +62,13 @@ pure subroutine dft_start_pot(abcissa, num_mesh_points, nuc, vxc) end do - end subroutine dft_start_pot + end subroutine thomas_fermi_start_pot !> Calculate and store density and density derivatives on radial grid. !! Further calculates and stores exchange-correlation potential and energy density on grid. subroutine density_grid(pp, max_l, num_alpha, poly_order, alpha, num_mesh_points, abcissa, dzdr,& - & dz, xcnr, omega, camAlpha, camBeta, rho, drho, ddrho, vxc, exc, xalpha_const) + & dz, xcnr, omega, camAlpha, camBeta, rho, drho, ddrho, tau, vxc, vtau, exc, xalpha_const) !> density matrix supervector real(dp), intent(in) :: pp(:, 0:,:,:) @@ -115,6 +118,12 @@ subroutine density_grid(pp, max_l, num_alpha, poly_order, alpha, num_mesh_points !> 2nd deriv. of density on grid real(dp), intent(out) :: ddrho(:,:) + !> kinetic energy density on grid + real(dp), intent(out) :: tau(:,:) + + !> orbital-dependent tau potential on grid + real(dp), intent(out) :: vtau(:,:) + !> xc potential on grid real(dp), intent(out) :: vxc(:,:) @@ -149,6 +158,8 @@ subroutine density_grid(pp, max_l, num_alpha, poly_order, alpha, num_mesh_points ddrho(:,:) = 0.0_dp exc(:) = 0.0_dp vxc(:,:) = 0.0_dp + vtau(:,:) = 0.0_dp + tau(:,:) = 0.0_dp ! get density on grid do ii = 1, num_mesh_points @@ -158,8 +169,9 @@ subroutine density_grid(pp, max_l, num_alpha, poly_order, alpha, num_mesh_points rho = max(rho, 0.0_dp) ! get density derivatives on grid - if (xcFunctional%isGGA(xcnr) .or. xcFunctional%isLongRangeCorrected(xcnr)& - & .or. xcFunctional%isGlobalHybrid(xcnr) .or. xcFunctional%isCAMY(xcnr)) then + if (xcFunctional%isGGA(xcnr) .or. xcFunctional%isMGGA(xcnr)& + & .or. xcFunctional%isLongRangeCorrected(xcnr) .or. xcFunctional%isGlobalHybrid(xcnr)& + & .or. xcFunctional%isCAMY(xcnr)) then do ii = 1, num_mesh_points drho(ii, 1) = density_at_point_1st(pp(1, :,:,:), max_l, num_alpha, poly_order, alpha,& @@ -178,14 +190,22 @@ subroutine density_grid(pp, max_l, num_alpha, poly_order, alpha, num_mesh_points rhor = transpose(rho) * rec4pi ! get contracted gradients of the density - if (xcFunctional%isGGA(xcnr) .or. xcFunctional%isLongRangeCorrected(xcnr)& - & .or. xcFunctional%isGlobalHybrid(xcnr) .or. xcFunctional%isCAMY(xcnr)) then + if (xcFunctional%isGGA(xcnr) .or. xcFunctional%isMGGA(xcnr)& + & .or. xcFunctional%isLongRangeCorrected(xcnr) .or. xcFunctional%isGlobalHybrid(xcnr)& + & .or. xcFunctional%isCAMY(xcnr)) then allocate(sigma(3, nn)) sigma(1, :) = drho(:, 1) * drho(:, 1) * rec4pi**2 sigma(2, :) = drho(:, 1) * drho(:, 2) * rec4pi**2 sigma(3, :) = drho(:, 2) * drho(:, 2) * rec4pi**2 end if + if (xcFunctional%isMGGA(xcnr)) then + do ii = 1, num_mesh_points + tau(ii, 1) = tau_at_point(pp(1, :,:,:), max_l, num_alpha, poly_order, alpha, abcissa(ii)) + tau(ii, 2) = tau_at_point(pp(2, :,:,:), max_l, num_alpha, poly_order, alpha, abcissa(ii)) + end do + end if + select case (xcnr) case(xcFunctional%HF_Exchange) return @@ -217,6 +237,21 @@ subroutine density_grid(pp, max_l, num_alpha, poly_order, alpha, num_mesh_points case(xcFunctional%CAMY_PBEh) call getExcVxc_CAMY_PBEh(abcissa, dz, dzdr, rho, drho, sigma, omega, camAlpha, camBeta, exc,& & vxc) + case(xcFunctional%MGGA_TPSS) + call getExcVxc_MGGA_TPSS(abcissa, dz, dzdr, rho, drho, sigma, tau, exc, vxc, vtau) + case(xcFunctional%MGGA_SCAN) + call getExcVxc_MGGA_SCAN(abcissa, dz, dzdr, rho, drho, sigma, tau, exc, vxc, vtau) + case(xcFunctional%MGGA_r2SCAN) + call getExcVxc_MGGA_r2SCAN(abcissa, dz, dzdr, rho, drho, sigma, tau, exc, vxc, vtau) + case(xcFunctional%MGGA_r4SCAN) + call getExcVxc_MGGA_r4SCAN(abcissa, dz, dzdr, rho, drho, sigma, tau, exc, vxc, vtau) + case(xcFunctional%MGGA_TASK) + call getExcVxc_MGGA_TASK(abcissa, dz, dzdr, rho, drho, sigma, tau, exc, vxc, vtau) + case(xcFunctional%MGGA_TASK_CC) + call getExcVxc_MGGA_TASK_CC(abcissa, dz, dzdr, rho, drho, sigma, tau, exc, vxc, vtau) + case(xcFunctional%CAMY_MGGA_wB97M) + call getExcVxc_CAMY_MGGA_wB97M(abcissa, dz, dzdr, rho, drho, sigma, tau, omega, camAlpha,& + & camBeta, exc, vxc, vtau) case default write(*, '(A,I2,A)') 'XCNR=', xcnr, ' not implemented!' stop @@ -299,8 +334,11 @@ end subroutine dft_vxc_energy !> Calculates a single matrix element of the exchange correlation potential. - pure subroutine dft_exc_matrixelement(num_mesh_points, weight, abcissa, vxc, alpha1, poly1,& - & alpha2, poly2, ll, exc_matrixelement) + pure subroutine dft_exc_matrixelement(xcnr, num_mesh_points, weight, abcissa, vxc, vtau, alpha1,& + & poly1, alpha2, poly2, ll, exc_matrixelement) + + !> identifier of exchange-correlation type + integer, intent(in) :: xcnr !> number of numerical integration points integer, intent(in) :: num_mesh_points @@ -314,6 +352,9 @@ pure subroutine dft_exc_matrixelement(num_mesh_points, weight, abcissa, vxc, alp !> xc potential on grid real(dp), intent(in) :: vxc(:,:) + !> orbital-dependent tau potential on grid + real(dp), intent(in) :: vtau(:,:) + !> basis exponent of 1st basis real(dp), intent(in) :: alpha1 @@ -332,10 +373,10 @@ pure subroutine dft_exc_matrixelement(num_mesh_points, weight, abcissa, vxc, alp !> single matrix element of the exchange correlation potential real(dp), intent(out) :: exc_matrixelement(2) - !> stores product of two basis functions and r^2 + !! stores product of two basis functions and r^2 real(dp) :: basis - !> auxiliary variable + !! auxiliary variable integer :: ii exc_matrixelement(:) = 0.0_dp @@ -347,6 +388,18 @@ pure subroutine dft_exc_matrixelement(num_mesh_points, weight, abcissa, vxc, alp exc_matrixelement(2) = exc_matrixelement(2) - weight(ii) * vxc(ii, 2) * basis end do + if (xcFunctional%isMGGA(xcnr)) then + do ii = 1, num_mesh_points + basis = basis_1st_times_basis_1st_times_r2(alpha1, poly1, alpha2, poly2, ll, abcissa(ii))& + & + basis_times_basis(alpha1, poly1, alpha2, poly2, ll, abcissa(ii))& + & * (ll * (ll + 1)) + + exc_matrixelement(1) = exc_matrixelement(1) - weight(ii) * vtau(ii, 1) * basis * 0.5_dp + exc_matrixelement(2) = exc_matrixelement(2) - weight(ii) * vtau(ii, 2) * basis * 0.5_dp + end do + + end if + end subroutine dft_exc_matrixelement diff --git a/slateratom/lib/diagonalizations.f90 b/slateratom/lib/diagonalizations.f90 index 2fd4a10a..2703ae7f 100644 --- a/slateratom/lib/diagonalizations.f90 +++ b/slateratom/lib/diagonalizations.f90 @@ -34,8 +34,9 @@ subroutine diagonalize_overlap(max_l, num_alpha, poly_order, ss) !! eigenvalues of overlap matrices real(dp), allocatable :: eigenvalues(:) - !> auxiliary variables - integer :: ll, diagsize + !! auxiliary variables + integer :: ll, diagsize, ii + real(dp) :: e_min, e_max, cond_num do ll = 0, max_l @@ -46,7 +47,7 @@ subroutine diagonalize_overlap(max_l, num_alpha, poly_order, ss) overlap = ss(ll, :,:) - call heev(overlap, eigenvalues, 'U', 'N') + call heev(overlap, eigenvalues, 'U', 'V') write(*, '(A,I3,A,E16.8)') 'Smallest eigenvalue of overlap for l= ', ll, ' : ', eigenvalues(1) @@ -57,11 +58,30 @@ subroutine diagonalize_overlap(max_l, num_alpha, poly_order, ss) stop end if + if (ll == 0) then + e_min = minval(eigenvalues) + e_max = maxval(eigenvalues) + end if + + if (minval(eigenvalues) < e_min) then + e_min = minval(eigenvalues) + end if + + if (maxval(eigenvalues) > e_max) then + e_max = maxval(eigenvalues) + end if + deallocate(overlap, eigenvalues) end do + + cond_num = abs(e_max / e_min) + write(*, '(A,E16.8)') 'Condition number is ', cond_num + ! 16 is due to double precision + write(*, '(A,I2)') 'Expect convergence only up to approx. 1e-', 16 - int(anint(log10(cond_num))) write(*,*) ' ' + end subroutine diagonalize_overlap diff --git a/slateratom/lib/diismixer.F90 b/slateratom/lib/diismixer.F90 new file mode 100644 index 00000000..434b8503 --- /dev/null +++ b/slateratom/lib/diismixer.F90 @@ -0,0 +1,236 @@ +#:include 'common.fypp' + +!> Contains an DIIS mixer +!! The DIIS mixing is done by building a weighted combination over the previous input charges to +!! minimise the residue of the error. +!! Only a specified number of previous charge vectors are considered. +!! The modification based on from Kovalenko et al. (J. Comput. Chem., 20: 928-936 1999) and Patrick +!! Briddon to add a contribution from the gradient vector as well is also used. +!! In order to use the mixer you have to create and reset it. +module diismixer + use common_accuracy, only : dp + use lapackroutines, only : gesv + implicit none + + private + public :: TDiisMixer, TDiisMixer_init, TDiisMixer_reset + public :: TDiisMixer_mix + + !> Contains the necessary data for an DIIS mixer. + type TDiisMixer + private + + !> Initial mixing parameter + real(dp) :: initMixParam + + !> Max. nr. of stored prev. vectors + integer :: mPrevVector + + !> Nr. of stored previous vectors + integer :: iPrevVector + + !> Nr. of elements in the vectors + integer :: nElem + + !> Index for the storage + integer :: indx + + !> Stored previous input charges + real(dp), allocatable :: prevQInput(:,:) + + !> Stored prev. charge differences + real(dp), allocatable :: previousMetric(:,:) + + !> True if DIIS used from iteration 2 as well as mixing + logical :: tFromStart + + !> force modification for gDIIS? + logical :: tAddIntrpGradient + + !> Alpha factor to add in new information + real(dp) :: alpha + + !> Holds DIIS mixed gradients from older iterations for downhill direction + real(dp), allocatable :: deltaR(:) + + end type TDiisMixer + +contains + + !> Creates a DIIS mixer instance. + subroutine TDiisMixer_init(this, nGeneration, initMixParam, tFromStart, alpha) + + !> Pointer to an initialized DIIS mixer on exit + type(TDiisMixer), intent(out) :: this + + !> Nr. of generations (including actual) to consider + integer, intent(in) :: nGeneration + + !> Mixing parameter for the first nGeneration cycles + real(dp), intent(in) :: initMixParam + + !> True if using DIIS from iteration 2 as well as mixing + logical, intent(in), optional :: tFromStart + + !> If present, fraction of extrapolated downhill direction to include in DIIS space + real(dp), intent(in), optional :: alpha + + @:ASSERT(nGeneration >= 2) + + this%nElem = 0 + this%mPrevVector = nGeneration + + allocate(this%prevQInput(this%nElem, this%mPrevVector)) + allocate(this%previousMetric(this%nElem, this%mPrevVector)) + + this%initMixParam = initMixParam + + if (present(tFromStart)) then + this%tFromStart = tFromStart + else + this%tFromStart = .false. + end if + + if (present(alpha)) then + this%tAddIntrpGradient = .true. + this%alpha = alpha + allocate(this%deltaR(this%nElem)) + else + this%tAddIntrpGradient = .false. + this%alpha = 0.0_dp + allocate(this%deltaR(0)) + end if + + this%deltaR(:) = 0.0_dp + + end subroutine TDiisMixer_init + + + !> Makes the mixer ready for a new SCC cycle. + subroutine TDiisMixer_reset(this, nElem) + + !> DIIS mixer instance + type(TDiisMixer), intent(inout) :: this + + !> Nr. of elements in the vectors to mix + integer, intent(in) :: nElem + + @:ASSERT(nElem > 0) + + if (nElem /= this%nElem) then + this%nElem = nElem + deallocate(this%prevQInput) + deallocate(this%previousMetric) + allocate(this%prevQInput(this%nElem, this%mPrevVector)) + allocate(this%previousMetric(this%nElem, this%mPrevVector)) + if (this%tAddIntrpGradient) then + deallocate(this%deltaR) + allocate(this%deltaR(this%nElem)) + this%deltaR(:) = 0.0_dp + end if + end if + this%iPrevVector = 0 + this%indx = 0 + + end subroutine TDiisMixer_reset + + + !> Mixes charges according to the DIIS method. + subroutine TDiisMixer_mix(this, qInpResult, qDiff, commtr) + + !> Pointer to the diis mixer + type(TDiisMixer), intent(inout) :: this + + !> Input charges on entry, mixed charges on exit. + real(dp), intent(inout) :: qInpResult(:) + + !> Charge difference vector between output and input charges + real(dp), intent(in) :: qDiff(:) + + !> Commutator [F,PS] (flattened) + real(dp), intent(in) :: commtr(:) + + real(dp), allocatable :: aa(:,:), bb(:,:) + integer :: ii, jj + + @:ASSERT(size(qInpResult) == this%nElem) + @:ASSERT(size(qDiff) == this%nElem) + + if (this%iPrevVector < this%mPrevVector) then + this%iPrevVector = this%iPrevVector + 1 + end if + + ! Store previous Fock matrix and commutator + call storeVectors_(this%prevQInput, this%previousMetric, this%indx, qInpResult, commtr,& + & this%mPrevVector) + ! call storeVectors_(this%prevQInput, this%prevQDiff, this%indx, qInpResult, qDiff,& + ! & this%mPrevVector) + + if (this%tFromStart .or. this%iPrevVector == this%mPrevVector) then + + allocate(aa(this%iPrevVector + 1, this%iPrevVector + 1)) + allocate(bb(this%iPrevVector + 1, 1)) + + aa(:,:) = 0.0_dp + bb(:,:) = 0.0_dp + + ! (due to the hermitian property of our density matrices, the dot-product below is real) + do ii = 1, this%iPrevVector + do jj = 1, this%iPrevVector + aa(ii, jj) = dot_product(this%previousMetric(:, ii), this%previousMetric(:, jj)) + end do + end do + aa(this%iPrevVector + 1, 1:this%iPrevVector) = -1.0_dp + aa(1:this%iPrevVector, this%iPrevVector + 1) = -1.0_dp + + bb(this%iPrevVector + 1, 1) = -1.0_dp + + ! Solve DIIS system of linear equations + call gesv(aa, bb) + + qInpResult(:) = 0.0_dp + do ii = 1, this%iPrevVector + qInpResult(:) = qInpResult + bb(ii, 1) * (this%prevQInput(:, ii)) + ! qInpResult(:) = qInpResult + bb(ii, 1) * (this%prevQInput(:, ii) +& + ! & this%previousMetric(:, ii)) + end do + + end if + + if (this%iPrevVector < this%mPrevVector) then + ! First few iterations return simple mixed vector + qInpResult(:) = qInpResult + this%initMixParam * qDiff + end if + + end subroutine TDiisMixer_mix + + + !> Stores a vector pair in a limited storage. + !! If the stack is full, oldest vector pair is overwritten. + subroutine storeVectors_(prevQInp, prevQDiff, indx, qInput, qDiff, mPrevVector) + + !> Contains previous vectors of the first type + real(dp), intent(inout) :: prevQInp(:,:) + + !> Contains previous vectors of the second type + real(dp), intent(inout) :: prevQDiff(:,:) + + !> Indexing of data + integer, intent(inout) :: indx + + !> New first vector + real(dp), intent(in) :: qInput(:) + + !> New second vector + real(dp), intent(in) :: qDiff(:) + + !> Size of the stacks. + integer, intent(in) :: mPrevVector + + indx = mod(indx, mPrevVector) + 1 + prevQInp(:, indx) = qInput + prevQDiff(:, indx) = qDiff + + end subroutine storeVectors_ + +end module diismixer \ No newline at end of file diff --git a/slateratom/lib/globals.f90 b/slateratom/lib/globals.f90 index 92e50a35..55850cb9 100644 --- a/slateratom/lib/globals.f90 +++ b/slateratom/lib/globals.f90 @@ -6,6 +6,7 @@ module globals use broydenmixer, only : TBroydenMixer, TBroydenMixer_init use simplemixer, only : TSimpleMixer, TSimpleMixer_init use confinement, only : TConfInp + use diismixer, only : TDiisMixer, TDiisMixer_init implicit none @@ -85,26 +86,35 @@ module globals !> wavefunction coefficients real(dp), allocatable :: cof(:,:,:,:) - !> relative changes during scf - real(dp) :: change_max + !> maximum (absolute) value in [F,PS] + real(dp) :: commutator_max !> density matrix supervector - real(dp), allocatable :: pp(:,:,:,:) + real(dp), allocatable :: pp(:,:,:,:), pp_old(:,:,:,:) + + !> density matrix max difference + real(dp) :: pp_diff !> fock matrix supervector real(dp), allocatable :: ff(:,:,:,:) + !> commutator [F, PS] + real(dp), allocatable :: commutator(:,:,:,:) + !> potential matrix supervectors real(dp), allocatable :: pot_new(:,:,:,:), pot_old(:,:,:,:) !> eigenvalues - real(dp), allocatable :: eigval(:,:,:) + real(dp), allocatable :: eigval(:,:,:), eigval_old(:,:,:) + + !> eigenvalue difference vector norm + real(dp) :: eigval_diff !> zora scaled eigenvalues real(dp), allocatable :: eigval_scaled(:,:,:) !> total energy - real(dp) :: total_ene + real(dp) :: total_ene, total_ene_old, total_ene_diff !> kinetic energy real(dp) :: kinetic_energy @@ -154,6 +164,12 @@ module globals !> 2nd deriv. of density on grid real(dp), allocatable :: ddrho(:,:) + !> kinetic energy density on grid + real(dp), allocatable :: tau(:,:) + + !> orbital-dependent tau potential on grid + real(dp), allocatable :: vtau(:,:) + !> xc potential on grid real(dp), allocatable :: vxc(:,:) @@ -172,12 +188,15 @@ module globals !> true, if zero-order regular approximation for relativistic effects is desired logical :: tZora - !> true, if SCF cycle reached convergency - logical :: tConverged + !> true, if SCF cycle reached convergency on a given quantity + logical :: tCommutatorConverged, tEnergyConverged, tEigenspectrumConverged, tDensityConverged !> identifier of mixer integer :: mixnr + !> DIIS subspace size + integer, parameter :: n_vec_diis = 10 + !> mixer instance type(TMixer), allocatable :: pMixer @@ -187,6 +206,9 @@ module globals !> broyden mixer (if used) type(TBroydenMixer), allocatable :: pBroydenMixer + !> DIIS mixer (if used) + type(TDiisMixer), allocatable :: pDiisMixer + !> mixing factor real(dp) :: mixing_factor @@ -215,6 +237,8 @@ subroutine allocate_globals() allocate(rho(num_mesh_points, 2)) allocate(drho(num_mesh_points, 2)) allocate(ddrho(num_mesh_points, 2)) + allocate(tau(num_mesh_points, 2)) + allocate(vtau(num_mesh_points, 2)) allocate(exc(num_mesh_points)) allocate(vxc(num_mesh_points, 2)) @@ -226,10 +250,12 @@ subroutine allocate_globals() allocate(vconf(num_mesh_points, 0:max_l)) allocate(vconf_matrix(0:max_l, problemsize, problemsize)) allocate(ff(2, 0:max_l, problemsize, problemsize)) + allocate(commutator(2, 0:max_l, problemsize, problemsize)) allocate(pot_old(2, 0:max_l, problemsize, problemsize)) allocate(pot_new(2, 0:max_l, problemsize, problemsize)) allocate(eigval(2, 0:max_l, problemsize)) + allocate(eigval_old(2, 0:max_l, problemsize)) allocate(eigval_scaled(2, 0:max_l, problemsize)) allocate(jj(0:max_l, problemsize, problemsize, 0:max_l, problemsize, problemsize)) @@ -245,12 +271,15 @@ subroutine allocate_globals() ! fourth index of cof is the eigenvalue index, see densmatrix build allocate(cof(2, 0:max_l, problemsize, problemsize)) allocate(pp(2, 0:max_l, problemsize, problemsize)) + allocate(pp_old(2, 0:max_l, problemsize, problemsize)) weight(:) = 0.0_dp abcissa(:) = 0.0_dp rho(:,:) = 0.0_dp drho(:,:) = 0.0_dp ddrho(:,:) = 0.0_dp + tau(:,:) = 0.0_dp + vtau(:,:) = 0.0_dp eigval(:,:,:) = 0.0_dp eigval_scaled(:,:,:) = 0.0_dp @@ -273,6 +302,10 @@ subroutine allocate_globals() call TBroydenMixer_init(pBroydenMixer, maxiter, mixing_factor, 0.01_dp, 1.0_dp, 1.0e5_dp,& & 1.0e-2_dp) call TMixer_init(pMixer, pBroydenMixer) + case(mixerTypes%diis) + allocate(pDiisMixer) + call TDiisMixer_init(pDiisMixer, n_vec_diis, mixing_factor, .false.) + call TMixer_init(pMixer, pDiisMixer) case default error stop "Unknown mixer type." end select diff --git a/slateratom/lib/hamiltonian.f90 b/slateratom/lib/hamiltonian.f90 index dab8d521..53781292 100644 --- a/slateratom/lib/hamiltonian.f90 +++ b/slateratom/lib/hamiltonian.f90 @@ -5,8 +5,9 @@ module hamiltonian use dft, only : dft_exc_matrixelement use mixer, only : TMixer, TMixer_mix use zora_routines, only : zora_t_correction + use utilities, only : compute_commutator use xcfunctionals, only : xcFunctional - + implicit none private @@ -18,8 +19,8 @@ module hamiltonian !> Main driver routine for Fock matrix build-up. Also calls mixer with potential matrix. subroutine build_hamiltonian(pMixer, iScf, tt, uu, nuc, vconf, jj, kk, kk_lr, pp, max_l,& - & num_alpha, poly_order, problemsize, xcnr, num_mesh_points, weight, abcissa, vxc, alpha,& - & pot_old, pot_new, tZora, ff, camAlpha, camBeta) + & num_alpha, poly_order, problemsize, xcnr, num_mesh_points, weight, abcissa, vxc, vtau,& + & alpha, pot_old, pot_new, tZora, ff, commutator, camAlpha, camBeta) !> mixer instances type(TMixer), intent(inout) :: pMixer @@ -78,6 +79,9 @@ subroutine build_hamiltonian(pMixer, iScf, tt, uu, nuc, vconf, jj, kk, kk_lr, pp !> xc potential on grid real(dp), intent(in) :: vxc(:,:) + !> orbital-dependent tau potential on grid + real(dp), intent(in) :: vtau(:,:) + !> basis exponents real(dp), intent(in) :: alpha(0:,:) @@ -93,6 +97,9 @@ subroutine build_hamiltonian(pMixer, iScf, tt, uu, nuc, vconf, jj, kk, kk_lr, pp !> fock matrix supervector real(dp), intent(out) :: ff(:,0:,:,:) + !> commutator [F,PS] + real(dp), intent(inout) :: commutator(:,0:,:,:) + !> CAM alpha parameter real(dp), intent(in) :: camAlpha @@ -131,58 +138,61 @@ subroutine build_hamiltonian(pMixer, iScf, tt, uu, nuc, vconf, jj, kk, kk_lr, pp call build_coulomb_matrix(jj, p_total, max_l, num_alpha, poly_order, j_matrix) ! build exchange(-correlation) potential matrices: - ! pure Hartree-Fock if (xcnr == xcFunctional%HF_Exchange) then call build_hf_ex_matrix(kk, pp, max_l, num_alpha, poly_order, k_matrix) - end if - - ! pure DFT - if (xcFunctional%isLDA(xcnr) .or. xcFunctional%isGGA(xcnr)) then - call build_dft_exc_matrix(max_l, num_alpha, poly_order, alpha, num_mesh_points, abcissa,& - & weight, vxc, k_matrix) - end if - ! HF - DFT hybrid - if (xcFunctional%isLongRangeCorrected(xcnr)) then + elseif (xcFunctional%isLongRangeCorrected(xcnr)) then call build_hf_ex_matrix(kk_lr, pp, max_l, num_alpha, poly_order, k_matrix) - call build_dft_exc_matrix(max_l, num_alpha, poly_order, alpha, num_mesh_points, abcissa,& - & weight, vxc, k_matrix2) + call build_dft_exc_matrix(xcnr, max_l, num_alpha, poly_order, alpha, num_mesh_points,& + & abcissa, weight, vxc, vtau, k_matrix2) k_matrix(:,:,:,:) = k_matrix + k_matrix2 elseif (xcnr == xcFunctional%HYB_B3LYP) then call build_hf_ex_matrix(kk, pp, max_l, num_alpha, poly_order, k_matrix) - call build_dft_exc_matrix(max_l, num_alpha, poly_order, alpha, num_mesh_points, abcissa,& - & weight, vxc, k_matrix2) + call build_dft_exc_matrix(xcnr, max_l, num_alpha, poly_order, alpha, num_mesh_points,& + & abcissa, weight, vxc, vtau, k_matrix2) ! B3LYP parameters a=0.20, b=0.72, c=0.81 (libXC defaults) ! --> 0.20 * HF exchange + full libXC DFT exchange k_matrix(:,:,:,:) = 0.20_dp * k_matrix + k_matrix2 elseif (xcnr == xcFunctional%HYB_PBE0) then call build_hf_ex_matrix(kk, pp, max_l, num_alpha, poly_order, k_matrix) - call build_dft_exc_matrix(max_l, num_alpha, poly_order, alpha, num_mesh_points, abcissa,& - & weight, vxc, k_matrix3) + call build_dft_exc_matrix(xcnr, max_l, num_alpha, poly_order, alpha, num_mesh_points,& + & abcissa, weight, vxc, vtau, k_matrix3) k_matrix(:,:,:,:) = camAlpha * k_matrix + k_matrix3 elseif (xcFunctional%isCAMY(xcnr)) then call build_hf_ex_matrix(kk, pp, max_l, num_alpha, poly_order, k_matrix) call build_hf_ex_matrix(kk_lr, pp, max_l, num_alpha, poly_order, k_matrix2) - call build_dft_exc_matrix(max_l, num_alpha, poly_order, alpha, num_mesh_points, abcissa,& - & weight, vxc, k_matrix3) - if (xcnr == xcFunctional%CAMY_B3LYP) then - ! CAMY-B3LYP parameters (libXC defaults) - k_matrix(:,:,:,:) = camAlpha * k_matrix + camBeta * k_matrix2 + k_matrix3 - elseif (xcnr == xcFunctional%CAMY_PBEh) then - ! CAMY-PBEh - k_matrix(:,:,:,:) = camAlpha * k_matrix + camBeta * k_matrix2 + k_matrix3 - end if + call build_dft_exc_matrix(xcnr, max_l, num_alpha, poly_order, alpha, num_mesh_points,& + & abcissa, weight, vxc, vtau, k_matrix3) + k_matrix(:,:,:,:) = camAlpha * k_matrix + camBeta * k_matrix2 + k_matrix3 + else + ! Semilocal xc functionals + call build_dft_exc_matrix(xcnr, max_l, num_alpha, poly_order, alpha, num_mesh_points,& + & abcissa, weight, vxc, vtau, k_matrix) end if ! build mixer input - pot_new(1, :,:,:) = - real(nuc, dp) * uu + j_matrix - k_matrix(1, :,:,:) - pot_new(2, :,:,:) = - real(nuc, dp) * uu + j_matrix - k_matrix(2, :,:,:) + if (iScf == 0) then + pot_new(1, :,:,:) = -k_matrix(1, :,:,:) + pot_new(2, :,:,:) = -k_matrix(2, :,:,:) + ! for the Thomas-Fermi guess + ! pot_new(1, :,:,:) = -real(nuc, dp) * uu + j_matrix - k_matrix(1, :,:,:) + ! pot_new(2, :,:,:) = -real(nuc, dp) * uu + j_matrix - k_matrix(2, :,:,:) + else + pot_new(1, :,:,:) = -real(nuc, dp) * uu + j_matrix - k_matrix(1, :,:,:) + pot_new(2, :,:,:) = -real(nuc, dp) * uu + j_matrix - k_matrix(2, :,:,:) + end if + + ! mixer allocate(pot_diff, mold=pot_old) pot_diff(:,0:,:,:) = pot_old - pot_new - call TMixer_mix(pMixer, pot_new, pot_diff) + + if (iScf /= 0) then + ! Do not call mixer on the 0th (guess) iteration + call TMixer_mix(pMixer, pot_new, pot_diff, commutator) + end if ! Not sure: before or after mixer (potential .ne. Matrix elements)? ! Should be irrelevant once self-consistency is reached. @@ -351,8 +361,11 @@ end subroutine build_hf_ex_matrix !> Builds DFT exchange matrix to be added to the Fock matrix by calculating the single matrix !! elements and putting them together. - subroutine build_dft_exc_matrix(max_l, num_alpha, poly_order, alpha, num_mesh_points, abcissa,& - & weight, vxc, k_matrix) + subroutine build_dft_exc_matrix(xcnr, max_l, num_alpha, poly_order, alpha, num_mesh_points,& + & abcissa, weight, vxc, vtau, k_matrix) + + !> identifier of exchange-correlation type + integer, intent(in) :: xcnr !> maximum angular momentum integer, intent(in) :: max_l @@ -378,6 +391,9 @@ subroutine build_dft_exc_matrix(max_l, num_alpha, poly_order, alpha, num_mesh_po !> xc potential on grid real(dp), intent(in) :: vxc(:,:) + !> orbital-dependent tau potential on grid + real(dp), intent(in) :: vtau(:,:) + !> DFT exchange matrix real(dp), intent(out) :: k_matrix(:,0:,:,:) @@ -405,8 +421,8 @@ subroutine build_dft_exc_matrix(max_l, num_alpha, poly_order, alpha, num_mesh_po do mm = start, poly_order(ii) tt = tt + 1 - call dft_exc_matrixelement(num_mesh_points, weight, abcissa, vxc, alpha(ii, jj), kk,& - & alpha(ii, ll), mm, ii, exc_matrixelement) + call dft_exc_matrixelement(xcnr, num_mesh_points, weight, abcissa, vxc, vtau,& + & alpha(ii, jj), kk, alpha(ii, ll), mm, ii, exc_matrixelement) k_matrix(1, ii, ss, tt) = exc_matrixelement(1) k_matrix(2, ii, ss, tt) = exc_matrixelement(2) diff --git a/slateratom/lib/input.F90 b/slateratom/lib/input.F90 index c3f01454..4d82e3dd 100644 --- a/slateratom/lib/input.F90 +++ b/slateratom/lib/input.F90 @@ -114,9 +114,10 @@ subroutine read_input_1(nuc, max_l, occ_shells, maxiter, scftol, poly_order, min write(*, '(A)') 'Enter nuclear charge, maximal angular momentum (s=0), max. SCF, SCF tol., ZORA' read(*,*) nuc, max_l, maxiter, scftol, tZora - write(*, '(A)') 'Enter XC functional:& - & 0: HF, 1: X-Alpha, 2: LDA-PW91, 3: GGA-PBE96, 4: GGA-BLYP, 5: LCY-PBE96, 6: LCY-BNL,& - & 7: PBE0, 8: B3LYP, 9: CAMY-B3LYP, 10: CAMY-PBEh' + write(*, '(A)') 'Enter XC functional:' + write(*, '(A)') '0: HF, 1: X-Alpha, 2: LDA-PW91, 3: GGA-PBE96, 4: GGA-BLYP, 5: LCY-PBE96,' + write(*, '(A)') '6: LCY-BNL, 7: PBE0, 8: B3LYP, 9: CAMY-B3LYP, 10: CAMY-PBEh, 11: TPSS,' + write(*, '(A)') '12: SCAN, 13: r2SCAN, 14: r4SCAN, 15: TASK, 16: TASK+CC, 17: Y-wB97M' read(*,*) xcnr if (xcFunctional%isNotImplemented(xcnr)) then @@ -386,6 +387,14 @@ subroutine echo_input(nuc, max_l, occ_shells, maxiter, scftol, poly_order, num_a if (xcnr == xcFunctional%HYB_B3LYP) write(*, '(A)') 'Global hybrid: B3LYP' if (xcnr == xcFunctional%CAMY_B3LYP) write(*, '(A)') 'CAM: CAMY-B3LYP' if (xcnr == xcFunctional%CAMY_PBEh) write(*, '(A)') 'CAM: CAMY-PBEh' + if (xcnr == xcFunctional%MGGA_TPSS) write(*, '(A)') 'meta-GGA: TPSS' + if (xcnr == xcFunctional%MGGA_SCAN) write(*, '(A)') 'meta-GGA: SCAN' + if (xcnr == xcFunctional%MGGA_r2SCAN) write(*, '(A)') 'meta-GGA: r2SCAN' + if (xcnr == xcFunctional%MGGA_r4SCAN) write(*, '(A)') 'meta-GGA: r4SCAN' + if (xcnr == xcFunctional%MGGA_TASK) write(*, '(A)') 'meta-GGA: TASK' + if (xcnr == xcFunctional%MGGA_TASK_CC) write(*, '(A)') 'meta-GGA: TASK+CC' + if (xcnr == xcFunctional%CAMY_MGGA_wB97M) write(*, '(A)') 'CAMY meta-GGA: wB97M' + write(*, '(A,I6)') 'Max. number of SCF iterations: ', maxiter write(*, '(A,ES9.2E2)') 'SCF tolerance [a.u.]: ', scftol diff --git a/slateratom/lib/lapackroutines.F90 b/slateratom/lib/lapackroutines.F90 index 390ba7cc..9036f5f8 100644 --- a/slateratom/lib/lapackroutines.F90 +++ b/slateratom/lib/lapackroutines.F90 @@ -1,4 +1,4 @@ -#:include 'common.fypp' +#:include 'common.fypp' !> Contains F90 wrapper functions for some commonly used lapack calls needed in the code. !! The interface of all LAPACK calls must be defined in the module lapack. @@ -8,7 +8,7 @@ module lapackroutines implicit none private - public :: getrf, getrs + public :: getrf, getrs, gesv !> Computes the LU decomposition of a general rectangular matrix using partial pivoting with row @@ -29,7 +29,146 @@ module lapackroutines end interface getrs + !> Computes the solution to a real system of linear equations A * X = B, where A is an N-by-N + !> matrix and X and B are N-by-NRHS matrices + interface gesv + module procedure gesv_dble + module procedure gesv_dcomplex + end interface gesv + contains + + !> Double precision version of gesv + subroutine gesv_dble(aa, bb, nEquation, nSolution, iError) + + !> Contains the coefficients on entry, the LU factorisation on exit. + real(rdp), intent(inout) :: aa(:,:) + + !> Right hand side(s) of the linear equation on entry, solution(s) on exit. + real(rdp), intent(inout) :: bb(:,:) + + !> The size of the problem (nr. of variables and equations). Must be only specified if different + !> from size(aa, dim=1). + integer, intent(in), optional :: nEquation + + !> Nr. of right hand sides (nr. of solutions). Must be only specified if different from size(b, + !> dim=2). + integer, intent(in), optional :: nSolution + + !> Error flag. If present, Lapack error flags are reported and noncritical errors (iError > 0) + !> will not abort the program. + integer, intent(out), optional :: iError + + integer :: info + integer :: nn, nrhs, lda, ldb + integer, allocatable :: ipiv(:) + character(len=100) :: error_string + + lda = size(aa, dim=1) + if (present(nEquation)) then + @:ASSERT(nEquation >= 1 .and. nEquation <= lda) + nn = nEquation + else + nn = lda + end if + @:ASSERT(size(aa, dim=2) >= nn) + + ldb = size(bb, dim=1) + @:ASSERT(ldb >= nn) + nrhs = size(bb, dim=2) + if (present(nSolution)) then + @:ASSERT(nSolution <= nrhs) + nrhs = nSolution + end if + + info = 0 + allocate(ipiv(nn)) + call dgesv(nn, nrhs, aa, lda, ipiv, bb, ldb, info) + + if (info < 0) then + 99020 format ('Failure in linear equation solver dgesv,', & + & ' illegal argument at position ',i10) + write (error_string, 99020) info + error stop error_string + else + if (present(iError)) then + iError = info + elseif (info > 0) then + 99030 format ('Linear dependent system in linear equation solver dgesv,', & + & ' info flag: ',i10) + write (error_string, 99030) info + error stop error_string + end if + end if + + end subroutine gesv_dble + + + !> Double precision version of gesv + subroutine gesv_dcomplex(aa, bb, nEquation, nSolution, iError) + + !> Contains the coefficients on entry, the LU factorisation on exit. + complex(rdp), intent(inout) :: aa(:,:) + + !> Right hand side(s) of the linear equation on entry, solution(s) on exit. + complex(rdp), intent(inout) :: bb(:,:) + + !> The size of the problem (nr. of variables and equations). Must be only specified if different + !> from size(aa, dim=1). + integer, intent(in), optional :: nEquation + + !> Nr. of right hand sides (nr. of solutions). Must be only specified if different from size(b, + !> dim=2). + integer, intent(in), optional :: nSolution + + !> Error flag. If present, Lapack error flags are reported and noncritical errors (iError > 0) + !> will not abort the program. + integer, intent(out), optional :: iError + + integer :: info + integer :: nn, nrhs, lda, ldb + integer, allocatable :: ipiv(:) + character(len=100) :: error_string + + lda = size(aa, dim=1) + if (present(nEquation)) then + @:ASSERT(nEquation >= 1 .and. nEquation <= lda) + nn = nEquation + else + nn = lda + end if + @:ASSERT(size(aa, dim=2) >= nn) + + ldb = size(bb, dim=1) + @:ASSERT(ldb >= nn) + nrhs = size(bb, dim=2) + if (present(nSolution)) then + @:ASSERT(nSolution <= nrhs) + nrhs = nSolution + end if + + info = 0 + allocate(ipiv(nn)) + call zgesv(nn, nrhs, aa, lda, ipiv, bb, ldb, info) + + if (info < 0) then + 99020 format ('Failure in linear equation solver dgesv,', & + & ' illegal argument at position ',i10) + write (error_string, 99020) info + error stop error_string + else + if (present(iError)) then + iError = info + elseif (info > 0) then + 99030 format ('Linear dependent system in linear equation solver dgesv,', & + & ' info flag: ',i10) + write (error_string, 99030) info + error stop error_string + end if + end if + + end subroutine gesv_dcomplex + !> Double precision version of getrf. subroutine getrf_dble(aa, ipiv, nRow, nColumn, iError) diff --git a/slateratom/lib/mixer.f90 b/slateratom/lib/mixer.f90 index 1ac8230f..5d5ecaf6 100644 --- a/slateratom/lib/mixer.f90 +++ b/slateratom/lib/mixer.f90 @@ -4,6 +4,7 @@ module mixer use common_accuracy, only : dp use broydenmixer, only : TBroydenMixer, TBroydenMixer_mix, TBroydenMixer_reset use simplemixer, only : TSimpleMixer, TSimpleMixer_mix, TSimpleMixer_reset + use diismixer, only : TDiisMixer, TDiisMixer_init, TDiisMixer_mix, TDiisMixer_reset implicit none private @@ -23,6 +24,9 @@ module mixer !> Broyden mixer instance type(TBroydenMixer), allocatable :: pBroydenMixer + !> DIIS mixer instance + type(TDiisMixer), allocatable :: pDiisMixer + end type TMixer @@ -30,6 +34,7 @@ module mixer interface TMixer_init module procedure TMixer_initSimple module procedure TMixer_initBroyden + module procedure TMixer_initDiis end interface TMixer_init @@ -43,6 +48,7 @@ module mixer type :: TMixerTypesEnum integer :: simple = 1 integer :: broyden = 2 + integer :: diis = 3 end type TMixerTypesEnum !> Contains mixer types @@ -80,8 +86,22 @@ subroutine TMixer_initBroyden(this, pBroyden) end subroutine TMixer_initBroyden + + subroutine TMixer_initDiis(this, pDiis) + + !> Mixer instance + type(TMixer), intent(out) :: this + + !> A valid DIIS mixer instance on exit + type(TDiisMixer), allocatable, intent(inout) :: pDiis + + this%mixerType = mixerTypes%diis + call move_alloc(pDiis, this%pDiisMixer) - !> Resets the mixer. + end subroutine TMixer_initDIIS + + + !> Resets the mixer.pDiff(1:size(diff)) => diff subroutine TMixer_reset(this, nElem) !> Mixer instance @@ -95,13 +115,15 @@ subroutine TMixer_reset(this, nElem) call TSimpleMixer_reset(this%pSimpleMixer, nElem) case(mixerTypes%broyden) call TBroydenMixer_reset(this%pBroydenMixer, nElem) + case(mixerTypes%diis) + call TDiisMixer_reset(this%pDiisMixer, nElem) end select end subroutine TMixer_reset !> Mixes two vectors. - subroutine TMixer_mix1D(this, inp, diff) + subroutine TMixer_mix1D(this, inp, diff, commtr) !> Mixer instance type(TMixer), intent(inout) :: this @@ -112,18 +134,23 @@ subroutine TMixer_mix1D(this, inp, diff) !> Difference between input and output vectors (measure of lack of convergence) real(dp), intent(in) :: diff(:) + !> Commutator [F,PS] + real(dp), intent(in) :: commtr(:) + select case (this%mixerType) case(mixerTypes%simple) call TSimpleMixer_mix(this%pSimpleMixer, inp, diff) case(mixerTypes%broyden) call TBroydenMixer_mix(this%pBroydenMixer, inp, diff) + case(mixerTypes%diis) + call TDiisMixer_mix(this%pDiisMixer, inp, diff, commtr) end select end subroutine TMixer_mix1D !> Mixes two 4D matrices. - subroutine TMixer_mix4D(this, inp, diff) + subroutine TMixer_mix4D(this, inp, diff, commtr) !> Mixer instance type(TMixer), intent(inout) :: this @@ -134,16 +161,23 @@ subroutine TMixer_mix4D(this, inp, diff) !> Difference between input and output vectors (measure of lack of convergence) real(dp), intent(in), contiguous, target :: diff(:,0:,:,:) + !> Commutator [F,PS] + real(dp), intent(in), contiguous, target :: commtr(:,0:,:,:) + !! Difference between input and output vectors (1D pointer) real(dp), pointer :: pDiff(:) !! Input vector on entry, result vector on exit (1D pointer) real(dp), pointer :: pInp(:) + !! Commutator [F,PS] + real(dp), pointer :: pCommtr(:) + pInp(1:size(inp)) => inp pDiff(1:size(diff)) => diff + pCommtr(1:size(diff)) => commtr - call TMixer_mix1D(this, pInp, pDiff) + call TMixer_mix1D(this, pInp, pDiff, pCommtr) end subroutine TMixer_mix4D diff --git a/slateratom/lib/output.f90 b/slateratom/lib/output.f90 index 352906cf..7795ff91 100644 --- a/slateratom/lib/output.f90 +++ b/slateratom/lib/output.f90 @@ -9,6 +9,7 @@ module output use coulomb_potential, only : cou_pot use common_taggedout, only : TTaggedwriter, TTaggedwriter_init, writetag use utilities, only : fak + use xcfunctionals, only : xcFunctional implicit none private @@ -292,20 +293,46 @@ end subroutine write_potentials_file_standard !> Writes potentials and mesh info to file on standard (internal) integration mesh; !! in principle one could read in the points from another file to have other meshes! - subroutine write_densities_file_standard(num_mesh_points, abcissa, weight, rho, drho, ddrho) + subroutine write_densities_file_standard(xcnr, num_mesh_points, abcissa, weight, rho, drho,& + & ddrho, tau) - real(dp), intent(in) :: abcissa(:), weight(:) - real(dp), intent(in) :: rho(:,:), drho(:,:), ddrho(:,:) + !> identifier of exchange-correlation type + integer, intent(in) :: xcnr + + !> number of numerical integration points integer, intent(in) :: num_mesh_points + + !> numerical integration abcissas + real(dp), intent(in) :: abcissa(:) + + !> numerical integration weights + real(dp), intent(in) :: weight(:) + + !> density on grid + real(dp), intent(in) :: rho(:,:) + + !> 1st deriv. of density on grid + real(dp), intent(in) :: drho(:,:) + + !> 2nd deriv. of density on grid + real(dp), intent(in) :: ddrho(:,:) + + !> kinetic energy density on grid + real(dp), intent(in) :: tau(:,:) + real(dp) :: enumber, zeta, r_seitz integer :: ii open(95, file='dens.dat', form='formatted', status='unknown') write(95, '(A)') '# 1st line: number of mesh points' write(95, '(A)') '# rho and r_seitz are calculated from total density' - write(95, '(A)') '# zeta and r_seitz only correct of rho > 1d-12' + write(95, '(A)') '# zeta and r_seitz only correct of rho > 1.0e-12' write(95, '(A)') '' - write(95, '(A)') '# abcissa weight rho drho ddrho zeta r_seitz' + if (xcFunctional%isMGGA(xcnr)) then + write(95, '(A)') '# abcissa weight rho drho ddrho zeta r_seitz tau' + else + write(95, '(A)') '# abcissa weight rho drho ddrho zeta r_seitz' + end if write(95, '(I0)') num_mesh_points enumber = 0.0_dp @@ -313,11 +340,11 @@ subroutine write_densities_file_standard(num_mesh_points, abcissa, weight, rho, ! note division of total density by 4*pi in calculation of r_seitz ! commonly r_seitz=((4*pi*rho)/3)**(-1/3) but our rho is from the ! radial part only and the angular part must be taken into account - ! explicitely; during integration this happens implicitely, see enumber + ! explicitly; during integration this happens explicitly, see enumber do ii = 1, num_mesh_points - if ((rho(ii, 1) + rho(ii, 2)) > 1.0d-12) then + if ((rho(ii, 1) + rho(ii, 2)) > 1.0e-12_dp) then zeta = (rho(ii, 1) - rho(ii, 2)) / (rho(ii, 1) + rho(ii, 2)) r_seitz = (4.0_dp * pi / 3.0_dp& & * ((rho(ii, 1) + rho(ii, 2)) / 4.0_dp / pi))**(-1.0_dp / 3.0_dp) @@ -326,8 +353,15 @@ subroutine write_densities_file_standard(num_mesh_points, abcissa, weight, rho, r_seitz = 0.0_dp end if - write(95, '(7ES21.12E3)') abcissa(ii), weight(ii), rho(ii, 1) + rho(ii, 2),& - & drho(ii, 1) + drho(ii, 2), ddrho(ii, 1) + ddrho(ii, 2), zeta, r_seitz + if (xcFunctional%isMGGA(xcnr)) then + write(95, '(8ES21.12E3)') abcissa(ii), weight(ii), rho(ii, 1) + rho(ii, 2),& + & drho(ii, 1) + drho(ii, 2), ddrho(ii, 1) + ddrho(ii, 2), zeta, r_seitz,& + & tau(ii, 1) + tau(ii, 2) + else + write(95, '(7ES21.12E3)') abcissa(ii), weight(ii), rho(ii, 1) + rho(ii, 2),& + & drho(ii, 1) + drho(ii, 2), ddrho(ii, 1) + ddrho(ii, 2), zeta, r_seitz + end if + enumber = enumber + weight(ii) * (rho(ii, 1) + rho(ii, 2)) * abcissa(ii)**2 end do diff --git a/slateratom/lib/sap.f90 b/slateratom/lib/sap.f90 new file mode 100644 index 00000000..0e8fe73f --- /dev/null +++ b/slateratom/lib/sap.f90 @@ -0,0 +1,2303 @@ +!> Module for atomic guess through superposition of atomic potentials +!! (SAP) method + +module sap + + !> Reference: + !! Susi Lehtola, Lucas Visscher, Eberhard Engel; + !! Efficient implementation of the superposition of atomic potentials + !! initial guess for electronic structure calculations + !! in Gaussian basis sets. + !! J. Chem. Phys. 14 April 2020; 152 (14): 144105. + !! https://doi.org/10.1063/5.0004046 + !! + !! used data is labeled helfem_large.dirac in the SI of the paper + + use common_accuracy, only: dp + use common_message, only: error + + implicit none + private + + public :: sap_start_pot + +contains + + !> Compute SAP potential for an atom on a grid. + subroutine sap_start_pot(abcissa, nuc, v) + + !> numerical integration abcissas + real(dp), intent(in) :: abcissa(:) + + !> nuclear charge, i.e. atomic number + integer, intent(in) :: nuc + + !> xc potential on grid for two spin channels v(:, 1) and v(:, 2) + real(dp), intent(out) :: v(:, :) + + !! exp. index + integer :: nexp + + !! effective charge + real(dp), allocatable :: zeff(:) + + !! tabulated SAP data (exponents, coefficients) + real(dp), allocatable :: sap_data(:, :) + + allocate(zeff, mold=abcissa) + zeff = 0.0_dp + + v(:,:) = 0.0_dp + + call get_sap_data(nuc, sap_data) + + ! compute effective charge + do nexp = 1, size(sap_data, dim=1) + zeff(:) = zeff(:) + sap_data(nexp, 2) * erfc(sqrt(sap_data(nexp, 1)) * abcissa) + end do + + v(:, 1) = v(:, 1) + zeff / abcissa + v(:, 2) = v(:, 1) + + deallocate(sap_data) + deallocate(zeff) + + end subroutine sap_start_pot + + + !> Get tabulated SAP data array + subroutine get_sap_data(Natom, out) + + !> nuclear charge of atom + integer, intent(in) :: Natom + + !> output array + real(dp), intent(out), allocatable:: out(:, :) + + select case (Natom) + case (1) + allocate(out(4, 2)) + out(:,:) = transpose(reshape([[0.04268788542106363, -0.4185582672035864],& + [0.08366825542528471, -0.5962131922279497],& + [0.163989780633558, 1.524537907893517],& + [0.3214199700417737, -1.509766448461981]],& + shape=[2, 4])) + case (2) + allocate(out(5, 2)) + out(:,:) = transpose(reshape([[0.08366825542528471, -1.355205479616188],& + [0.163989780633558, 2.055414703345832],& + [0.3214199700417737, -3.585641909762671],& + [0.6299831412818762, 3.577647758042076],& + [1.234766956912478, -2.692215072009049]],& + shape=[2, 5])) + case (3) + allocate(out(9, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -0.7812202443437855],& + [0.02177953337809369, 0.7878101197566139],& + [0.04268788542106363, -1.834061208952335],& + [0.08366825542528471, 3.144340503349667],& + [0.163989780633558, -5.862783425312955],& + [0.3214199700417737, 7.556086712982506],& + [0.6299831412818762, -9.186191175249405],& + [1.234766956912478, 7.028106110417866],& + [2.420143235548455, -3.852087392648173]],& + shape=[2, 9])) + case (4) + allocate(out(9, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -1.684101067949086],& + [0.04268788542106363, 2.010666946873243],& + [0.08366825542528471, -3.766492405644385],& + [0.163989780633558, 5.218894453777466],& + [0.3214199700417737, -8.457585407944862],& + [0.6299831412818762, 10.28838749043643],& + [1.234766956912478, -11.26269935470191],& + [2.420143235548455, 7.400723657789058],& + [4.743480741674971, -3.747794312635961]],& + shape=[2, 9])) + case (5) + allocate(out(11, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -1.000032957054088],& + [0.02177953337809369, 1.724570476113513],& + [0.04268788542106363, -3.39669319935274],& + [0.08366825542528471, 3.536343834137369],& + [0.163989780633558, -5.306160429419833],& + [0.3214199700417737, 5.143829342290701],& + [0.6299831412818762, -7.905614915624028],& + [1.234766956912478, 9.050180592370452],& + [2.420143235548455, -9.910984211092],& + [4.743480741674971, 6.27473211862889],& + [9.297222253682943, -3.210170650998236]],& + shape=[2, 11])) + case (6) + allocate(out(9, 2)) + out(:,:) = transpose(reshape([[0.04268788542106363, -1.261992879455647],& + [0.08366825542528471, 1.856334428972332],& + [0.163989780633558, -3.633981649269117],& + [0.3214199700417737, 3.953077307669446],& + [0.6299831412818762, -8.253920026065316],& + [1.234766956912478, 7.178058194345795],& + [2.420143235548455, -8.611687745898962],& + [4.743480741674971, 6.945998759241775],& + [9.297222253682943, -4.171886389540305]],& + shape=[2, 9])) + case (7) + allocate(out(9, 2)) + out(:,:) = transpose(reshape([[0.04268788542106363, -1.052755375898414],& + [0.08366825542528471, 0.8940734185162],& + [0.163989780633558, -2.897407143755117],& + [0.3214199700417737, 3.934491195715964],& + [0.6299831412818762, -8.398524643387645],& + [1.234766956912478, 7.50688491249457],& + [2.420143235548455, -10.11875403433805],& + [4.743480741674971, 8.213310290622758],& + [9.297222253682943, -5.081318619970261]],& + shape=[2, 9])) + case (8) + allocate(out(11, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -1.303093470731824],& + [0.04268788542106363, 2.680316414385743],& + [0.08366825542528471, -4.956605911003862],& + [0.163989780633558, 5.393036064349872],& + [0.3214199700417737, -7.334251391635917],& + [0.6299831412818762, 6.169044227252016],& + [1.234766956912478, -10.38518856556038],& + [2.420143235548455, 8.253574505710276],& + [4.743480741674971, -8.77926564484369],& + [9.297222253682943, 5.973193470417755],& + [18.22255561721856, -3.710759698339984]],& + shape=[2, 11])) + case (9) + allocate(out(10, 2)) + out(:,:) = transpose(reshape([[0.04268788542106363, -0.8534547253765368],& + [0.08366825542528471, 0.4317019303168763],& + [0.163989780633558, -1.113489109611692],& + [0.3214199700417737, -0.3972697870995034],& + [0.6299831412818762, 0.07449690638532047],& + [1.234766956912478, -5.779926691142464],& + [2.420143235548455, 4.125841244924231],& + [4.743480741674971, -7.521000012122386],& + [9.297222253682943, 6.513433162788715],& + [18.22255561721856, -4.480332919062562]],& + shape=[2, 10])) + case (10) + allocate(out(9, 2)) + out(:,:) = transpose(reshape([[0.08366825542528471, -1.902350849093636],& + [0.163989780633558, 2.783781029778766],& + [0.3214199700417737, -5.499603264208417],& + [0.6299831412818762, 6.158487736014649],& + [1.234766956912478, -11.69101849943399],& + [2.420143235548455, 8.699803143157624],& + [4.743480741674971, -12.7073407022981],& + [9.297222253682943, 10.11627001053421],& + [18.22255561721856, -5.958028604451101]],& + shape=[2, 9])) + case (11) + allocate(out(12, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -0.9168342651105377],& + [0.02177953337809369, 0.7158732077805325],& + [0.04268788542106363, -0.7548534333291173],& + [0.08366825542528471, -0.1175181805956527],& + [0.163989780633558, 0.03194724798959214],& + [0.3214199700417737, -2.168022868048865],& + [0.6299831412818762, 1.898600546119269],& + [1.234766956912478, -6.903178811480757],& + [2.420143235548455, 6.636541098385351],& + [4.743480741674971, -14.48740461794659],& + [9.297222253682943, 12.1209366263065],& + [18.22255561721856, -7.056086550069722]],& + shape=[2, 12])) + case (12) + allocate(out(12, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -2.944302301131529],& + [0.04268788542106363, 4.613997280459444],& + [0.08366825542528471, -6.272272958543908],& + [0.163989780633558, 5.516111563774757],& + [0.3214199700417737, -4.967518429970369],& + [0.6299831412818762, 1.552244046761189],& + [1.234766956912478, -3.974227231810801],& + [2.420143235548455, 0.08404480060562491],& + [4.743480741674971, -2.36661117587937],& + [9.297222253682943, -4.010052213154268],& + [18.22255561721856, 4.803185159398708],& + [35.71620900974838, -4.034598540509478]],& + shape=[2, 12])) + case (13) + allocate(out(14, 2)) + out(:,:) = transpose(reshape([[0.005669391237529597, -0.5909439250651047],& + [0.011112006825558, 0.5722753595107974],& + [0.02177953337809369, -1.34434200878718],& + [0.04268788542106363, 0.5877102622503116],& + [0.08366825542528471, -1.546703855934538],& + [0.163989780633558, -0.01306685495728743],& + [0.3214199700417737, -1.01538781158888],& + [0.6299831412818762, 0.3357770781040017],& + [1.234766956912478, -3.547210661658028],& + [2.420143235548455, -1.474410769107635],& + [4.743480741674971, 1.240931189822732],& + [9.297222253682943, -8.96333019839949],& + [18.22255561721856, 8.010281154656695],& + [35.71620900974838, -5.251578958846395]],& + shape=[2, 14])) + case (14) + allocate(out(12, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -0.8127697353011172],& + [0.04268788542106363, 0.2540161869455915],& + [0.08366825542528471, -0.8260441653692396],& + [0.163989780633558, -0.7042284475028282],& + [0.3214199700417737, -2.552601511764806],& + [0.6299831412818762, -1.505396562657552],& + [1.234766956912478, 3.303393574256916],& + [2.420143235548455, -9.690376613114495],& + [4.743480741674971, 9.045648330647964],& + [9.297222253682943, -15.49272349011153],& + [18.22255561721856, 11.44490882809623],& + [35.71620900974838, -6.463826394125135]],& + shape=[2, 12])) + case (15) + allocate(out(12, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -0.5992678117117975],& + [0.04268788542106363, -0.5639590451519325],& + [0.08366825542528471, -0.3279153039984521],& + [0.163989780633558, -1.126289570398512],& + [0.3214199700417737, -0.9332405743480194],& + [0.6299831412818762, -4.421751029323786],& + [1.234766956912478, 6.871837385580875],& + [2.420143235548455, -15.16434673283948],& + [4.743480741674971, 15.45938829617808],& + [9.297222253682943, -20.83107788400957],& + [18.22255561721856, 14.13607957604108],& + [35.71620900974838, -7.499457306018485]],& + shape=[2, 12])) + case (16) + allocate(out(13, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -1.748811040801229],& + [0.04268788542106363, 2.845631621603388],& + [0.08366825542528471, -5.392239935230464],& + [0.163989780633558, 5.040648057358339],& + [0.3214199700417737, -7.884977125562727],& + [0.6299831412818762, 2.485891971737146],& + [1.234766956912478, -2.994288264773786],& + [2.420143235548455, -0.1290586609393358],& + [4.743480741674971, -5.32780085131526],& + [9.297222253682943, 3.837245954200625],& + [18.22255561721856, -9.305896442849189],& + [35.71620900974838, 6.987646126188338],& + [70.00376965910681, -4.413991409615846]],& + shape=[2, 13])) + case (17) + allocate(out(12, 2)) + out(:,:) = transpose(reshape([[0.04268788542106363, -2.636824076374978],& + [0.08366825542528471, 3.893888689319283],& + [0.163989780633558, -6.755512725554581],& + [0.3214199700417737, 5.247693471188541],& + [0.6299831412818762, -10.81530330848182],& + [1.234766956912478, 6.393424695415888],& + [2.420143235548455, -5.076906891306862],& + [4.743480741674971, -3.899564246763475],& + [9.297222253682943, 4.646057634497993],& + [18.22255561721856, -11.24528831912903],& + [35.71620900974838, 8.283061239490053],& + [70.00376965910681, -5.034726162301013]],& + shape=[2, 12])) + case (18) + allocate(out(12, 2)) + out(:,:) = transpose(reshape([[0.04268788542106363, -1.465912932323135],& + [0.08366825542528471, 0.8208771993740811],& + [0.163989780633558, -2.222161542420508],& + [0.3214199700417737, 0.2881619631662033],& + [0.6299831412818762, -5.233347484027036],& + [1.234766956912478, -2.322904476779513],& + [2.420143235548455, 4.629048535309266],& + [4.743480741674971, -12.710690271575],& + [9.297222253682943, 11.59485676488839],& + [18.22255561721856, -16.11130312993191],& + [35.71620900974838, 10.59347901405999],& + [70.00376965910681, -5.860103639740828]],& + shape=[2, 12])) + case (19) + allocate(out(14, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -1.868893032172494],& + [0.02177953337809369, 3.078620213603926],& + [0.04268788542106363, -4.31582827114562],& + [0.08366825542528471, 3.423672902305952],& + [0.163989780633558, -3.997059524144788],& + [0.3214199700417737, -0.6914836289797677],& + [0.6299831412818762, -0.4589081831509247],& + [1.234766956912478, -8.944512780741206],& + [2.420143235548455, 9.727343792110332],& + [4.743480741674971, -15.93850292658317],& + [9.297222253682943, 13.50298732925148],& + [18.22255561721856, -17.47155213092628],& + [35.71620900974838, 11.28918729657016],& + [70.00376965910681, -6.335071055997602]],& + shape=[2, 14])) + case (20) + allocate(out(14, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -1.52525767346701],& + [0.02177953337809369, 0.7075816656063125],& + [0.04268788542106363, -0.832417261160117],& + [0.08366825542528471, -0.4449924404343619],& + [0.163989780633558, 1.290201511646956],& + [0.3214199700417737, -6.566388854744218],& + [0.6299831412818762, 3.164121788609918],& + [1.234766956912478, -9.190243014527368],& + [2.420143235548455, 6.880546056716412],& + [4.743480741674971, -12.15471686268575],& + [9.297222253682943, 10.25346390275809],& + [18.22255561721856, -15.724817379858],& + [35.71620900974838, 10.69684514173423],& + [70.00376965910681, -6.553926580195096]],& + shape=[2, 14])) + case (21) + allocate(out(15, 2)) + out(:,:) = transpose(reshape([[0.005669391237529597, -0.8552034009326803],& + [0.011112006825558, 0.9627373355381224],& + [0.02177953337809369, -2.500977194512416],& + [0.04268788542106363, 2.03459082563495],& + [0.08366825542528471, -3.921158842204022],& + [0.163989780633558, 3.045579381818243],& + [0.3214199700417737, -4.590542378326063],& + [0.6299831412818762, -1.311264557618415],& + [1.234766956912478, -4.090548139967723],& + [2.420143235548455, 1.804400855267886],& + [4.743480741674971, -8.217338427959476],& + [9.297222253682943, 7.726204846054316],& + [18.22255561721856, -14.76115518511506],& + [35.71620900974838, 10.59653780347435],& + [70.00376965910681, -6.921862921152012]],& + shape=[2, 15])) + case (22) + allocate(out(14, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -0.8063277009968317],& + [0.02177953337809369, 0.73311399546742],& + [0.04268788542106363, -1.492087839801115],& + [0.08366825542528471, 0.7256488069106126],& + [0.163989780633558, -2.471993486678912],& + [0.3214199700417737, -1.449695436956972],& + [0.6299831412818762, -0.4657828277959197],& + [1.234766956912478, -8.171648535630084],& + [2.420143235548455, 3.687349068954063],& + [4.743480741674971, -8.708827288268367],& + [9.297222253682943, 8.234626300472883],& + [18.22255561721856, -15.78979951803922],& + [35.71620900974838, 11.50842548951914],& + [70.00376965910681, -7.533001027156701]],& + shape=[2, 14])) + case (23) + allocate(out(14, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -1.686619506929702],& + [0.04268788542106363, 3.188741842070385],& + [0.08366825542528471, -5.148078081609128],& + [0.163989780633558, 4.15394079318321],& + [0.3214199700417737, -6.74895392568942],& + [0.6299831412818762, 1.939840487302718],& + [1.234766956912478, -7.605838704002963],& + [2.420143235548455, -3.538753213426389],& + [4.743480741674971, 4.441538538027089],& + [9.297222253682943, -11.08003329409985],& + [18.22255561721856, 8.452894140820717],& + [35.71620900974838, -12.62985983394901],& + [70.00376965910681, 8.13432300137356],& + [137.2073885318493, -4.873142243071214]],& + shape=[2, 14])) + case (24) + allocate(out(14, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -2.106144823921113],& + [0.04268788542106363, 3.980829489885537],& + [0.08366825542528471, -5.994532061338305],& + [0.163989780633558, 4.851140769250378],& + [0.3214199700417737, -7.409478412713725],& + [0.6299831412818762, 2.619964972185699],& + [1.234766956912478, -7.158408840565244],& + [2.420143235548455, -5.550860529532656],& + [4.743480741674971, 5.046611120415037],& + [9.297222253682943, -10.7286066434317],& + [18.22255561721856, 7.932173420398613],& + [35.71620900974838, -12.64185859471036],& + [70.00376965910681, 8.319026248762384],& + [137.2073885318493, -5.159856114684544]],& + shape=[2, 14])) + case (25) + allocate(out(14, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -0.6340877213818601],& + [0.02177953337809369, -0.5089406782436754],& + [0.04268788542106363, -0.1943858422259837],& + [0.08366825542528471, 0.02777538878490304],& + [0.163989780633558, -1.064093356759258],& + [0.3214199700417737, -0.8895238627010258],& + [0.6299831412818762, -3.45552763478554],& + [1.234766956912478, -4.444926846008457],& + [2.420143235548455, -1.699175533503876],& + [4.743480741674971, -9.113211921183392],& + [9.297222253682943, 12.70362931335694],& + [18.22255561721856, -21.76230917967041],& + [35.71620900974838, 15.87959512264206],& + [70.00376965910681, -9.844817248320425]],& + shape=[2, 14])) + case (26) + allocate(out(16, 2)) + out(:,:) = transpose(reshape([[0.005669391237529597, -0.5460467216779534],& + [0.011112006825558, 0.3606577134278268],& + [0.02177953337809369, -1.195251775550787],& + [0.04268788542106363, 0.2237606831367884],& + [0.08366825542528471, -0.7910077976630419],& + [0.163989780633558, -1.588195839009131],& + [0.3214199700417737, 1.233673743845429],& + [0.6299831412818762, -6.503713323851116],& + [1.234766956912478, 1.043648906808812],& + [2.420143235548455, -10.73371897498146],& + [4.743480741674971, 4.252512341015972],& + [9.297222253682943, -8.425313347950578],& + [18.22255561721856, 6.228235593531281],& + [35.71620900974838, -12.50932107912377],& + [70.00376965910681, 8.731403494603],& + [137.2073885318493, -5.781323616561281]],& + shape=[2, 16])) + case (27) + allocate(out(14, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -2.528532055404781],& + [0.04268788542106363, 3.769250462868627],& + [0.08366825542528471, -5.705125780945309],& + [0.163989780633558, 5.232529499686279],& + [0.3214199700417737, -6.852861972987739],& + [0.6299831412818762, 1.46303019062907],& + [1.234766956912478, -5.772713408783602],& + [2.420143235548455, -6.287488362075237],& + [4.743480741674971, -0.5329790820687776],& + [9.297222253682943, -4.516536824638024],& + [18.22255561721856, 3.754386153683299],& + [35.71620900974838, -11.67969724182331],& + [70.00376965910681, 8.722875845662202],& + [137.2073885318493, -6.066137423802701]],& + shape=[2, 14])) + case (28) + allocate(out(14, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -1.145055559700069],& + [0.04268788542106363, 1.235558740113447],& + [0.08366825542528471, -2.172119210598339],& + [0.163989780633558, 1.569054934551787],& + [0.3214199700417737, -2.703123285940819],& + [0.6299831412818762, -2.018595038174681],& + [1.234766956912478, -3.469156095081416],& + [2.420143235548455, -9.723353525325365],& + [4.743480741674971, 1.254665517539252],& + [9.297222253682943, -6.096447473508306],& + [18.22255561721856, 5.490701651142444],& + [35.71620900974838, -13.52028713531035],& + [70.00376965910681, 9.923699477905757],& + [137.2073885318493, -6.625542997613337]],& + shape=[2, 14])) + case (29) + allocate(out(14, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -1.751416886562481],& + [0.04268788542106363, 2.683338125355363],& + [0.08366825542528471, -4.254084901537681],& + [0.163989780633558, 3.565769808263212],& + [0.3214199700417737, -4.834211733341363],& + [0.6299831412818762, 0.4489044065703638],& + [1.234766956912478, -5.094064988974424],& + [2.420143235548455, -7.875397540978156],& + [4.743480741674971, -2.141188224719372],& + [9.297222253682943, -4.260544704025961],& + [18.22255561721856, 5.17232108002645],& + [35.71620900974838, -14.19475007016445],& + [70.00376965910681, 10.615495636579],& + [137.2073885318493, -7.080170006490505]],& + shape=[2, 14])) + case (30) + allocate(out(14, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -1.963742940281833],& + [0.04268788542106363, 2.275211191519475],& + [0.08366825542528471, -3.284164746822171],& + [0.163989780633558, 2.769912266760912],& + [0.3214199700417737, -4.228262691394775],& + [0.6299831412818762, -0.5144980953555205],& + [1.234766956912478, -3.871620914251253],& + [2.420143235548455, -7.589968777807371],& + [4.743480741674971, -3.969661601484404],& + [9.297222253682943, -4.28152382101689],& + [18.22255561721856, 6.369179377361434],& + [35.71620900974838, -15.78920794741134],& + [70.00376965910681, 11.7061551574734],& + [137.2073885318493, -7.627806457289665]],& + shape=[2, 14])) + case (31) + allocate(out(16, 2)) + out(:,:) = transpose(reshape([[0.005669391237529597, -0.6144875043171396],& + [0.011112006825558, 0.645019736904942],& + [0.02177953337809369, -1.361550048950448],& + [0.04268788542106363, 0.6272760151769035],& + [0.08366825542528471, -1.551940243531135],& + [0.163989780633558, -0.1599206291575683],& + [0.3214199700417737, -0.8207455298979767],& + [0.6299831412818762, -3.006044477748219],& + [1.234766956912478, -2.125409198692068],& + [2.420143235548455, -7.670524948043749],& + [4.743480741674971, -4.594654682441615],& + [9.297222253682943, -5.967646518256515],& + [18.22255561721856, 8.874254762427881],& + [35.71620900974838, -18.1396865718998],& + [70.00376965910681, 13.11497783887899],& + [137.2073885318493, -8.248918000452477]],& + shape=[2, 16])) + case (32) + allocate(out(14, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -1.929473722630064],& + [0.04268788542106363, 2.656334247774794],& + [0.08366825542528471, -4.888204175592364],& + [0.163989780633558, 3.820401422545729],& + [0.3214199700417737, -6.358795209449454],& + [0.6299831412818762, 3.109851340799651],& + [1.234766956912478, -7.729020964769006],& + [2.420143235548455, -2.19282654383278],& + [4.743480741674971, -8.493037646709126],& + [9.297222253682943, -5.747540776588721],& + [18.22255561721856, 10.00768268387765],& + [35.71620900974838, -19.58757381106261],& + [70.00376965910681, 14.11465394437255],& + [137.2073885318493, -8.782450788736242]],& + shape=[2, 14])) + case (33) + allocate(out(14, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -0.7679072594354466],& + [0.04268788542106363, -0.2630270365664273],& + [0.08366825542528471, -0.9617293739770503],& + [0.163989780633558, -0.1730366954052442],& + [0.3214199700417737, -3.391387913716244],& + [0.6299831412818762, -0.446247244017286],& + [1.234766956912478, -3.420383544034848],& + [2.420143235548455, -6.353496007141075],& + [4.743480741674971, -3.412845661878237],& + [9.297222253682943, -12.67319323256379],& + [18.22255561721856, 15.89818016134086],& + [35.71620900974838, -23.69609072408639],& + [70.00376965910681, 16.22268437824096],& + [137.2073885318493, -9.56151984675978]],& + shape=[2, 14])) + case (34) + allocate(out(15, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -0.5482843479080657],& + [0.02177953337809369, 0.3322848915559007],& + [0.04268788542106363, -1.635620422828651],& + [0.08366825542528471, 0.9185617815019214],& + [0.163989780633558, -2.36564426219411],& + [0.3214199700417737, -1.432083212202997],& + [0.6299831412818762, -3.373339062323794],& + [1.234766956912478, 0.2662438130064402],& + [2.420143235548455, -10.28779324842617],& + [4.743480741674971, 1.8020903072902],& + [9.297222253682943, -19.35468437091913],& + [18.22255561721856, 21.12648076226469],& + [35.71620900974838, -27.21167887549382],& + [70.00376965910681, 18.04134663043078],& + [137.2073885318493, -10.2778803837532]],& + shape=[2, 15])) + case (35) + allocate(out(14, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -0.7752297921769014],& + [0.04268788542106363, -0.1860541848500361],& + [0.08366825542528471, -1.081734944095842],& + [0.163989780633558, -0.07515246482398652],& + [0.3214199700417737, -3.274894157679228],& + [0.6299831412818762, -3.688500926346023],& + [1.234766956912478, 1.804842333076522],& + [2.420143235548455, -12.40857070694619],& + [4.743480741674971, 5.26487111543247],& + [9.297222253682943, -23.88733944151318],& + [18.22255561721856, 24.20616176884505],& + [35.71620900974838, -29.24039051969885],& + [70.00376965910681, 19.19196336818277],& + [137.2073885318493, -10.84997144740657]],& + shape=[2, 14])) + case (36) + allocate(out(13, 2)) + out(:,:) = transpose(reshape([[0.04268788542106363, -2.315640245942632],& + [0.08366825542528471, 2.551871241768822],& + [0.163989780633558, -5.195725474040955],& + [0.3214199700417737, 3.40357032418251],& + [0.6299831412818762, -12.33444903325289],& + [1.234766956912478, 10.03123393841088],& + [2.420143235548455, -19.5158962123096],& + [4.743480741674971, 12.09129829891026],& + [9.297222253682943, -30.1439242400229],& + [18.22255561721856, 27.97483518905938],& + [35.71620900974838, -31.55815403070301],& + [70.00376965910681, 20.46746176294982],& + [137.2073885318493, -11.45648151900969]],& + shape=[2, 13])) + case (37) + allocate(out(16, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -2.310813043993903],& + [0.02177953337809369, 4.350733911091993],& + [0.04268788542106363, -6.702976151136681],& + [0.08366825542528471, 6.668531755152799],& + [0.163989780633558, -9.203473289075191],& + [0.3214199700417737, 5.381848490360426],& + [0.6299831412818762, -10.13288545561954],& + [1.234766956912478, 3.320984141668305],& + [2.420143235548455, -8.647734191152267],& + [4.743480741674971, -3.226284619071521],& + [9.297222253682943, -8.467507911846042],& + [18.22255561721856, -2.391277117421851],& + [35.71620900974838, 4.099891467718408],& + [70.00376965910681, -12.87111280183308],& + [137.2073885318493, 9.382559465477243],& + [268.9264815224247, -6.250484650319095]],& + shape=[2, 16])) + case (38) + allocate(out(16, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -2.179206017138313],& + [0.02177953337809369, 2.230979425279656],& + [0.04268788542106363, -3.177888619018631],& + [0.08366825542528471, 2.836789899061841],& + [0.163989780633558, -3.527011938640499],& + [0.3214199700417737, -3.363381187024061],& + [0.6299831412818762, -0.6217338123824447],& + [1.234766956912478, -4.876159032806754],& + [2.420143235548455, -2.009781687054783],& + [4.743480741674971, -8.510337699903175],& + [9.297222253682943, -3.629010556964204],& + [18.22255561721856, -8.054243391379714],& + [35.71620900974838, 8.925811413209885],& + [70.00376965910681, -16.30134769110009],& + [137.2073885318493, 11.09808023739606],& + [268.9264815224247, -6.841559341534776]],& + shape=[2, 16])) + case (39) + allocate(out(17, 2)) + out(:,:) = transpose(reshape([[0.005669391237529597, -1.107599995433702],& + [0.011112006825558, 1.396149586420506],& + [0.02177953337809369, -3.314586645457894],& + [0.04268788542106363, 2.940880254842341],& + [0.08366825542528471, -5.246629188768566],& + [0.163989780633558, 5.183645196259022],& + [0.3214199700417737, -9.79052671790123],& + [0.6299831412818762, 2.474236886948347],& + [1.234766956912478, -5.742113955318928],& + [2.420143235548455, -1.780234917998314],& + [4.743480741674971, -8.748298838734627],& + [9.297222253682943, -2.604689259082079],& + [18.22255561721856, -10.70503756776452],& + [35.71620900974838, 11.42786356620491],& + [70.00376965910681, -18.25113547407091],& + [137.2073885318493, 12.15650724805892],& + [268.9264815224247, -7.288430178203271]],& + shape=[2, 17])) + case (40) + allocate(out(16, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -1.125075370147442],& + [0.02177953337809369, 1.623692981336717],& + [0.04268788542106363, -2.709255590107205],& + [0.08366825542528471, 1.883190856751753],& + [0.163989780633558, -4.822829566299333],& + [0.3214199700417737, 0.8361250536108855],& + [0.6299831412818762, -6.765411242726259],& + [1.234766956912478, -2.705329236458056],& + [2.420143235548455, -0.6737395494710654],& + [4.743480741674971, -10.61726611061022],& + [9.297222253682943, -0.07440138072706759],& + [18.22255561721856, -14.46521399612539],& + [35.71620900974838, 14.53352043172345],& + [70.00376965910681, -20.49154210486449],& + [137.2073885318493, 13.33295549650211],& + [268.9264815224247, -7.759420672388387]],& + shape=[2, 16])) + case (41) + allocate(out(15, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -1.636085063421888],& + [0.04268788542106363, 2.723145055623718],& + [0.08366825542528471, -4.867695230805111],& + [0.163989780633558, 3.18773118919853],& + [0.3214199700417737, -7.747279116636491],& + [0.6299831412818762, 1.089148434679373],& + [1.234766956912478, -11.56391292094486],& + [2.420143235548455, 7.7444741895888],& + [4.743480741674971, -17.56918991706334],& + [9.297222253682943, 6.251788704423234],& + [18.22255561721856, -20.72095651284326],& + [35.71620900974838, 19.05906619864982],& + [70.00376965910681, -23.4477034334559],& + [137.2073885318493, 14.79134009062545],& + [268.9264815224247, -8.293871667618077]],& + shape=[2, 15])) + case (42) + allocate(out(15, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -2.212583721165402],& + [0.04268788542106363, 4.183831486839154],& + [0.08366825542528471, -6.880174509045901],& + [0.163989780633558, 5.31537304311496],& + [0.3214199700417737, -10.30109088489553],& + [0.6299831412818762, 4.479843367385911],& + [1.234766956912478, -15.90621158384602],& + [2.420143235548455, 11.03884855052456],& + [4.743480741674971, -19.68325271271169],& + [9.297222253682943, 8.370438350946642],& + [18.22255561721856, -23.33020177565049],& + [35.71620900974838, 20.7383979645092],& + [70.00376965910681, -24.62973948789295],& + [137.2073885318493, 15.47737874643644],& + [268.9264815224247, -8.660856834548895]],& + shape=[2, 15])) + case (43) + allocate(out(16, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -0.8897171346825417],& + [0.02177953337809369, -0.2106305563738715],& + [0.04268788542106363, -0.328922509241238],& + [0.08366825542528471, -0.3216947424953105],& + [0.163989780633558, -0.7531391945522046],& + [0.3214199700417737, -3.624013453518273],& + [0.6299831412818762, -4.01013395760674],& + [1.234766956912478, -6.989458672353067],& + [2.420143235548455, 1.65660820924677],& + [4.743480741674971, -10.88975640432909],& + [9.297222253682943, 1.518799068871886],& + [18.22255561721856, -18.74159770016558],& + [35.71620900974838, 17.16080415551551],& + [70.00376965910681, -22.65534773282707],& + [137.2073885318493, 14.81195547408424],& + [268.9264815224247, -8.733754849573415]],& + shape=[2, 16])) + case (44) + allocate(out(16, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -1.150399163544762],& + [0.02177953337809369, 1.172352870176837],& + [0.04268788542106363, -3.156104921708902],& + [0.08366825542528471, 3.341947147280734],& + [0.163989780633558, -4.853877993940841],& + [0.3214199700417737, 0.2929280920652673],& + [0.6299831412818762, -6.399289839202538],& + [1.234766956912478, -6.688734957017004],& + [2.420143235548455, 0.6934794583357871],& + [4.743480741674971, -9.323152869474143],& + [9.297222253682943, 0.5548612978309393],& + [18.22255561721856, -18.53111198940314],& + [35.71620900974838, 16.55664937593974],& + [70.00376965910681, -22.44774729665369],& + [137.2073885318493, 14.91840042942204],& + [268.9264815224247, -8.98019964010632]],& + shape=[2, 16])) + case (45) + allocate(out(15, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -1.551424617856242],& + [0.04268788542106363, 2.200190542119344],& + [0.08366825542528471, -4.309034579680883],& + [0.163989780633558, 4.284838140556531],& + [0.3214199700417737, -8.433982115486288],& + [0.6299831412818762, 2.127406124491245],& + [1.234766956912478, -17.18875862355344],& + [2.420143235548455, 8.633826395031065],& + [4.743480741674971, -14.55210307409288],& + [9.297222253682943, 4.909201228874736],& + [18.22255561721856, -22.23997398046777],& + [35.71620900974838, 18.61480557103641],& + [70.00376965910681, -23.84086478292011],& + [137.2073885318493, 15.72909536107909],& + [268.9264815224247, -9.383221589130812]],& + shape=[2, 15])) + case (46) + allocate(out(15, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -0.8183109850773462],& + [0.04268788542106363, 0.3501577250863193],& + [0.08366825542528471, -1.712566308728128],& + [0.163989780633558, 1.49437699491682],& + [0.3214199700417737, -5.253161094806273],& + [0.6299831412818762, -0.7316952955588931],& + [1.234766956912478, -15.00434934231453],& + [2.420143235548455, 4.387141908868216],& + [4.743480741674971, -9.872004721546546],& + [9.297222253682943, 1.433487950707786],& + [18.22255561721856, -19.84536134917289],& + [35.71620900974838, 16.38836608291604],& + [70.00376965910681, -22.75384579109959],& + [137.2073885318493, 15.50390445580706],& + [268.9264815224247, -9.566140229998041]],& + shape=[2, 15])) + case (47) + allocate(out(15, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -2.208886560187466],& + [0.04268788542106363, 3.927438619369241],& + [0.08366825542528471, -6.67755450621371],& + [0.163989780633558, 6.579421252543398],& + [0.3214199700417737, -10.52925459442486],& + [0.6299831412818762, 5.109274077418377],& + [1.234766956912478, -19.32286537555046],& + [2.420143235548455, 5.325528669520281],& + [4.743480741674971, -10.19013059890131],& + [9.297222253682943, 2.424265635781921],& + [18.22255561721856, -20.9833150524646],& + [35.71620900974838, 16.74453170911875],& + [70.00376965910681, -23.29071700351778],& + [137.2073885318493, 16.00993792561349],& + [268.9264815224247, -9.91767419810526]],& + shape=[2, 15])) + case (48) + allocate(out(15, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -2.721490860196127],& + [0.04268788542106363, 4.162217377468551],& + [0.08366825542528471, -6.262440203174265],& + [0.163989780633558, 6.435970720558544],& + [0.3214199700417737, -10.91660685712122],& + [0.6299831412818762, 4.901970288323355],& + [1.234766956912478, -16.93129077513004],& + [2.420143235548455, 0.7623168184072711],& + [4.743480741674971, -6.688311224686913],& + [9.297222253682943, 0.6440959523897618],& + [18.22255561721856, -20.02050143911038],& + [35.71620900974838, 15.70136619824916],& + [70.00376965910681, -23.08186208293773],& + [137.2073885318493, 16.22623322781874],& + [268.9264815224247, -10.21166714085871]],& + shape=[2, 15])) + case (49) + allocate(out(17, 2)) + out(:,:) = transpose(reshape([[0.005669391237529597, -0.6489144704246428],& + [0.011112006825558, 0.6801164417993277],& + [0.02177953337809369, -1.68133922573179],& + [0.04268788542106363, 1.068167730234563],& + [0.08366825542528471, -2.493946442380548],& + [0.163989780633558, 1.232299955561757],& + [0.3214199700417737, -4.195829998701811],& + [0.6299831412818762, -2.167742133140564],& + [1.234766956912478, -8.973937809467316],& + [2.420143235548455, -7.544794704765081],& + [4.743480741674971, -0.9576158672571182],& + [9.297222253682943, -2.644844491034746],& + [18.22255561721856, -17.91653545945883],& + [35.71620900974838, 13.93182896077633],& + [70.00376965910681, -22.52172298543155],& + [137.2073885318493, 16.31844884436578],& + [268.9264815224247, -10.48363834494376]],& + shape=[2, 17])) + case (50) + allocate(out(15, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -1.306720823567503],& + [0.04268788542106363, 1.128113766711976],& + [0.08366825542528471, -2.48890273885263],& + [0.163989780633558, -0.3404406256449874],& + [0.3214199700417737, -4.720318968247739],& + [0.6299831412818762, 1.024648180988152],& + [1.234766956912478, -11.27415699139237],& + [2.420143235548455, -6.288981087564025],& + [4.743480741674971, -3.78703928203322],& + [9.297222253682943, 1.075500623090193],& + [18.22255561721856, -21.14811065385584],& + [35.71620900974838, 15.96495384722948],& + [70.00376965910681, -24.28202215570491],& + [137.2073885318493, 17.42806933302199],& + [268.9264815224247, -10.98459242417857]],& + shape=[2, 15])) + case (51) + allocate(out(15, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -1.241736204354083],& + [0.04268788542106363, 0.2605090973374899],& + [0.08366825542528471, -1.589132765067916],& + [0.163989780633558, -0.326147229920025],& + [0.3214199700417737, -4.197098995646229],& + [0.6299831412818762, -1.288437518087449],& + [1.234766956912478, -8.818732681451365],& + [2.420143235548455, -7.187616961542517],& + [4.743480741674971, -5.61052675859537],& + [9.297222253682943, 3.911947506479919],& + [18.22255561721856, -23.57600608468056],& + [35.71620900974838, 17.47781664924696],& + [70.00376965910681, -25.79369177110493],& + [137.2073885318493, 18.44859419914428],& + [268.9264815224247, -11.46974048175821]],& + shape=[2, 15])) + case (52) + allocate(out(16, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -0.6860747901348532],& + [0.02177953337809369, 0.3756584312395717],& + [0.04268788542106363, -1.953803957021591],& + [0.08366825542528471, 1.19313236977905],& + [0.163989780633558, -3.4833980351832],& + [0.3214199700417737, -1.800269400438992],& + [0.6299831412818762, -3.269351397349965],& + [1.234766956912478, -7.081864984356798],& + [2.420143235548455, -7.73559208936058],& + [4.743480741674971, -7.2971919211559],& + [9.297222253682943, 6.155405556317419],& + [18.22255561721856, -25.27635276643559],& + [35.71620900974838, 18.45661759423092],& + [70.00376965910681, -27.01972911693156],& + [137.2073885318493, 19.35525598411914],& + [268.9264815224247, -11.93244147731707]],& + shape=[2, 16])) + case (53) + allocate(out(15, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -1.28129982902783],& + [0.04268788542106363, 0.4664910747815156],& + [0.08366825542528471, -2.210536460876028],& + [0.163989780633558, 0.884983135969378],& + [0.3214199700417737, -7.240514372650068],& + [0.6299831412818762, 1.801884596294258],& + [1.234766956912478, -11.5530646504485],& + [2.420143235548455, -3.056516881566495],& + [4.743480741674971, -12.88513854111079],& + [9.297222253682943, 11.05319655290805],& + [18.22255561721856, -28.79922844155226],& + [35.71620900974838, 20.73132891301066],& + [70.00376965910681, -29.05249167443253],& + [137.2073885318493, 20.61685968795791],& + [268.9264815224247, -12.47595310925726]],& + shape=[2, 15])) + case (54) + allocate(out(15, 2)) + out(:,:) = transpose(reshape([[0.04268788542106363, -3.683197842866093],& + [0.08366825542528471, 5.205931402912938],& + [0.163989780633558, -9.024266066826385],& + [0.3214199700417737, 4.022210345530766],& + [0.6299831412818762, -11.63057922455482],& + [1.234766956912478, 3.520784391905181],& + [2.420143235548455, -19.21185415540822],& + [4.743480741674971, 4.910550822154619],& + [9.297222253682943, -11.57667394576129],& + [18.22255561721856, 0.9801449468359351],& + [35.71620900974838, -16.9435564042069],& + [70.00376965910681, 13.24194221175276],& + [137.2073885318493, -18.52011200587731],& + [268.9264815224247, 11.99118703044951],& + [527.0959037839524, -7.282511506040692]],& + shape=[2, 15])) + case (55) + allocate(out(17, 2)) + out(:,:) = transpose(reshape([[0.005669391237529597, -0.7382588321343064],& + [0.011112006825558, 0.1236757037695497],& + [0.02177953337809369, -0.3235517116263509],& + [0.04268788542106363, -0.3744562286883593],& + [0.08366825542528471, -1.102203898131847],& + [0.163989780633558, -2.276765912771225],& + [0.3214199700417737, -2.717457186430693],& + [0.6299831412818762, -3.264108747243881],& + [1.234766956912478, -7.089836951345205],& + [2.420143235548455, -5.694025553762913],& + [4.743480741674971, -12.86886639893055],& + [9.297222253682943, 10.78408151119947],& + [18.22255561721856, -27.82288983464241],& + [35.71620900974838, 19.83979313075542],& + [70.00376965910681, -30.03096850775182],& + [137.2073885318493, 21.83902394212782],& + [268.9264815224247, -13.28318452439271]],& + shape=[2, 17])) + case (56) + allocate(out(17, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -3.33866850999766],& + [0.02177953337809369, 5.129114085342735],& + [0.04268788542106363, -7.62967876624316],& + [0.08366825542528471, 8.811950444243848],& + [0.163989780633558, -12.96809362061322],& + [0.3214199700417737, 5.069862117990851],& + [0.6299831412818762, -8.260466739535332],& + [1.234766956912478, -1.867711670696735],& + [2.420143235548455, -13.03674224019051],& + [4.743480741674971, -2.070004284381866],& + [9.297222253682943, -6.667962543666363],& + [18.22255561721856, -1.608647659420967],& + [35.71620900974838, -15.88657208532095],& + [70.00376965910681, 12.01980371400714],& + [137.2073885318493, -18.24141249060631],& + [268.9264815224247, 12.19014871492982],& + [527.0959037839524, -7.644918465841329]],& + shape=[2, 17])) + case (57) + allocate(out(18, 2)) + out(:,:) = transpose(reshape([[0.005669391237529597, -0.7169928619074426],& + [0.011112006825558, 0.1421212371606657],& + [0.02177953337809369, -1.913261220277263],& + [0.04268788542106363, 1.760648717566255],& + [0.08366825542528471, -2.588861264182924],& + [0.163989780633558, -0.2579838429919619],& + [0.3214199700417737, -7.794988338440817],& + [0.6299831412818762, 2.223671563548123],& + [1.234766956912478, -9.525335312842799],& + [2.420143235548455, -6.753806422195339],& + [4.743480741674971, -7.762787777697667],& + [9.297222253682943, -2.656653323414503],& + [18.22255561721856, -4.170768843003316],& + [35.71620900974838, -14.255062051001],& + [70.00376965910681, 10.60002989321947],& + [137.2073885318493, -17.64981355471537],& + [268.9264815224247, 12.11013004992856],& + [527.0959037839524, -7.790286648752669]],& + shape=[2, 18])) + case (58) + allocate(out(17, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -0.8889826244558208],& + [0.02177953337809369, 0.9245868131984025],& + [0.04268788542106363, -1.967003563884646],& + [0.08366825542528471, 0.5692705661058426],& + [0.163989780633558, -4.344813488423824],& + [0.3214199700417737, -1.377392068505287],& + [0.6299831412818762, -8.736962504684925],& + [1.234766956912478, 2.035104520618916],& + [2.420143235548455, -15.70297385379672],& + [4.743480741674971, -1.075805239379406],& + [9.297222253682943, -9.005963817238808],& + [18.22255561721856, 1.69991659373045],& + [35.71620900974838, -19.09386935085058],& + [70.00376965910681, 13.74443661794066],& + [137.2073885318493, -19.79979541152716],& + [268.9264815224247, 13.21952309738845],& + [527.0959037839524, -8.199276286235545]],& + shape=[2, 17])) + case (59) + allocate(out(17, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -2.822390327666653],& + [0.02177953337809369, 3.813072243705392],& + [0.04268788542106363, -5.643339502159506],& + [0.08366825542528471, 6.143626164644957],& + [0.163989780633558, -8.885349275544286],& + [0.3214199700417737, 0.802558071911335],& + [0.6299831412818762, -5.306747917085886],& + [1.234766956912478, -4.679338421672583],& + [2.420143235548455, -9.99717490747571],& + [4.743480741674971, -8.098610430955887],& + [9.297222253682943, -3.110457137227058],& + [18.22255561721856, -2.301443591713905],& + [35.71620900974838, -16.61099404096603],& + [70.00376965910681, 12.07815235480666],& + [137.2073885318493, -19.18734842538834],& + [268.9264815224247, 13.15888002607971],& + [527.0959037839524, -8.353094883292215]],& + shape=[2, 17])) + case (60) + allocate(out(18, 2)) + out(:,:) = transpose(reshape([[0.005669391237529597, -0.5312693642448494],& + [0.011112006825558, -0.09744413542392749],& + [0.02177953337809369, -0.2458776592945924],& + [0.04268788542106363, -0.2866951345931739],& + [0.08366825542528471, -1.007198382069873],& + [0.163989780633558, -1.948770533281277],& + [0.3214199700417737, -2.250549945627426],& + [0.6299831412818762, -5.638539184339606],& + [1.234766956912478, -4.300401466818585],& + [2.420143235548455, -9.80603111624805],& + [4.743480741674971, -10.04190324051888],& + [9.297222253682943, -2.198727849230636],& + [18.22255561721856, -2.071924503310584],& + [35.71620900974838, -17.30066770670237],& + [70.00376965910681, 12.5418006645632],& + [137.2073885318493, -19.82665790914325],& + [268.9264815224247, 13.63704907576903],& + [527.0959037839524, -8.626191609485147]],& + shape=[2, 18])) + case (61) + allocate(out(19, 2)) + out(:,:) = transpose(reshape([[0.002892546549759998, -0.8159663874967578],& + [0.005669391237529597, 1.310085059389849],& + [0.011112006825558, -1.61124809323519],& + [0.02177953337809369, 1.64770724272239],& + [0.04268788542106363, -2.400493239423668],& + [0.08366825542528471, 0.8497941068926593],& + [0.163989780633558, -3.101158147444949],& + [0.3214199700417737, -0.4892336475022603],& + [0.6299831412818762, -8.86905042741273],& + [1.234766956912478, -0.9469264332728926],& + [2.420143235548455, -12.8164824078558],& + [4.743480741674971, -8.689200809050817],& + [9.297222253682943, -4.541595049086027],& + [18.22255561721856, 0.939367797691375],& + [35.71620900974838, -20.13401811034419],& + [70.00376965910681, 14.52294576191343],& + [137.2073885318493, -21.37683240091428],& + [268.9264815224247, 14.51017614733428],& + [527.0959037839524, -8.987870962904424]],& + shape=[2, 19])) + case (62) + allocate(out(17, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -2.403130459220847],& + [0.02177953337809369, 4.599563783034682],& + [0.04268788542106363, -7.160251412540674],& + [0.08366825542528471, 7.149390524253249],& + [0.163989780633558, -10.00416019931436],& + [0.3214199700417737, 5.427121568471193],& + [0.6299831412818762, -11.90157711878419],& + [1.234766956912478, 0.4358878880739212],& + [2.420143235548455, -13.65904680266976],& + [4.743480741674971, -8.441517502069473],& + [9.297222253682943, -6.39568217843771],& + [18.22255561721856, 3.396932490170002],& + [35.71620900974838, -22.31884954869747],& + [70.00376965910681, 15.93662675470114],& + [137.2073885318493, -22.57574201375246],& + [268.9264815224247, 15.23390584625304],& + [527.0959037839524, -9.319471619470278]],& + shape=[2, 17])) + case (63) + allocate(out(17, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -2.541653681604657],& + [0.02177953337809369, 3.113938718102872],& + [0.04268788542106363, -4.526067550294101],& + [0.08366825542528471, 4.640848839655519],& + [0.163989780633558, -6.151734987273812],& + [0.3214199700417737, -1.876445326954126],& + [0.6299831412818762, -2.317599184811115],& + [1.234766956912478, -7.897424373775721],& + [2.420143235548455, -7.068135771900415],& + [4.743480741674971, -13.67454019188881],& + [9.297222253682943, -3.977595917880535],& + [18.22255561721856, 2.235588900744915],& + [35.71620900974838, -21.54616831243038],& + [70.00376965910681, 15.21041212975979],& + [137.2073885318493, -22.50590785965323],& + [268.9264815224247, 15.41653398796916],& + [527.0959037839524, -9.534049417765345]],& + shape=[2, 17])) + case (64) + allocate(out(18, 2)) + out(:,:) = transpose(reshape([[0.005669391237529597, -0.8443003723121336],& + [0.011112006825558, 0.9263189568350754],& + [0.02177953337809369, -3.136728424854482],& + [0.04268788542106363, 3.189147920627875],& + [0.08366825542528471, -4.29195410466491],& + [0.163989780633558, 2.886949462470511],& + [0.3214199700417737, -9.703156023409974],& + [0.6299831412818762, 2.938855034622975],& + [1.234766956912478, -10.84768938642083],& + [2.420143235548455, -4.7627155285154],& + [4.743480741674971, -15.30758645483002],& + [9.297222253682943, -4.530912631569663],& + [18.22255561721856, 3.267492958897492],& + [35.71620900974838, -22.31320308335125],& + [70.00376965910681, 15.53218514414039],& + [137.2073885318493, -23.06546233786503],& + [268.9264815224247, 15.87280726421159],& + [527.0959037839524, -9.810048394012213]],& + shape=[2, 18])) + case (65) + allocate(out(17, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -0.8966318249586038],& + [0.02177953337809369, 1.053945099934936],& + [0.04268788542106363, -2.06163786444813],& + [0.08366825542528471, 1.083682771772146],& + [0.163989780633558, -4.405916484072804],& + [0.3214199700417737, 0.1025753282010555],& + [0.6299831412818762, -9.194234363734722],& + [1.234766956912478, -1.034987159073353],& + [2.420143235548455, -10.9083543419838],& + [4.743480741674971, -10.2576626688242],& + [9.297222253682943, -10.62637014687061],& + [18.22255561721856, 8.597536757588387],& + [35.71620900974838, -26.25054533779621],& + [70.00376965910681, 18.05599416792393],& + [137.2073885318493, -24.94431035220623],& + [268.9264815224247, 16.89833929203451],& + [527.0959037839524, -10.2114228734863]],& + shape=[2, 17])) + case (66) + allocate(out(26, 2)) + out(:,:) = transpose(reshape([[0.0001, -0.03699918063153063],& + [0.000196, 0.2373986363989182],& + [0.00038416, -0.8495940527644983],& + [0.0007529535999999996, 2.428561427135463],& + [0.001475789055999999, -6.400460002217756],& + [0.002892546549759998, 9.960182332404173],& + [0.005669391237529597, -10.17469556653896],& + [0.011112006825558, 8.008915379024188],& + [0.02177953337809369, -9.016167079726756],& + [0.04268788542106363, 8.261123340415452],& + [0.08366825542528471, -8.024175282596843],& + [0.163989780633558, 6.401949091286951],& + [0.3214199700417737, -13.09130969510625],& + [0.6299831412818762, 7.34874167480848],& + [1.234766956912478, -16.75324833770719],& + [2.420143235548455, 1.743766361039889],& + [4.743480741674971, -23.08248585687397],& + [9.297222253682943, 0.869877518969588],& + [18.22255561721856, -3.811515371446148],& + [35.71620900974838, -10.99050229450222],& + [70.00376965910681, -0.7714789829333313],& + [137.2073885318493, -4.991437545511872],& + [268.9264815224247, 1.194389079988468],& + [527.0959037839524, -4.852316613541916],& + [1033.107971416546, 2.88477746405988],& + [2024.891623976431, -2.4932964434322]],& + shape=[2, 26])) + case (67) + allocate(out(21, 2)) + out(:,:) = transpose(reshape([[0.0007529535999999996, 0.2588172435353044],& + [0.001475789055999999, -1.719396420288831],& + [0.002892546549759998, 2.42793519073166],& + [0.005669391237529597, -1.993259930983186],& + [0.011112006825558, 0.3136797277256846],& + [0.02177953337809369, -0.1630405047908425],& + [0.04268788542106363, -0.5042719766497612],& + [0.08366825542528471, 0.3441740125417709],& + [0.163989780633558, -2.893046129494905],& + [0.3214199700417737, -1.905408166348934],& + [0.6299831412818762, -3.68142219632864],& + [1.234766956912478, -8.176514312624931],& + [2.420143235548455, -5.539149239659309],& + [4.743480741674971, -15.85169520229101],& + [9.297222253682943, -9.904886402189732],& + [18.22255561721856, 9.834417268633842],& + [35.71620900974838, -27.73921944200993],& + [70.00376965910681, 19.10739466175437],& + [137.2073885318493, -26.35939477011561],& + [268.9264815224247, 17.93643321469426],& + [527.0959037839524, -10.79214662584127]],& + shape=[2, 21])) + case (68) + allocate(out(19, 2)) + out(:,:) = transpose(reshape([[0.002892546549759998, -1.27208674054728],& + [0.005669391237529597, 2.421214115977591],& + [0.011112006825558, -3.270577666593454],& + [0.02177953337809369, 3.538120922903545],& + [0.04268788542106363, -3.767716443981044],& + [0.08366825542528471, 2.82282286978807],& + [0.163989780633558, -5.725236785394372],& + [0.3214199700417737, 3.338118964573368],& + [0.6299831412818762, -11.06780766477459],& + [1.234766956912478, -1.256089732458349],& + [2.420143235548455, -11.36578112357529],& + [4.743480741674971, -11.16292016970692],& + [9.297222253682943, -15.90517021692358],& + [18.22255561721856, 15.18520703306422],& + [35.71620900974838, -31.79782880702987],& + [70.00376965910681, 21.83984285942279],& + [137.2073885318493, -28.35592523962259],& + [268.9264815224247, 19.00633072189521],& + [527.0959037839524, -11.20451689701744]],& + shape=[2, 19])) + case (69) + allocate(out(17, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -2.075267546199029],& + [0.02177953337809369, 3.593936577904969],& + [0.04268788542106363, -5.388050294015557],& + [0.08366825542528471, 5.273977061733603],& + [0.163989780633558, -7.502584751695395],& + [0.3214199700417737, 3.259387116879225],& + [0.6299831412818762, -8.516460593789816],& + [1.234766956912478, -3.913348350673914],& + [2.420143235548455, -9.6144315674901],& + [4.743480741674971, -11.78939910233021],& + [9.297222253682943, -17.56530469655991],& + [18.22255561721856, 16.51012862473726],& + [35.71620900974838, -32.4334911853075],& + [70.00376965910681, 22.0604000389576],& + [137.2073885318493, -28.85928200930357],& + [268.9264815224247, 19.43986749649048],& + [527.0959037839524, -11.48007681933814]],& + shape=[2, 17])) + case (70) + allocate(out(17, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -2.009081379452255],& + [0.02177953337809369, 1.826372204348445],& + [0.04268788542106363, -2.5645682066679],& + [0.08366825542528471, 1.989267578348517],& + [0.163989780633558, -2.207304621115327],& + [0.3214199700417737, -4.837013762444258],& + [0.6299831412818762, -0.1199803948402405],& + [1.234766956912478, -9.087172340601683],& + [2.420143235548455, -7.120097145438194],& + [4.743480741674971, -12.29198481142521],& + [9.297222253682943, -19.30048879981041],& + [18.22255561721856, 17.57046326994896],& + [35.71620900974838, -32.71623520553112],& + [70.00376965910681, 22.01269836723804],& + [137.2073885318493, -29.21489578485489],& + [268.9264815224247, 19.8148828484118],& + [527.0959037839524, -11.74486181611428]],& + shape=[2, 17])) + case (71) + allocate(out(18, 2)) + out(:,:) = transpose(reshape([[0.005669391237529597, -1.111256900321166],& + [0.011112006825558, 1.422985557594473],& + [0.02177953337809369, -3.342970409505369],& + [0.04268788542106363, 2.980154754504838],& + [0.08366825542528471, -5.310948193297918],& + [0.163989780633558, 5.296797009130387],& + [0.3214199700417737, -9.874507727359742],& + [0.6299831412818762, 1.594426338611811],& + [1.234766956912478, -7.251816344047256],& + [2.420143235548455, -10.26851499491022],& + [4.743480741674971, -8.4313189208915],& + [9.297222253682943, -24.13114803782082],& + [18.22255561721856, 20.68188495418872],& + [35.71620900974838, -34.41960857313825],& + [70.00376965910681, 22.94927649328019],& + [137.2073885318493, -30.16305273160106],& + [268.9264815224247, 20.44759377802256],& + [527.0959037839524, -12.06797605243969]],& + shape=[2, 18])) + case (72) + allocate(out(17, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -1.112602099339711],& + [0.02177953337809369, 1.589909003349021],& + [0.04268788542106363, -2.712799926288426],& + [0.08366825542528471, 1.988367443904281],& + [0.163989780633558, -5.234694685786963],& + [0.3214199700417737, 1.394292421638966],& + [0.6299831412818762, -8.473875023424625],& + [1.234766956912478, -2.301626682281494],& + [2.420143235548455, -11.25995799154043],& + [4.743480741674971, -7.308662287890911],& + [9.297222253682943, -26.46364459395409],& + [18.22255561721856, 21.453449010849],& + [35.71620900974838, -34.17961519211531],& + [70.00376965910681, 22.51032546907663],& + [137.2073885318493, -30.31176043301821],& + [268.9264815224247, 20.73706427589059],& + [527.0959037839524, -12.31416870906833]],& + shape=[2, 17])) + case (73) + allocate(out(16, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -1.643301260448425],& + [0.04268788542106363, 2.637219189105963],& + [0.08366825542528471, -4.618848055746639],& + [0.163989780633558, 2.386034353490686],& + [0.3214199700417737, -6.661585985362763],& + [0.6299831412818762, -1.786379255820066],& + [1.234766956912478, -8.609911476145498],& + [2.420143235548455, -5.375464136246592],& + [4.743480741674971, -11.23924457933754],& + [9.297222253682943, -24.26005035545677],& + [18.22255561721856, 18.23250980395824],& + [35.71620900974838, -30.82505836244673],& + [70.00376965910681, 19.92382913734764],& + [137.2073885318493, -29.21075047273189],& + [268.9264815224247, 20.49789708526805],& + [527.0959037839524, -12.44689562942767]],& + shape=[2, 16])) + case (74) + allocate(out(17, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -2.118398681399412],& + [0.04268788542106363, 3.816525800619274],& + [0.08366825542528471, -6.288813097402453],& + [0.163989780633558, 4.127201564610004],& + [0.3214199700417737, -9.07045080140233],& + [0.6299831412818762, 1.492176346480846],& + [1.234766956912478, -12.97010948881507],& + [2.420143235548455, 0.1512741446495056],& + [4.743480741674971, -17.93358114361763],& + [9.297222253682943, -14.39840850234032],& + [18.22255561721856, 0.859917402267456],& + [35.71620900974838, -5.081548534333706],& + [70.00376965910681, -14.42776833474636],& + [137.2073885318493, 10.82367956638336],& + [268.9264815224247, -17.27153169736266],& + [527.0959037839524, 11.38557018339634],& + [1033.107971416546, -7.095734726986848]],& + shape=[2, 17])) + case (75) + allocate(out(17, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -0.9427029447688255],& + [0.02177953337809369, -0.05955321155488491],& + [0.04268788542106363, -0.6835330398753285],& + [0.08366825542528471, 0.2680472256615758],& + [0.163989780633558, -2.061694569885731],& + [0.3214199700417737, -2.036225683987141],& + [0.6299831412818762, -8.548756275326014],& + [1.234766956912478, -0.7500824332237244],& + [2.420143235548455, -13.59652968496084],& + [4.743480741674971, -1.712933272123337],& + [9.297222253682943, -33.44035017490387],& + [18.22255561721856, 22.28777827322483],& + [35.71620900974838, -32.4007666260004],& + [70.00376965910681, 20.84499305859208],& + [137.2073885318493, -30.73763220384717],& + [268.9264815224247, 21.64797380007803],& + [527.0959037839524, -13.07803223709925]],& + shape=[2, 17])) + case (76) + allocate(out(17, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -1.050015463551972],& + [0.02177953337809369, 0.7488444717600942],& + [0.04268788542106363, -2.534344915300608],& + [0.08366825542528471, 2.839698520489037],& + [0.163989780633558, -5.31201315112412],& + [0.3214199700417737, 1.343187313526869],& + [0.6299831412818762, -10.92646013572812],& + [1.234766956912478, -0.5045365318655968],& + [2.420143235548455, -13.27731340378523],& + [4.743480741674971, -1.085987225174904],& + [9.297222253682943, -34.05220905691385],& + [18.22255561721856, 20.81878664344549],& + [35.71620900974838, -30.56616438925266],& + [70.00376965910681, 19.57317001372576],& + [137.2073885318493, -30.52093264833093],& + [268.9264815224247, 21.8110915850848],& + [527.0959037839524, -13.30480162700405]],& + shape=[2, 17])) + case (77) + allocate(out(16, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -1.481523777461916],& + [0.04268788542106363, 1.711421129424707],& + [0.08366825542528471, -3.351651976794528],& + [0.163989780633558, 2.287929197453195],& + [0.3214199700417737, -5.863052232918562],& + [0.6299831412818762, -4.329587753978558],& + [1.234766956912478, -9.668804003624246],& + [2.420143235548455, -4.681009995518252],& + [4.743480741674971, -6.920605624793097],& + [9.297222253682943, -29.24199591064826],& + [18.22255561721856, 14.84261363558471],& + [35.71620900974838, -25.31840609898791],& + [70.00376965910681, 15.97966506006196],& + [137.2073885318493, -28.95974464248866],& + [268.9264815224247, 21.39932740177028],& + [527.0959037839524, -13.40457440708087]],& + shape=[2, 16])) + case (78) + allocate(out(16, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -0.8215603719486353],& + [0.04268788542106363, 0.09639250366672059],& + [0.08366825542528471, -1.17039816264878],& + [0.163989780633558, 0.01470195360889193],& + [0.3214199700417737, -3.31340142985573],& + [0.6299831412818762, -6.668549781257752],& + [1.234766956912478, -8.834146911627613],& + [2.420143235548455, -6.040942977182567],& + [4.743480741674971, -4.448045207420364],& + [9.297222253682943, -31.01125701889396],& + [18.22255561721856, 14.25596719095483],& + [35.71620900974838, -24.46302059013397],& + [70.00376965910681, 15.62311328947544],& + [137.2073885318493, -29.36637769732624],& + [268.9264815224247, 21.84345784643665],& + [527.0959037839524, -13.69593263584693]],& + shape=[2, 16])) + case (79) + allocate(out(17, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -2.223106366058346],& + [0.04268788542106363, 3.788759244605899],& + [0.08366825542528471, -6.438291231170297],& + [0.163989780633558, 5.68232112750411],& + [0.3214199700417737, -9.808620888739824],& + [0.6299831412818762, 1.546653222292662],& + [1.234766956912478, -18.07414864748716],& + [2.420143235548455, 2.975595489144325],& + [4.743480741674971, -14.76127413660288],& + [9.297222253682943, -15.88222673535347],& + [18.22255561721856, -9.089758425951004],& + [35.71620900974838, 7.250008851289749],& + [70.00376965910681, -25.15676052123308],& + [137.2073885318493, 17.70025069266558],& + [268.9264815224247, -22.42635157331824],& + [527.0959037839524, 14.20993980765343],& + [1033.107971416546, -8.292989909241442]],& + shape=[2, 17])) + case (80) + allocate(out(17, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -2.862733485642821],& + [0.04268788542106363, 4.439925104146823],& + [0.08366825542528471, -6.585235074162483],& + [0.163989780633558, 6.235058523714542],& + [0.3214199700417737, -11.5268414132297],& + [0.6299831412818762, 3.545705184340477],& + [1.234766956912478, -19.0162630006671],& + [2.420143235548455, 2.093893751502037],& + [4.743480741674971, -13.23856161534786],& + [9.297222253682943, -16.13918179273605],& + [18.22255561721856, -11.02365566790104],& + [35.71620900974838, 9.09285493195057],& + [70.00376965910681, -26.44688675552607],& + [137.2073885318493, 18.35245618969202],& + [268.9264815224247, -23.01043517887592],& + [527.0959037839524, 14.58198766596615],& + [1033.107971416546, -8.492087367223576]],& + shape=[2, 17])) + case (81) + allocate(out(18, 2)) + out(:,:) = transpose(reshape([[0.005669391237529597, -0.668365372268724],& + [0.011112006825558, 0.6757472147845078],& + [0.02177953337809369, -1.679120843986993],& + [0.04268788542106363, 0.9200177795460149],& + [0.08366825542528471, -2.225945938150289],& + [0.163989780633558, 0.5385053720438009],& + [0.3214199700417737, -4.273235573655256],& + [0.6299831412818762, -4.529588063473057],& + [1.234766956912478, -9.25617684829922],& + [2.420143235548455, -10.41217102746305],& + [4.743480741674971, 1.73659521798254],& + [9.297222253682943, -33.54565785921295],& + [18.22255561721856, 10.54258928453783],& + [35.71620900974838, -21.50926161091775],& + [70.00376965910681, 14.90955107938498],& + [137.2073885318493, -30.97113763546804],& + [268.9264815224247, 23.37122681012261],& + [527.0959037839524, -14.62357198550696]],& + shape=[2, 18])) + case (82) + allocate(out(16, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -1.497850464621024],& + [0.04268788542106363, 1.413205203980397],& + [0.08366825542528471, -2.948329334882146],& + [0.163989780633558, -0.7836353017337387],& + [0.3214199700417737, -3.985954123083502],& + [0.6299831412818762, -2.148619307845365],& + [1.234766956912478, -11.57561890536454],& + [2.420143235548455, -9.41288761422038],& + [4.743480741674971, 0.7861812328919768],& + [9.297222253682943, -31.29922001017258],& + [18.22255561721856, 6.940702277235687],& + [35.71620900974838, -19.05495279235765],& + [70.00376965910681, 13.81009005475789],& + [137.2073885318493, -31.03301733545959],& + [268.9264815224247, 23.68133825180121],& + [527.0959037839524, -14.89143183092665]],& + shape=[2, 16])) + case (83) + allocate(out(16, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -1.49225621270034],& + [0.04268788542106363, 0.5877251257006719],& + [0.08366825542528471, -1.937719178094994],& + [0.163989780633558, -0.6662144217989407],& + [0.3214199700417737, -4.074036280042492],& + [0.6299831412818762, -4.17089676798787],& + [1.234766956912478, -8.423529559979215],& + [2.420143235548455, -12.33799174148589],& + [4.743480741674971, 2.498995818430558],& + [9.297222253682943, -31.1683973162435],& + [18.22255561721856, 5.286023871973157],& + [35.71620900974838, -18.32582380715758],& + [70.00376965910681, 14.00736614689231],& + [137.2073885318493, -31.87571897311136],& + [268.9264815224247, 24.3264262531884],& + [527.0959037839524, -15.23395295758291]],& + shape=[2, 16])) + case (84) + allocate(out(18, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -0.7827540693641737],& + [0.02177953337809369, 0.4557045987545507],& + [0.04268788542106363, -2.203057499327087],& + [0.08366825542528471, 1.497004572899641],& + [0.163989780633558, -4.496554678656139],& + [0.3214199700417737, -1.185073914008171],& + [0.6299831412818762, -6.022945520489884],& + [1.234766956912478, -7.952718060194456],& + [2.420143235548455, -10.19744747555524],& + [4.743480741674971, -4.247537973569706],& + [9.297222253682943, -17.58148649739451],& + [18.22255561721856, -17.00987933378201],& + [35.71620900974838, 12.96731074852869],& + [70.00376965910681, -27.98368807457155],& + [137.2073885318493, 18.26123780169291],& + [268.9264815224247, -23.78053557052044],& + [527.0959037839524, 15.41625533835031],& + [1033.107971416546, -9.153834392792746]],& + shape=[2, 18])) + case (85) + allocate(out(17, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -1.585640642617363],& + [0.04268788542106363, 0.8335289270617068],& + [0.08366825542528471, -2.566110006533563],& + [0.163989780633558, 0.3373182844370604],& + [0.3214199700417737, -7.019824992865324],& + [0.6299831412818762, -0.3861212804913521],& + [1.234766956912478, -13.0815099850297],& + [2.420143235548455, -5.279042884707451],& + [4.743480741674971, -9.485548824071884],& + [9.297222253682943, -11.6684081107378],& + [18.22255561721856, -23.10914050042629],& + [35.71620900974838, 17.14389277249575],& + [70.00376965910681, -30.68406607955694],& + [137.2073885318493, 19.87845177948475],& + [268.9264815224247, -24.970872156322],& + [527.0959037839524, 16.06120779179037],& + [1033.107971416546, -9.418114091909956]],& + shape=[2, 17])) + case (86) + allocate(out(17, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -0.9010112127871253],& + [0.04268788542106363, -0.6717963756527752],& + [0.08366825542528471, -0.9726466927677393],& + [0.163989780633558, -0.7804148010909557],& + [0.3214199700417737, -6.991981878876686],& + [0.6299831412818762, -0.6872555837035179],& + [1.234766956912478, -12.48670750111341],& + [2.420143235548455, -5.699661180377007],& + [4.743480741674971, -9.7488287165761],& + [9.297222253682943, -10.38899650424719],& + [18.22255561721856, -24.92238756269217],& + [35.71620900974838, 17.58746709674597],& + [70.00376965910681, -30.43163277208805],& + [137.2073885318493, 19.4171749651432],& + [268.9264815224247, -24.93597174063325],& + [527.0959037839524, 16.18287456408143],& + [1033.107971416546, -9.568224103364628]],& + shape=[2, 17])) + case (87) + allocate(out(19, 2)) + out(:,:) = transpose(reshape([[0.005669391237529597, -0.9049353507293745],& + [0.011112006825558, 0.453593598407906],& + [0.02177953337809369, -0.7734386483134585],& + [0.04268788542106363, 0.0003257889475207776],& + [0.08366825542528471, -1.791314246711408],& + [0.163989780633558, -2.414091581260436],& + [0.3214199700417737, -2.800323494535405],& + [0.6299831412818762, -5.080160063051153],& + [1.234766956912478, -8.921106780442642],& + [2.420143235548455, -8.56982527882792],& + [4.743480741674971, -7.801054614246823],& + [9.297222253682943, -11.15610307955649],& + [18.22255561721856, -24.79515109676868],& + [35.71620900974838, 16.3254110137932],& + [70.00376965910681, -28.85951706022024],& + [137.2073885318493, 18.05688271275721],& + [268.9264815224247, -24.38516742736101],& + [527.0959037839524, 16.08767703175545],& + [1033.107971416546, -9.67170142363625]],& + shape=[2, 19])) + case (88) + allocate(out(19, 2)) + out(:,:) = transpose(reshape([[0.005669391237529597, -0.6609776464190986],& + [0.011112006825558, -1.104675314217729],& + [0.02177953337809369, 0.7103434752070825],& + [0.04268788542106363, -1.340850665084872],& + [0.08366825542528471, 1.653799034691474],& + [0.163989780633558, -7.783811617257015],& + [0.3214199700417737, 0.6369658547337167],& + [0.6299831412818762, -4.938371473297593],& + [1.234766956912478, -10.85992869711481],& + [2.420143235548455, -6.398133945185691],& + [4.743480741674971, -10.14296466339147],& + [9.297222253682943, -8.39505708985962],& + [18.22255561721856, -27.44526936672628],& + [35.71620900974838, 17.25174764031544],& + [70.00376965910681, -29.01798915513791],& + [137.2073885318493, 17.9656113111414],& + [268.9264815224247, -24.61100574955344],& + [527.0959037839524, 16.33178124763072],& + [1033.107971416546, -9.851213180474303]],& + shape=[2, 19])) + case (89) + allocate(out(19, 2)) + out(:,:) = transpose(reshape([[0.005669391237529597, -0.7418099547737711],& + [0.011112006825558, -0.1754829726560274],& + [0.02177953337809369, -1.307933250111091],& + [0.04268788542106363, 1.000030818369851],& + [0.08366825542528471, -1.728697281563655],& + [0.163989780633558, -2.770838241631282],& + [0.3214199700417737, -6.250009670708096],& + [0.6299831412818762, 1.687499101753929],& + [1.234766956912478, -15.68871520875837],& + [2.420143235548455, -2.997714491735678],& + [4.743480741674971, -13.12245197256561],& + [9.297222253682943, -5.322433851310052],& + [18.22255561721856, -30.12239310913719],& + [35.71620900974838, 18.09691865509376],& + [70.00376965910681, -29.13407131237909],& + [137.2073885318493, 17.88423909340054],& + [268.9264815224247, -24.86247162055224],& + [527.0959037839524, 16.59142771153711],& + [1033.107971416546, -10.03509244227303]],& + shape=[2, 19])) + case (90) + allocate(out(18, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -0.929892846382586],& + [0.02177953337809369, 0.8398868545568803],& + [0.04268788542106363, -1.849807619864123],& + [0.08366825542528471, -0.3826497172603922],& + [0.163989780633558, -3.420107543669474],& + [0.3214199700417737, -5.131852164226075],& + [0.6299831412818762, -3.725378531071328],& + [1.234766956912478, -7.428407744970173],& + [2.420143235548455, -10.90476497392956],& + [4.743480741674971, -6.853250515341642],& + [9.297222253682943, -10.0342839306395],& + [18.22255561721856, -26.10574820524198],& + [35.71620900974838, 13.38282527314732],& + [70.00376965910681, -24.95358142675832],& + [137.2073885318493, 14.80291743576527],& + [268.9264815224247, -23.34885677701095],& + [527.0959037839524, 16.09598719491623],& + [1033.107971416546, -10.05303476201959]],& + shape=[2, 18])) + case (91) + allocate(out(20, 2)) + out(:,:) = transpose(reshape([[0.002892546549759998, -0.4303354937991912],& + [0.005669391237529597, 0.7887152982461885],& + [0.011112006825558, -2.176550874157329],& + [0.02177953337809369, 2.045625426995684],& + [0.04268788542106363, -2.656156615506916],& + [0.08366825542528471, 0.6532528292300412],& + [0.163989780633558, -3.923683818706195],& + [0.3214199700417737, -2.048205790837528],& + [0.6299831412818762, -7.35774070979096],& + [1.234766956912478, -6.973509158124216],& + [2.420143235548455, -12.28539482096676],& + [4.743480741674971, -6.047042335849255],& + [9.297222253682943, -8.569489174289629],& + [18.22255561721856, -28.22024710243568],& + [35.71620900974838, 13.99362333770841],& + [70.00376965910681, -25.13995368406177],& + [137.2073885318493, 14.9173398995772],& + [268.9264815224247, -23.73638082016259],& + [527.0959037839524, 16.41799367917702],& + [1033.107971416546, -10.25186007224653]],& + shape=[2, 20])) + case (92) + allocate(out(20, 2)) + out(:,:) = transpose(reshape([[0.002892546549759998, -0.7747145242761349],& + [0.005669391237529597, 1.329074779183884],& + [0.011112006825558, -1.732296683845561],& + [0.02177953337809369, 1.616563135368779],& + [0.04268788542106363, -2.373040286467585],& + [0.08366825542528471, 0.253547111467924],& + [0.163989780633558, -2.439801451648236],& + [0.3214199700417737, -3.55387194728246],& + [0.6299831412818762, -7.775994858180638],& + [1.234766956912478, -6.109061220777221],& + [2.420143235548455, -14.21604330139235],& + [4.743480741674971, -5.069115607300773],& + [9.297222253682943, -7.96334150293842],& + [18.22255561721856, -28.87716199271381],& + [35.71620900974838, 13.14551141252741],& + [70.00376965910681, -24.14930772501975],& + [137.2073885318493, 14.21112976409495],& + [268.9264815224247, -23.65837206086144],& + [527.0959037839524, 16.544904215727],& + [1033.107971416546, -10.40860725566557]],& + shape=[2, 20])) + case (93) + allocate(out(18, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -0.6027158766170686],& + [0.02177953337809369, 0.7563919888639248],& + [0.04268788542106363, -1.942267183857211],& + [0.08366825542528471, 0.3661201732793415],& + [0.163989780633558, -2.289485658561716],& + [0.3214199700417737, -3.552965488757764],& + [0.6299831412818762, -8.10727799529559],& + [1.234766956912478, -6.174658787655062],& + [2.420143235548455, -15.00556100712129],& + [4.743480741674971, -5.29631016102212],& + [9.297222253682943, -6.459570625564083],& + [18.22255561721856, -30.05562581596314],& + [35.71620900974838, 12.68124639696907],& + [70.00376965910681, -23.5232305318932],& + [137.2073885318493, 13.81087681092322],& + [268.9264815224247, -23.78086036798777],& + [527.0959037839524, 16.7624885244295],& + [1033.107971416546, -10.58659439416904]],& + shape=[2, 18])) + case (94) + allocate(out(19, 2)) + out(:,:) = transpose(reshape([[0.005669391237529597, -0.592335940640794],& + [0.011112006825558, -0.1711959515448598],& + [0.02177953337809369, 0.1202917417886056],& + [0.04268788542106363, -0.9808466919421335],& + [0.08366825542528471, 0.01757123737115762],& + [0.163989780633558, -3.594289513137483],& + [0.3214199700417737, -1.426157100388082],& + [0.6299831412818762, -8.047247586786398],& + [1.234766956912478, -7.920910091313999],& + [2.420143235548455, -13.42992323404178],& + [4.743480741674971, -7.821320117684081],& + [9.297222253682943, -3.359152300516143],& + [18.22255561721856, -32.28507468360476],& + [35.71620900974838, 13.07508332282305],& + [70.00376965910681, -23.6467120856978],& + [137.2073885318493, 13.99483466055244],& + [268.9264815224247, -24.27612920827232],& + [527.0959037839524, 17.14650234021246],& + [1033.107971416546, -10.80298879717708]],& + shape=[2, 19])) + case (95) + allocate(out(18, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -3.097643688830374],& + [0.02177953337809369, 4.523819103408982],& + [0.04268788542106363, -6.73390594346256],& + [0.08366825542528471, 7.684899957701418],& + [0.163989780633558, -11.06679525835352],& + [0.3214199700417737, 2.285898635451304],& + [0.6299831412818762, -7.316951614640857],& + [1.234766956912478, -9.69814621511614],& + [2.420143235548455, -12.42661194705579],& + [4.743480741674971, -9.518254954207805],& + [9.297222253682943, -1.343494483880932],& + [18.22255561721856, -33.351833320281],& + [35.71620900974838, 12.50558926624944],& + [70.00376965910681, -23.09392436483176],& + [137.2073885318493, 13.74517658771947],& + [268.9264815224247, -24.52945730549982],& + [527.0959037839524, 17.42988733202219],& + [1033.107971416546, -10.99825178639225]],& + shape=[2, 18])) + case (96) + allocate(out(19, 2)) + out(:,:) = transpose(reshape([[0.005669391237529597, -0.4868470235795712],& + [0.011112006825558, -0.5404405066713025],& + [0.02177953337809369, -0.8759178040381812],& + [0.04268788542106363, 0.6977089871215867],& + [0.08366825542528471, -1.550734546264721],& + [0.163989780633558, -0.914238745928742],& + [0.3214199700417737, -7.695432458480354],& + [0.6299831412818762, 0.7664599928539246],& + [1.234766956912478, -15.13222834843327],& + [2.420143235548455, -8.418580508674495],& + [4.743480741674971, -14.03690791991539],& + [9.297222253682943, 2.96312093490269],& + [18.22255561721856, -36.19670291896909],& + [35.71620900974838, 13.41782479127869],& + [70.00376965910681, -23.77897806721739],& + [137.2073885318493, 14.42077518673614],& + [268.9264815224247, -25.35044422606006],& + [527.0959037839524, 17.96012891735882],& + [1033.107971416546, -11.24856573601926]],& + shape=[2, 19])) + case (97) + allocate(out(18, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -2.865375375462648],& + [0.02177953337809369, 3.926992408135789],& + [0.04268788542106363, -5.816062264433185],& + [0.08366825542528471, 6.418859034675734],& + [0.163989780633558, -9.108706058876123],& + [0.3214199700417737, 0.3518077436510794],& + [0.6299831412818762, -5.829751471017516],& + [1.234766956912478, -10.88447724983416],& + [2.420143235548455, -11.9520087785495],& + [4.743480741674971, -13.21245201023703],& + [9.297222253682943, 3.761390193918487],& + [18.22255561721856, -36.3438545972167],& + [35.71620900974838, 12.17036457988434],& + [70.00376965910681, -22.88232462131418],& + [137.2073885318493, 14.01021647267044],& + [268.9264815224247, -25.51406199159101],& + [527.0959037839524, 18.20551099110162],& + [1033.107971416546, -11.43606700550542]],& + shape=[2, 18])) + case (98) + allocate(out(19, 2)) + out(:,:) = transpose(reshape([[0.005669391237529597, -0.5638055074410318],& + [0.011112006825558, -0.3314587609547743],& + [0.02177953337809369, 0.1607012420454339],& + [0.04268788542106363, -0.6529201997673226],& + [0.08366825542528471, 0.1219027348161035],& + [0.163989780633558, -3.708631314104423],& + [0.3214199700417737, -0.992236091842642],& + [0.6299831412818762, -7.98284346939181],& + [1.234766956912478, -8.905040769954212],& + [2.420143235548455, -13.34273181058234],& + [4.743480741674971, -14.61109794711228],& + [9.297222253682943, 6.352543284767307],& + [18.22255561721856, -37.79880237695761],& + [35.71620900974838, 11.99755068751983],& + [70.00376965910681, -22.90154810203239],& + [137.2073885318493, 14.28561156988144],& + [268.9264815224247, -26.0949510296341],& + [527.0959037839524, 18.63151888386346],& + [1033.107971416546, -11.66376102311864]],& + shape=[2, 19])) + case (99) + allocate(out(18, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -0.5891333977750719],& + [0.02177953337809369, 0.9461652379575298],& + [0.04268788542106363, -1.897463227816843],& + [0.08366825542528471, 0.3428371509444332],& + [0.163989780633558, -2.326674887410263],& + [0.3214199700417737, -1.321915196782356],& + [0.6299831412818762, -10.54910277063391],& + [1.234766956912478, -5.367796703212662],& + [2.420143235548455, -17.11180374817923],& + [4.743480741674971, -13.50728825165424],& + [9.297222253682943, 6.386164470051881],& + [18.22255561721856, -36.82220279372996],& + [35.71620900974838, 9.821322881092783],& + [70.00376965910681, -21.42957774992101],& + [137.2073885318493, 13.53093850146979],& + [268.9264815224247, -26.06581966963131],& + [527.0959037839524, 18.79566534800688],& + [1033.107971416546, -11.83431519277644]],& + shape=[2, 18])) + case (100) + allocate(out(17, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -0.6745390652213246],& + [0.04268788542106363, 0.53190723573789],& + [0.08366825542528471, -2.795758437365294],& + [0.163989780633558, 1.495227232575417],& + [0.3214199700417737, -5.05615134164691],& + [0.6299831412818762, -6.728453058749437],& + [1.234766956912478, -9.123947560787201],& + [2.420143235548455, -13.82384353876114],& + [4.743480741674971, -18.39323494583368],& + [9.297222253682943, 11.01350556313992],& + [18.22255561721856, -39.47484817355871],& + [35.71620900974838, 10.68427317589521],& + [70.00376965910681, -22.41527084261179],& + [137.2073885318493, 14.55352161824703],& + [268.9264815224247, -27.10700306668878],& + [527.0959037839524, 19.42268694937229],& + [1033.107971416546, -12.10807174374349]],& + shape=[2, 17])) + case (101) + allocate(out(19, 2)) + out(:,:) = transpose(reshape([[0.005669391237529597, -0.4966458467201278],& + [0.011112006825558, -0.3286206530647178],& + [0.02177953337809369, 0.3122100784348731],& + [0.04268788542106363, -0.9907041115293396],& + [0.08366825542528471, 0.1729696697802865],& + [0.163989780633558, -3.064263089385349],& + [0.3214199700417737, -1.354272019525524],& + [0.6299831412818762, -6.595116499054711],& + [1.234766956912478, -11.05630834726617],& + [2.420143235548455, -11.48283587914193],& + [4.743480741674971, -22.05247733485885],& + [9.297222253682943, 13.85336030262988],& + [18.22255561721856, -40.37057800334878],& + [35.71620900974838, 10.19471216341481],& + [70.00376965910681, -22.4375556637533],& + [137.2073885318493, 14.92790234088898],& + [268.9264815224247, -27.77531688497402],& + [527.0959037839524, 19.89183466543909],& + [1033.107971416546, -12.3482948879651]],& + shape=[2, 19])) + case (102) + allocate(out(18, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -2.562327903906805],& + [0.02177953337809369, 3.148097679325247],& + [0.04268788542106363, -4.535494620007739],& + [0.08366825542528471, 4.556646459701369],& + [0.163989780633558, -5.732067410544914],& + [0.3214199700417737, -3.128131917585051],& + [0.6299831412818762, -1.469511281349696],& + [1.234766956912478, -15.33482826589898],& + [2.420143235548455, -8.47271971165901],& + [4.743480741674971, -25.42581175809028],& + [9.297222253682943, 15.83235777798109],& + [18.22255561721856, -40.32028293528128],& + [35.71620900974838, 8.980225399252959],& + [70.00376965910681, -21.96551027835812],& + [137.2073885318493, 14.97167128068395],& + [268.9264815224247, -28.24860798905138],& + [527.0959037839524, 20.27681683580158],& + [1033.107971416546, -12.57052136101294]],& + shape=[2, 18])) + case (103) + allocate(out(19, 2)) + out(:,:) = transpose(reshape([[0.005669391237529597, -1.211295226274331],& + [0.011112006825558, 1.505637007463065],& + [0.02177953337809369, -3.598538076605109],& + [0.04268788542106363, 3.275135800504358],& + [0.08366825542528471, -5.817219881391793],& + [0.163989780633558, 6.411204687523423],& + [0.3214199700417737, -14.4850705179997],& + [0.6299831412818762, 7.6131461734185],& + [1.234766956912478, -20.5398186952516],& + [2.420143235548455, -5.313271041959524],& + [4.743480741674971, -28.66799433797132],& + [9.297222253682943, 17.455484941951],& + [18.22255561721856, -39.9505325332284],& + [35.71620900974838, 7.643531463574618],& + [70.00376965910681, -21.50010807067156],& + [137.2073885318493, 15.04890404129401],& + [268.9264815224247, -28.74584604194388],& + [527.0959037839524, 20.6723204087466],& + [1033.107971416546, -12.79567010117836]],& + shape=[2, 19])) + case (104) + allocate(out(18, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -0.9183556490023506],& + [0.02177953337809369, 1.043555888873584],& + [0.04268788542106363, -1.954030304581238],& + [0.08366825542528471, 0.7684354505754527],& + [0.163989780633558, -4.03080639865766],& + [0.3214199700417737, -1.252932431818408],& + [0.6299831412818762, -7.673803286768816],& + [1.234766956912478, -8.499880532406678],& + [2.420143235548455, -11.69981972704409],& + [4.743480741674971, -25.80101706250571],& + [9.297222253682943, 14.08215762715554],& + [18.22255561721856, -35.4055245029158],& + [35.71620900974838, 3.038401144265663],& + [70.00376965910681, -18.60282251168974],& + [137.2073885318493, 13.4429808894638],& + [268.9264815224247, -28.24940170533955],& + [527.0959037839524, 20.63811064208858],& + [1033.107971416546, -12.92524752969258]],& + shape=[2, 18])) + case (105) + allocate(out(17, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -1.548976326186676],& + [0.04268788542106363, 2.27564196754247],& + [0.08366825542528471, -4.489908279851079],& + [0.163989780633558, 2.148587442934513],& + [0.3214199700417737, -8.061700131744146],& + [0.6299831412818762, -2.077075835317373],& + [1.234766956912478, -13.61903039366007],& + [2.420143235548455, -5.894809454679489],& + [4.743480741674971, -31.71297904103994],& + [9.297222253682943, 17.57063820213079],& + [18.22255561721856, -36.59750148653984],& + [35.71620900974838, 3.275496244430542],& + [70.00376965910681, -19.55945435166359],& + [137.2073885318493, 14.57954128086567],& + [268.9264815224247, -29.38289213553071],& + [527.0959037839524, 21.30480756051838],& + [1033.107971416546, -13.21038526220946]],& + shape=[2, 17])) + case (106) + allocate(out(18, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -0.677533250494136],& + [0.02177953337809369, 0.2179312683578019],& + [0.04268788542106363, -0.6385374820438301],& + [0.08366825542528471, -0.4703897007120759],& + [0.163989780633558, -3.14500232030332],& + [0.3214199700417737, -2.719048737026242],& + [0.6299831412818762, -6.523536682208942],& + [1.234766956912478, -10.09148898527928],& + [2.420143235548455, -8.259423639814486],& + [4.743480741674971, -29.99767864411115],& + [9.297222253682943, 14.31740106421057],& + [18.22255561721856, -32.19788229413098],& + [35.71620900974838, -0.8937135681626387],& + [70.00376965910681, -17.17504293331876],& + [137.2073885318493, 13.36162125691772],& + [268.9264815224247, -29.11113783938345],& + [527.0959037839524, 21.36629231978441],& + [1033.107971416546, -13.36282983228121]],& + shape=[2, 18])) + case (107) + allocate(out(18, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -1.298646724545804],& + [0.02177953337809369, 0.4464604489946851],& + [0.04268788542106363, -0.9783423846031383],& + [0.08366825542528471, -0.02447341351398791],& + [0.163989780633558, -1.253272487632785],& + [0.3214199700417737, -6.344697961523707],& + [0.6299831412818762, -4.171289879297547],& + [1.234766956912478, -10.51525339042564],& + [2.420143235548455, -8.44407281158783],& + [4.743480741674971, -29.44113088228914],& + [9.297222253682943, 11.7560197278799],& + [18.22255561721856, -28.42866041330853],& + [35.71620900974838, -4.391887385980226],& + [70.00376965910681, -15.39038378477562],& + [137.2073885318493, 12.57688123430125],& + [268.9264815224247, -29.09306853171438],& + [527.0959037839524, 21.53507042268757],& + [1033.107971416546, -13.53925178266506]],& + shape=[2, 18])) + case (108) + allocate(out(18, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -0.8341201077157905],& + [0.02177953337809369, 0.8790079144666834],& + [0.04268788542106363, -2.283173940496454],& + [0.08366825542528471, 1.475081697575661],& + [0.163989780633558, -3.167066785023053],& + [0.3214199700417737, -2.77909827102485],& + [0.6299831412818762, -9.160898144582461],& + [1.234766956912478, -8.925981476153538],& + [2.420143235548455, -6.70056432452111],& + [4.743480741674971, -31.38374833459966],& + [9.297222253682943, 11.287273288297],& + [18.22255561721856, -26.52256742934696],& + [35.71620900974838, -6.170834725373425],& + [70.00376965910681, -15.04709996806923],& + [137.2073885318493, 12.83545416744892],& + [268.9264815224247, -29.69612549326848],& + [527.0959037839524, 21.96771418547723],& + [1033.107971416546, -13.77325225309048]],& + shape=[2, 18])) + case (109) + allocate(out(17, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -1.407885967637412],& + [0.04268788542106363, 1.344102207571268],& + [0.08366825542528471, -3.147294190712273],& + [0.163989780633558, 2.097782246768475],& + [0.3214199700417737, -7.831320263445377],& + [0.6299831412818762, -4.908788286149502],& + [1.234766956912478, -14.03986150026321],& + [2.420143235548455, -1.154428042471409],& + [4.743480741674971, -35.68506939709187],& + [9.297222253682943, 12.74505364894867],& + [18.22255561721856, -26.45730164647102],& + [35.71620900974838, -6.238136500120163],& + [70.00376965910681, -16.10822957009077],& + [137.2073885318493, 14.08763639628887],& + [268.9264815224247, -30.88333916664124],& + [527.0959037839524, 22.65012596547604],& + [1033.107971416546, -14.06304593395907]],& + shape=[2, 17])) + case (110) + allocate(out(17, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -0.8473364649689756],& + [0.04268788542106363, 0.02715228963643312],& + [0.08366825542528471, -1.438781350851059],& + [0.163989780633558, 0.3357661515474319],& + [0.3214199700417737, -5.682243831455708],& + [0.6299831412818762, -7.300320878624916],& + [1.234766956912478, -13.3563629090786],& + [2.420143235548455, -0.9442454874515533],& + [4.743480741674971, -35.01565833389759],& + [9.297222253682943, 9.891752883791924],& + [18.22255561721856, -22.94107347726822],& + [35.71620900974838, -8.95118299126625],& + [70.00376965910681, -15.17304385453463],& + [137.2073885318493, 13.92209500074387],& + [268.9264815224247, -31.21789243072271],& + [527.0959037839524, 22.96292967163026],& + [1033.107971416546, -14.27155398722971]],& + shape=[2, 17])) + case (111) + allocate(out(18, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -0.6835231560231705],& + [0.02177953337809369, 0.17575886806992],& + [0.04268788542106363, -0.9472186794073423],& + [0.08366825542528471, -0.01717608273520455],& + [0.163989780633558, -2.179500749678482],& + [0.3214199700417737, -3.199406468178495],& + [0.6299831412818762, -8.11611665478631],& + [1.234766956912478, -13.98707836359245],& + [2.420143235548455, -0.4670339062431594],& + [4.743480741674971, -34.22056054472341],& + [9.297222253682943, 7.027167659776751],& + [18.22255561721856, -19.65827765141148],& + [35.71620900974838, -11.29485685401596],& + [70.00376965910681, -14.57168279995676],& + [137.2073885318493, 13.97929956112057],& + [268.9264815224247, -31.67386135307606],& + [527.0959037839524, 23.32571672275662],& + [1033.107971416546, -14.49164954789558]],& + shape=[2, 18])) + case (112) + allocate(out(18, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -0.7436983334214347],& + [0.02177953337809369, -0.4710327829033076],& + [0.04268788542106363, -0.2087244133585955],& + [0.08366825542528471, -0.005182653274459881],& + [0.163989780633558, -2.022545835352503],& + [0.3214199700417737, -4.964443393429974],& + [0.6299831412818762, -5.140563590084639],& + [1.234766956912478, -16.83545307665918],& + [2.420143235548455, 1.174309486872517],& + [4.743480741674971, -34.19984179674066],& + [9.297222253682943, 4.930194775515702],& + [18.22255561721856, -17.24860304151662],& + [35.71620900974838, -12.76138948102016],& + [70.00376965910681, -14.68927820818499],& + [137.2073885318493, 14.528755688807],& + [268.9264815224247, -32.41096889413893],& + [527.0959037839524, 23.80656543147052],& + [1033.107971416546, -14.73809988258029]],& + shape=[2, 18])) + case (113) + allocate(out(19, 2)) + out(:,:) = transpose(reshape([[0.005669391237529597, -0.7244503730306064],& + [0.011112006825558, 0.7372723947355553],& + [0.02177953337809369, -1.990498364346422],& + [0.04268788542106363, 1.342310738691594],& + [0.08366825542528471, -3.026690916114603],& + [0.163989780633558, 1.554312489308359],& + [0.3214199700417737, -8.040784788434394],& + [0.6299831412818762, -2.255246505344985],& + [1.234766956912478, -18.99387099919841],& + [2.420143235548455, 1.915332954435144],& + [4.743480741674971, -33.34905883995816],& + [9.297222253682943, 2.295104585122317],& + [18.22255561721856, -14.63662634743378],& + [35.71620900974838, -14.22919883392751],& + [70.00376965910681, -14.83910924103111],& + [137.2073885318493, 15.0828600958921],& + [268.9264815224247, -33.13887666189112],& + [527.0959037839524, 24.28053725860082],& + [1033.107971416546, -14.98331864607479]],& + shape=[2, 19])) + case (114) + allocate(out(17, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -1.942411746713333],& + [0.04268788542106363, 2.37050702329725],& + [0.08366825542528471, -4.897245339117944],& + [0.163989780633558, 0.7749787140637636],& + [0.3214199700417737, -6.501573912799358],& + [0.6299831412818762, -1.626044757664204],& + [1.234766956912478, -20.45031990855932],& + [2.420143235548455, 2.594327971339226],& + [4.743480741674971, -32.82015891373158],& + [9.297222253682943, 0.3242318332195282],& + [18.22255561721856, -12.92179788649082],& + [35.71620900974838, -14.77549800276756],& + [70.00376965910681, -15.74182532727718],& + [137.2073885318493, 16.15276426076889],& + [268.9264815224247, -34.16295129060745],& + [527.0959037839524, 24.8795893471688],& + [1033.107971416546, -15.2565720641287]],& + shape=[2, 17])) + case (115) + allocate(out(17, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -2.053460385359358],& + [0.04268788542106363, 1.639023249968886],& + [0.08366825542528471, -3.7128916811198],& + [0.163989780633558, 1.03508884459734],& + [0.3214199700417737, -7.818995296955109],& + [0.6299831412818762, -2.034415453672409],& + [1.234766956912478, -18.12701560556889],& + [2.420143235548455, -0.5084394887089729],& + [4.743480741674971, -29.25786279141903],& + [9.297222253682943, -3.976335898041725],& + [18.22255561721856, -9.447393417358398],& + [35.71620900974838, -16.67346948385239],& + [70.00376965910681, -15.5764399766922],& + [137.2073885318493, 16.42775212973356],& + [268.9264815224247, -34.69646213203669],& + [527.0959037839524, 25.26409793831408],& + [1033.107971416546, -15.48278055182891]],& + shape=[2, 17])) + case (116) + allocate(out(18, 2)) + out(:,:) = transpose(reshape([[0.011112006825558, -0.9318931638278798],& + [0.02177953337809369, 0.5207830175164645],& + [0.04268788542106363, -2.367354397235886],& + [0.08366825542528471, 1.371776267587848],& + [0.163989780633558, -5.066408341424903],& + [0.3214199700417737, -1.842410333112639],& + [0.6299831412818762, -7.916420451118029],& + [1.234766956912478, -12.13566579081089],& + [2.420143235548455, -6.306347028585151],& + [4.743480741674971, -23.58655345597072],& + [9.297222253682943, -9.851472971582552],& + [18.22255561721856, -4.863588897918817],& + [35.71620900974838, -19.3744182215305],& + [70.00376965910681, -14.77910132508259],& + [137.2073885318493, 16.22196791728493],& + [268.9264815224247, -34.92878696892876],& + [527.0959037839524, 25.5159581573098],& + [1033.107971416546, -15.68006401256972]],& + shape=[2, 18])) + case (117) + allocate(out(17, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -2.112764893099666],& + [0.04268788542106363, 1.670027275569737],& + [0.08366825542528471, -3.775026024319232],& + [0.163989780633558, 0.4969745390117168],& + [0.3214199700417737, -8.05486012995243],& + [0.6299831412818762, -2.02515933662653],& + [1.234766956912478, -17.29834204912186],& + [2.420143235548455, -1.692559435963631],& + [4.743480741674971, -27.32995729148388],& + [9.297222253682943, -7.386572480201721],& + [18.22255561721856, -7.504521444439888],& + [35.71620900974838, -16.0801872164011],& + [70.00376965910681, -18.62356871366501],& + [137.2073885318493, 19.26550386846066],& + [268.9264815224247, -37.08027223497629],& + [527.0959037839524, 26.59029909782112],& + [1033.107971416546, -16.05901353061199]],& + shape=[2, 17])) + case (118) + allocate(out(17, 2)) + out(:,:) = transpose(reshape([[0.02177953337809369, -1.294760107470211],& + [0.04268788542106363, -0.3777095396071672],& + [0.08366825542528471, -1.15623075235635],& + [0.163989780633558, -2.062383782118559],& + [0.3214199700417737, -6.740785725414753],& + [0.6299831412818762, -3.014338135719299],& + [1.234766956912478, -16.3562148809433],& + [2.420143235548455, -2.396625004708767],& + [4.743480741674971, -26.42468926310539],& + [9.297222253682943, -8.888857021927834],& + [18.22255561721856, -6.852011650800705],& + [35.71620900974838, -15.48754817247391],& + [70.00376965910681, -20.30353319644928],& + [137.2073885318493, 20.72343978285789],& + [268.9264815224247, -38.26823274046183],& + [527.0959037839524, 27.2466142848134],& + [1033.107971416546, -16.34613409411395]],& + shape=[2, 17])) + case default + call error("Bad atomic number supplied!") + end select + + end subroutine get_sap_data + +end module sap \ No newline at end of file diff --git a/slateratom/lib/total_energy.f90 b/slateratom/lib/total_energy.f90 index 6e44f7e7..d7e15c8e 100644 --- a/slateratom/lib/total_energy.f90 +++ b/slateratom/lib/total_energy.f90 @@ -125,17 +125,9 @@ subroutine getTotalEnergy(tt, uu, nuc, vconf, jj, kk, kk_lr, pp, max_l, num_alph elseif (xcFunctional%isCAMY(xcnr)) then hf_x_energy = hf_ex_energy(kk, pp, max_l, num_alpha, poly_order) hf_x_energy_lr = hf_ex_energy(kk_lr, pp, max_l, num_alpha, poly_order) - if (xcnr == xcFunctional%CAMY_B3LYP) then - ! CAMY-B3LYP parameters a=0.20, b=0.72, c=0.81 (libXC defaults) - hf_x_energy = camAlpha * hf_x_energy - hf_x_energy_lr = camBeta * hf_x_energy_lr - hf_x_energy = hf_x_energy + hf_x_energy_lr - elseif (xcnr == xcFunctional%CAMY_PBEh) then - ! CAMY-PBEh - hf_x_energy = camAlpha * hf_x_energy - hf_x_energy_lr = camBeta * hf_x_energy_lr - hf_x_energy = hf_x_energy + hf_x_energy_lr - end if + hf_x_energy = camAlpha * hf_x_energy + hf_x_energy_lr = camBeta * hf_x_energy_lr + hf_x_energy = hf_x_energy + hf_x_energy_lr end if ! pure HF: @@ -150,13 +142,13 @@ subroutine getTotalEnergy(tt, uu, nuc, vconf, jj, kk, kk_lr, pp, max_l, num_alph ! pure HF if (xcnr == xcFunctional%HF_Exchange) then total_energy = dummy1 + 0.5_dp * coulomb + 0.5_dp * hf_x_energy - ! (semi-)local functionals - elseif ((xcnr == xcFunctional%X_Alpha) .or. xcFunctional%isLDA(xcnr)& - & .or. xcFunctional%isGGA(xcnr)) then - total_energy = dummy1 + 0.5_dp * coulomb + dft_xc_energy - ! global hybrids, LC, CAM functionals - else + ! global and range-separated hybrids + elseif (xcFunctional%isGlobalHybrid(xcnr) .or. xcFunctional%isLongRangeCorrected(xcnr)& + & .or. xcFunctional%isCAMY(xcnr)) then total_energy = dummy1 + 0.5_dp * coulomb + dft_xc_energy + 0.5_dp * hf_x_energy + ! purely emilocal xc functionals + else + total_energy = dummy1 + 0.5_dp * coulomb + dft_xc_energy end if end subroutine getTotalEnergy @@ -298,17 +290,9 @@ subroutine getTotalEnergyZora(tt, uu, nuc, vconf, jj, kk, kk_lr, pp, max_l, num_ elseif (xcFunctional%isCAMY(xcnr)) then hf_x_energy = hf_ex_energy(kk, pp, max_l, num_alpha, poly_order) hf_x_energy_lr = hf_ex_energy(kk_lr, pp, max_l, num_alpha, poly_order) - if (xcnr == xcFunctional%CAMY_B3LYP) then - ! CAMY-B3LYP parameters a=0.20, b=0.72, c=0.81 (libXC defaults) - hf_x_energy = camAlpha * hf_x_energy - hf_x_energy_lr = camBeta * hf_x_energy_lr - hf_x_energy = hf_x_energy + hf_x_energy_lr - elseif (xcnr == xcFunctional%CAMY_PBEh) then - ! CAMY-PBEh - hf_x_energy = camAlpha * hf_x_energy - hf_x_energy_lr = camBeta * hf_x_energy_lr - hf_x_energy = hf_x_energy + hf_x_energy_lr - end if + hf_x_energy = camAlpha * hf_x_energy + hf_x_energy_lr = camBeta * hf_x_energy_lr + hf_x_energy = hf_x_energy + hf_x_energy_lr end if call dft_exc_energy(num_mesh_points, rho, exc, weight, abcissa, dft_xc_energy) diff --git a/slateratom/lib/utilities.f90 b/slateratom/lib/utilities.f90 index 1b1f8a66..42d34fec 100644 --- a/slateratom/lib/utilities.f90 +++ b/slateratom/lib/utilities.f90 @@ -6,7 +6,9 @@ module utilities implicit none private - public :: check_convergence, check_electron_number + public :: check_electron_number, check_convergence_energy, check_convergence_commutator,& + & check_convergence_eigenspectrum, compute_commutator, check_convergence_pot,& + & check_convergence_density public :: vector_length, fak, zeroOutCpotOfEmptyDensitySpinChannels @@ -33,8 +35,8 @@ end subroutine zeroOutCpotOfEmptyDensitySpinChannels !> Checks SCF convergence by comparing new and old potential. - pure subroutine check_convergence(pot_old, pot_new, max_l, problemsize, scftol, iScf, change_max,& - & tConverged) + pure subroutine check_convergence_pot(pot_old, pot_new, max_l, problemsize, scftol, iScf,& + & change_max, tConverged) !> old and new potential to compare real(dp), intent(in) :: pot_old(:,0:,:,:), pot_new(:,0:,:,:) @@ -62,10 +64,6 @@ pure subroutine check_convergence(pot_old, pot_new, max_l, problemsize, scftol, change_max = 0.0_dp - if (iScf < 3) then - tConverged = .false. - end if - do ii = 1, 2 do jj = 0, max_l do kk = 1, problemsize @@ -82,7 +80,216 @@ pure subroutine check_convergence(pot_old, pot_new, max_l, problemsize, scftol, tConverged = .false. end if - end subroutine check_convergence + if (iScf < 3) then + tConverged = .false. + end if + + end subroutine check_convergence_pot + + + !> Check convergence by finding the maximum absolute value of the orbital commutator [F,PS] + pure subroutine check_convergence_commutator(commutator, scftol, iScf, commutator_max,& + & tConverged) + + !> commutator [F, PS] + real(dp), intent(in) :: commutator(:, 0:, :, :) + + !> scf tolerance, i.e. convergence criteria + real(dp), intent(in) :: scftol + + !> current SCF step + integer, intent(in) :: iScf + + !> orbital gradient norm value + real(dp), intent(out) :: commutator_max + + !> true, if SCF converged + logical, intent(out) :: tConverged + + commutator_max = maxval(abs(commutator)) + + tConverged = commutator_max < scftol + + if (iScf < 3) then + tConverged = .false. + end if + + end subroutine check_convergence_commutator + + + !> Compute the commutator [F,PS] in MO basis + subroutine compute_commutator(max_l, num_alpha, poly_order, ff, pp, ss, commutator) + !> maximum angular momentum + integer, intent(in) :: max_l + + !> number of exponents in each shell + integer, intent(in) :: num_alpha(0:) + + !> highest polynomial order + l in each shell + integer, intent(in) :: poly_order(0:) + + !> Fock matrix + real(dp), intent(in) :: ff(:, 0:, :, :) + + !> density matrix supervector + real(dp), intent(in) :: pp(:,0:,:,:) + + !> overlap supervector + real(dp), intent(in) :: ss(0:,:,:) + + !> commutator [F,PS] + real(dp), intent(out) :: commutator(:, 0:, :, :) + + !! auxilliary variables + integer :: iSpin, ll, diagsize + real(dp), allocatable :: fps(:,:), spf(:,:) + + commutator = 0.0_dp + + diagsize = size(ff, dim=4) + allocate(fps(diagsize, diagsize)) + allocate(spf(diagsize, diagsize)) + + do iSpin = 1, 2 + do ll = 0, max_l + ! Compute [F,PS]= FPS - SPF + fps = matmul(ff(iSpin, ll, :, :), matmul(pp(iSpin, ll, :, :), ss(ll, :, :))) + spf = matmul(matmul(ss(ll, :, :), pp(iSpin, ll, :, :)), ff(iSpin, ll, :, :)) + commutator(iSpin, ll, :, :) = fps - spf + end do + end do + + deallocate(fps) + deallocate(spf) + + end subroutine + + + !> Checks convergence by computing max. density change from the last SCF iteration. + pure subroutine check_convergence_density(pp_old, pp_new, scftol, iScf, res, tConverged) + + !> old and new energy to compare + real(dp), intent(in) :: pp_old(:,:,:,:), pp_new(:,:,:,:) + + !> scf tolerance, i.e. convergence criteria + real(dp), intent(in) :: scftol + + !> current SCF step + integer, intent(in) :: iScf + + !> obtained maximum change in energy + real(dp), intent(out) :: res + + !> true, if SCF converged + logical, intent(out) :: tConverged + + res = 0.0_dp + + res = maxval(abs(pp_new - pp_old)) + tConverged = res < scftol + + if (iScf < 3) then + tConverged = .false. + end if + + end subroutine check_convergence_density + + + !> Checks convergence by computing energy change from the last SCF iteration. + pure subroutine check_convergence_energy(energy_old, energy_new, scftol, iScf, change,& + & tConverged) + + !> old and new energy to compare + real(dp), intent(in) :: energy_new, energy_old + + !> scf tolerance, i.e. convergence criteria + real(dp), intent(in) :: scftol + + !> current SCF step + integer, intent(in) :: iScf + + !> obtained maximum change in energy + real(dp), intent(out) :: change + + !> true, if SCF converged + logical, intent(out) :: tConverged + + change = 0.0_dp + + change = energy_new - energy_old + tConverged = abs(change) < scftol + + if (iScf < 3) then + tConverged = .false. + end if + + end subroutine check_convergence_energy + + + !> Checks convergence by evaluating change in the occupied part of the eigenspectrum + pure subroutine check_convergence_eigenspectrum(max_l, num_alpha, poly_order, eigval_new,& + & eigval_old, occ, scftol, iScf, res, tConverged) + + !> maximum angular momentum + integer, intent(in) :: max_l + + !> number of exponents in each shell + integer, intent(in) :: num_alpha(0:) + + !> highest polynomial order + l in each shell + integer, intent(in) :: poly_order(0:) + + !> old and new eigenspectra to compare + real(dp), intent(in) :: eigval_new(:,0:,:), eigval_old(:,0:,:) + + !> occupations + real(dp), intent(in) :: occ(:,0:,:) + + !> scf tolerance, i.e. convergence criteria + real(dp), intent(in) :: scftol + + !> current SCF step + integer, intent(in) :: iScf + + !> obtained change + real(dp), intent(out) :: res + + !> true, if SCF converged + logical, intent(out) :: tConverged + + ! Loop indices + integer :: iSpin, ll, diagsize, ii + + ! Occupation + real(dp) :: occ_ii + + ! Difference + real(dp) :: e_diff + + ! Max. difference, only occupied orbitals contribute + res = 0.0_dp + do iSpin = 1, 2 + do ll = 0, max_l + diagsize = num_alpha(ll) * poly_order(ll) + do ii = 1, diagsize + occ_ii = abs(occ(iSpin, ll, ii)) + if (occ_ii > 1e-16) then + e_diff = abs(eigval_new(iSpin, ll, ii) - eigval_old(iSpin, ll, ii)) + if (e_diff > res) then + res = e_diff + end if + end if + end do + end do + end do + + tConverged = res < scftol + + if (iScf < 3) then + tConverged = .false. + end if + + end subroutine check_convergence_eigenspectrum !> Checks conservation of electron number during SCF. If this fluctuates you are in deep trouble. diff --git a/slateratom/lib/xcfunctionals.F90 b/slateratom/lib/xcfunctionals.F90 index 7f4904f6..5694088b 100644 --- a/slateratom/lib/xcfunctionals.F90 +++ b/slateratom/lib/xcfunctionals.F90 @@ -9,15 +9,22 @@ module xcfunctionals use utilities, only : zeroOutCpotOfEmptyDensitySpinChannels #:if LIBXC_VERSION_MAJOR == 6 use xc_f03_lib_m, only : xc_f03_func_t, xc_f03_func_init, xc_f03_func_end, xc_f03_lda_exc_vxc,& - & xc_f03_gga_exc_vxc, xc_f03_func_set_ext_params, XC_LDA_X, XC_LDA_X_YUKAWA, XC_LDA_C_PW,& - & XC_GGA_X_PBE, XC_GGA_X_B88, XC_GGA_X_SFAT_PBE, XC_HYB_GGA_XC_B3LYP,& - & XC_HYB_GGA_XC_CAMY_B3LYP, XC_GGA_C_PBE, XC_GGA_C_LYP, XC_POLARIZED + & xc_f03_gga_exc_vxc, xc_f03_mgga_exc_vxc, xc_f03_func_set_ext_params,& + & xc_f03_func_set_ext_params_name, XC_POLARIZED,& + & XC_LDA_X, XC_LDA_X_YUKAWA, XC_LDA_C_PW, XC_GGA_X_PBE, XC_GGA_X_B88,& + & XC_GGA_X_SFAT_PBE, XC_HYB_GGA_XC_B3LYP, XC_HYB_GGA_XC_CAMY_B3LYP, XC_GGA_C_PBE,& + & XC_GGA_C_LYP, XC_MGGA_X_SCAN, XC_MGGA_X_R4SCAN, XC_MGGA_C_SCAN, XC_MGGA_X_TASK,& + & XC_MGGA_X_R2SCAN, XC_MGGA_C_R2SCAN, XC_MGGA_X_TPSS, XC_MGGA_C_TPSS, XC_MGGA_C_CC,& + & XC_HYB_MGGA_XC_YWB97M #:elif LIBXC_VERSION_MAJOR == 7 use xc_f03_lib_m, only : xc_f03_func_t, xc_f03_func_init, xc_f03_func_end, xc_f03_lda_exc_vxc,& - & xc_f03_gga_exc_vxc, xc_f03_func_set_ext_params, XC_POLARIZED + & xc_f03_gga_exc_vxc, xc_f03_mgga_exc_vxc, xc_f03_func_set_ext_params,& + & xc_f03_func_set_ext_params_name, XC_POLARIZED use xc_f03_funcs_m, only : XC_LDA_X, XC_LDA_X_YUKAWA, XC_LDA_C_PW, XC_GGA_X_PBE, XC_GGA_X_B88,& & XC_GGA_X_SFAT_PBE, XC_HYB_GGA_XC_B3LYP, XC_HYB_GGA_XC_CAMY_B3LYP, XC_GGA_C_PBE,& - & XC_GGA_C_LYP + & XC_GGA_C_LYP, XC_MGGA_X_SCAN, XC_MGGA_X_R4SCAN, XC_MGGA_C_SCAN, XC_MGGA_X_TASK,& + & XC_MGGA_X_R2SCAN, XC_MGGA_C_R2SCAN, XC_MGGA_X_TPSS, XC_MGGA_C_TPSS, XC_MGGA_C_CC,& + & XC_HYB_MGGA_XC_YWB97M #:endif implicit none @@ -29,6 +36,8 @@ module xcfunctionals public :: getExcVxc_LCY_PBE96, getExcVxc_LCY_BNL public :: getExcVxc_HYB_B3LYP, getExcVxc_HYB_PBE0 public :: getExcVxc_CAMY_B3LYP, getExcVxc_CAMY_PBEh + public :: getExcVxc_MGGA_TPSS, getExcVxc_MGGA_SCAN, getExcVxc_MGGA_r2SCAN, getExcVxc_MGGA_r4SCAN + public :: getExcVxc_MGGA_TASK, getExcVxc_MGGA_TASK_CC, getExcVxc_CAMY_MGGA_wB97M interface libxcVxcToInternalVxc @@ -36,7 +45,6 @@ module xcfunctionals module procedure :: libxcVxcToInternalVxc_separate end interface libxcVxcToInternalVxc - !> Enumerates available xc-functionals. type :: TXcFunctionalsEnum @@ -74,10 +82,32 @@ module xcfunctionals !> CAMY-PBEh integer :: CAMY_PBEh = 10 + !> MGGA-TPSS + integer :: MGGA_TPSS = 11 + + !> MGGA-SCAN + integer :: MGGA_SCAN = 12 + + !> MGGA-r2SCAN + integer :: MGGA_r2SCAN = 13 + + !> MGGA-r4SCAN + integer :: MGGA_r4SCAN = 14 + + !> MGGA-TASK + integer :: MGGA_TASK = 15 + + !> MGGA-TASK+CC + integer :: MGGA_TASK_CC = 16 + + !> CAMY-MGGA-WB97M + integer :: CAMY_MGGA_wB97M = 17 + contains procedure :: isLDA => TXcFunctionalsEnum_isLDA procedure :: isGGA => TXcFunctionalsEnum_isGGA + procedure :: isMGGA => TXcFunctionalsEnum_isMGGA procedure :: isGlobalHybrid => TXcFunctionalsEnum_isGlobalHybrid procedure :: isLongRangeCorrected => TXcFunctionalsEnum_isLongRangeCorrected procedure :: isCAMY => TXcFunctionalsEnum_isCAMY @@ -128,6 +158,28 @@ pure function TXcFunctionalsEnum_isGGA(this, xcnr) result(isGGA) end function TXcFunctionalsEnum_isGGA + pure function TXcFunctionalsEnum_isMGGA(this, xcnr) result(isMGGA) + + !> Class instance + class(TXcFunctionalsEnum), intent(in) :: this + + !> identifier of exchange-correlation type + integer, intent(in) :: xcnr + + !> True, if xc-functional index corresponds to an MGGA functional + logical :: isMGGA + + isMGGA = .false. + + if (xcnr == this%MGGA_SCAN .or. xcnr == this%MGGA_r2SCAN .or. xcnr == this%MGGA_TASK& + & .or. xcnr == this%MGGA_r4SCAN .or. xcnr == this%MGGA_TPSS& + & .or. xcnr == this%MGGA_TASK_CC .or. xcnr == this%CAMY_MGGA_wB97M) then + isMGGA = .true. + end if + + end function TXcFunctionalsEnum_isMGGA + + pure function TXcFunctionalsEnum_isLongRangeCorrected(this, xcnr) result(isLongRangeCorrected) !> Class instance @@ -181,7 +233,7 @@ pure function TXcFunctionalsEnum_isCAMY(this, xcnr) result(isCamy) isCamy = .false. - if (xcnr == this%CAMY_B3LYP .or. xcnr == this%CAMY_PBEh) then + if (xcnr == this%CAMY_B3LYP .or. xcnr == this%CAMY_PBEh .or. xcnr == this%CAMY_MGGA_wB97M) then isCamy = .true. end if @@ -201,7 +253,7 @@ pure function TXcFunctionalsEnum_isNotImplemented(this, xcnr) result(isNotImplem isNotImplemented = .false. - if (xcnr < 0 .or. xcnr > 10) then + if (xcnr < 0 .or. xcnr > 17) then isNotImplemented = .true. end if @@ -442,8 +494,8 @@ subroutine getExcVxc_GGA_BLYP(abcissa, dz, dzdr, rho, drho, sigma, exc, vxc) end subroutine getExcVxc_GGA_BLYP - !> Calculates exc and vxc for the LCY-PBE96 xc-functional. - subroutine getExcVxc_LCY_PBE96(abcissa, dz, dzdr, rho, drho, sigma, omega, exc, vxc) + !> Calculates exc, vxc, and vtau for the MGGA-TPSS xc-functional. + subroutine getExcVxc_MGGA_TPSS(abcissa, dz, dzdr, rho, drho, sigma, tau, exc, vxc, vtau) !> numerical integration abcissas real(dp), intent(in) :: abcissa(:) @@ -463,8 +515,8 @@ subroutine getExcVxc_LCY_PBE96(abcissa, dz, dzdr, rho, drho, sigma, omega, exc, !> contracted gradients of the density real(dp), intent(in), allocatable :: sigma(:,:) - !> range-separation parameter - real(dp), intent(in) :: omega + !> kinetic energy density + real(dp), intent(in):: tau(:,:) !> exc energy density on grid real(dp), intent(out) :: exc(:) @@ -472,9 +524,15 @@ subroutine getExcVxc_LCY_PBE96(abcissa, dz, dzdr, rho, drho, sigma, omega, exc, !> xc potential on grid real(dp), intent(out) :: vxc(:,:) + !> orbital-dependent tau potential on grid + real(dp), intent(out) :: vtau(:,:) + !! density in libxc compatible format, i.e. rho/(4pi) real(dp), allocatable :: rhor(:,:) + !! kinetic energy density in libxc compatible format + real(dp), allocatable :: rtau(:,:) + !! libxc related objects type(xc_f03_func_t) :: xcfunc_x, xcfunc_c @@ -493,11 +551,31 @@ subroutine getExcVxc_LCY_PBE96(abcissa, dz, dzdr, rho, drho, sigma, omega, exc, !! first partial derivative of the energy per unit volume in terms of sigma (correlation) real(dp), allocatable :: vcsigma(:,:) + !! first partial derivative of the energy per unit volume in terms of tau (exchange) + real(dp), allocatable :: vxtau(:,:) + + !! first partial derivative of the energy per unit volume in terms of tau (correlation) + real(dp), allocatable :: vctau(:,:) + + !! laplacian for libxc (dummy) + real(dp), allocatable :: lapl(:,:) + + !! first partial derivative of the energy per unit volume in terms of laplacian (exchange) + !! (dummy) + real(dp), allocatable :: vxlapl(:,:) + + !! first partial derivative of the energy per unit volume in terms of laplacian (correlation) + !! (dummy) + real(dp), allocatable :: vclapl(:,:) + nn = size(rho, dim=1) ! divide by 4*pi to catch different normalization of spherical harmonics allocate(rhor(2, nn)) rhor(:,:) = transpose(rho) * rec4pi + allocate(rtau(2, nn)) + rtau(:,:) = transpose(tau) + allocate(ex(nn)) ex(:) = 0.0_dp allocate(ec(nn)) @@ -512,19 +590,33 @@ subroutine getExcVxc_LCY_PBE96(abcissa, dz, dzdr, rho, drho, sigma, omega, exc, allocate(vcsigma(3, nn)) vcsigma(:,:) = 0.0_dp - call xc_f03_func_init(xcfunc_x, XC_GGA_X_SFAT_PBE, XC_POLARIZED) - call xc_f03_func_set_ext_params(xcfunc_x, [omega]) - call xc_f03_func_init(xcfunc_c, XC_GGA_C_PBE, XC_POLARIZED) + allocate(vxtau(2, nn)) + vxtau(:,:) = 0.0_dp + allocate(vctau(2, nn)) + vctau(:,:) = 0.0_dp - ! exchange - call xc_f03_gga_exc_vxc(xcfunc_x, nn, rhor(1, 1), sigma(1, 1), ex(1), vx(1, 1), vxsigma(1, 1)) + allocate(lapl(2, nn)) + lapl(:,:) = 0.0_dp + allocate(vxlapl(2, nn)) + vxlapl(:,:) = 0.0_dp + allocate(vclapl(2, nn)) + vclapl(:,:) = 0.0_dp + + call xc_f03_func_init(xcfunc_x, XC_MGGA_X_TPSS, XC_POLARIZED) + call xc_f03_func_init(xcfunc_c, XC_MGGA_C_TPSS, XC_POLARIZED) + + ! Exchange energy and potential + call xc_f03_mgga_exc_vxc(xcfunc_x, nn, rhor(1, 1), sigma(1, 1), lapl(1, 1), rtau(1, 1), ex(1),& + & vx(1, 1), vxsigma(1, 1), vxlapl(1, 1), vxtau(1, 1)) + ! Correlation energy and potential + call xc_f03_mgga_exc_vxc(xcfunc_c, nn, rhor(1, 1), sigma(1, 1), lapl(1, 1), rtau(1, 1), ec(1),& + & vc(1, 1), vcsigma(1, 1), vclapl(1, 1), vctau(1, 1)) - ! correlation - call xc_f03_gga_exc_vxc(xcfunc_c, nn, rhor(1, 1), sigma(1, 1), ec(1), vc(1, 1), vcsigma(1, 1)) call zeroOutCpotOfEmptyDensitySpinChannels(rho, vc) exc(:) = ex + ec vxc(:,:) = transpose(vx + vc) + vtau(:,:) = transpose(vxtau + vctau) call libxcVxcToInternalVxc(abcissa, dz, dzdr, drho, vxsigma, vcsigma, vxc) @@ -532,11 +624,11 @@ subroutine getExcVxc_LCY_PBE96(abcissa, dz, dzdr, rho, drho, sigma, omega, exc, call xc_f03_func_end(xcfunc_x) call xc_f03_func_end(xcfunc_c) - end subroutine getExcVxc_LCY_PBE96 + end subroutine getExcVxc_MGGA_TPSS - !> Calculates exc and vxc for the LCY-BNL xc-functional. - subroutine getExcVxc_LCY_BNL(abcissa, dz, dzdr, rho, drho, sigma, omega, exc, vxc) + !> Calculates exc, vxc, and vtau for the MGGA-SCAN xc-functional. + subroutine getExcVxc_MGGA_SCAN(abcissa, dz, dzdr, rho, drho, sigma, tau, exc, vxc, vtau) !> numerical integration abcissas real(dp), intent(in) :: abcissa(:) @@ -556,8 +648,8 @@ subroutine getExcVxc_LCY_BNL(abcissa, dz, dzdr, rho, drho, sigma, omega, exc, vx !> contracted gradients of the density real(dp), intent(in), allocatable :: sigma(:,:) - !> range-separation parameter - real(dp), intent(in) :: omega + !> kinetic energy density + real(dp), intent(in):: tau(:,:) !> exc energy density on grid real(dp), intent(out) :: exc(:) @@ -565,9 +657,15 @@ subroutine getExcVxc_LCY_BNL(abcissa, dz, dzdr, rho, drho, sigma, omega, exc, vx !> xc potential on grid real(dp), intent(out) :: vxc(:,:) + !> orbital-dependent tau potential on grid + real(dp), intent(out) :: vtau(:,:) + !! density in libxc compatible format, i.e. rho/(4pi) real(dp), allocatable :: rhor(:,:) + !! kinetic energy density in libxc compatible format + real(dp), allocatable :: rtau(:,:) + !! libxc related objects type(xc_f03_func_t) :: xcfunc_x, xcfunc_c @@ -580,14 +678,37 @@ subroutine getExcVxc_LCY_BNL(abcissa, dz, dzdr, rho, drho, sigma, omega, exc, vx !! exchange and correlation potential on grid real(dp), allocatable :: vx(:,:), vc(:,:) + !! first partial derivative of the energy per unit volume in terms of sigma (exchange) + real(dp), allocatable :: vxsigma(:,:) + !! first partial derivative of the energy per unit volume in terms of sigma (correlation) real(dp), allocatable :: vcsigma(:,:) + !! first partial derivative of the energy per unit volume in terms of tau (exchange) + real(dp), allocatable :: vxtau(:,:) + + !! first partial derivative of the energy per unit volume in terms of tau (correlation) + real(dp), allocatable :: vctau(:,:) + + !! laplacian for libxc (dummy) + real(dp), allocatable :: lapl(:,:) + + !! first partial derivative of the energy per unit volume in terms of laplacian (exchange) + !! (dummy) + real(dp), allocatable :: vxlapl(:,:) + + !! first partial derivative of the energy per unit volume in terms of laplacian (correlation) + !! (dummy) + real(dp), allocatable :: vclapl(:,:) + nn = size(rho, dim=1) ! divide by 4*pi to catch different normalization of spherical harmonics allocate(rhor(2, nn)) rhor(:,:) = transpose(rho) * rec4pi + allocate(rtau(2, nn)) + rtau(:,:) = transpose(tau) + allocate(ex(nn)) ex(:) = 0.0_dp allocate(ec(nn)) @@ -597,34 +718,50 @@ subroutine getExcVxc_LCY_BNL(abcissa, dz, dzdr, rho, drho, sigma, omega, exc, vx allocate(vc(2, nn)) vc(:,:) = 0.0_dp + allocate(vxsigma(3, nn)) + vxsigma(:,:) = 0.0_dp allocate(vcsigma(3, nn)) vcsigma(:,:) = 0.0_dp - call xc_f03_func_init(xcfunc_x, XC_LDA_X_YUKAWA, XC_POLARIZED) - call xc_f03_func_set_ext_params(xcfunc_x, [omega]) - call xc_f03_func_init(xcfunc_c, XC_GGA_C_PBE, XC_POLARIZED) + allocate(vxtau(2, nn)) + vxtau(:,:) = 0.0_dp + allocate(vctau(2, nn)) + vctau(:,:) = 0.0_dp - ! exchange - call xc_f03_lda_exc_vxc(xcfunc_x, nn, rhor(1, 1), ex(1), vx(1, 1)) + allocate(lapl(2, nn)) + lapl(:,:) = 0.0_dp + allocate(vxlapl(2, nn)) + vxlapl(:,:) = 0.0_dp + allocate(vclapl(2, nn)) + vclapl(:,:) = 0.0_dp + + call xc_f03_func_init(xcfunc_x, XC_MGGA_X_SCAN, XC_POLARIZED) + call xc_f03_func_init(xcfunc_c, XC_MGGA_C_SCAN, XC_POLARIZED) + + ! Exchange energy and potential + call xc_f03_mgga_exc_vxc(xcfunc_x, nn, rhor(1, 1), sigma(1, 1), lapl(1, 1), rtau(1, 1), ex(1),& + & vx(1, 1), vxsigma(1, 1), vxlapl(1, 1), vxtau(1, 1)) + ! Correlation energy and potential + call xc_f03_mgga_exc_vxc(xcfunc_c, nn, rhor(1, 1), sigma(1, 1), lapl(1, 1), rtau(1, 1), ec(1),& + & vc(1, 1), vcsigma(1, 1), vclapl(1, 1), vctau(1, 1)) - ! correlation - call xc_f03_gga_exc_vxc(xcfunc_c, nn, rhor(1, 1), sigma(1, 1), ec(1), vc(1, 1), vcsigma(1, 1)) call zeroOutCpotOfEmptyDensitySpinChannels(rho, vc) exc(:) = ex + ec vxc(:,:) = transpose(vx + vc) + vtau(:,:) = transpose(vxtau + vctau) - call libxcVxcToInternalVxc(abcissa, dz, dzdr, drho, vcsigma, vxc) + call libxcVxcToInternalVxc(abcissa, dz, dzdr, drho, vxsigma, vcsigma, vxc) ! finalize libxc objects call xc_f03_func_end(xcfunc_x) call xc_f03_func_end(xcfunc_c) - end subroutine getExcVxc_LCY_BNL + end subroutine getExcVxc_MGGA_SCAN - !> Calculates exc and vxc for the HYB-PBE0 xc-functional. - subroutine getExcVxc_HYB_PBE0(abcissa, dz, dzdr, rho, drho, sigma, camAlpha, exc, vxc) + !> Calculates exc, vxc, and vtau for the MGGA-r2SCAN xc-functional. + subroutine getExcVxc_MGGA_r2SCAN(abcissa, dz, dzdr, rho, drho, sigma, tau, exc, vxc, vtau) !> numerical integration abcissas real(dp), intent(in) :: abcissa(:) @@ -644,8 +781,8 @@ subroutine getExcVxc_HYB_PBE0(abcissa, dz, dzdr, rho, drho, sigma, camAlpha, exc !> contracted gradients of the density real(dp), intent(in), allocatable :: sigma(:,:) - !> CAM alpha parameter - real(dp), intent(in) :: camAlpha + !> kinetic energy density + real(dp), intent(in):: tau(:,:) !> exc energy density on grid real(dp), intent(out) :: exc(:) @@ -653,9 +790,15 @@ subroutine getExcVxc_HYB_PBE0(abcissa, dz, dzdr, rho, drho, sigma, camAlpha, exc !> xc potential on grid real(dp), intent(out) :: vxc(:,:) + !> orbital-dependent tau potential on grid + real(dp), intent(out) :: vtau(:,:) + !! density in libxc compatible format, i.e. rho/(4pi) real(dp), allocatable :: rhor(:,:) + !! kinetic energy density in libxc compatible format + real(dp), allocatable :: rtau(:,:) + !! libxc related objects type(xc_f03_func_t) :: xcfunc_x, xcfunc_c @@ -674,14 +817,31 @@ subroutine getExcVxc_HYB_PBE0(abcissa, dz, dzdr, rho, drho, sigma, camAlpha, exc !! first partial derivative of the energy per unit volume in terms of sigma (correlation) real(dp), allocatable :: vcsigma(:,:) - !! first partial derivative of the energy per unit volume in terms of sigma (x+c) - real(dp), allocatable :: vxcsigma(:,:) + !! first partial derivative of the energy per unit volume in terms of tau (exchange) + real(dp), allocatable :: vxtau(:,:) + + !! first partial derivative of the energy per unit volume in terms of tau (correlation) + real(dp), allocatable :: vctau(:,:) + + !! laplacian for libxc (dummy) + real(dp), allocatable :: lapl(:,:) + + !! first partial derivative of the energy per unit volume in terms of laplacian (exchange) + !! (dummy) + real(dp), allocatable :: vxlapl(:,:) + + !! first partial derivative of the energy per unit volume in terms of laplacian (correlation) + !! (dummy) + real(dp), allocatable :: vclapl(:,:) nn = size(rho, dim=1) ! divide by 4*pi to catch different normalization of spherical harmonics allocate(rhor(2, nn)) rhor(:,:) = transpose(rho) * rec4pi + allocate(rtau(2, nn)) + rtau(:,:) = transpose(tau) + allocate(ex(nn)) ex(:) = 0.0_dp allocate(ec(nn)) @@ -695,35 +855,46 @@ subroutine getExcVxc_HYB_PBE0(abcissa, dz, dzdr, rho, drho, sigma, camAlpha, exc vxsigma(:,:) = 0.0_dp allocate(vcsigma(3, nn)) vcsigma(:,:) = 0.0_dp - allocate(vxcsigma(3, nn)) - vxcsigma(:,:) = 0.0_dp - call xc_f03_func_init(xcfunc_x, XC_GGA_X_PBE, XC_POLARIZED) - call xc_f03_func_init(xcfunc_c, XC_GGA_C_PBE, XC_POLARIZED) + allocate(vxtau(2, nn)) + vxtau(:,:) = 0.0_dp + allocate(vctau(2, nn)) + vctau(:,:) = 0.0_dp - ! exchange - call xc_f03_gga_exc_vxc(xcfunc_x, nn, rhor(1, 1), sigma(1, 1), ex(1), vx(1, 1), vxsigma(1, 1)) + allocate(lapl(2, nn)) + lapl(:,:) = 0.0_dp + allocate(vxlapl(2, nn)) + vxlapl(:,:) = 0.0_dp + allocate(vclapl(2, nn)) + vclapl(:,:) = 0.0_dp + + call xc_f03_func_init(xcfunc_x, XC_MGGA_X_R2SCAN, XC_POLARIZED) + call xc_f03_func_init(xcfunc_c, XC_MGGA_C_R2SCAN, XC_POLARIZED) + + ! Exchange energy and potential + call xc_f03_mgga_exc_vxc(xcfunc_x, nn, rhor(1, 1), sigma(1, 1), lapl(1, 1), rtau(1, 1), ex(1),& + & vx(1, 1), vxsigma(1, 1), vxlapl(1, 1), vxtau(1, 1)) + ! Correlation energy and potential + call xc_f03_mgga_exc_vxc(xcfunc_c, nn, rhor(1, 1), sigma(1, 1), lapl(1, 1), rtau(1, 1), ec(1),& + & vc(1, 1), vcsigma(1, 1), vclapl(1, 1), vctau(1, 1)) - ! correlation - call xc_f03_gga_exc_vxc(xcfunc_c, nn, rhor(1, 1), sigma(1, 1), ec(1), vc(1, 1), vcsigma(1, 1)) call zeroOutCpotOfEmptyDensitySpinChannels(rho, vc) - ! build PBE0 functional - vxcsigma(:,:) = (1.0_dp - camAlpha) * vxsigma + vcsigma - vxc(:,:) = transpose((1.0_dp - camAlpha) * vx + vc) - exc(:) = (1.0_dp - camAlpha) * ex + ec + exc(:) = ex + ec + vxc(:,:) = transpose(vx + vc) + vtau(:,:) = transpose(vxtau + vctau) - call libxcVxcToInternalVxc(abcissa, dz, dzdr, drho, vxcsigma, vxc) + call libxcVxcToInternalVxc(abcissa, dz, dzdr, drho, vxsigma, vcsigma, vxc) ! finalize libxc objects call xc_f03_func_end(xcfunc_x) call xc_f03_func_end(xcfunc_c) - end subroutine getExcVxc_HYB_PBE0 + end subroutine getExcVxc_MGGA_r2SCAN - !> Calculates exc and vxc for the HYB-B3LYP xc-functional. - subroutine getExcVxc_HYB_B3LYP(abcissa, dz, dzdr, rho, drho, sigma, camAlpha, exc, vxc) + !> Calculates exc, vxc, and vtau for the MGGA-r4SCAN xc-functional. + subroutine getExcVxc_MGGA_r4SCAN(abcissa, dz, dzdr, rho, drho, sigma, tau, exc, vxc, vtau) !> numerical integration abcissas real(dp), intent(in) :: abcissa(:) @@ -743,8 +914,8 @@ subroutine getExcVxc_HYB_B3LYP(abcissa, dz, dzdr, rho, drho, sigma, camAlpha, ex !> contracted gradients of the density real(dp), intent(in), allocatable :: sigma(:,:) - !> CAM alpha parameter - real(dp), intent(in) :: camAlpha + !> kinetic energy density + real(dp), intent(in):: tau(:,:) !> exc energy density on grid real(dp), intent(out) :: exc(:) @@ -752,60 +923,111 @@ subroutine getExcVxc_HYB_B3LYP(abcissa, dz, dzdr, rho, drho, sigma, camAlpha, ex !> xc potential on grid real(dp), intent(out) :: vxc(:,:) + !> orbital-dependent tau potential on grid + real(dp), intent(out) :: vtau(:,:) + !! density in libxc compatible format, i.e. rho/(4pi) real(dp), allocatable :: rhor(:,:) + !! kinetic energy density in libxc compatible format, i.e. tau + real(dp), allocatable :: rtau(:,:) + !! libxc related objects - type(xc_f03_func_t) :: xcfunc_xc + type(xc_f03_func_t) :: xcfunc_x, xcfunc_c !! number of density grid points integer(c_size_t) :: nn - !! exc energy density on grid - real(dp), allocatable :: exc_tmp(:) + !! exchange and correlation energy on grid + real(dp), allocatable :: ex(:), ec(:) !! exchange and correlation potential on grid - real(dp), allocatable :: vxc_tmp(:,:) + real(dp), allocatable :: vx(:,:), vc(:,:) - !! first partial derivative of the energy per unit volume in terms of sigma (x+c) - real(dp), allocatable :: vxcsigma(:,:) + !! first partial derivative of the energy per unit volume in terms of sigma (exchange) + real(dp), allocatable :: vxsigma(:,:) + + !! first partial derivative of the energy per unit volume in terms of sigma (correlation) + real(dp), allocatable :: vcsigma(:,:) + + !! first partial derivative of the energy per unit volume in terms of tau (exchange) + real(dp), allocatable :: vxtau(:,:) + + !! first partial derivative of the energy per unit volume in terms of tau (correlation) + real(dp), allocatable :: vctau(:,:) + + !! laplacian for libxc (dummy) + real(dp), allocatable :: lapl(:,:) + + !! first partial derivative of the energy per unit volume in terms of laplacian (exchange) + !! (dummy) + real(dp), allocatable :: vxlapl(:,:) + + !! first partial derivative of the energy per unit volume in terms of laplacian (correlation) + !! (dummy) + real(dp), allocatable :: vclapl(:,:) nn = size(rho, dim=1) ! divide by 4*pi to catch different normalization of spherical harmonics allocate(rhor(2, nn)) rhor(:,:) = transpose(rho) * rec4pi - allocate(exc_tmp(nn)) - exc_tmp(:) = 0.0_dp + allocate(rtau(2, nn)) + rtau(:,:) = transpose(tau) - allocate(vxc_tmp(2, nn)) - vxc_tmp(:,:) = 0.0_dp + allocate(ex(nn)) + ex(:) = 0.0_dp + allocate(ec(nn)) + ec(:) = 0.0_dp + allocate(vx(2, nn)) + vx(:,:) = 0.0_dp + allocate(vc(2, nn)) + vc(:,:) = 0.0_dp - allocate(vxcsigma(3, nn)) - vxcsigma(:,:) = 0.0_dp + allocate(vxsigma(3, nn)) + vxsigma(:,:) = 0.0_dp + allocate(vcsigma(3, nn)) + vcsigma(:,:) = 0.0_dp - call xc_f03_func_init(xcfunc_xc, XC_HYB_GGA_XC_B3LYP, XC_POLARIZED) - ! Adjustable fraction of Fock-type exchange, otherwise standard parametrization taken from - ! J. Phys. Chem. 1994, 98, 45, 11623-11627; DOI: 10.1021/j100096a001 - call xc_f03_func_set_ext_params(xcfunc_xc, [camAlpha, 0.72_dp, 0.81_dp]) + allocate(vxtau(2, nn)) + vxtau(:,:) = 0.0_dp + allocate(vctau(2, nn)) + vctau(:,:) = 0.0_dp - ! exchange + correlation - call xc_f03_gga_exc_vxc(xcfunc_xc, nn, rhor(1, 1), sigma(1, 1), exc_tmp(1), vxc_tmp(1, 1),& - & vxcsigma(1, 1)) - exc(:) = exc_tmp - vxc(:,:) = transpose(vxc_tmp) + allocate(lapl(2, nn)) + lapl(:,:) = 0.0_dp + allocate(vxlapl(2, nn)) + vxlapl(:,:) = 0.0_dp + allocate(vclapl(2, nn)) + vclapl(:,:) = 0.0_dp - call libxcVxcToInternalVxc(abcissa, dz, dzdr, drho, vxcsigma, vxc) + call xc_f03_func_init(xcfunc_x, XC_MGGA_X_R4SCAN, XC_POLARIZED) + call xc_f03_func_init(xcfunc_c, XC_MGGA_C_R2SCAN, XC_POLARIZED) + + ! Exchange energy and potential + call xc_f03_mgga_exc_vxc(xcfunc_x, nn, rhor(1, 1), sigma(1, 1), lapl(1, 1), rtau(1, 1), ex(1),& + & vx(1, 1), vxsigma(1, 1), vxlapl(1, 1), vxtau(1, 1)) + ! Correlation energy and potential + call xc_f03_mgga_exc_vxc(xcfunc_c, nn, rhor(1, 1), sigma(1, 1), lapl(1, 1), rtau(1, 1), ec(1),& + & vc(1, 1), vcsigma(1, 1), vclapl(1, 1), vctau(1, 1)) + + call zeroOutCpotOfEmptyDensitySpinChannels(rho, vc) + + exc(:) = ex + ec + vxc(:,:) = transpose(vx + vc) + vtau(:,:) = transpose(vxtau + vctau) + + call libxcVxcToInternalVxc(abcissa, dz, dzdr, drho, vxsigma, vcsigma, vxc) ! finalize libxc objects - call xc_f03_func_end(xcfunc_xc) + call xc_f03_func_end(xcfunc_x) + call xc_f03_func_end(xcfunc_c) - end subroutine getExcVxc_HYB_B3LYP + end subroutine getExcVxc_MGGA_r4SCAN - !> Calculates exc and vxc for the CAMY-B3LYP xc-functional. - subroutine getExcVxc_CAMY_B3LYP(abcissa, dz, dzdr, rho, drho, sigma, omega, camAlpha, camBeta,& - & exc, vxc) + !> Calculates exc, vxc, and vtau for the MGGA-TASK xc-functional. + subroutine getExcVxc_MGGA_TASK(abcissa, dz, dzdr, rho, drho, sigma, tau, exc, vxc, vtau) !> numerical integration abcissas real(dp), intent(in) :: abcissa(:) @@ -825,14 +1047,8 @@ subroutine getExcVxc_CAMY_B3LYP(abcissa, dz, dzdr, rho, drho, sigma, omega, camA !> contracted gradients of the density real(dp), intent(in), allocatable :: sigma(:,:) - !> range-separation parameter - real(dp), intent(in) :: omega - - !> CAM alpha parameter - real(dp), intent(in) :: camAlpha - - !> CAM beta parameter - real(dp), intent(in) :: camBeta + !> kinetic energy density + real(dp), intent(in) :: tau(:,:) !> exc energy density on grid real(dp), intent(out) :: exc(:) @@ -840,53 +1056,812 @@ subroutine getExcVxc_CAMY_B3LYP(abcissa, dz, dzdr, rho, drho, sigma, omega, camA !> xc potential on grid real(dp), intent(out) :: vxc(:,:) + !> orbital-dependent tau potential on grid + real(dp), intent(out) :: vtau(:,:) + !! density in libxc compatible format, i.e. rho/(4pi) real(dp), allocatable :: rhor(:,:) - !! exc energy density on grid - real(dp), allocatable :: exc_tmp(:) + !! kinetic energy density + real(dp), allocatable :: rtau(:,:) !! libxc related objects - type(xc_f03_func_t) :: xcfunc_xc + type(xc_f03_func_t) :: xcfunc_x, xcfunc_c !! number of density grid points integer(c_size_t) :: nn + !! exchange and correlation energy on grid + real(dp), allocatable :: ex(:), ec(:) + !! exchange and correlation potential on grid - real(dp), allocatable :: vxc_tmp(:,:) + real(dp), allocatable :: vx(:,:), vc(:,:) - !! first partial derivative of the energy per unit volume in terms of sigma (x+c) - real(dp), allocatable :: vxcsigma(:,:) + !! first partial derivative of the energy per unit volume in terms of sigma (exchange) + real(dp), allocatable :: vxsigma(:,:) + + !! first partial derivative of the energy per unit volume in terms of tau (exchange) + real(dp), allocatable :: vxtau(:,:) + + !! laplacian for libxc (dummy) + real(dp), allocatable :: lapl(:,:) + + !! first partial derivative of the energy per unit volume in terms of laplacian (exchange) + !! (dummy) + real(dp), allocatable :: vxlapl(:,:) nn = size(rho, dim=1) ! divide by 4*pi to catch different normalization of spherical harmonics allocate(rhor(2, nn)) rhor(:,:) = transpose(rho) * rec4pi - allocate(exc_tmp(nn)) - exc_tmp(:) = 0.0_dp + allocate(rtau(2, nn)) + rtau(:,:) = transpose(tau) - allocate(vxc_tmp(2, nn)) - vxc_tmp(:,:) = 0.0_dp + allocate(ex(nn)) + ex(:) = 0.0_dp + allocate(ec(nn)) + ec(:) = 0.0_dp + allocate(vx(2, nn)) + vx(:,:) = 0.0_dp + allocate(vc(2, nn)) + vc(:,:) = 0.0_dp - allocate(vxcsigma(3, nn)) - vxcsigma(:,:) = 0.0_dp + allocate(vxsigma(3, nn)) + vxsigma(:,:) = 0.0_dp - call xc_f03_func_init(xcfunc_xc, XC_HYB_GGA_XC_CAMY_B3LYP, XC_POLARIZED) - call xc_f03_func_set_ext_params(xcfunc_xc, [0.81_dp, camAlpha + camBeta, -camBeta, omega]) + allocate(vxtau(2, nn)) + vxtau(:,:) = 0.0_dp - ! exchange + correlation - call xc_f03_gga_exc_vxc(xcfunc_xc, nn, rhor(1, 1), sigma(1, 1), exc_tmp(1), vxc_tmp(1, 1),& - & vxcsigma(1, 1)) - exc(:) = exc_tmp - vxc(:,:) = transpose(vxc_tmp) + allocate(lapl(2, nn)) + lapl(:,:) = 0.0_dp + allocate(vxlapl(2, nn)) + vxlapl(:,:) = 0.0_dp - call libxcVxcToInternalVxc(abcissa, dz, dzdr, drho, vxcsigma, vxc) + call xc_f03_func_init(xcfunc_x, XC_MGGA_X_TASK, XC_POLARIZED) + call xc_f03_func_init(xcfunc_c, XC_LDA_C_PW, XC_POLARIZED) + + ! Exchange energy and potential + call xc_f03_mgga_exc_vxc(xcfunc_x, nn, rhor(1, 1), sigma(1, 1), lapl(1, 1), rtau(1, 1), ex(1),& + & vx(1, 1), vxsigma(1, 1), vxlapl(1, 1), vxtau(1, 1)) + ! Correlation energy and potential + call xc_f03_lda_exc_vxc(xcfunc_c, nn, rhor(1, 1), ec(1), vc(1, 1)) + call zeroOutCpotOfEmptyDensitySpinChannels(rho, vc) + + exc(:) = ex + ec + vxc(:,:) = transpose(vx + vc) + vtau(:,:) = transpose(vxtau) + + call libxcVxcToInternalVxc(abcissa, dz, dzdr, drho, vxsigma, vxc) ! finalize libxc objects - call xc_f03_func_end(xcfunc_xc) + call xc_f03_func_end(xcfunc_x) + call xc_f03_func_end(xcfunc_c) - end subroutine getExcVxc_CAMY_B3LYP + end subroutine getExcVxc_MGGA_TASK + + + !> Calculates exc, vxc, and vtau for the MGGA-TASK+CC xc-functional. + !! TASK exchange with CC correlation + !! correlation: 10.1063/1.4865942 + !! total functional: 10.1103/PhysRevResearch.4.023061 + subroutine getExcVxc_MGGA_TASK_CC(abcissa, dz, dzdr, rho, drho, sigma, tau, exc, vxc, vtau) + + !> numerical integration abcissas + real(dp), intent(in) :: abcissa(:) + + !> step width in linear coordinates + real(dp), intent(in) :: dz + + !> dz/dr + real(dp), intent(in) :: dzdr(:) + + !> density on grid + real(dp), intent(in) :: rho(:,:) + + !> 1st deriv. of density on grid + real(dp), intent(in) :: drho(:,:) + + !> contracted gradients of the density + real(dp), intent(in), allocatable :: sigma(:,:) + + !> kinetic energy density + real(dp), intent(in):: tau(:,:) + + !> exc energy density on grid + real(dp), intent(out) :: exc(:) + + !> xc potential on grid + real(dp), intent(out) :: vxc(:,:) + + !> orbital-dependent tau potential on grid + real(dp), intent(out) :: vtau(:,:) + + !! density in libxc compatible format, i.e. rho/(4pi) + real(dp), allocatable :: rhor(:,:) + + !! kinetic energy density in libxc compatible format + real(dp), allocatable :: rtau(:,:) + + !! libxc related objects + type(xc_f03_func_t) :: xcfunc_x, xcfunc_c + + !! number of density grid points + integer(c_size_t) :: nn + + !! exchange and correlation energy on grid + real(dp), allocatable :: ex(:), ec(:) + + !! exchange and correlation potential on grid + real(dp), allocatable :: vx(:,:), vc(:,:) + + !! first partial derivative of the energy per unit volume in terms of sigma (exchange) + real(dp), allocatable :: vxsigma(:,:) + + !! first partial derivative of the energy per unit volume in terms of sigma (correlation) + real(dp), allocatable :: vcsigma(:,:) + + !! first partial derivative of the energy per unit volume in terms of tau (exchange) + real(dp), allocatable :: vxtau(:,:) + + !! first partial derivative of the energy per unit volume in terms of tau (correlation) + real(dp), allocatable :: vctau(:,:) + + !! laplacian for libxc (dummy) + real(dp), allocatable :: lapl(:,:) + + !! first partial derivative of the energy per unit volume in terms of laplacian (exchange) + !! (dummy) + real(dp), allocatable :: vxlapl(:,:) + + !! first partial derivative of the energy per unit volume in terms of laplacian (correlation) + !! (dummy) + real(dp), allocatable :: vclapl(:,:) + + nn = size(rho, dim=1) + ! divide by 4*pi to catch different normalization of spherical harmonics + allocate(rhor(2, nn)) + rhor(:,:) = transpose(rho) * rec4pi + + allocate(rtau(2, nn)) + rtau(:,:) = transpose(tau) + + allocate(ex(nn)) + ex(:) = 0.0_dp + allocate(ec(nn)) + ec(:) = 0.0_dp + allocate(vx(2, nn)) + vx(:,:) = 0.0_dp + allocate(vc(2, nn)) + vc(:,:) = 0.0_dp + + allocate(vxsigma(3, nn)) + vxsigma(:,:) = 0.0_dp + allocate(vcsigma(3, nn)) + vcsigma(:,:) = 0.0_dp + + allocate(vxtau(2, nn)) + vxtau(:,:) = 0.0_dp + allocate(vctau(2, nn)) + vctau(:,:) = 0.0_dp + + allocate(lapl(2, nn)) + lapl(:,:) = 0.0_dp + allocate(vxlapl(2, nn)) + vxlapl(:,:) = 0.0_dp + allocate(vclapl(2, nn)) + vclapl(:,:) = 0.0_dp + + call xc_f03_func_init(xcfunc_x, XC_MGGA_X_TASK, XC_POLARIZED) + call xc_f03_func_init(xcfunc_c, XC_MGGA_C_CC, XC_POLARIZED) + + ! Exchange energy and potential + call xc_f03_mgga_exc_vxc(xcfunc_x, nn, rhor(1, 1), sigma(1, 1), lapl(1, 1), rtau(1, 1), ex(1),& + & vx(1, 1), vxsigma(1, 1), vxlapl(1, 1), vxtau(1, 1)) + ! Correlation energy and potential + call xc_f03_mgga_exc_vxc(xcfunc_c, nn, rhor(1, 1), sigma(1, 1), lapl(1, 1), rtau(1, 1), ec(1),& + & vc(1, 1), vcsigma(1, 1), vclapl(1, 1), vctau(1, 1)) + + call zeroOutCpotOfEmptyDensitySpinChannels(rho, vc) + + exc(:) = ex + ec + vxc(:,:) = transpose(vx + vc) + vtau(:,:) = transpose(vxtau + vctau) + + call libxcVxcToInternalVxc(abcissa, dz, dzdr, drho, vxsigma, vcsigma, vxc) + + ! finalize libxc objects + call xc_f03_func_end(xcfunc_x) + call xc_f03_func_end(xcfunc_c) + + end subroutine getExcVxc_MGGA_TASK_CC + + + !> Calculates exc and vxc for the LCY-PBE96 xc-functional. + subroutine getExcVxc_LCY_PBE96(abcissa, dz, dzdr, rho, drho, sigma, omega, exc, vxc) + + !> numerical integration abcissas + real(dp), intent(in) :: abcissa(:) + + !> step width in linear coordinates + real(dp), intent(in) :: dz + + !> dz/dr + real(dp), intent(in) :: dzdr(:) + + !> density on grid + real(dp), intent(in) :: rho(:,:) + + !> 1st deriv. of density on grid + real(dp), intent(in) :: drho(:,:) + + !> contracted gradients of the density + real(dp), intent(in), allocatable :: sigma(:,:) + + !> range-separation parameter + real(dp), intent(in) :: omega + + !> exc energy density on grid + real(dp), intent(out) :: exc(:) + + !> xc potential on grid + real(dp), intent(out) :: vxc(:,:) + + !! density in libxc compatible format, i.e. rho/(4pi) + real(dp), allocatable :: rhor(:,:) + + !! libxc related objects + type(xc_f03_func_t) :: xcfunc_x, xcfunc_c + + !! number of density grid points + integer(c_size_t) :: nn + + !! exchange and correlation energy on grid + real(dp), allocatable :: ex(:), ec(:) + + !! exchange and correlation potential on grid + real(dp), allocatable :: vx(:,:), vc(:,:) + + !! first partial derivative of the energy per unit volume in terms of sigma (exchange) + real(dp), allocatable :: vxsigma(:,:) + + !! first partial derivative of the energy per unit volume in terms of sigma (correlation) + real(dp), allocatable :: vcsigma(:,:) + + nn = size(rho, dim=1) + ! divide by 4*pi to catch different normalization of spherical harmonics + allocate(rhor(2, nn)) + rhor(:,:) = transpose(rho) * rec4pi + + allocate(ex(nn)) + ex(:) = 0.0_dp + allocate(ec(nn)) + ec(:) = 0.0_dp + allocate(vx(2, nn)) + vx(:,:) = 0.0_dp + allocate(vc(2, nn)) + vc(:,:) = 0.0_dp + + allocate(vxsigma(3, nn)) + vxsigma(:,:) = 0.0_dp + allocate(vcsigma(3, nn)) + vcsigma(:,:) = 0.0_dp + + call xc_f03_func_init(xcfunc_x, XC_GGA_X_SFAT_PBE, XC_POLARIZED) + call xc_f03_func_set_ext_params(xcfunc_x, [omega]) + call xc_f03_func_init(xcfunc_c, XC_GGA_C_PBE, XC_POLARIZED) + + ! exchange + call xc_f03_gga_exc_vxc(xcfunc_x, nn, rhor(1, 1), sigma(1, 1), ex(1), vx(1, 1), vxsigma(1, 1)) + + ! correlation + call xc_f03_gga_exc_vxc(xcfunc_c, nn, rhor(1, 1), sigma(1, 1), ec(1), vc(1, 1), vcsigma(1, 1)) + call zeroOutCpotOfEmptyDensitySpinChannels(rho, vc) + + exc(:) = ex + ec + vxc(:,:) = transpose(vx + vc) + + call libxcVxcToInternalVxc(abcissa, dz, dzdr, drho, vxsigma, vcsigma, vxc) + + ! finalize libxc objects + call xc_f03_func_end(xcfunc_x) + call xc_f03_func_end(xcfunc_c) + + end subroutine getExcVxc_LCY_PBE96 + + + !> Calculates exc and vxc for the LCY-BNL xc-functional. + subroutine getExcVxc_LCY_BNL(abcissa, dz, dzdr, rho, drho, sigma, omega, exc, vxc) + + !> numerical integration abcissas + real(dp), intent(in) :: abcissa(:) + + !> step width in linear coordinates + real(dp), intent(in) :: dz + + !> dz/dr + real(dp), intent(in) :: dzdr(:) + + !> density on grid + real(dp), intent(in) :: rho(:,:) + + !> 1st deriv. of density on grid + real(dp), intent(in) :: drho(:,:) + + !> contracted gradients of the density + real(dp), intent(in), allocatable :: sigma(:,:) + + !> range-separation parameter + real(dp), intent(in) :: omega + + !> exc energy density on grid + real(dp), intent(out) :: exc(:) + + !> xc potential on grid + real(dp), intent(out) :: vxc(:,:) + + !! density in libxc compatible format, i.e. rho/(4pi) + real(dp), allocatable :: rhor(:,:) + + !! libxc related objects + type(xc_f03_func_t) :: xcfunc_x, xcfunc_c + + !! number of density grid points + integer(c_size_t) :: nn + + !! exchange and correlation energy on grid + real(dp), allocatable :: ex(:), ec(:) + + !! exchange and correlation potential on grid + real(dp), allocatable :: vx(:,:), vc(:,:) + + !! first partial derivative of the energy per unit volume in terms of sigma (correlation) + real(dp), allocatable :: vcsigma(:,:) + + nn = size(rho, dim=1) + ! divide by 4*pi to catch different normalization of spherical harmonics + allocate(rhor(2, nn)) + rhor(:,:) = transpose(rho) * rec4pi + + allocate(ex(nn)) + ex(:) = 0.0_dp + allocate(ec(nn)) + ec(:) = 0.0_dp + allocate(vx(2, nn)) + vx(:,:) = 0.0_dp + allocate(vc(2, nn)) + vc(:,:) = 0.0_dp + + allocate(vcsigma(3, nn)) + vcsigma(:,:) = 0.0_dp + + call xc_f03_func_init(xcfunc_x, XC_LDA_X_YUKAWA, XC_POLARIZED) + call xc_f03_func_set_ext_params(xcfunc_x, [omega]) + call xc_f03_func_init(xcfunc_c, XC_GGA_C_PBE, XC_POLARIZED) + + ! exchange + call xc_f03_lda_exc_vxc(xcfunc_x, nn, rhor(1, 1), ex(1), vx(1, 1)) + + ! correlation + call xc_f03_gga_exc_vxc(xcfunc_c, nn, rhor(1, 1), sigma(1, 1), ec(1), vc(1, 1), vcsigma(1, 1)) + call zeroOutCpotOfEmptyDensitySpinChannels(rho, vc) + + exc(:) = ex + ec + vxc(:,:) = transpose(vx + vc) + + call libxcVxcToInternalVxc(abcissa, dz, dzdr, drho, vcsigma, vxc) + + ! finalize libxc objects + call xc_f03_func_end(xcfunc_x) + call xc_f03_func_end(xcfunc_c) + + end subroutine getExcVxc_LCY_BNL + + + !> Calculates exc and vxc for the HYB-PBE0 xc-functional. + subroutine getExcVxc_HYB_PBE0(abcissa, dz, dzdr, rho, drho, sigma, camAlpha, exc, vxc) + + !> numerical integration abcissas + real(dp), intent(in) :: abcissa(:) + + !> step width in linear coordinates + real(dp), intent(in) :: dz + + !> dz/dr + real(dp), intent(in) :: dzdr(:) + + !> density on grid + real(dp), intent(in) :: rho(:,:) + + !> 1st deriv. of density on grid + real(dp), intent(in) :: drho(:,:) + + !> contracted gradients of the density + real(dp), intent(in), allocatable :: sigma(:,:) + + !> CAM alpha parameter + real(dp), intent(in) :: camAlpha + + !> exc energy density on grid + real(dp), intent(out) :: exc(:) + + !> xc potential on grid + real(dp), intent(out) :: vxc(:,:) + + !! density in libxc compatible format, i.e. rho/(4pi) + real(dp), allocatable :: rhor(:,:) + + !! libxc related objects + type(xc_f03_func_t) :: xcfunc_x, xcfunc_c + + !! number of density grid points + integer(c_size_t) :: nn + + !! exchange and correlation energy on grid + real(dp), allocatable :: ex(:), ec(:) + + !! exchange and correlation potential on grid + real(dp), allocatable :: vx(:,:), vc(:,:) + + !! first partial derivative of the energy per unit volume in terms of sigma (exchange) + real(dp), allocatable :: vxsigma(:,:) + + !! first partial derivative of the energy per unit volume in terms of sigma (correlation) + real(dp), allocatable :: vcsigma(:,:) + + !! first partial derivative of the energy per unit volume in terms of sigma (x+c) + real(dp), allocatable :: vxcsigma(:,:) + + nn = size(rho, dim=1) + ! divide by 4*pi to catch different normalization of spherical harmonics + allocate(rhor(2, nn)) + rhor(:,:) = transpose(rho) * rec4pi + + allocate(ex(nn)) + ex(:) = 0.0_dp + allocate(ec(nn)) + ec(:) = 0.0_dp + allocate(vx(2, nn)) + vx(:,:) = 0.0_dp + allocate(vc(2, nn)) + vc(:,:) = 0.0_dp + + allocate(vxsigma(3, nn)) + vxsigma(:,:) = 0.0_dp + allocate(vcsigma(3, nn)) + vcsigma(:,:) = 0.0_dp + allocate(vxcsigma(3, nn)) + vxcsigma(:,:) = 0.0_dp + + call xc_f03_func_init(xcfunc_x, XC_GGA_X_PBE, XC_POLARIZED) + call xc_f03_func_init(xcfunc_c, XC_GGA_C_PBE, XC_POLARIZED) + + ! exchange + call xc_f03_gga_exc_vxc(xcfunc_x, nn, rhor(1, 1), sigma(1, 1), ex(1), vx(1, 1), vxsigma(1, 1)) + + ! correlation + call xc_f03_gga_exc_vxc(xcfunc_c, nn, rhor(1, 1), sigma(1, 1), ec(1), vc(1, 1), vcsigma(1, 1)) + call zeroOutCpotOfEmptyDensitySpinChannels(rho, vc) + + ! build PBE0 functional + vxcsigma(:,:) = (1.0_dp - camAlpha) * vxsigma + vcsigma + vxc(:,:) = transpose((1.0_dp - camAlpha) * vx + vc) + exc(:) = (1.0_dp - camAlpha) * ex + ec + + call libxcVxcToInternalVxc(abcissa, dz, dzdr, drho, vxcsigma, vxc) + + ! finalize libxc objects + call xc_f03_func_end(xcfunc_x) + call xc_f03_func_end(xcfunc_c) + + end subroutine getExcVxc_HYB_PBE0 + + + !> Calculates exc and vxc for the HYB-B3LYP xc-functional. + subroutine getExcVxc_HYB_B3LYP(abcissa, dz, dzdr, rho, drho, sigma, camAlpha, exc, vxc) + + !> numerical integration abcissas + real(dp), intent(in) :: abcissa(:) + + !> step width in linear coordinates + real(dp), intent(in) :: dz + + !> dz/dr + real(dp), intent(in) :: dzdr(:) + + !> density on grid + real(dp), intent(in) :: rho(:,:) + + !> 1st deriv. of density on grid + real(dp), intent(in) :: drho(:,:) + + !> contracted gradients of the density + real(dp), intent(in), allocatable :: sigma(:,:) + + !> CAM alpha parameter + real(dp), intent(in) :: camAlpha + + !> exc energy density on grid + real(dp), intent(out) :: exc(:) + + !> xc potential on grid + real(dp), intent(out) :: vxc(:,:) + + !! density in libxc compatible format, i.e. rho/(4pi) + real(dp), allocatable :: rhor(:,:) + + !! libxc related objects + type(xc_f03_func_t) :: xcfunc_xc + + !! number of density grid points + integer(c_size_t) :: nn + + !! exc energy density on grid + real(dp), allocatable :: exc_tmp(:) + + !! exchange and correlation potential on grid + real(dp), allocatable :: vxc_tmp(:,:) + + !! first partial derivative of the energy per unit volume in terms of sigma (x+c) + real(dp), allocatable :: vxcsigma(:,:) + + nn = size(rho, dim=1) + ! divide by 4*pi to catch different normalization of spherical harmonics + allocate(rhor(2, nn)) + rhor(:,:) = transpose(rho) * rec4pi + + allocate(exc_tmp(nn)) + exc_tmp(:) = 0.0_dp + + allocate(vxc_tmp(2, nn)) + vxc_tmp(:,:) = 0.0_dp + + allocate(vxcsigma(3, nn)) + vxcsigma(:,:) = 0.0_dp + + call xc_f03_func_init(xcfunc_xc, XC_HYB_GGA_XC_B3LYP, XC_POLARIZED) + ! Adjustable fraction of Fock-type exchange, otherwise standard parametrization taken from + ! J. Phys. Chem. 1994, 98, 45, 11623-11627; DOI: 10.1021/j100096a001 + call xc_f03_func_set_ext_params(xcfunc_xc, [camAlpha, 0.72_dp, 0.81_dp]) + + ! exchange + correlation + call xc_f03_gga_exc_vxc(xcfunc_xc, nn, rhor(1, 1), sigma(1, 1), exc_tmp(1), vxc_tmp(1, 1),& + & vxcsigma(1, 1)) + exc(:) = exc_tmp + vxc(:,:) = transpose(vxc_tmp) + + call libxcVxcToInternalVxc(abcissa, dz, dzdr, drho, vxcsigma, vxc) + + ! finalize libxc objects + call xc_f03_func_end(xcfunc_xc) + + end subroutine getExcVxc_HYB_B3LYP + + + !> Calculates exc and vxc for the CAMY-B3LYP xc-functional. + subroutine getExcVxc_CAMY_B3LYP(abcissa, dz, dzdr, rho, drho, sigma, omega, camAlpha, camBeta,& + & exc, vxc) + + !> numerical integration abcissas + real(dp), intent(in) :: abcissa(:) + + !> step width in linear coordinates + real(dp), intent(in) :: dz + + !> dz/dr + real(dp), intent(in) :: dzdr(:) + + !> density on grid + real(dp), intent(in) :: rho(:,:) + + !> 1st deriv. of density on grid + real(dp), intent(in) :: drho(:,:) + + !> contracted gradients of the density + real(dp), intent(in), allocatable :: sigma(:,:) + + !> range-separation parameter + real(dp), intent(in) :: omega + + !> CAM alpha parameter + real(dp), intent(in) :: camAlpha + + !> CAM beta parameter + real(dp), intent(in) :: camBeta + + !> exc energy density on grid + real(dp), intent(out) :: exc(:) + + !> xc potential on grid + real(dp), intent(out) :: vxc(:,:) + + !! density in libxc compatible format, i.e. rho/(4pi) + real(dp), allocatable :: rhor(:,:) + + !! exc energy density on grid + real(dp), allocatable :: exc_tmp(:) + + !! libxc related objects + type(xc_f03_func_t) :: xcfunc_xc + + !! number of density grid points + integer(c_size_t) :: nn + + !! exchange and correlation potential on grid + real(dp), allocatable :: vxc_tmp(:,:) + + !! first partial derivative of the energy per unit volume in terms of sigma (x+c) + real(dp), allocatable :: vxcsigma(:,:) + + nn = size(rho, dim=1) + ! divide by 4*pi to catch different normalization of spherical harmonics + allocate(rhor(2, nn)) + rhor(:,:) = transpose(rho) * rec4pi + + allocate(exc_tmp(nn)) + exc_tmp(:) = 0.0_dp + + allocate(vxc_tmp(2, nn)) + vxc_tmp(:,:) = 0.0_dp + + allocate(vxcsigma(3, nn)) + vxcsigma(:,:) = 0.0_dp + + call xc_f03_func_init(xcfunc_xc, XC_HYB_GGA_XC_CAMY_B3LYP, XC_POLARIZED) + call xc_f03_func_set_ext_params(xcfunc_xc, [0.81_dp, camAlpha + camBeta, -camBeta, omega]) + + ! exchange + correlation + call xc_f03_gga_exc_vxc(xcfunc_xc, nn, rhor(1, 1), sigma(1, 1), exc_tmp(1), vxc_tmp(1, 1),& + & vxcsigma(1, 1)) + exc(:) = exc_tmp + vxc(:,:) = transpose(vxc_tmp) + + call libxcVxcToInternalVxc(abcissa, dz, dzdr, drho, vxcsigma, vxc) + + ! finalize libxc objects + call xc_f03_func_end(xcfunc_xc) + + end subroutine getExcVxc_CAMY_B3LYP + + + !> Calculates exc and vxc for the wB97M xc-functional with Yukawa screening. + subroutine getExcVxc_CAMY_MGGA_wB97M(abcissa, dz, dzdr, rho, drho, sigma, tau, omega, camAlpha, camBeta,& + & exc, vxc, vtau) + + !> numerical integration abcissas + real(dp), intent(in) :: abcissa(:) + + !> step width in linear coordinates + real(dp), intent(in) :: dz + + !> dz/dr + real(dp), intent(in) :: dzdr(:) + + !> density on grid + real(dp), intent(in) :: rho(:,:) + + !> 1st deriv. of density on grid + real(dp), intent(in) :: drho(:,:) + + !> contracted gradients of the density + real(dp), intent(in), allocatable :: sigma(:,:) + + !> kinetic energy density + real(dp), intent(in):: tau(:,:) + + !> range-separation parameter + real(dp), intent(in) :: omega + + !> CAM alpha parameter + real(dp), intent(in) :: camAlpha + + !> CAM beta parameter + real(dp), intent(in) :: camBeta + + !> exc energy density on grid + real(dp), intent(out) :: exc(:) + + !> xc potential on grid + real(dp), intent(out) :: vxc(:,:) + + !> orbital-dependent tau potential on grid + real(dp), intent(out) :: vtau(:,:) + + !! density in libxc compatible format, i.e. rho/(4pi) + real(dp), allocatable :: rhor(:,:) + + !! kinetic energy density in libxc compatible format + real(dp), allocatable :: rtau(:,:) + + !! exc energy density on grid + real(dp), allocatable :: exc_tmp(:) + + !! libxc related objects + type(xc_f03_func_t) :: xcfunc_xc + + !! number of density grid points + integer(c_size_t) :: nn + + !! exchange and correlation potential on grid + real(dp), allocatable :: vxc_tmp(:,:) + + !! first partial derivative of the energy per unit volume in terms of sigma (x+c) + real(dp), allocatable :: vxcsigma(:,:) + + !! laplacian for libxc (dummy) + real(dp), allocatable :: lapl(:,:) + + !! first partial derivative of the energy per unit volume in terms of tau + real(dp), allocatable :: vxctau(:,:) + + !! first partial derivative of the energy per unit volume in terms of laplacian (correlation) + !! (dummy) + real(dp), allocatable :: vxclapl(:,:) + + !! original definition of the wB97M-V functional with + !! non-local VV10 correlation: 10.1063/1.4952647 + + !! later version that uses D3-BJ: 10.1021/acs.jctc.8b00842 + + !! Transforming the Hartree-Fock exchange parameter to CAM style: + !! (alpha + beta) E_gl - beta E_sr = E_lr + c_x E_sr + !! E_gl = E_sr + E_lr + !! for c_x = 0.15: + !! -beta = c_x - 1 => beta = 1 - c_x = 0.85 + !! alpha + beta = 1 => alpha = 1 - beta = 0.15 + + !! Values from paper: + !! alpha = 0.15 + !! beta = 0.85 + !! omega = 0.3 (from paper) + + nn = size(rho, dim=1) + ! divide by 4*pi to catch different normalization of spherical harmonics + allocate(rhor(2, nn)) + rhor(:,:) = transpose(rho) * rec4pi + + allocate(rtau(2, nn)) + rtau(:,:) = transpose(tau) + + ! dummy + allocate(lapl(2, nn)) + lapl(:,:) = 0.0_dp + + allocate(exc_tmp(nn)) + exc_tmp(:) = 0.0_dp + + allocate(vxc_tmp(2, nn)) + vxc_tmp(:,:) = 0.0_dp + + allocate(vxcsigma(3, nn)) + vxcsigma(:,:) = 0.0_dp + + allocate(vxctau(2, nn)) + vxctau(:,:) = 0.0_dp + + allocate(vxclapl(2, nn)) + vxclapl(:,:) = 0.0_dp + + call xc_f03_func_init(xcfunc_xc, XC_HYB_MGGA_XC_YWB97M, XC_POLARIZED) + call xc_f03_func_set_ext_params_name(xcfunc_xc, "_alpha", camAlpha + camBeta) + call xc_f03_func_set_ext_params_name(xcfunc_xc, "_beta", -camBeta) + ! cx,00 + alpha = 1 must hold for the UEG limit to be satisfied + call xc_f03_func_set_ext_params_name(xcfunc_xc, "_cx00", camBeta) + call xc_f03_func_set_ext_params_name(xcfunc_xc, "_omega", omega) + + call xc_f03_mgga_exc_vxc(xcfunc_xc, nn, rhor(1, 1), sigma(1, 1), lapl(1, 1), rtau(1, 1), exc_tmp(1),& + & vxc_tmp(1, 1), vxcsigma(1, 1), vxclapl(1, 1), vxctau(1, 1)) + + exc(:) = exc_tmp + vxc(:,:) = transpose(vxc_tmp) + vtau(:,:) = transpose(vxctau) + + call libxcVxcToInternalVxc(abcissa, dz, dzdr, drho, vxcsigma, vxc) + + ! finalize libxc objects + call xc_f03_func_end(xcfunc_xc) + + end subroutine getExcVxc_CAMY_MGGA_wB97M !> Calculates exc and vxc for the CAMY-PBEh xc-functional. diff --git a/slateratom/prog/main.F90 b/slateratom/prog/main.F90 index 9ac24388..db844aa3 100644 --- a/slateratom/prog/main.F90 +++ b/slateratom/prog/main.F90 @@ -15,9 +15,12 @@ program HFAtom use output, only : write_eigvec, write_eigval, write_moments, write_energies,& & write_energies_tagged, write_potentials_file_standard, write_densities_file_standard,& & write_waves_file_standard, write_wave_coeffs_file, cusp_values, writeAveragePotential + use sap, only : sap_start_pot use totalenergy, only : getTotalEnergy, getTotalEnergyZora - use dft, only : check_accuracy, dft_start_pot, density_grid - use utilities, only : check_electron_number, check_convergence + use dft, only : check_accuracy, density_grid, thomas_fermi_start_pot + use utilities, only : check_electron_number, check_convergence_energy,& + & check_convergence_commutator, check_convergence_eigenspectrum,& + & compute_commutator, check_convergence_density use zora_routines, only : scaled_zora use cmdargs, only : parse_command_arguments use common_poisson, only : TBeckeGridParams @@ -79,6 +82,13 @@ program HFAtom if (nuc > 36) num_mesh_points = 1250 if (nuc > 54) num_mesh_points = 1500 + ! meta-GGA functionals sometimes exhibit extraordinary slow + ! convergence w.r.t the number of radial grid points + ! see 10.1063/5.0121187 + if (xcFunctional%isMGGA(xcnr)) then + num_mesh_points = num_mesh_points + 1500 + end if + call echo_input(nuc, max_l, occ_shells, maxiter, scftol, poly_order, num_alpha, alpha, conf_type,& & confInp, occ, num_occ, num_power, num_alphas, xcnr, tZora, num_mesh_points, xalpha_const) @@ -129,12 +139,16 @@ program HFAtom call hfex_lr(kk_lr, max_l, num_alpha, alpha, poly_order, problemsize, omega, grid_params) end if - ! convergence flag - tConverged = .false. + ! convergence flags + tCommutatorConverged = .false. + tEnergyConverged = .false. + tEigenspectrumConverged = .false. - ! DFT start potential + ! Generate guess for DFT; + ! Thomas-Fermi guess potential is currently disabled if (.not. (xcnr == xcFunctional%HF_Exchange)) then - call dft_start_pot(abcissa, num_mesh_points, nuc, vxc) + ! SAP potential + call sap_start_pot(abcissa, nuc, vxc) end if ! build initial fock matrix, core hamiltonian only @@ -146,17 +160,23 @@ program HFAtom ! kinetic energy, nuclear-electron, and confinement matrix elements which are constant during SCF call build_hamiltonian(pMixer, 0, tt, uu, nuc, vconf_matrix, jj, kk, kk_lr, pp, max_l, num_alpha,& - & poly_order, problemsize, xcnr, num_mesh_points, weight, abcissa, vxc, alpha, pot_old,& - & pot_new, tZora, ff, camAlpha, camBeta) + & poly_order, problemsize, xcnr, num_mesh_points, weight, abcissa, vxc, vtau, alpha, pot_old,& + & pot_new, tZora, ff, commutator, camAlpha, camBeta) + + pp_old(:,:,:,:) = pp ! self-consistency cycles write(*,*) 'Energies in Hartree' write(*,*) - write(*,*) ' Iter | Total energy | HF-X energy | XC energy | Change in pot' - write(*,*) '--------------------------------------------------------------------------' + write(*,*) ' Iter | Total energy | P | [F,PS] | E | lambda' + write(*,*) '-------------------------------------------------------------------------------------& + &--------------------' lpScf: do iScf = 1, maxiter pot_old(:,:,:,:) = pot_new + total_ene_old = total_ene + eigval_old(:,:,:) = eigval + pp_old(:,:,:,:) = pp ! diagonalize call diagonalize(max_l, num_alpha, poly_order, ff, ss, cof, eigval) @@ -166,12 +186,15 @@ program HFAtom ! get electron density, derivatives, exc related potentials and energy densities call density_grid(pp, max_l, num_alpha, poly_order, alpha, num_mesh_points, abcissa, dzdr,& - & dz, xcnr, omega, camAlpha, camBeta, rho, drho, ddrho, vxc, exc, xalpha_const) + & dz, xcnr, omega, camAlpha, camBeta, rho, drho, ddrho, tau, vxc, vtau, exc, xalpha_const) ! build Fock matrix and get total energy during SCF - call build_hamiltonian(pMixer, iScf, tt, uu, nuc, vconf_matrix, jj, kk, kk_lr, pp, max_l,& - & num_alpha, poly_order, problemsize, xcnr, num_mesh_points, weight, abcissa, vxc, alpha,& - & pot_old, pot_new, tZora, ff, camAlpha, camBeta) + call build_hamiltonian(pMixer, iScf, tt, uu, nuc, vconf_matrix, jj, kk, kk_lr, pp, max_l, num_alpha,& + & poly_order, problemsize, xcnr, num_mesh_points, weight, abcissa, vxc, vtau, alpha, pot_old,& + & pot_new, tZora, ff, commutator, camAlpha, camBeta) + + ! compute [F,PS] + call compute_commutator(max_l, num_alpha, poly_order, ff, pp, ss, commutator) if (tZora) then call getTotalEnergyZora(tt, uu, nuc, vconf_matrix, jj, kk, kk_lr, pp, max_l, num_alpha,& @@ -185,13 +208,20 @@ program HFAtom & total_ene) end if - call check_convergence(pot_old, pot_new, max_l, problemsize, scftol, iScf, change_max,& - & tConverged) + call check_convergence_commutator(commutator, scftol, iScf, commutator_max,& + & tCommutatorConverged) + call check_convergence_density(pp_old, pp, scftol, iScf, pp_diff, tDensityConverged) + call check_convergence_energy(total_ene_old, total_ene, scftol, iScf, total_ene_diff,& + & tEnergyConverged) + call check_convergence_eigenspectrum(max_l, num_alpha, poly_order, eigval, eigval_old, occ,& + & scftol, iScf, eigval_diff, tEigenspectrumConverged) - write(*, '(I4,2X,3(1X,F16.9),3X,E16.9)') iScf, total_ene, exchange_energy, x_en_2, change_max + ! Print SCF loop information + write(*, '(I4,5X,E16.9,4X,E16.9,4X,E16.9,4X,E16.9,4X,E16.9)') iScf, total_ene, pp_diff,& + & commutator_max, total_ene_diff, eigval_diff ! if self-consistency is reached, exit loop - if (tConverged) exit lpScf + if (tCommutatorConverged .and. tEnergyConverged .and. tEigenspectrumConverged) exit lpScf ! check conservation of number of electrons during SCF call check_electron_number(cof, ss, occ, max_l, num_alpha, poly_order, problemsize) @@ -201,7 +231,7 @@ program HFAtom end do lpScf ! handle non-converged calculations - if (.not. tConverged) then + if (.not. (tEnergyConverged .and. tCommutatorConverged .and. tEigenspectrumConverged)) then call error('SCF is NOT converged, maximal SCF iterations exceeded.') end if @@ -233,7 +263,8 @@ program HFAtom & exchange_energy, x_en_2, conf_energy, total_ene) end if - write(*, '(A,E20.12)') 'Potential Matrix Elements converged to ', change_max + write(*, '(A,E20.12)') '[F,PS] converged to', commutator_max + write(*, '(A,E20.12)') 'Density matrix converged to', pp_diff write(*, '(A)') ' ' if (tZora) then @@ -247,7 +278,7 @@ program HFAtom call write_potentials_file_standard(num_mesh_points, abcissa, weight, vxc, rho, nuc, pp, max_l,& & num_alpha, poly_order, alpha, problemsize) - call write_densities_file_standard(num_mesh_points, abcissa, weight, rho, drho, ddrho) + call write_densities_file_standard(xcnr, num_mesh_points, abcissa, weight, rho, drho, ddrho, tau) ! write wave functions and eventually invert to have positive starting gradient call write_waves_file_standard(num_mesh_points, abcissa, weight, alpha, num_alpha, poly_order,& diff --git a/sys/gnu.cmake b/sys/gnu.cmake index 702b9781..b67835d1 100644 --- a/sys/gnu.cmake +++ b/sys/gnu.cmake @@ -30,8 +30,12 @@ set(Fortran_FLAGS_RELEASE "-O2 -funroll-all-loops" set(Fortran_FLAGS_RELWITHDEBINFO "-g ${Fortran_FLAGS_RELEASE}" CACHE STRING "Fortran compiler flags for Release build") +# set(Fortran_FLAGS_DEBUG + # "-g -Wall -std=f2018 -fcheck=all -frecursive -ffpe-trap=invalid,zero -finit-real=nan -finit-integer='huge(1)'" + # CACHE STRING "Fortran compiler flags for Debug build") + set(Fortran_FLAGS_DEBUG - "-g -Wall -pedantic -std=f2018 -fcheck=all -frecursive -ffpe-trap=invalid,zero -finit-real=nan -finit-integer='huge(1)'" + "-g -Wall -std=f2018 -fcheck=all -frecursive -ffpe-trap=invalid,zero -finit-real=nan -finit-integer='huge(1)'" CACHE STRING "Fortran compiler flags for Debug build") set(Fortran_FLAGS_COVERAGE "-O0 -g --coverage")