Esempio n. 1
0
Detector::Detector(int nx, int ny, float_tt resX, float_tt resY) :
  error(0),
  shiftX(0),
  shiftY(0),
  Navg(0),
  thickness(0)
{
#if FLOAT_PRECISION == 1
	image = float2D(nx,ny,"ADFimag");
	image2 = float2D(nx,ny,"ADFimag");
#else
	image = double2D(nx,ny,"ADFimag");	
	image2 = double2D(nx,ny,"ADFimag");	
#endif
	m_imageIO=ImageIOPtr(new CImageIO(nx, ny, thickness, resX, resY, std::vector<double>(2+nx*ny), "STEM image"));
}
Esempio n. 2
0
WAVEFUNC::WAVEFUNC(int x, int y, float_tt resX, float_tt resY) :
detPosX(0),
detPosY(0),
iPosX(0),
iPosY(0),
thickness(0.0),
nx(x),
ny(y),
resolutionX(resX),
resolutionY(resY)
{
	char waveFile[256];
	const char *waveFileBase = "mulswav";
#if FLOAT_PRECISION == 1
	diffpat = float2D(nx,ny,"diffpat");
	avgArray = float2D(nx,ny,"avgArray");
#else
	diffpat = double2D(nx,ny,"diffpat");
	avgArray = double2D(nx,ny,"avgArray");
#endif

	m_imageIO=ImageIOPtr(new CImageIO(nx, ny, thickness, resolutionX, resolutionY));
	

#if FLOAT_PRECISION == 1
	wave = complex2Df(nx, ny, "wave");
	fftPlanWaveForw = fftwf_plan_dft_2d(nx,ny,wave[0],wave[0],FFTW_FORWARD, FFTW_ESTIMATE);
	fftPlanWaveInv = fftwf_plan_dft_2d(nx,ny,wave[0],wave[0],FFTW_BACKWARD, FFTW_ESTIMATE);
#else
	wave = complex2D(nx, ny, "wave");
	fftPlanWaveForw = fftw_plan_dft_2d(nx,ny,wave[0],wave[0],FFTW_FORWARD,
		fftMeasureFlag);
	fftPlanWaveInv = fftw_plan_dft_2d(nx,ny,wave[0],wave[0],FFTW_BACKWARD,
		fftMeasureFlag);
#endif

	sprintf(waveFile,"%s.img",waveFileBase);
	strcpy(fileout,waveFile);
	sprintf(fileStart,"mulswav.img");
}
Esempio n. 3
0
/*****************************************************************
* Create the amorphous part of the model
****************************************************************/
void makeAmorphous() {
	int g,p,iatom,ix,iy,iz,ic,atomCount = 0,amorphSites,amorphAtoms;
	static double *axCell,*byCell,*czCell=NULL;
	static double **Mm = NULL;
	double rCellx,rCelly,rCellz;
	double d,r;
	atom *amorphCell;
	// atom newAtom;
	// double xpos,ypos,zpos;
	int nx,ny,nz;
	int *randArray,randCount;


	if (Mm == NULL) {
		Mm = double2D(3,3,"Mm");
		axCell=Mm[0]; byCell=Mm[1]; czCell=Mm[2];
	}

	for (g=0;g<nGrains;g++) {
		/********************************************************
		* if this grain is an amorphous one ... 
		*/
		if (grains[g].amorphFlag == AMORPHOUS) {
			r = grains[g].rmin/grains[g].rFactor;
			/* create an hexagonally closed packed unit cell for initial amorphous structure 
			* The length of each vector is now 1 
			*/
			axCell[0] = r;     axCell[1] = 0;               axCell[2] = 0;
			byCell[0] = 0.5*r; byCell[1] = 0.5*sqrt(3.0)*r; byCell[2] = 0;
			czCell[0] = 0.5*r; czCell[1] = 0.5/sqrt(3.0)*r; czCell[2] = sqrt(5.0)/6*r;      
			/* size of rectangular cell containing 4 atoms: */
			rCellx = r; rCelly = sqrt(3.0)*r; rCellz = (sqrt(5.0)*r)/3.0;

			/* determine number of unit cells in super cell */
			nx = (int)(superCell.ax/rCellx);
			ny = (int)(superCell.by/rCelly);
			nz = (int)(superCell.cz/rCellz);
			amorphSites = 4*nx*ny*nz;
			amorphCell = (atom *)malloc((amorphSites+1)*sizeof(atom));

			atomCount = 0;
			for (ix=0;ix<=nx;ix++) {
				for (iy=0;iy<=ny;iy++) {
					for (iz=0;iz<=nz;iz++) {
						for (ic=0;ic<4;ic++) {
							/* check if this atom and any of the 4 atoms per rect. unit cell lie within the super cell 
							*/
							amorphCell[atomCount].x  = ix*rCellx-(ic==3)*axCell[0]+(ic % 2)*byCell[0]+(ic>1)*czCell[0]; 
							amorphCell[atomCount].y  = iy*rCelly-(ic==3)*axCell[1]+(ic % 2)*byCell[1]+(ic>1)*czCell[1]; 
							amorphCell[atomCount].z  = iz*rCellz-(ic==3)*axCell[2]+(ic % 2)*byCell[2]+(ic>1)*czCell[2]; 
							if ((amorphCell[atomCount].x >= 0) && 
								(amorphCell[atomCount].x < superCell.ax) &&
								(amorphCell[atomCount].y >= 0) && 
								(amorphCell[atomCount].y < superCell.by) &&
								(amorphCell[atomCount].z >= 0) && 
								(amorphCell[atomCount].z < superCell.cz)) {
									for (p=0;p<grains[g].nplanes;p++) {
										d = findLambda(grains[g].planes+p,&(amorphCell[atomCount].z),-1);
										if (d < 0)
											break;
									}
									/* if all the previous test have been successful, this atom is IN */
									if (p == grains[g].nplanes) atomCount++;
							}
						} /* ic ... */
					} /* iz ... */
				} /* iy ... */
			} /* ix ... */
			amorphSites = atomCount;
			/****************************************************************************************
			* Now we have all the sites within the bounding planes on which we can put atoms
			*/
			/* the true number of amorphous atoms is # of sites / rFactor^3 */
			amorphAtoms = (int)floor((double)amorphSites/pow(grains[g].rFactor,3.0));
			if (amorphAtoms > amorphSites) amorphAtoms = amorphSites;
			randCount = amorphSites;
			atomCount = superCell.natoms;


			superCell.atoms = (atom *)realloc(superCell.atoms,(atomCount+amorphAtoms+1)*sizeof(atom));
			if (superCell.atoms == NULL) {
				printf("makeAmorphous: Could not allocate memory for additional atoms!\n");
				exit(0);
			}

			randArray = (int *)malloc(amorphSites*sizeof(int));
			for (ix=0;ix<amorphSites;ix++) randArray[ix] = ix;
			/*
			printf("memory allocation: sC.atoms: %d .. %d, rArray: %d .. %d\n",
			(int)superCell.atoms,(int)superCell.atoms+(atomCount+amorphAtoms+1)*sizeof(atom),
			(int)randArray,(int)randArray+amorphSites*sizeof(int));
			*/

			for (ix=amorphAtoms;ix>0;ix--) {
				do {
					iy = (int)((double)rand()*(double)(randCount-1)/(double)(RAND_MAX));
					if (iy >= randCount) iy = randCount-1;
					if (iy < 0) iy = 0;
					//	printf("%5d, iy: %d, sites: %d, atoms: %d  ",ix,iy,randCount,amorphAtoms);
					iz = randArray[iy];
					if (iz > amorphSites) {
						printf("%5d, iy: %d, sites: %d, atoms: %d  ",ix,iy,randCount,amorphAtoms);
						printf("iz: %d (%d)\n",iz,(int)superCell.atoms[atomCount].z);
						printf("makeAmorphous: Error because of overlapping memory areas!\n");
						for (iz=0;iz<=amorphAtoms;iz++)
							printf("iz=%d: %d\n",iz,randArray[iz]);
						exit(0);
					}
				} while (iz > amorphSites);

				/* replace already choosen sites with unused ones, so that we don't occupy
				* any site twice 
				*/
				if (iy == randCount-1)  randCount--;	
				else 
					randArray[iy] = randArray[--randCount];


				iatom = ix % grains[g].natoms;
				superCell.atoms[atomCount].q = grains[g].unitCell[iatom].q;
				superCell.atoms[atomCount].dw = grains[g].unitCell[iatom].dw;
				superCell.atoms[atomCount].occ = grains[g].unitCell[iatom].occ;
				superCell.atoms[atomCount].Znum = grains[g].unitCell[iatom].Znum;
				superCell.atoms[atomCount].x = amorphCell[iz].x;
				superCell.atoms[atomCount].y = amorphCell[iz].y;
				superCell.atoms[atomCount].z = amorphCell[iz].z;
				atomCount++;
			} 
			superCell.natoms = atomCount;
			free(randArray);
			free(amorphCell);
		} /* end of if amorph,i.e. crystalline */
	} /* g=0..nGrains .. */

}
Esempio n. 4
0
/********************************************************************
* This function adds only the crystalline atoms to the superCell
* the amorphous ones are handled by makeAmorphous,  and makeSpecial
********************************************************************/
void makeSuperCell() {
	int g,p,iatom,ix,iy,iz,atomCount = 0;
	// atom *atomPtr;
	// atomPtr = (atom *)malloc(sizeof(atom));
	static double *axCell,*byCell,*czCell=NULL;
	static double **Mm = NULL, **Mminv = NULL, **Mrot = NULL,**Mr=NULL,**Mr2=NULL;
	static double **a = NULL,**b= NULL;
	double maxLength,dx,dy,dz,d,dxs,dys,dzs;
	atom newAtom;
	// double xpos,ypos,zpos;
	int nxmin,nxmax,nymin,nymax,nzmin,nzmax;

	/* claculate maximum length in supercell box, which is naturally 
	* the room diagonal:
	*/
	maxLength = vectLength(&(superCell.ax));
	/*	 maxLength = sqrt(superCell.ax*superCell.ax+
	superCell.by*superCell.by+
	superCell.cz*superCell.cz);
	*/

	if (Mm == NULL) {
		Mm = double2D(3,3,"Mm");
		Mminv = double2D(3,3,"Mminv");
		Mrot = double2D(3,3,"Mrot");
		Mr	 = double2D(3,3,"Mr");
		Mr2   = double2D(3,3,"Mr");
		axCell=Mm[0]; byCell=Mm[1]; czCell=Mm[2];
		a = double2D(1,3,"a");
		b = double2D(1,3,"b");
	}

	atomCount = superCell.natoms;
	for (g=0;g<nGrains;g++) {
		/********************************************************
		* if this grain is a crystalline one ... 
		*/
		if (grains[g].amorphFlag == 0) {
			dx = grains[g].shiftx/superCell.ax; 
			dy = grains[g].shifty/superCell.by; 
			dz = grains[g].shiftz/superCell.cz;
			/* find the rotated unit cell vectors .. */
			makeCellVect(grains+g, axCell, byCell, czCell);
			// showMatrix(Mm,3,3,"M");
			///////////////////////////////////////////////////////////////////

			memset(Mrot[0],0,3*3*sizeof(double));
			Mrot[0][0] = 1.0; Mrot[1][1] = 1.0; Mrot[2][2] = 1.0; 
			memcpy(Mr2[0],Mrot[0],3*3*sizeof(double));


			memset(Mr[0],0,3*3*sizeof(double));
			Mr[0][0] = 1.0; Mr[1][1] = cos(grains[g].tiltx); Mr[1][2] = sin(grains[g].tiltx); 
			Mr[2][1] = -sin(grains[g].tiltx); Mr[2][2] = cos(grains[g].tiltx);
			matrixProduct(Mrot,3,3,Mr,3,3,Mr2);
			memcpy(Mrot[0],Mr2[0],3*3*sizeof(double));
			// showMatrix(Mrot,3,3,"Mrotx");

			memset(Mr[0],0,3*3*sizeof(double));
			Mr[1][1] = 1.0; Mr[0][0] = cos(grains[g].tilty); Mr[0][2] = -sin(grains[g].tilty); 
			Mr[2][0] = sin(grains[g].tilty); Mr[2][2] = cos(grains[g].tilty);
			matrixProduct(Mrot,3,3,Mr,3,3,Mr2);
			memcpy(Mrot[0],Mr2[0],3*3*sizeof(double));
			// showMatrix(Mrot,3,3,"Mrotxy");

			memset(Mr[0],0,3*3*sizeof(double));
			Mr[2][2] = 1.0; Mr[0][0] = cos(grains[g].tiltz); Mr[0][1] = sin(grains[g].tiltz); 
			Mr[1][0] = -sin(grains[g].tiltz); Mr[1][1] = cos(grains[g].tiltz);
			matrixProduct(Mrot,3,3,Mr,3,3,Mr2);
			memcpy(Mrot[0],Mr2[0],3*3*sizeof(double));		
			// showMatrix(Mrot,3,3,"Mrotxyz");

			///////////////////////////////////////////////////////////////////
			/*
			rotateVect(axCell,axCell,grains[g].tiltx,grains[g].tilty,grains[g].tiltz);
			rotateVect(byCell,byCell,grains[g].tiltx,grains[g].tilty,grains[g].tiltz);
			rotateVect(czCell,czCell,grains[g].tiltx,grains[g].tilty,grains[g].tiltz);
			*/
			inverse_3x3(Mminv[0],Mm[0]);
			matrixProduct(Mm,3,3,Mrot,3,3,Mr2);
			memcpy(Mm[0],Mr2[0],3*3*sizeof(double));
			// showMatrix(Mm,3,3,"M");
			inverse_3x3(Mr2[0],Mm[0]);

			/* find out how far we will have to go in units of unit cell vectors.
			* when creating the supercell by checking the number of unit cell vectors 
			* necessary to reach every corner of the supercell box.
			*/
			memset(a[0],0,3*sizeof(double));
			matrixProduct(a,1,3,Mr2,3,3,b);
			// showMatrix(Mm,3,3,"M");
			// showMatrix(Mminv,3,3,"M");
			nxmin = nxmax = (int)floor(b[0][0]-dx); 
			nymin = nymax = (int)floor(b[0][1]-dy); 
			nzmin = nzmax = (int)floor(b[0][2]-dz);
			for (ix=0;ix<=1;ix++) for (iy=0;iy<=1;iy++) for (iz=0;iz<=1;iz++) {
				a[0][0]=ix*superCell.ax; a[0][1]=iy*superCell.by; a[0][2]=iz*superCell.cz;

				matrixProduct(a,1,3,Mr2,3,3,b);
				// showMatrix(b,1,3,"b");
				if (nxmin > (int)floor(b[0][0]-dx)) nxmin=(int)floor(b[0][0]-dx);
				if (nxmax < (int)ceil( b[0][0]-dx)) nxmax=(int)ceil( b[0][0]-dx);
				if (nymin > (int)floor(b[0][1]-dy)) nymin=(int)floor(b[0][1]-dy);
				if (nymax < (int)ceil( b[0][1]-dy)) nymax=(int)ceil( b[0][1]-dy);
				if (nzmin > (int)floor(b[0][2]-dz)) nzmin=(int)floor(b[0][2]-dz);
				if (nzmax < (int)ceil( b[0][2]-dz)) nzmax=(int)ceil( b[0][2]-dz);	  
			}
			// nxmin--;nxmax++;nymin--;nymax++;nzmin--;nzmax++;
			superCell.atoms = (atom *)realloc(superCell.atoms,(superCell.natoms+1+
				(nxmax-nxmin)*(nymax-nymin)*
				(nzmax-nzmin)*grains[g].natoms)*
				sizeof(atom));
			// showMatrix(Mm,3,3,"Mm");
			// showMatrix(Mminv,3,3,"Mminv");
			printf("Grain %d: range: (%d..%d, %d..%d, %d..%d)\n",
				g,nxmin,nxmax,nymin,nymax,nzmin,nzmax);

			dx = grains[g].shiftx; 
			dy = grains[g].shifty; 
			dz = grains[g].shiftz;
			for (iatom=0;iatom<grains[g].natoms;iatom++) {
				memcpy(&newAtom,&(grains[g].unitCell[iatom]),sizeof(atom));
				// We need to convert the cartesian coordinates of this atom
				// to fractional ones:
				b[0][0] = newAtom.x;
				b[0][1] = newAtom.y;
				b[0][2] = newAtom.z;
				matrixProduct(b,1,3,Mminv,3,3,a);
				newAtom.x = a[0][0]; newAtom.y = a[0][1]; newAtom.z = a[0][2];
				//printf("%2d: %d (%g,%g,%g) (%g,%g,%g)\n",iatom,newAtom.Znum,
				//		 b[0][0],b[0][1],b[0][2],a[0][0],a[0][1],a[0][2]);
				for (ix=nxmin;ix<=nxmax;ix++) {
					for (iy=nymin;iy<=nymax;iy++) {
						for (iz=nzmin;iz<=nzmax;iz++) {
							/* atom position in reduced coordinates: */
							// a[0][0] = ix+newAtom.x; a[0][1] = iy+newAtom.y; a[0][2] = iz+newAtom.z;		 
							a[0][0] = newAtom.x+ix; a[0][1] = newAtom.y+iy; a[0][2] = newAtom.z+iz;
							matrixProduct(a,1,3,Mm,3,3,b);

							/*	  
							b[0][0] = a[0][0]*Mm[0][0]+a[0][1]*Mm[0][1]+a[0][2]*Mm[0][2];
							b[0][1] = a[0][0]*Mm[1][0]+a[0][1]*Mm[1][1]+a[0][2]*Mm[1][2];
							b[0][2] = a[0][0]*Mm[2][0]+a[0][1]*Mm[2][1]+a[0][2]*Mm[2][2];
							*/
							/* // same as matrixProduct: 
							b[0][0] = a[0][0]*Mm[0][0]+a[0][1]*Mm[1][0]+a[0][2]*Mm[2][0];
							b[0][1] = a[0][0]*Mm[0][1]+a[0][1]*Mm[1][1]+a[0][2]*Mm[2][1];
							b[0][2] = a[0][0]*Mm[0][2]+a[0][1]*Mm[1][2]+a[0][2]*Mm[2][2];
							*/
							superCell.atoms[atomCount].x  = b[0][0]+dx; 
							superCell.atoms[atomCount].y  = b[0][1]+dy; 
							superCell.atoms[atomCount].z  = b[0][2]+dz; 
							if ((superCell.atoms[atomCount].x >= 0) && 
								(superCell.atoms[atomCount].x < superCell.ax) &&
								(superCell.atoms[atomCount].y >= 0) && 
								(superCell.atoms[atomCount].y < superCell.by) &&
								(superCell.atoms[atomCount].z >= 0) && 
								(superCell.atoms[atomCount].z < superCell.cz)) {
									// If this is a sphere:
									if (grains[g].sphereRadius > 0) {
										dxs = superCell.atoms[atomCount].x - grains[g].sphereX;
										dys = superCell.atoms[atomCount].y - grains[g].sphereY;
										dzs = superCell.atoms[atomCount].z - grains[g].sphereZ;
										if (dxs*dxs+dys*dys+dzs*dzs < grains[g].sphereRadius*grains[g].sphereRadius) { 
											superCell.atoms[atomCount].dw = newAtom.dw;
											superCell.atoms[atomCount].occ = newAtom.occ;
											superCell.atoms[atomCount].q = newAtom.q;
											superCell.atoms[atomCount].Znum = newAtom.Znum;
											atomCount++;
										}
									}
									// If this is a straight-edged grain
									else {
										for (p=0;p<grains[g].nplanes;p++) {
											/*
											printf("hello %d (%g %g %g)\n",g,
											superCell.atoms[atomCount].x,superCell.atoms[atomCount].y,
											superCell.atoms[atomCount].z);
											*/
											d = findLambda(grains[g].planes+p,&(superCell.atoms[atomCount].z),-1);

											/*
											printf("%3d lambda: %g (%g %g %g), (%g %g %g), %d\n",atomCount,d,
											newAtom.x,newAtom.y,newAtom.z,
											superCell.atoms[atomCount].x,superCell.atoms[atomCount].y,
											superCell.atoms[atomCount].z,grains[g].nplanes);
											*/		
											if (d < 0)
												break;
										}
										/* if all the previous test have been successful, this atom is IN,
										* which means that we also need to copy the other data elements
										* for this atom. 
										*/
										if (p == grains[g].nplanes) {
											superCell.atoms[atomCount].q = newAtom.q;
											superCell.atoms[atomCount].dw = newAtom.dw;
											superCell.atoms[atomCount].occ = newAtom.occ;
											superCell.atoms[atomCount].Znum = newAtom.Znum;
											atomCount++;
										}
									} // if this is a sphere or not ...
							}
						} /* iz ... */
					} /* iy ... */
				} /* ix ... */
			} /* iatom ... */
			superCell.natoms = atomCount;
		} /* end of if !amorph,i.e. crystalline */
	} /* g=0..nGrains .. */
	/*
	atomPtr->x = 0.5; atomPtr->y = 0.2; atomPtr->z = 0.7;
	findLambda(grains[0].planes,&(atomPtr->z),1);
	*/ 

}