📄 cdselect.c
字号:
/*************************************************************************Include Files*************************************************************************/#include <stdio.h>#include <math.h>#include <stdlib.h>#include "iomngr.h"#include "strsub.h"#include "parse.h"#include "sortsub.h"#include "particle.h"#include "cdhouse.h"#include "cdsubs.h"#ifdef __TURBO__#include <alloc.h>#endif/*************************************************************************Global Variables*************************************************************************/extern Particle_t *a;extern Simulation_t *s;extern FILE *out;extern LIST *inlist;/*************************************************************************Local Function Prototypes*************************************************************************/void nearneighbor (double, double, double, BYTE *, int, BOOLEAN); /*************************************************************************Exported Functions*************************************************************************/void read_select (char *instr) { typedef enum { _AND, _OR, _NOT, _XOR, _ONLY } loptype; loptype lop; char *tokstr; BYTE *tsel = NULL; BYTE PrevSel; double x1,y1,z1; double x2,y2,z2; double xc,yc,zc; double xdel, ydel, zdel; double nx,ny,nz; double umin,umax,utmp, dbox; double dot1, dot2, t; double lo; double hi; double Value; int idir; int i,n,n1,n2,nskip,u; int ntag, ntype, iset; double (*c)[NDIR] = (double (*)[NDIR]) a->cur; int np = a->np; BOOLEAN AtomFound; BOOLEAN NoNeighbors; BOOLEAN OmitPoint; BOOLEAN UseAbsoluteValue; BOOLEAN UseMagnitude; int index; /* GET FIRST TOKEN */ tokstr = strhed (&instr); /* Check for KEEP option */ if (!strcmpi("KEEP",tokstr)) { tokstr = strhed (&instr); if (!strcmpi("ON",tokstr)) a->selkeep = TRUE; else if (!strcmpi("OFF",tokstr)) a->selkeep = FALSE; else { IncrementNumberOfWarnings(); printf ("WARNING: Unknown option (%s) to SELECT KEEP\n", tokstr); } return; } /* Check for non-zero number of particles */ if (a->np==0) return; /* Allocate arrays */ ALLOCATE (tsel, BYTE, a->np) CHECK_HEAP /* INITIALIZE tsel */ LOOP (i, a->np) tsel[i] = FALSE; CHECK_HEAP /* PARSE LOGICAL OPERATION */ if (!strcmpi(tokstr,"AND" )) lop = _AND ; else if (!strcmpi(tokstr,"OR" )) lop = _OR ; else if (!strcmpi(tokstr,"NOT" )) lop = _NOT ; else if (!strcmpi(tokstr,"XOR" )) lop = _XOR ; else lop = _ONLY; CHECK_HEAP /* IF NOT DEFAULT lop PARSE COMMAND OPTION */ if (lop!=_ONLY) tokstr = strhed (&instr); CHECK_HEAP /* PERFORM COMMAND OPTION */ if (!strcmpi(tokstr,"ALL")) { LOOP (i, a->np) tsel[i] = TRUE; } /* PERFORM COMMAND OPTION */ else if (!strcmpi(tokstr,"NONE")) { LOOP (i, a->np) tsel[i] = FALSE; } else if (!strcmpi(tokstr,"BOX")) { x1 = ANGS*dblstrf (&instr); y1 = ANGS*dblstrf (&instr); z1 = ANGS*dblstrf (&instr); x2 = ANGS*dblstrf (&instr); y2 = ANGS*dblstrf (&instr); z2 = ANGS*dblstrf (&instr); LOOP (i,np) tsel[i] = ( x1<=c[i][0] && c[i][0]<x2 && y1<=c[i][1] && c[i][1]<y2 && z1<=c[i][2] && c[i][2]<z2 ); } else if (!strcmpi(tokstr,"EATOM")) { lo = dblstrf (&instr)/s->eunit; hi = dblstrf (&instr)/s->eunit; if (a->eatom!=NULL) { LOOP (i, a->np) { tsel[i] = (a->eatom[i]>=lo && a->eatom[i]<=hi); } } } else if (!strcmpi(tokstr,"ELLIPSE")) { x1 = ANGS*dblstrf (&instr); y1 = ANGS*dblstrf (&instr); z1 = ANGS*dblstrf (&instr); x2 = ANGS*dblstrf (&instr); y2 = ANGS*dblstrf (&instr); z2 = ANGS*dblstrf (&instr); LOOP (i, a->np) { xdel = (c[i][X]-x1)/x2; ydel = (c[i][Y]-y1)/y2; zdel = (c[i][Z]-z1)/z2; tsel[i] = (xdel*xdel + ydel*ydel + zdel*zdel) < 1.0; } } else if (!strcmpi(tokstr,"INDEX")) { n1 = intstrf (&instr); n2 = intstrf (&instr); nskip = intstrf (&instr); if (n1 < 1 ) n1 = 1; if (n2 > np) n2=np; if (n2 == 0) n2 = n1; if (nskip==0) nskip = 1; LOOP (i, a->np) tsel[i] = FALSE; for (i=n1-1; i<n2; i+=nskip) tsel[i] = TRUE; } /* NEW SELECT OPTIONS (28 Mar 1992) */ else if (!strcmpi(tokstr,"ILIST")) { char str[256], *s; int Index; n = intstrf(&instr); while (n && m_gets_list (str, 256, inlist)) { s = str; while (*s) { /* Test for index in range */ Index = intstrf (&s) - 1; if (Index>=a->np || Index<0) { printf ("ERROR (read_select): Index in ILIST command (%i)", Index); printf (" is out of range [0..%i]\n", a->np-1); CleanAfterError(); } tsel[Index] = 1; n--; } } } else if (!strcmpi(tokstr,"LAYER")) { /* find layer parameters */ tokstr = strhed (&instr); if (!strcmpi(tokstr,"X")) u = 0; else if (!strcmpi(tokstr,"Y")) u = 1; else if (!strcmpi(tokstr,"Z")) u = 2; else { printf ("WARNING: select layer direction unrecognized."); IncrementNumberOfWarnings(); FREE (tsel) return; } /* test if box is needed */ if (!a->surf[u] && (!a->IsInitializedBox)) { printf ("WARNING: cannot use select layer "); printf ("without first specifying box in %c direction.\n",'X'+u); IncrementNumberOfWarnings(); FREE (tsel) return; } /* read number of layers */ n = intstrf (&instr); if (n<=0) { printf ("WARNING: select layer must have positive number of layers."); IncrementNumberOfWarnings(); FREE (tsel) return; } /* test for existance of indivual layer specification */ if (!instr) { printf ("WARNING: select layer command did not specify an layers."); IncrementNumberOfWarnings(); FREE (tsel) return; } /* find umin and umax: */ /* if repeating boundary (umin,umax)==(0,box) */ /* else (umin,umax) == min,max coordinate */ if (!a->surf[u]) { umin = 0; umax = a->bcur[u]; } else { umin = c[0][u]; umax = umin; LOOP (i,np) { utmp = c[i][u]; if (utmp<umin) umin = utmp; else if (utmp>umax) umax = utmp; } } dbox = (umax-umin) / n; while (*instr) { i = intstrf(&instr); x1 = (i-1) * dbox + umin; x2 = i * dbox + umin; LOOP(i,np) tsel[i] = tsel[i] || (x1 <= c[i][u]) && (c[i][u] <= x2); } } else if (!strcmpi(tokstr,"NEAR")) { /* Initilize flag for no neighbors */ NoNeighbors = FALSE; /* Read number of neighbors to select */ n = intstrf(&instr); /* Check for options */ tokstr = strhed (&instr); /* Find neighbors of indexed atom */ if (!strcmpi(tokstr,"INDEX")) { OmitPoint = TRUE; index = intstrf (&instr)-1; xc = c[index][X]; yc = c[index][Y]; zc = c[index][Z]; } /* Find neighbors of first point in set */ else if (!strcmpi(tokstr,"SET")) { OmitPoint = TRUE; AtomFound = FALSE; iset = intstrf (&instr); LOOP (i,np) { if (IS_SET(i,iset)) { xc = c[i][X]; yc = c[i][Y]; zc = c[i][Z]; AtomFound = TRUE; break; } } if (!AtomFound) { NoNeighbors = TRUE; } } /* Find neighbors of point */ else if (!strcmpi(tokstr,"POINT")) { OmitPoint = FALSE; xc = dblstrf(&instr)*1e-8; yc = dblstrf(&instr)*1e-8; zc = dblstrf(&instr)*1e-8; } /* Find neighbors of first selected atom */ else if ( !strcmpi(tokstr,"SEL") || IsBlank(tokstr) ) { OmitPoint = TRUE; AtomFound = FALSE; LOOP (i,np) { if (IS_SELECT(i)) { xc = c[i][X]; yc = c[i][Y]; zc = c[i][Z]; AtomFound = TRUE; break; } } if (!AtomFound) { NoNeighbors = TRUE; } } /* Unrecognized option */ else { printf ("WARNING: Unrecognized SELECT NEAR option.\n"); IncrementNumberOfWarnings(); NoNeighbors = TRUE; } /* Call near neighbor routine */ if (!NoNeighbors) nearneighbor (xc,yc,zc, tsel, n, OmitPoint); } else if (!strcmpi(tokstr,"PLANE")) { nx = dblstrf(&instr); ny = dblstrf(&instr); nz = dblstrf(&instr); x1 = 1e-8*dblstrf(&instr); y1 = 1e-8*dblstrf(&instr); z1 = 1e-8*dblstrf(&instr); x2 = 1e-8*dblstrf(&instr); y2 = 1e-8*dblstrf(&instr); z2 = 1e-8*dblstrf(&instr); if (nx==0 && ny==0 && nz==0) { printf ( "ERROR (read_select): plane normal is zero."); FREE (tsel) return; } dot1 = nx*x1 + ny*y1 + nz*z1; dot2 = nx*x2 + ny*y2 + nz*z2; if (dot1>dot2) { t = dot1; dot1 = dot2; dot2 = t; } LOOP (i,np) { t = nx*c[i][0] + ny*c[i][1] + nz*c[i][2]; tsel[i] = (dot1<=t) && (t<=dot2); } } else if (!strcmpi(tokstr,"SET")) { /* Read set number */ iset = intstrf(&instr); if (iset<1 || iset>MAX_SET) { printf("ERROR (read_select): Set"); printf(" (%i) out of range [1,%i].", iset, MAX_SET); FREE (tsel) return; } /* Test set */ LOOP (i, np) { tsel[i] = IS_SET(i,iset); } } else if (!strcmpi(tokstr,"TAG")) { ntag = intstrf(&instr); if (a->tag!=NULL) LOOP (i, np) tsel[i] = (a->tag[i]==ntag); } else if (!strcmpi(tokstr,"TYPE")) { ntype = intstrf(&instr)-1; LOOP(i, np) tsel[i] = (a->type[i]==ntype); } else if (!strcmpi(tokstr,"VELOCITY")) { tokstr = strhed (&instr); /* Check Absolute Value Flag */ UseAbsoluteValue = FALSE; if (!strcmpi("ABS",tokstr)) { UseAbsoluteValue = TRUE; tokstr = strhed (&instr); } /* Read direction / magnitude flag */ UseMagnitude = FALSE; if (!strcmpi("X",tokstr)) { idir = X; } else if (!strcmpi("Y",tokstr)) { idir = Y; } else if (!strcmpi("Z",tokstr)) { idir = Z; } else if (!strcmpi("MAG",tokstr)) { UseMagnitude = TRUE; } /* Read velocity limits in units of cm/sec, convert to cm/time step */ lo = dblstrf (&instr)*s->dtime; hi = dblstrf (&instr)*s->dtime; if (a->v!=NULL) { LOOP (i, a->np) { if (UseMagnitude) { Value = sqrt ( a->v[i*NDIR+X]*a->v[i*NDIR+X] + a->v[i*NDIR+Y]*a->v[i*NDIR+Y] + a->v[i*NDIR+Z]*a->v[i*NDIR+Z] ); } else { Value = a->v[i*NDIR+idir]; } if (UseAbsoluteValue) Value = fabs(Value); tsel[i] = (Value >= lo && Value <= hi); } } } /* Unrecognized option */ else { ERROR_PREFIX printf ("Unrecognized SELECT option (%s).\n", tokstr); CleanAfterError(); } CHECK_HEAP /* COMBINE SELECTION WITH PREVIOUS SELECTION */ a->nsel = 0; LOOP (i, np) { /* Store previous value of selection */ PrevSel = IS_SELECT(i); /* Intialize to unselected */ REMOVE_SELECT(i) /* Combine with current value of select */ switch (lop) { case _ONLY: if (tsel[i]) APPLY_SELECT(i) break; case _AND: if (tsel[i] && PrevSel) APPLY_SELECT(i); break; case _OR: if (tsel[i] || PrevSel) APPLY_SELECT(i) break; case _NOT: if (!tsel[i]) APPLY_SELECT(i) break; case _XOR: if ( (tsel[i] || PrevSel) && !(tsel[i] && PrevSel) ) APPLY_SELECT(i) break; } /* Sum selected atoms */ if (IS_SELECT(i)) a->nsel++; } CHECK_HEAP /* Print number selected */ if (s->PrintInfo) printf ("*** NUMBER SELECTED %i\n", a->nsel); CHECK_HEAP /* FREE STORAGE */ FREE (tsel) } /* END OF read_select */void read_tag (char *instr) { int i, itag; /* DO IF (1) Argument string AND (2) selected particles */ /* Assign tag values if particle selected and tag value entered */ if (a->nsel != 0 && instr[0] != '\0' ) { /* Allocate array new */ if (a->tag == NULL) { /* Allocate space for tag array */ ALLOCATE (a->tag, BYTE, a->np) } /* Read and assign tag value */ itag = intstrf (&instr); LOOP (i, a->np) if (IS_SELECT(i)) a->tag[i] = itag; } }void read_set (char *instr) { unsigned int i; unsigned int iset; BOOLEAN addflag; BOOLEAN subflag; BOOLEAN clrflag; char *tokstr; tokstr = strhed (&instr); /* PARSE OPTION */ addflag = subflag = clrflag = FALSE; if (!strcmpi(tokstr,"ADD")) addflag = TRUE; else if (!strcmpi(tokstr,"SUB")) subflag = TRUE; else if (!strcmpi(tokstr,"CLEAR")) clrflag = TRUE; else { printf ("ERROR (read_set): unknown option.\n"); return; } /* RETURN IF NO PARTICLES SELECTED */ CheckForNoneSelected(); if (a->nsel==0) return; /* RETURN IF NO SET ARRAY AND EITHER SUB OR CLEAR */ if (a->Selection==NULL && (subflag || clrflag)) return; /* SET BITS */ iset = intstrf(&instr); /* Is set in allowed range? */ if (iset<1 || iset>MAX_SET) { printf ("ERROR (read_set): set (%i) out of range [1,%i].\n", iset, MAX_SET); return; } /* apply set to particles */ LOOP (i, a->np) { if (IS_SELECT(i) || clrflag) { /* Add particle to set */ if (addflag) { APPLY_SET(i, iset) } /* Remove particle from set */ else if (subflag) REMOVE_SET(i, iset) /* Clear set entirely */ else if (clrflag) REMOVE_SET(i, iset) } } }void CheckForNoneSelected(void) { if (a->nsel==0) { IncrementNumberOfWarnings(); printf ("WARNING: No atoms are selected\n"); } }/*************************************************************************Local Functions*************************************************************************/void nearneighbor (double xc, double yc, double zc,unsigned char *tsel, int nnear,BOOLEAN OmitPoint) { unsigned i; unsigned u; unsigned *index = NULL; double *rlist = NULL; double rsq; double r[NDIR]; double rd; double (*c)[NDIR] = (double (*)[NDIR]) a->cur; int NumAtom; ALLOCATE (index, unsigned, a->np) ALLOCATE (rlist, double, a->np) r[0] = xc; r[1] = yc; r[2] = zc; NumAtom = 0; LOOP (i,a->np) { rsq = 0; LOOP(u,NDIR) { rd = fabs(r[u] - c[i][u]); if (!a->surf[u] && 2*rd>a->bcur[u]) rd = a->bcur[u] - rd; rsq = rsq + rd*rd; } if (!OmitPoint || rsq>0.0) { index[i] = i; rlist[i] = rsq; NumAtom++; } } /* sort rlist */ sortdx (rlist, index, NumAtom); /* Select nearest atoms */ /* Sanity check: Make sure number of neighbers does not exceed number of eligible atoms */ if (nnear>NumAtom) LOOP(i, NumAtom) tsel[index[i]] = 1; else LOOP(i,nnear) tsel[index[i]] = 1; /* release storage */ FREE (rlist) FREE (index) }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -