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

📄 cdfill.c

📁 一个很好的分子动力学程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------Compile Switches------------------------------------------------------------------------*//*------------------------------------------------------------------------File Includes------------------------------------------------------------------------*/#include <stdio.h>#include <stdlib.h>#include <math.h>#include "cdalloc.h"#include "cdvect.h"#include "iomngr.h"#include "particle.h"#include "cdfill.h"#include  "cdsubs.h"#include "cdhouse.h"#include "strsub.h"#include "parse.h"/*------------------------------------------------------------------------Defines------------------------------------------------------------------------*/#define BOUNDARY_TYPE int#define FILL_NONE 0#define FILL_BOX  1#define FILL_PARALLELPIPED 2#define FILL_CYLINDER 3#define FILL_SPHERE  4/*  Constants representing the three monoclinic directions  */#define U 0#define V 1#define W 2#define NVECT 3#ifndef NSTR#define NSTR 1024#endif#ifndef ANGS#define ANGS 1e-8#endif/*------------------------------------------------------------------------Macros------------------------------------------------------------------------*/#define CLEAN_AFTER_ERROR CleanAfterError();/*Replacement macros when testing program alone from XMD*/#ifdef TEST_DRIVER#define INCREMENT_WARNING#define GETS(STR,N,FILE) fgets(STR,N,stdin)#undef WRITEMSG#undef WRITEVAR#define WRITEMSG \   { \   printf ("In file %s at line %i.\n", __FILE__, __LINE__); \   }#define WRITEVAR(VAR_NAME,VAR_TYPE) \      { \      printf ("FILE %s LINE %i :", __FILE__, __LINE__); \      printf ("%s = ", #VAR_NAME); \      printf (#VAR_TYPE, (VAR_NAME) ); \      printf ("\n"); \      }#else#define INCREMENT_WARNING IncrementNumberOfWarnings();#define GETS(STR,N,FILE) m_gets_list(STR,N,FILE)#endif/*------------------------------------------------------------------------Defines------------------------------------------------------------------------*/typedef double Matrix_t[NDIR][NDIR];/*------------------------------------------------------------------------External Variables------------------------------------------------------------------------*/#ifdef TEST_DRIVERParticle_t *a;LIST       *inlist;#elseextern Particle_t *a;extern LIST       *inlist;#endif/*------------------------------------------------------------------------Module wide variables------------------------------------------------------------------------*/static int      NumPart_m   = 0;static int     *FillType_m = NULL;static Coord_t *FillPart_m = NULL;static BOUNDARY_TYPE BoundaryType_m = FILL_NONE;/*Vector sets describing orientation,repeating cell and re-oriented repeating cell*/static Coord_t Orient_m    [NDIR] = { {1,0,0}, {0,1,0}, {0,0,1} };static Coord_t Cell_m      [NDIR] = { {1e-8,0,0}, {0,1e-8,0}, {0,0,1e-8} };/*Matrix for transforming betweenoriginal ("real") coordinates and re-oriented cell coordinatesNote:  This matrix does necessarily represent rotations.This matrix has units of cm or 1/cm (since they convert betweencoordinates (cm) and "cell vectors" (unitless).*/static Matrix_t RealToOrientCell_m;/*  Alignment of cell origin within space  */static Coord_t  Align_m        = {0.0, 0.0, 0.0};/*Margin to leave between boundary and particles.This space created by scaling the coordinates after theyhave been included within boundary*/static double   Margin_m = 0.0;static BOOLEAN  CellRead_m = FALSE;/*  BOX boundary  */static Coord_t  Box_m[2];/*  CYLINDER boundary  */static double   CylLength_m;static double   CylRadius_m;static Coord_t  CylCenter_m;static Coord_t  CylAxis_m;static Matrix_t CylRealToOrient_m;static Matrix_t CylOrientToReal_m;/*  SPHERE boundary  */static double   SphRadius_m;static double   SphRadiusSqr_m;static Coord_t  SphCenter_m;/*------------------------------------------------------------------------Local Function Prototypes------------------------------------------------------------------------*/static int  FillBoundary     (void);static void ReadCellAngs     (Coord_t [NDIR]);static void AddParticle      (Particle_t *, int, Coord_t);static void GetLimits        (int [NVECT][2], BOUNDARY_TYPE);/*  Box routines  */static void    GetCornersBOX     (Coord_t **, int *);static BOOLEAN IsWithinMarginBOX (Coord_t );static void    GetMarginScaleBOX (Matrix_t, Coord_t );/*  Cylinder routines  */static void    GetCornersCYLINDER     (Coord_t **, int *);static BOOLEAN IsWithinMarginCYLINDER (Coord_t );static void    GetMarginScaleCYLINDER (Matrix_t, Coord_t );/*  Sphere routines  */static void    GetCornersSPHERE     (Coord_t **, int *);static BOOLEAN IsWithinMarginSPHERE (Coord_t );static void    GetMarginScaleSPHERE (Matrix_t, Coord_t );#ifdef TEST_DRIVERvoid PrintVector(Coord_t , char *);void PrintMatrix (Matrix_t m, char *);void PrintCoord (Particle_t *);#endif/*------------------------------------------------------------------------Exported Functions------------------------------------------------------------------------*/                             /*   READ FILL COMMAND *//*Fill specified boundary with particles using defined orientation*/void read_fill (char *instr)   {   int  idir;   int  ivector;   int  jvector;   int  ipart;	int  NumNewPart;   char *BufferPtr;   char BufferStr[NSTR];   char *tokstr = NULL;   double swap;   static Coord_t Zaxis = {0.0, 0.0, 1.0};   tokstr = strhed (&instr);   /*  Align option  */   if (!strcmpi(tokstr,"ALIGN" ))      {      Align_m[X] = ANGS*dblstrf (&instr);      Align_m[Y] = ANGS*dblstrf (&instr);      Align_m[Z] = ANGS*dblstrf (&instr);      }   /*  Read boundary  */   else if (!strcmpi(tokstr,"BOUNDARY" ))      {      tokstr = strhed (&instr);      if (!strcmpi(tokstr, "BOX"))         {         BoundaryType_m = FILL_BOX;         Box_m[0][X] = ANGS*dblstrf(&instr);         Box_m[0][Y] = ANGS*dblstrf(&instr);         Box_m[0][Z] = ANGS*dblstrf(&instr);         Box_m[1][X] = ANGS*dblstrf(&instr);         Box_m[1][Y] = ANGS*dblstrf(&instr);         Box_m[1][Z] = ANGS*dblstrf(&instr);         LOOP (idir, NDIR)            {            if (Box_m[0][idir] > Box_m[1][idir])               {               swap           = Box_m[0][idir];               Box_m[0][idir] = Box_m[1][idir];               Box_m[1][idir] = swap;               }            }         }      else if (!strcmpi(tokstr, "CYLINDER"))         {         BoundaryType_m = FILL_CYLINDER;         CylRadius_m    = ANGS*dblstrf(&instr);         CylLength_m    = ANGS*dblstrf(&instr);         CylCenter_m[X] = ANGS*dblstrf(&instr);         CylCenter_m[Y] = ANGS*dblstrf(&instr);         CylCenter_m[Z] = ANGS*dblstrf(&instr);         CylAxis_m  [X] = dblstrf(&instr);         CylAxis_m  [Y] = dblstrf(&instr);         CylAxis_m  [Z] = dblstrf(&instr);         /*  Orientation matrix rotates cylinder axis into z  */         MakeRotationMatrix(CylRealToOrient_m, Zaxis, CylAxis_m);         InvertMatrix      (CylOrientToReal_m, CylRealToOrient_m);         }      else if (!strcmpi(tokstr, "SPHERE"))         {         BoundaryType_m = FILL_SPHERE;         SphRadius_m    = ANGS*dblstrf(&instr);         SphCenter_m[X] = ANGS*dblstrf(&instr);         SphCenter_m[Y] = ANGS*dblstrf(&instr);         SphCenter_m[Z] = ANGS*dblstrf(&instr);         SphRadiusSqr_m = SphRadius_m * SphRadius_m;         }      else         {         printf ("WARNING:  Unrecognized BOUNDARY option.\n");         INCREMENT_WARNING         }      }   /*  Cell option  */   else if      (!strcmpi(tokstr,"CELL"))      {      ReadCellAngs (Cell_m);      CellRead_m = TRUE;      }   /*  go option  */   else if (!strcmpi(tokstr,"GO" ))      {      /*  If no boundary specified, use repeating box  */      if (FILL_NONE==BoundaryType_m)         {         BoundaryType_m = FILL_BOX;         Box_m[0][X] = 0.0;         Box_m[0][Y] = 0.0;         Box_m[0][Z] = 0.0;         Box_m[1][X] = a->bcur[X];         Box_m[1][Y] = a->bcur[Y];         Box_m[1][Z] = a->bcur[Z];         }      /*  Test for fill prepared  */      if      (      0==NumPart_m ||      FILL_NONE==BoundaryType_m      )         {         printf ("ERROR:  Cannot perform fill without first calling");         printf (" FILL PARTICLE.\n");         CLEAN_AFTER_ERROR         }      /*  Do actual fill  */      NumNewPart = 			FillBoundary();		printf ("***   Number new particles  %i\n", NumNewPart);		/*  Make neighbor list as invalid  */		a->InvalidNeighborList = TRUE;      }	/*  Margin option  */   else if (!strcmpi(tokstr,"MARGIN" ))		{		Margin_m = ANGS*dblstrf(&instr);		if (Margin_m < 0.0)			{			printf ("ERROR:  FILL MARGIN (%le) is less than zero.\n",				Margin_m/ANGS);			CleanAfterError();			}		}   /*  Orient option  */   else if (!strcmpi(tokstr,"ORIENT" ))      {      /*  Read vector  */      LOOP (ivector, NVECT)      LOOP (idir,  NDIR )         Orient_m[ivector][idir] = dblstrf(&instr);      /*  Normalized orientation vectors  */      Normalize(Orient_m[U]);      Normalize(Orient_m[V]);      Normalize(Orient_m[W]);      /*  Insure that orientation vectors are orthogonal  */      LOOP (ivector, NDIR)      LOOP (jvector, ivector)         {         if (fabs(GetDot(Orient_m[ivector], Orient_m[jvector])) > 1e-6)            {            printf               (               "ERROR:  Orientation vectors %i and %i are not orthogonal\n",               jvector+1,               ivector+1               );            CLEAN_AFTER_ERROR            }         }      }   /*  particle option  */   else if (!strcmpi(tokstr,"PARTICLE" ))      {      /*  Free previous allocation  */      FREE(FillType_m)      FREE(FillPart_m)      /*  Allocate particles  */      NumPart_m = intstrf (&instr);      ALLOCATE (FillType_m, int,     NumPart_m)      ALLOCATE (FillPart_m, Coord_t, NumPart_m);      /*  Read particles  */      LOOP (ipart, NumPart_m)         {         GETS ( BufferStr, NSTR, inlist);         BufferPtr = BufferStr;         FillType_m[ipart]    = intstrf (&BufferPtr)-1;         FillPart_m[ipart][X] = ANGS*dblstrf (&BufferPtr);         FillPart_m[ipart][Y] = ANGS*dblstrf (&BufferPtr);         FillPart_m[ipart][Z] = ANGS*dblstrf (&BufferPtr);         }      }   else      {      printf ("Warning:  Unrecognized option to FILL command.\n");      INCREMENT_WARNING      }   }/*Read and store cell vectors in format  x1 y1 z1  x2 y2 z2  x3 y3 z3*/static void ReadCellAngs (Matrix_t Matrix)   {   char  BufferStr[NSTR];   char *BufferPtr = NULL;   int   ivector;   LOOP (ivector, NDIR)      {      GETS (BufferStr, NSTR, inlist);      BufferPtr = BufferStr;      Matrix[ivector][X] = ANGS*dblstrf (&BufferPtr);      Matrix[ivector][Y] = ANGS*dblstrf (&BufferPtr);      Matrix[ivector][Z] = ANGS*dblstrf (&BufferPtr);      }   }/*Fill boundary with particles.Set all new particles to SELECTED.Unselect all previous particles*/static int FillBoundary (void)   {   int ipart;   int idir;   int ivect;   int jvect;   int kvect;   int Limits[NVECT][2];	int NumNewPart = 0;   BOOLEAN UseThisPoint = FALSE;   Coord_t Point;   Coord_t  Decompose;   Matrix_t ScaleMatrix;	int      CellMultiple;   Coord_t  CenterPoint;   Coord_t  ScaledPoint;	Matrix_t OrientToReal;	Matrix_t RealToOrient;	Coord_t  RealCell[NDIR];   Coord_t  *RealFillPart = NULL;	/*  Remove selection from all current particles  */	LOOP (ipart, a->np)		REMOVE_SELECT(ipart)   /*   Calculate matrix for converting new orientation to real coordinates   NOTE: Since Orient_m is unitary matrix (rotation matrix), can         invert it simply by transposing it.   */   CopyMatrix       (OrientToReal,  Orient_m);   CopyMatrix       (RealToOrient,  OrientToReal);   TransposeMatrix  (RealToOrient);   /*  Calculate re-oriented cell directions  */	MatrixVectorMultN(RealCell, OrientToReal, Cell_m, 3);   /*  Calculate particles in real space */   ALLOCATE (RealFillPart, Coord_t, NumPart_m)	MatrixVectorMultN		(RealFillPart, OrientToReal, FillPart_m, NumPart_m);	/*	Calculate matrix that converts real space coordinate to    coordinates expressed as combination of real space cell vectors	*/	InvertMatrix    (RealToOrientCell_m, RealCell);	TransposeMatrix (RealToOrientCell_m);	   /*   Linearly translate alignment point by cell vectors   so that it is within a repeating cell centered at   the origin.      The resulting displacement from the origin   will be added to all atoms which fill the boundary.   */   MatrixVectorMult (Decompose, RealToOrientCell_m, Align_m);   LOOP (ivect, NVECT)      {      CellMultiple = fabs(Decompose[ivect])+0.5;      if (Decompose[ivect] < 0)         CellMultiple = -CellMultiple;      LOOP (idir, NDIR)         {         Align_m[idir] -= CellMultiple * RealCell[ivect][idir];         }      }   /*  Get lower and upper cell vector counts  */   GetLimits (Limits, BoundaryType_m);   /*   Get values for scaling atoms withing margin distance of boundary surface   */   if (BoundaryType_m==FILL_BOX)      {      GetMarginScaleBOX (ScaleMatrix, CenterPoint);      }   else if (BoundaryType_m==FILL_CYLINDER)      {      GetMarginScaleCYLINDER (ScaleMatrix, CenterPoint);      }   else if (BoundaryType_m==FILL_SPHERE)      {      GetMarginScaleSPHERE (ScaleMatrix, CenterPoint);      }   /*  Sum over vector limits  */	NumNewPart = 0;   for (ivect=Limits[U][0]; ivect <=Limits[U][1]; ivect++)   for (jvect=Limits[V][0]; jvect <=Limits[V][1]; jvect++)   for (kvect=Limits[W][0]; kvect <=Limits[W][1]; kvect++)      {      /*  Sum over individual particles  */      LOOP (ipart, NumPart_m)         {         /*  Loop over directions  */         LOOP (idir, NDIR)            {            Point[idir] =               RealFillPart[ipart][idir] +               ivect * RealCell[U][idir] +               jvect * RealCell[V][idir] +               kvect * RealCell[W][idir] +               Align_m[idir] -               CenterPoint[idir];            }

⌨️ 快捷键说明

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