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

📄 cdfunc.c

📁 一个很好的分子动力学程序
💻 C
📖 第 1 页 / 共 2 页
字号:
			a[ -2] = 2.0*a[ -1] - a[0];			break;		case FUNC_EXTRAP_CONST_VALUE:			a[ -1] = a[  0];			a[ -2] = a[  0];			break;		case FUNC_EXTRAP_ZERO:			a[ -1] = 0.0;			a[ -2] = 0.0;			break;		default:			/*  Assertion will print error if this is reached  */			ASSERT(0)		}	n = F->NumCoeff+1;   switch (GET_EXT_EXTRAP(F->BoundaryType))      {      case FUNC_EXTRAP_CONST_SLOPE:         a[n  ] = 2.0*a[n-1] - a[n-2];         a[n+1] = 2.0*a[n  ] - a[n-1];         break;      case FUNC_EXTRAP_CONST_VALUE:         a[n  ] = a[n-1];			a[n+1] = a[n-1];         break;      case FUNC_EXTRAP_ZERO:         a[n  ] = 0.0;         a[n+1] = 0.0;         break;      default:			/*  Assertion will print error if this is reached  */			ASSERT(0)		}	/*   INTERPOLATE DERIVATIVES  */	p = F->Coeff;   LOOP (k, F->NumCoeff)      {      i = k-2;      j = k-1;      l = k+1;      m = k+2;      n = k+3;      *p++ = (                      a[k]                            )   ;      *p++ = ( 2*a[i] -16*a[j]           + 16*a[l] - 2*a[m]         )/24;      *p++ = (  -a[i] +16*a[j] - 30*a[k] + 16*a[l] -   a[m]         )/24;      *p++ = (-9*a[i] +39*a[j] - 70*a[k] + 66*a[l] -33*a[m] + 7*a[n])/24;      *p++ = (13*a[i] -64*a[j] +126*a[k] -124*a[l] +61*a[m] -12*a[n])/24;      *p++ = (-5*a[i] +25*a[j] - 50*a[k] + 50*a[l] -25*a[m] + 5*a[n])/24;      }	/*  Calculate slope at endpoints  */	i = 6*0;	p = F->Coeff;	F->InteriorValue = a[0];	F->InteriorSlope = F->TableFactor* p[i+1];	i = 6*F->NumCoeff;	F->ExteriorValue = a[F->NumCoeff];	F->ExteriorSlope = F->TableFactor*		(p[i+1] + 2*p[i+2] + 3*p[i+3] + 4*p[i+4] + 5*p[i+5]);   }/*Read Polynomial Function from input*/static void ReadPolyFunction(Function_t *F,char       *InputStr,LIST       *InList)   {   char ReadBuffer[NBUFF];   char *TempStr;   BOOLEAN EndOfFile;   int iread;   int icoeff;   F->Power1         = INTSTRF (&InputStr);   F->Power2         = INTSTRF (&InputStr);   F->x0             = DBLSTRF (&InputStr);   F->ExteriorCutoff = DBLSTRF (&InputStr);   F->InteriorCutoff = 0.0;   F->NumCoeff       = F->Power2 - F->Power1 + 1;   F->f0             = (FunctionCall_t *) GetPolyValue;   F->f1             = (FunctionCall_t *) GetPolyDeriv;   /*  Allocate space for coefficients  */	if (F->Coeff!=NULL)		FREE(F->Coeff)   ALLOCATE (F->Coeff, double, 2*F->NumCoeff)   /*  Read coefficients  */   iread = 0;   ReadBuffer[0] = '\0';   TempStr          = ReadBuffer;   EndOfFile      = FALSE;   while (iread<F->NumCoeff && !EndOfFile)      {      /*  Read new line if current line is blank  */      if (IsBlank(TempStr))         {         EndOfFile =            (NULL==FGETS(ReadBuffer, NBUFF, InList));         TempStr = ReadBuffer;         }      /*  Premature end-of-file, end program  */      if (EndOfFile)         {         printf ("ERROR: File ends before coefficients were found\n");         CleanAfterError();         }      F->Coeff[iread] = DBLSTRF (&TempStr);      iread++;      }   /*  Calcualte coefficients for first derivative  */   LOOP (icoeff, F->NumCoeff)      {      F->Coeff [icoeff + F->NumCoeff] =         ( icoeff + F->Power1 ) * F->Coeff[icoeff];      }	/*  Calculate slope at endpoints  */	F->InteriorValue = GetPolyValue(F, F->InteriorCutoff);	F->InteriorSlope = GetPolyDeriv(F, F->InteriorCutoff);	F->ExteriorValue = GetPolyValue(F, F->ExteriorCutoff);	F->ExteriorSlope = GetPolyDeriv(F, F->ExteriorCutoff);   }static void ScaleTableFunction (Function_t *F, double Scale, int ScaleType)   {   int iseg;   int ipow;   int icoeff;	/*   	To scale function input, 	only need to scale factor for converting argument units   to table units (table nodes spaced a unit distance apart)	*/   if (FUNC_INPUT==ScaleType)      {      F->TableFactor /= Scale;      }   else if (FUNC_OUTPUT==ScaleType)      {      LOOP (icoeff, 6*F->NumCoeff)         F->Coeff[icoeff] *= Scale;      }   }static void ScalePolyFunction (Function_t *F, double Scale, int ScaleType)   {   int icoeff;   /*   Scale function input   */   if (FUNC_INPUT==ScaleType)      {      /*  Scale polynomial origin  */      F->x0             *= Scale;      /*  Scale DERIV=0 Coefficients  */      LOOP (icoeff, F->NumCoeff)         {         F->Coeff[icoeff] /= pow(Scale, F->Power1+icoeff);         }      /*  Scale DERIV=1 Coefficients  */      LOOP (icoeff, F->NumCoeff)         {         F->Coeff[icoeff+F->NumCoeff]            /= pow(Scale, F->Power1+icoeff);         }      ASSERT (F->Power1+F->NumCoeff==F->Power2)      }   /*   Scale function output   */   else if (FUNC_OUTPUT==ScaleType)      {      LOOP (icoeff, 2*F->NumCoeff)         {         F->Coeff[icoeff] *=Scale;         }      }   /*   ERROR   */   else      {      printf ("INTERNAL ERROR:  Invalid scale flag.\n");      CleanAfterError();      }   }static double GetTableValue (Function_t *F, double x)   {   double *p;   double q;   int    m;   if (NULL==F->Coeff)      return 0.0;   if (x<F->InteriorCutoff || x>=F->ExteriorCutoff)      return OutOfRangeValue (F, x, DERIV_ZERO);   m  = (q = F->TableFactor * (x - F->InteriorCutoff) );   q -= m;   /*   This should happen because out of range values are handled above   */   ASSERT(m<F->NumCoeff)   /*  Point to m'th item (6 numbers per item)  */   p = &(F->Coeff[6*m]);   /*  Interpolate  */   return p[0] + (p[1] + (p[2] + (p[3] + (p[4] + p[5]*q)*q)*q)*q)*q;   }static double GetTableDeriv (Function_t *F, double x)   {   int m;   double q;   double *p;	if (F->Coeff==NULL)      return 0.0;   if (x<F->InteriorCutoff || x>=F->ExteriorCutoff)      return OutOfRangeValue (F, x, DERIV_ONE);   m  = (q = F->TableFactor * (x - F->InteriorCutoff) );   q -= m;   /*   This should happen because out of range values are handled above   */   ASSERT(m<F->NumCoeff)   /*  Point to m'th item (6 numbers per item)  */   p = &(F->Coeff[6*m]);   /*  Interpolate  */   return      F->TableFactor *      ( p[1] + (2*p[2] + (3*p[3] + (4*p[4] + 5*p[5]*q)*q)*q)*q );   }static double GetPolyValue (Function_t *F, double x)   {   double dx;   double *p;   if (x<=F->InteriorCutoff || x>=F->ExteriorCutoff)      return OutOfRangeValue (F, x, DERIV_ZERO);   dx = x - F->x0;   p  = F->Coeff;   if (0==F->Power1)      return poly (dx, F->NumCoeff-1, p);   else if (1==F->Power1)      return dx * poly (dx, F->NumCoeff-1, p);   else if (2==F->Power1)      return dx * dx * poly (dx, F->NumCoeff-1, p);   else      return pow (dx, F->Power1) * poly (dx, F->NumCoeff-1, p);   }static double GetPolyDeriv (Function_t *F, double x)   {   double dx;   double *p;   if (x<F->InteriorCutoff || x>F->ExteriorCutoff)      return OutOfRangeValue (F, x, DERIV_ONE);   dx = x - F->x0;   p  = F->Coeff+F->NumCoeff;   if (0==F->Power1)      return poly (dx, F->NumCoeff-2, p+1);   else if (1==F->Power1)      return poly (dx, F->NumCoeff-1, p);   else if (2==F->Power1)      return  dx * poly (dx, F->NumCoeff-1, p);   else      return pow (dx, F->Power1-1) * poly (dx, F->NumCoeff-1, p);   }static double GetNullValue (Function_t *F, double x)	{	return 0.0;	}static double OutOfRangeValue (Function_t *F, double x, int Deriv)   {   double dx;   /*   Argument less than interior cutoff   Do this first because POLY only has this kind of cutoff   */   if (x <= F->InteriorCutoff)      {      switch (GET_INT_BOUND(F->BoundaryType))         {         case FUNC_BOUND_CONST_SLOPE:            if (DERIV_ONE==Deriv)               {               return F->InteriorSlope;               }            else if (DERIV_ZERO==Deriv)               {               dx  = x - F->InteriorCutoff;               return F->InteriorValue + F->InteriorSlope * dx;               }				break;			case FUNC_BOUND_CONST_VALUE:				if (DERIV_ONE==Deriv)					{					return 0.0;					}				else					{					return F->InteriorValue;					}			case FUNC_BOUND_ZERO:				return 0.0;			case FUNC_BOUND_OUTOFRANGE:				ERROR_PREFIX				printf ("Function within interior cutoff.\n");				CleanAfterError();				break;			}      ASSERT(0)      }   /*  Argument exceeds exterior cutoff  */   if (x >= F->ExteriorCutoff)      {      switch (GET_EXT_BOUND(F->BoundaryType))         {         case FUNC_BOUND_CONST_SLOPE:            if (DERIV_ONE==Deriv)               {               return F->ExteriorSlope;               }            else if (DERIV_ZERO==Deriv)               {               dx  = x - F->ExteriorCutoff;               return F->ExteriorValue + F->ExteriorSlope * dx;               }            break;         case FUNC_BOUND_CONST_VALUE:            if (DERIV_ONE==Deriv)               {               return F->ExteriorValue;               }            else               {               return 0.0;               }			case FUNC_BOUND_ZERO:            return 0.0;			case FUNC_BOUND_OUTOFRANGE:				ERROR_PREFIX				printf ("Function within exterior cutoff.\n");            CleanAfterError();            break;         }		ASSERT(0)      }   /*  Execution should never reach here  */	ASSERT (0)   return 0.0;   }double poly (double x, int n, double *p)   {   double ReturnValue = p[n];   while (n>0)      {      n--;      ReturnValue = ReturnValue * x + p[n];      }   return ReturnValue;   }/*************************************************************************Local Function for Stand-Alone Test Version*************************************************************************/#ifdef LOCALBOOLEAN IsWhiteSpace (char InChar)   {   return      InChar==' '  ||      InChar=='\t' ||      InChar=='\r' ||      InChar=='\n';   }BOOLEAN IsBlank (char *String)   {   while (IsWhiteSpace(*String))      String++;   return (*String=='\0');   }char *strhed (char **String)   {   char *TokenStr;   /*  Find first non-whitespace  */   while (IsWhiteSpace(**String))      {      (*String)++;      }   TokenStr = *String;   /*  Find Next Whitespace Character  */   while (!IsWhiteSpace(**String) && **String!='\0')      {      (*String)++;      }   /*  If end of line, return  */   if (**String=='\0')      {      return TokenStr;      }   /*  Mark as end of string, find next non-whitespace  */   (**String)='\0';   (*String)++;   while (IsWhiteSpace(**String))      (*String)++;   return TokenStr;   }double dblstr (char **String)   {   char *TokenStr;   TokenStr = strhed (String);   return atof (TokenStr);   }double intstr (char **String)   {   return atoi (strhed(String));   }void CleanAfterError(void)   {   exit(0);   }BOOLEAN IsFirstToken(char *Token, char *String)	{	int Len;	while (IsWhiteSpace(*String))		String++;	return 		!STRNCMPI(Token,String,Len) && 		(IsWhiteSpace(String[Len]) || String[Len]=='\0');	}/*************************************************************************Test Driver*************************************************************************/int main ()   {   Function_t *F = NULL;   int BoundaryType;   char Buffer[1024];   char *InStr  = NULL;   char *TokStr = NULL;   char *String = "POLY 2 2 4 4";   double Cutoff;   int i;   double x;   strcpy (Buffer, String);   inlist = stdin;	/*  Intialize Function  */	F = FUNC_CreateNullFunction();   F->BoundaryType =      MAKE_BOUND_FLAG         (         FUNC_EXTRAP_CONST_SLOPE, FUNC_BOUND_OUTOFRANGE,         FUNC_EXTRAP_ZERO,        FUNC_BOUND_ZERO         );   fgets (Buffer, 1024, stdin);   InStr = Buffer;   TokStr = strhed (&InStr);   FUNC_ParseRead (F, InStr);   Cutoff = FUNC_GetCutoff(F);   LOOP (i, 101)      {      x = F->InteriorCutoff + 0.01*i*(F->ExteriorCutoff-F->InteriorCutoff);      printf ("%le %le %le\n", x, F->f0(F,x), F->f1(F,x));      }/*  Write out values  */#if 0   printf ("x f(x): %le %le\n", 0.0, FUNC_GetValue(F,0.0));   printf ("x f(x): %le %le\n", 0.5, FUNC_GetValue(F,0.5));   printf ("x f(x): %le %le\n", 2.0, FUNC_GetValue(F,2.0));   printf ("x f(x): %le %le\n", 4.0, FUNC_GetValue(F,4.0));   printf ("x f0(x): %le %le\n", 0.0, F->f0(F,0.0));   printf ("x f1(x): %le %le\n", 0.0, F->f1(F,0.0));#endif   return 0;   }#endif

⌨️ 快捷键说明

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