/* *************************************************** */ /* Distribute for free!! and feel free to modify */ /* as long as this header remains unchanged */ /* Original coding and design */ /* Sxren Koch;skoch@geo.aau.dk */ /* *************************************************** */ #include #include #include #include #include "vector_math.c" #define TRUE 1 #define FALSE 0 float dspacing(int hkl[],float celleparametre[]); void datainput(float celleparametre[]); float volumen(float celleparametre[]); void base(float x[],float y[],float z[],float celleparametre[]); void vector(float v[],int hkl[],float a[],float b[], float c[]); void hklinput(int hkl[]); void convert(float a[],int b[]); int my_printf(char *str, ...); FILE *debug_file; char *debug_file_name = "out.txt"; FILE *input; static void input_construct (void) __attribute__((constructor)); static void input_construct (void) { input = stdin;}; main() { float celleparametre[6],vinkel; int hkl[3],zonea[3],fortsaet,cont,valg,max,antal_vektorer; char input_buffer; float d,vol,x[3],y[3],z[3],ar[3],br[3],cr[3],lar,lbr,lcr,var,vbr,vcr; float hkla[3],hklb[3]; int hklra[3],hklrb[3],hklx[3],hkly[3]; float angle,vektor1,vektor2,dspacex,dspacey,vektor1d,vektor2d,angled; int hkl1[3],hkl2[3],overflowkontrol; debug_file = fopen(debug_file_name, "w"); printf("\n\n Crystallography\n\n"); printf(" Made by:\n Soren Koch: skoch@geo.aau.dk\n"); printf("\n\n\n Input all distances in Aangstroem\n"); printf("\n Output is generated in the file: OUT.TXT\n\n"); datainput(celleparametre); base(x,y,z,celleparametre); my_printf("\n\n Cartesian kordinate-system placed with b parallel to y og a in the x-y-plane"); my_printf("\n Cartesian celleparameters:\n\n"); my_printf(" a: %f %f %f\n b: %f %f %f\n c: %f %f %f\n",x[0],x[1],x[2],y[0],y[1],y[2],z[0],z[1],z[2]); vol = volumen(celleparametre); my_printf("\n cellvolume: %f A",vol); crossp(ar,y,z); ar[0]=ar[0]/vol; ar[1]=ar[1]/vol; ar[2]=ar[2]/vol; lar = sqrt(ar[0]*ar[0] + ar[1]*ar[1] + ar[2]*ar[2]); crossp(br,z,x); br[0]=br[0]/vol; br[1]=br[1]/vol; br[2]=br[2]/vol; lbr = sqrt(br[0]*br[0] + br[1]*br[1] + br[2]*br[2]); crossp(cr,x,y); cr[0]=cr[0]/vol; cr[1]=cr[1]/vol; cr[2]=cr[2]/vol; lcr = sqrt(cr[0]*cr[0] + cr[1]*cr[1] + cr[2]*cr[2]); my_printf("\n resiprocal lattice-parameters - cartesian basis\n"); my_printf(" a* %f %f %f\n",ar[0],ar[1],ar[2]); my_printf(" b* %f %f %f\n",br[0],br[1],br[2]); my_printf(" c* %f %f %f\n\n",cr[0],cr[1],cr[2]); var = vektorvinkel(br,cr); vbr = vektorvinkel(cr,ar); vcr = vektorvinkel(ar,br); my_printf("\n Reciprocal lattice-parameters\n"); my_printf(" a*: %f b*: %f c*: %f\n",lar,lbr,lcr); my_printf(" angles: %f %f %f\n",var,vbr,vcr); overflowkontrol = 0; for(;;) { overflowkontrol++; if (overflowkontrol == 100) { return; } /* ----------MENU-------- */ my_printf("\n Select subprograme:\n"); printf(" 1: Calculate d-spacings\n"); printf(" 2: Calculate angles in reciprocal space\n"); printf(" 3: Index TEM-negative\n"); printf(" 4: Calculate angles between hkl vectors\n"); printf(" 5: Calculate reciprocal vector form hkl-indices\n"); printf("\n 99: EXIT\n\n Select: "); fflush(stdout); fscanf(input,"%i",&valg); /* ------- END MENU ----- */ if (valg == 99) { return; } if (valg == 1) { /* calculation of d-spacings from manually given hkl-indices */ fortsaet = TRUE; while(fortsaet) { hklinput(hkl); d = dspacing(hkl,celleparametre); my_printf("\nhkl-vector: %i %i %i\n",hkl[0],hkl[1],hkl[2]); my_printf("d-spacing: %f\n",d); vector(hkla,hkl,ar,br,cr); /* my_printf("\nReciprocal vector: %f %f %f\n\n",hkla[0],hkla[1],hkla[2]); */ printf("more d-spacing calculations (1 for Yes)?"); fflush(stdout); fscanf(input, "%i",&cont); fortsaet = FALSE; if(cont == 1) { fortsaet = TRUE; } else { fortsaet = FALSE; valg = 0; } /* end d-spacing calculations */ } } if (valg == 2) { /* CALCULATION OF ANGLES IN RECIPROCAL SPACE FROM 2 HKL-VECTORS */ printf("\n Input first hkl:\n"); hklinput(hklra); vector(hkla,hklra,ar,br,cr); printf("\n Input second hkl:\n"); hklinput(hklrb); vector(hklb,hklrb,ar,br,cr); vinkel=vektorvinkel(hkla,hklb); my_printf("\n h,k,l: %i %i %i\n h,k,l: %i %i %i\n",hklra[0],hklra[1],hklra[2],hklrb[0],hklrb[1],hklrb[2]); my_printf(" Reciprocal angle: %f\n",vinkel); valg = 0; /* END RECIPROCAL CALCULATIONS */ } if (valg == 3) { /* INDICING TEM-NEGATIVES USING 2 SHORTEST VECTORS AND INTERVECTORANGLE */ max = 1; /* DATAINPUT BY USER */ printf("\n\n Input length of first d(longest) "); fscanf(input,"%f",&vektor1); printf("\n Input estimated error of first d (in percent) "); fscanf(input,"%f",&vektor1d); printf("\n Input length of second d "); fscanf(input,"%f",&vektor2); printf("\n Input estimated error of second d (in percent) "); fscanf(input,"%f",&vektor2d); printf("\n Input angle "); fscanf(input,"%f",&angle); if (angle>90) { angle=180-angle; printf("calculating for acute angle; %f",angle); } printf("\n Input input estimated error of angle (in degrees) "); fscanf(input,"%f",&angled); printf("\n input maximal indices:"); fscanf(input,"%i",&max); my_printf("\nCalculating for vectors\n"); my_printf("d: %f error: %f percent\n",vektor1,vektor1d); my_printf("d: %f error: %f percent\n",vektor2,vektor2d); my_printf("angle: %f error: %f degrees\n",angle,angled); antal_vektorer = 0; /* END DATAINPUT */ /* GENERATING HKL-INDICES */ for (hklx[0]=-max;hklx[0](vektor1-vektor1*vektor1d/100)) { for (hkly[0]=-max;hkly[0](vektor2-vektor2*vektor2d/100)) { vector(hkla,hklx,ar,br,cr); vector(hklb,hkly,ar,br,cr); vinkel=vektorvinkel(hkla,hklb); printf("",vinkel); if (vinkel >90) { vinkel=180-vinkel; } if (vinkel < (angle+angled)) { if (vinkel > (angle-angled)) { /* OUTPUT FITTING VECTORS */ my_printf("vector fit:\n"); my_printf("h,k,l: %i %i %i d: %f\n",hklx[0],hklx[1],hklx[2],dspacex); my_printf("h,k,l: %i %i %i d: %f\n",hkly[0],hkly[1],hkly[2],dspacey); /* GENERATING ZONEAXIS FOR FITTING VECTORS*/ crosspi(zonea,hklx,hkly); my_printf("angle: %f Zoneaxis: %i %i %i\n",vinkel,zonea[0],zonea[1],zonea[2]); antal_vektorer++; /* END OUTPUT */ } } } } } } } } } } } } my_printf("found %i fitting vectors",antal_vektorer); /* END GENERATING INDICES AND END COMPARING */ valg = 0; } if (valg == 4) { /* CALCULATION OF ANGLES BETWEEN 2 HKL-VECTORS */ printf("\n Input first hkl:\n"); hklinput(hkl1); vector(hkla,hkl1,x,y,z); printf("\n Input second hkl:\n"); hklinput(hkl2); vector(hklb,hkl2,x,y,z); vinkel=vektorvinkel(hkla,hklb); my_printf("\n\n Vectors:\n"); my_printf(" h,k,l: %i %i %i\n",hkl1[0],hkl1[1],hkl1[2]); my_printf(" h,k,l: %i %i %i\n",hkl2[0],hkl2[1],hkl2[2]); my_printf(" Angle: %f\n",vinkel); valg = 0; /* END CALCULATIONS */ } if (valg == 5) { /* CALCULATION OF RECIPROCAL VECTOR USING CARTESIAN BASIS */ fortsaet = TRUE; while(fortsaet) { hklinput(hkl); vector(hkla,hkl,ar,br,cr); my_printf("\nhkl-vector: %i %i %i\n",hkl[0],hkl[1],hkl[2]); my_printf("Reciprocal vector: %f %f %f\n\n",hkla[0],hkla[1],hkla[2]); printf("more calculations (1 for Yes)?"); fflush(stdout); fscanf(input, "%i",&cont); fortsaet = FALSE; if(cont == 1) { fortsaet = TRUE; } else { fortsaet = FALSE; valg = 0; } /* end reciprocal calculations */ } /* END CALCULATIONS */ valg = 0; } } return; } float dspacing(int hkl[],float celleparametre[]) { /* GENERATING D-SPACING USING HKL-INDICES AND CELLPARAMETERS */ /* USING TRICLINIC CELL */ float d,e,f,g,h,i,j,k,l,pi; float a,b,c; float alfa,beta,gamma; pi = 3.141592; a = celleparametre[0]; b = celleparametre[1]; c = celleparametre[2]; alfa = celleparametre[3]*2*pi/360; beta = celleparametre[4]*2*pi/360; gamma = celleparametre[5]*2*pi/360; e = power(hkl[0],2)*power(sin(alfa),2)/(a*a); f = power(hkl[1],2)*power(sin(beta),2)/(b*b); g = power(hkl[2],2)*power(sin(gamma),2)/(c*c); i = 2*hkl[0]*hkl[1]*(cos(alfa)*cos(beta) - cos(gamma))/(a*b); j = 2*hkl[1]*hkl[2]*(cos(beta)*cos(gamma) - cos(alfa))/(b*c); k = 2*hkl[2]*hkl[0]*(cos(gamma)*cos(alfa) - cos(beta))/(c*a); h = power(cos(alfa),2) + power(cos(beta),2) + power(cos(gamma),2) - 2*cos(alfa)*cos(beta)*cos(gamma); l = e + f + g + i + j + k; d = 1/sqrt(l/(1-h)); /* d = 1/sqrt(l/(1 - power(cos(alfa),2) - power(cos(beta),2) - power(cos(gamma),2) + 2*cos(alfa)*cos(beta)*cos(gamma)));*/ return d; } void datainput(float celleparametre[]) { /* USERINPUT OF CELLPARAMETERS */ /* FIRST 3 ELEMENTS IN ARRAY IS LENGTH */ /* LAST 3 ELEMENTS IN ARRAY IS ANGLES */ float a,b,c,alfa,beta,gamma; printf("\ninput cellparameters\n"); printf(" a: "); fscanf(input,"%f",&a); printf(" b: "); fscanf(input,"%f",&b); printf(" c: "); fscanf(input,"%f",&c); printf(" alfa: "); fscanf(input,"%f",&alfa); printf(" beta: "); fscanf(input,"%f",&beta); printf(" gamma: "); fscanf(input,"%f",&gamma); /* OUTPUT TO ARRAY */ celleparametre[0]=a; celleparametre[1]=b; celleparametre[2]=c; celleparametre[3]=alfa; celleparametre[4]=beta; celleparametre[5]=gamma; return; } float volumen(float celleparametre[]) { /* CALCULATION OF CELLVOLUME USING CELLPARAMETERS */ /* B-AXIS ALONG Y AND A-AXIS IN THE X-Y-PLANE */ float volumen; float x[3],y[3],z[3],q[3]; base(x,y,z,celleparametre); crossp(q,y,z); volumen = prikp(x,q); return volumen; } void base(float x[],float y[],float z[],float celleparametre[]) { /* CALCULATION AF CARTESIAN CELLPARAMETERS USING TRICLINIC CELLPARAMETERS */ /* B-AXIS ALONG Y AND A-AXIS IN X-Y-PLANE */ /* CARTESIAN VECTORS:X,Y,Z */ float a,b,c,alfa,beta,gamma; float pi; pi=3.141592; a=celleparametre[0]; b=celleparametre[1]; c=celleparametre[2]; alfa=celleparametre[3]; beta=celleparametre[4]; gamma=celleparametre[5]; y[0] = 0; y[1] = b; y[2] = 0; x[0] = a*sin(gamma*2*pi/360); x[1] = a*cos(gamma*2*pi/360); x[2] = 0; z[1] = c*cos(alfa*2*pi/360); z[0] = (c*cos(beta*2*pi/360) - cos(gamma*2*pi/360)*c*cos(alfa*2*pi/360))/sin(gamma*2*pi/360); z[2] = sqrt(c*c - z[0]*z[0] - z[1]*z[1]); return; } void vector(float v[], int hkl[], float a[], float b[], float c[]) { /* CALCULATION OF A VECTORS FOR A GIVEN HKL-INDICES AND CARTESIAN BASIS */ /* RETURNVECTOR:V, INDICES:hkl AND CARTESIAN CELLPARAMETERS:a,b,c */ v[0] = hkl[0]*a[0] + hkl[1]*b[0] + hkl[2]*c[0]; v[1] = hkl[0]*a[1] + hkl[1]*b[1] + hkl[2]*c[1]; v[2] = hkl[0]*a[2] + hkl[1]*b[2] + hkl[2]*c[2]; return; } void hklinput(int hkl[]) { /* USERINPUT OF HKL-INDICES */ printf("\nInput hkl-indices\n"); printf(" h? "); fscanf(input,"%i",&hkl[0]); printf(" k? "); fscanf(input,"%i",&hkl[1]); printf(" l? "); fscanf(input,"%i",&hkl[2]); return; } int my_printf(char *str, ...) { va_list vargs; int res; va_start(vargs, str); res = vprintf(str, vargs); va_end(vargs); if (debug_file) { va_start(vargs, str); res = vfprintf(debug_file, str, vargs); va_end(vargs); } return res; }