Files
sics/cell.c
koennecke 6387994017 - First commit of the new UB based TAS calculation. A milestone has been
reached: it handles one test case correctly back and forth
- Fixed oscillation code
- Added a feature for switching off automatic updates in nxupdate
  Autoamtic updates cause problems when scanning...
2005-04-22 14:07:06 +00:00

188 lines
4.8 KiB
C

/**
* this is a little library for performing crystallographic cell transformations
* for SICS. Some of the actual code was lifted from the Risoe program tascom.
*
* copyright: see file COPYRIGHT
*
* Mark Koennecke, March 2005
*/
#include <stdio.h>
#include <assert.h>
#include <math.h>
#include "trigd.h"
#include "cell.h"
/* define constants */
#ifndef PI
#define PI (3.1415926536) /* pi */
#endif
#define TWOPI (2*PI) /* 2*pi */
/*****************************************************************************
* default value for a cell
****************************************************************************/
void defaultCell(plattice cell){
cell->a = 1.;
cell->b = 1.;
cell->c = 1.;
cell->alpha = 90.;
cell->beta = 90.;
cell->gamma = 90.;
}
/*******************************************************************************
* Transform direct lattice to reciprocal lattice.
*******************************************************************************/
int directToReciprocalLattice(lattice direct, plattice reciprocal)
{
double alfa, beta, gamma;
double cos_alfa, cos_beta, cos_gamma;
double sin_alfa, sin_beta, sin_gamma;
double ad, bd, cd;
double arg, vol;
alfa = direct.alpha;
beta = direct.beta;
gamma = direct.gamma;
cos_alfa = Cosd (alfa);
cos_beta = Cosd (beta);
cos_gamma = Cosd (gamma);
sin_alfa = Sind (alfa);
sin_beta = Sind (beta);
sin_gamma = Sind (gamma);
reciprocal->alpha = Acosd ((cos_beta*cos_gamma - cos_alfa)/sin_beta/sin_gamma);
reciprocal->beta =Acosd ((cos_alfa*cos_gamma - cos_beta)/sin_alfa/sin_gamma);
reciprocal->gamma = Acosd ((cos_alfa*cos_beta - cos_gamma)/sin_alfa/sin_beta);
ad = direct.a;
bd = direct.b;
cd = direct.c;
arg = 1 + 2*cos_alfa*cos_beta*cos_gamma - cos_alfa*cos_alfa -
cos_beta*cos_beta -
cos_gamma*cos_gamma;
if (arg < 0.0)
{
return REC_NO_VOLUME;
}
vol = ad*bd*cd*sqrt (arg);
reciprocal->a = bd*cd*sin_alfa/vol;
reciprocal->b = ad*cd*sin_beta/vol;
reciprocal->c = bd*ad*sin_gamma/vol;
return (0);
}
/*******************************************************************************
* Transform reciprocal lattice to direct lattice.
*******************************************************************************/
int reciprocalToDirectLattice(lattice reciprocal, plattice direct)
{
double alfa, beta, gamma;
double cos_alfa, cos_beta, cos_gamma;
double sin_alfa, sin_beta, sin_gamma;
double ar, br, cr;
double arg, vol;
alfa = reciprocal.alpha;
beta = reciprocal.beta;
gamma = reciprocal.gamma;
cos_alfa = Cosd (alfa);
cos_beta = Cosd (beta);
cos_gamma = Cosd (gamma);
sin_alfa = Sind (alfa);
sin_beta = Sind (beta);
sin_gamma = Sind (gamma);
direct->alpha = Acosd ((cos_beta*cos_gamma - cos_alfa)/sin_beta/sin_gamma);
direct->beta = Acosd ((cos_alfa*cos_gamma - cos_beta)/sin_alfa/sin_gamma);
direct->gamma = Acosd ((cos_alfa*cos_beta - cos_gamma)/sin_alfa/sin_beta);
ar = reciprocal.a;
br = reciprocal.b;
cr = reciprocal.c;
arg = 1 + 2*cos_alfa*cos_beta*cos_gamma - cos_alfa*cos_alfa -
cos_beta*cos_beta -
cos_gamma*cos_gamma;
if (arg < 0.0)
{
return REC_NO_VOLUME;
}
vol = ar*br*cr*sqrt (arg);
direct->a = br*cr*sin_alfa/vol;
direct->b = ar*cr*sin_beta/vol;
direct->c = br*ar*sin_gamma/vol;
return (0);
}
/***************************************************************************************
* Build a B matrix
***************************************************************************************/
int calculateBMatrix(lattice direct, MATRIX B) {
lattice reciprocal;
int status;
assert(MatRow(B) == 3);
assert(MatCol(B) == 3);
status = directToReciprocalLattice(direct,&reciprocal);
if(status < 0) {
return status;
}
mat_fill(B,ZERO_MATRIX);
/*
top row
*/
B[0][0] = reciprocal.a;
B[0][1] = reciprocal.b*Cosd(reciprocal.gamma);
B[0][2] = reciprocal.c*Cosd(reciprocal.beta);
/*
middle row
*/
B[1][1] = reciprocal.b*Sind(reciprocal.gamma);
B[1][2] = -reciprocal.c*Sind(reciprocal.beta)*Cosd(direct.alpha);
/*
bottom row
*/
B[2][2] = 1./direct.c;
return 1;
}
/*--------------------------------------------------------------------------*/
int cellFromUB(MATRIX UB, plattice direct){
MATRIX UBTRANS, GINV, G;
UBTRANS = mat_tran(UB);
if(UBTRANS == NULL){
return CELLNOMEMORY;
}
GINV = mat_mul(UBTRANS,UB);
if(GINV == NULL){
mat_free(UBTRANS);
return CELLNOMEMORY;
}
G = mat_inv(GINV);
if(G == NULL){
mat_free(UBTRANS);
mat_free(GINV);
return CELLNOMEMORY;
}
direct->a = sqrt(G[0][0]);
direct->b = sqrt(G[1][1]);
direct->c = sqrt(G[2][2]);
direct->alpha = Acosd(G[1][2]/(direct->b * direct->c));
direct->beta = Acosd(G[2][0]/(direct->a * direct->c));
direct->gamma = Acosd(G[0][1]/(direct->a * direct->c));
return 1;
}