⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fjt.cc

📁 大型并行量子化学软件;支持密度泛函(DFT)。可以进行各种量子化学计算。支持CHARMM并行计算。非常具有应用价值。
💻 CC
字号:
//// fjt.cc//// Copyright (C) 2001 Edward Valeev//// Author: Edward Valeev <edward.valeev@chemistry.gatech.edu>// Maintainer: EV//// This file is part of the SC Toolkit.//// The SC Toolkit is free software; you can redistribute it and/or modify// it under the terms of the GNU Library General Public License as published by// the Free Software Foundation; either version 2, or (at your option)// any later version.//// The SC Toolkit is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU Library General Public License for more details.//// You should have received a copy of the GNU Library General Public License// along with the SC Toolkit; see the file COPYING.LIB.  If not, write to// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.//// The U.S. Government is granted a limited license as per AL 91-7.//#ifdef __GNUG__#pragma implementation#endif/* These routines are based on the gamfun program of * Trygve Ulf Helgaker (fall 1984) * and calculates the incomplete gamma function as * described by McMurchie & Davidson, J. Comp. Phys. 26 (1978) 218. * The original routine computed the function for maximum j = 20. */#include <stdlib.h>#include <math.h>#include <iostream>#include <chemistry/qc/cints/fjt.h>using namespace std;/*------------------------------------------------------  Initialize Taylor_Fm_Eval object (computes incomplete  gamma function via Taylor interpolation) ------------------------------------------------------*/Taylor_Fjt_Eval::Taylor_Fjt_Eval(unsigned int mmax, double accuracy){  int i, m;  int T_idx;  double T, T_new;  double egamma, func, dfuncdT;  double term, sum, denom, rel_error;  cutoff = epsilon;  /*---------------------------------------    We are doing Taylor interpolation with    n=TAYLOR_ORDER terms here:    error <= delT^n/(n+1)!   ---------------------------------------*/  order_interp = TAYLOR_ORDER;  delT = 2.0*pow(cutoff*fac[order_interp+1],			1.0/order_interp);  max_m = mmax + order_interp - 1;  /*------------------------------------------------     Check if Taylor_Fm_Eval has been initialized with     the same mmax before:     2) yes  - re-initialize again     3) no - initialize   ------------------------------------------------*/  if (grid != NULL || T_crit != NULL) {    free_Taylor_Fm_Eval();  }    T_crit = new double[max_m + 1];   /*--- m=0 is included! ---*/  max_T = 0;  /*--- Figure out T_crit for each m and put into the T_crit ---*/  for(m=max_m;m>=0;m--) {    /*------------------------------------------      Newton-Raphson method to solve      T^{m-0.5}*exp(-T) = epsilon*Gamma(m+0.5)      The solution is the max T for which to do      the interpolation     ------------------------------------------*/    T = -log(epsilon);    egamma = epsilon*sqrt(M_PI)*df[2*m]/pow(2,m);    T_new = T;    do {      T = T_new;      func = pow(T,m-0.5) * exp(-T) - egamma;      dfuncdT = ((m-0.5) * pow(T,m-1.5) - pow(T,m-0.5)) * exp(-T);      if (dfuncdT >= 0.0) {	T_new *= 2.5;	continue;      }      T_new = T - func/dfuncdT;      if ( T_new <= 0.0 ) {	T_new = T / 2.0;      }    } while (fabs(func/egamma) >= SOFT_ZERO);    T_crit[m] = T_new;    T_idx = floor(T_new/delT);    if (T_idx > max_T)      max_T = T_idx;  }  /*-------------------------------------------------------    Tabulate the gamma function from t=delT to T_crit[m]:    1) include T=0 though the table is empty for T=0 since       Fm(0) is simple to compute    2) modified MacLaurin series converges fastest for       the largest m -> use it to compute Fmmax(T)       see JPC 94, 5564 (1990).    3) then either use the series to compute the rest       of the row or maybe use downward recursion   -------------------------------------------------------*/  grid = block_matrix(max_T+1,max_m+1);  /*--- do the mmax first ---*/  for(m=0;m<=max_m;m++)  for(T_idx = max_T;      T_idx >= 0;      T_idx--) {    T = T_idx*delT;    denom = (m+0.5);    term = 0.5*exp(-T)/denom;    sum = term;    do {      denom += 1.0;      term *= T/denom;      sum += term;      rel_error = term/sum;    } while (rel_error >= cutoff);    grid[T_idx][m] = sum;  }}Taylor_Fjt_Eval::~Taylor_Fm_Eval(){  delete[] T_crit;  T_crit = NULL;  free_block(grid);  grid = NULL;}/* Using the tabulated incomplete gamma function in gtable, compute * the incomplete gamma function for a particular wval for all 0<=j<=J. * The result is placed in the global intermediate int_fjttable. */double *Taylor_Fjt_Eval::compute_Fjt(double T, unsigned int l){    int m;  unsigned int T_ind;  double T_crit, two_T, exp_mT, h, F_m, F_mp1;  double *F_row;#define STATIC_OO2NP1#define STATIC_OON#include "static.h"  T_crit = Taylor_Fm_Eval.T_crit[l];  two_T = 2.0*T;  /*------------------------    First compute Fl(T) ...   ------------------------*/  if (T > T_crit) {    /*--- Asymptotic formula ---*/    F[l] = df[2*l]*sqrt(M_PI/2)/pow(two_T,l+0.5);  }  else {    /*--- Taylor interpolation ---*/    T_ind = floor(0.5+T/Taylor_Fm_Eval.delT);    h = T_ind*Taylor_Fm_Eval.delT - T;    F_row = Taylor_Fm_Eval.grid[T_ind] + l;    F[l] =          F_row[0] +	         h*(F_row[1] +	  oon[2]*h*(F_row[2] +	  oon[3]*h*(F_row[3] +	  oon[4]*h*(F_row[4] +	  oon[5]*h*(F_row[5])))));  }  /*------------------------------------    And then do downward recursion in m   ------------------------------------*/  if (l > 0) {    F_mp1 = F[l];    exp_mT = exp(-T);    for(m=l-1;m>=0;m--) {      F_m = (exp_mT + two_T*F_mp1)*oo2np1[m];      F[m] = F_m;      F_mp1 = F_m;    }  }  return Fjt_buffer;}/////////////////////////////////////////////////////////////////////////////// Local Variables:// mode: c++// c-file-style: "CLJ-CONDENSED"// End:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -