| [a0bcf1] | 1 | #include <stdlib.h>
 | 
|---|
 | 2 | #include <stdio.h>
 | 
|---|
 | 3 | #include <string.h>
 | 
|---|
 | 4 | #include <math.h>
 | 
|---|
 | 5 | #include <time.h>
 | 
|---|
 | 6 | 
 | 
|---|
| [e2f3fde] | 7 | #include <gsl/gsl_matrix.h>
 | 
|---|
 | 8 | #include <gsl/gsl_vector.h>
 | 
|---|
 | 9 | #include <gsl/gsl_eigen.h>
 | 
|---|
 | 10 | #include <gsl/gsl_blas.h>
 | 
|---|
 | 11 | 
 | 
|---|
| [a0bcf1] | 12 | #include "NanoCreator.h"
 | 
|---|
 | 13 | 
 | 
|---|
| [e2f3fde] | 14 | 
 | 
|---|
| [a0bcf1] | 15 | // ---------------------------------- F U N C T I O N S ----------------------------------------------
 | 
|---|
 | 16 | 
 | 
|---|
 | 17 | // ================================= File functions ==============================
 | 
|---|
 | 18 | 
 | 
|---|
 | 19 | #define LINE_SIZE 80
 | 
|---|
 | 20 | #define NDIM  3
 | 
|---|
 | 21 | 
 | 
|---|
 | 22 | /** Allocs memory and prints a message on fail.
 | 
|---|
 | 23 |  * \param *size size of alloc in bytes
 | 
|---|
 | 24 |  * \param *msg error msg
 | 
|---|
 | 25 |  * \return pointer to allocated memory
 | 
|---|
 | 26 |  */
 | 
|---|
 | 27 | void * Malloc (size_t size, const char *msg) 
 | 
|---|
 | 28 | {
 | 
|---|
 | 29 |   void *ptr = malloc(size);
 | 
|---|
 | 30 |   if (ptr == NULL) {
 | 
|---|
 | 31 |     if (msg == NULL)
 | 
|---|
 | 32 |       fprintf(stdout, "ERROR: Malloc\n");
 | 
|---|
 | 33 |     else
 | 
|---|
 | 34 |       fprintf(stdout, "ERROR: Malloc - %s\n", msg);
 | 
|---|
 | 35 |     return NULL;
 | 
|---|
 | 36 |   } else {
 | 
|---|
 | 37 |     return ptr;
 | 
|---|
 | 38 |   }
 | 
|---|
 | 39 | }
 | 
|---|
 | 40 | 
 | 
|---|
 | 41 | /** Callocs memory and prints a message on fail.
 | 
|---|
 | 42 |  * \param *size size of alloc in bytes
 | 
|---|
 | 43 |  * \param *value pointer to initial value
 | 
|---|
 | 44 |  * \param *msg error msg
 | 
|---|
 | 45 |  * \return pointer to allocated memory
 | 
|---|
 | 46 |  */
 | 
|---|
 | 47 | void * Calloc (size_t size, double value, const char *msg) 
 | 
|---|
 | 48 | {
 | 
|---|
 | 49 |   void *ptr = calloc(size, value);
 | 
|---|
 | 50 |   if (ptr == NULL) {
 | 
|---|
 | 51 |     if (msg == NULL)
 | 
|---|
 | 52 |       fprintf(stdout, "ERROR: Calloc\n");
 | 
|---|
 | 53 |     else
 | 
|---|
 | 54 |       fprintf(stdout, "ERROR: Calloc - %s\n", msg);
 | 
|---|
 | 55 |     return NULL;
 | 
|---|
 | 56 |   } else {
 | 
|---|
 | 57 |     return ptr;
 | 
|---|
 | 58 |   }
 | 
|---|
 | 59 | }
 | 
|---|
 | 60 | 
 | 
|---|
 | 61 | /** Frees memory only if ptr != NULL.
 | 
|---|
 | 62 |  * \param *ptr pointer to array
 | 
|---|
 | 63 |  * \param *msg
 | 
|---|
 | 64 |  */
 | 
|---|
 | 65 | void Free(void * ptr, const char *msg)
 | 
|---|
 | 66 | {
 | 
|---|
 | 67 |   if (ptr != NULL)
 | 
|---|
 | 68 |     free(ptr);
 | 
|---|
 | 69 |   else {
 | 
|---|
 | 70 |     if (msg == NULL)
 | 
|---|
 | 71 |       fprintf(stdout, "ERROR: Free\n");
 | 
|---|
 | 72 |     else
 | 
|---|
 | 73 |       fprintf(stdout, "ERROR: Free - %s\n", msg);
 | 
|---|
 | 74 |   }
 | 
|---|
 | 75 | }
 | 
|---|
 | 76 | 
 | 
|---|
 | 77 | /** Allocs memory and prints a message on fail.
 | 
|---|
 | 78 |  * \param **old_ptr pointer to old memory range 
 | 
|---|
 | 79 |  * \param *newsize new size of alloc in bytes
 | 
|---|
 | 80 |  * \param *msg error msg
 | 
|---|
 | 81 |  * \return pointer to allocated memory
 | 
|---|
 | 82 |  */
 | 
|---|
 | 83 | void * Realloc (void *old_ptr, size_t newsize, const char *msg) 
 | 
|---|
 | 84 | {
 | 
|---|
 | 85 |   if (old_ptr == NULL) {
 | 
|---|
 | 86 |     fprintf(stdout, "ERROR: Realloc -  old_ptr NULL\n");
 | 
|---|
 | 87 |     exit(255);
 | 
|---|
 | 88 |   }
 | 
|---|
 | 89 |   void *ptr = realloc(old_ptr, newsize);
 | 
|---|
 | 90 |   if (ptr == NULL) {
 | 
|---|
 | 91 |     if (msg == NULL)
 | 
|---|
 | 92 |       fprintf(stdout, "ERROR: Realloc\n");
 | 
|---|
 | 93 |     else
 | 
|---|
 | 94 |       fprintf(stdout, "ERROR: Realloc - %s\n", msg);
 | 
|---|
 | 95 |     return NULL;
 | 
|---|
 | 96 |   } else {
 | 
|---|
 | 97 |     return ptr;
 | 
|---|
 | 98 |   }
 | 
|---|
 | 99 | }
 | 
|---|
 | 100 | 
 | 
|---|
 | 101 | /** Reads a file's contents into a char buffer of appropiate size.
 | 
|---|
 | 102 |  * \param *filename name of file
 | 
|---|
 | 103 |  * \param pointer to integer holding read/allocated buffer length
 | 
|---|
 | 104 |  * \return pointer to allocated segment with contents
 | 
|---|
 | 105 |  */
 | 
|---|
 | 106 | char * ReadBuffer (char *filename, int *bufferlength) 
 | 
|---|
 | 107 | {
 | 
|---|
 | 108 |   if ((filename == NULL) || (bufferlength == NULL)) {
 | 
|---|
 | 109 |     fprintf(stderr, "ERROR: ReadBuffer - ptr to filename or bufferlength NULL\n");
 | 
|---|
 | 110 |     exit(255);
 | 
|---|
 | 111 |   }
 | 
|---|
 | 112 |   char *buffer = Malloc(sizeof(char)*LINE_SIZE, "ReadBuffer: buffer");
 | 
|---|
 | 113 |   int i = 0, number;
 | 
|---|
 | 114 |   FILE *file = fopen(filename, "r");
 | 
|---|
 | 115 |   if (file == NULL) {
 | 
|---|
 | 116 |     fprintf(stderr, "File open error: %s", filename);
 | 
|---|
 | 117 |     exit(255);
 | 
|---|
 | 118 |   }
 | 
|---|
 | 119 |   while ((number = fread(&buffer[i], sizeof(char), LINE_SIZE, file)) == LINE_SIZE) {
 | 
|---|
 | 120 |     //fprintf(stdout, "%s", &buffer[i]);
 | 
|---|
 | 121 |     i+= LINE_SIZE;
 | 
|---|
 | 122 |     buffer = (char *) Realloc(buffer, i+LINE_SIZE, "ReadBuffer: buffer");
 | 
|---|
 | 123 |   }
 | 
|---|
 | 124 |   fclose(file);
 | 
|---|
 | 125 |   fprintf(stdout, "Buffer length is %i\n", i);
 | 
|---|
 | 126 |   *bufferlength = i+(number);
 | 
|---|
 | 127 |   return buffer;
 | 
|---|
 | 128 | }
 | 
|---|
 | 129 | 
 | 
|---|
 | 130 | /** Extracts next line out of a buffer.
 | 
|---|
 | 131 |  * \param *buffer buffer to parse for newline
 | 
|---|
 | 132 |  * \param *line contains complete line on return
 | 
|---|
 | 133 |  * \return length of line, 0 if end of file
 | 
|---|
 | 134 |  */
 | 
|---|
 | 135 | int GetNextline(char *buffer, char *line)
 | 
|---|
 | 136 | {
 | 
|---|
 | 137 |   if ((buffer == NULL) || (line == NULL)) {
 | 
|---|
 | 138 |     fprintf(stderr, "ERROR: GetNextline - ptr to buffer or line NULL\n");
 | 
|---|
 | 139 |     exit(255);
 | 
|---|
 | 140 |   }
 | 
|---|
 | 141 |   int length;
 | 
|---|
 | 142 |   char *ptr = strchr(buffer, '\n');
 | 
|---|
 | 143 |   //fprintf(stdout, "Newline at %p from %p\n", ptr, buffer);
 | 
|---|
 | 144 |   if (ptr == NULL) { // buffer ends
 | 
|---|
 | 145 |     return 0;
 | 
|---|
 | 146 |   } else {
 | 
|---|
 | 147 |     //fprintf(stdout, "length of line is %d\n", length);
 | 
|---|
 | 148 |     length = (int)(ptr - buffer)/sizeof(char);
 | 
|---|
 | 149 |     strncpy(line, buffer, length);
 | 
|---|
 | 150 |     line[length]='\0';
 | 
|---|
 | 151 |     return length+1;
 | 
|---|
 | 152 |   }
 | 
|---|
 | 153 | }
 | 
|---|
 | 154 | 
 | 
|---|
 | 155 | /** Adds commentary stuff (needed for further stages) to Cell xyz files.
 | 
|---|
 | 156 |  * \param *filename  file name
 | 
|---|
 | 157 |  * \param atomicnumner number of atoms in xyz
 | 
|---|
 | 158 |  * \param **Vector list of three unit cell vectors
 | 
|---|
 | 159 |  * \param **Recivector list of three reciprocal unit cell vectors
 | 
|---|
 | 160 |  * \param atomicnumber number of atoms in cell
 | 
|---|
 | 161 |  */
 | 
|---|
 | 162 | void AddAtomicNumber(char *filename, int atomicnumber, double **Vector, double **Recivector) 
 | 
|---|
 | 163 | {
 | 
|---|
 | 164 |   if ((filename == NULL) || (Vector == NULL) || (Recivector == NULL)) {
 | 
|---|
 | 165 |     fprintf(stdout, "ERROR: AddAtomicNumber - ptr to filename, Vector or Recivector NULL\n");
 | 
|---|
 | 166 |     exit(255);
 | 
|---|
 | 167 |   }
 | 
|---|
 | 168 |   int bufferlength;
 | 
|---|
 | 169 |   char *buffer = ReadBuffer(filename, &bufferlength);
 | 
|---|
 | 170 |   FILE *file2 = fopen(filename, "w+");
 | 
|---|
 | 171 |   if (file2 == NULL) {
 | 
|---|
 | 172 |     fprintf(stdout, "ERROR: AddAtomicNumber: %s can't open for writing\n", filename);
 | 
|---|
 | 173 |     exit(255);
 | 
|---|
 | 174 |   }
 | 
|---|
 | 175 |   double volume = Determinant(Vector);
 | 
|---|
 | 176 |   time_t now;
 | 
|---|
 | 177 |   
 | 
|---|
 | 178 |   now = time((time_t *)NULL);   // Get the system time and put it into 'now' as 'calender time'
 | 
|---|
 | 179 |   // open for writing and prepend
 | 
|---|
 | 180 |   fprintf(file2,"%d\n", atomicnumber); // 2
 | 
|---|
 | 181 |   fprintf(file2,"\tgenerated with Nanotube creator on %s", ctime(&now));
 | 
|---|
 | 182 |   fwrite(buffer, sizeof(char), bufferlength, file2); // append buffer
 | 
|---|
 | 183 | 
 | 
|---|
 | 184 |   // Add primitive vectors as comment
 | 
|---|
 | 185 |   fprintf(file2,"\n****************************************\n\n");
 | 
|---|
 | 186 |   fprintf(file2,"Primitive vectors\n");
 | 
|---|
 | 187 |   fprintf(file2,"a(1) = %f\t%f\t%f\n", Vector[0][0], Vector[0][1], Vector[0][2]);
 | 
|---|
 | 188 |   fprintf(file2,"a(2) = %f\t%f\t%f\n", Vector[1][0], Vector[1][1], Vector[1][2]);
 | 
|---|
 | 189 |   fprintf(file2,"a(3) = %f\t%f\t%f\n", Vector[2][0], Vector[2][1], Vector[2][2]);
 | 
|---|
 | 190 |   fprintf(file2,"\nVolume = %f", volume);
 | 
|---|
 | 191 |   fprintf(file2,"\nReciprocal Vectors\n");
 | 
|---|
 | 192 |   fprintf(file2,"b(1) = %f\t%f\t%f\n", Recivector[0][0], Recivector[0][1], Recivector[0][2]);
 | 
|---|
 | 193 |   fprintf(file2,"b(2) = %f\t%f\t%f\n", Recivector[1][0], Recivector[1][1], Recivector[1][2]);
 | 
|---|
 | 194 |   fprintf(file2,"b(3) = %f\t%f\t%f\n", Recivector[2][0], Recivector[2][1], Recivector[2][2]);
 | 
|---|
 | 195 | 
 | 
|---|
 | 196 |   fclose(file2); // close file
 | 
|---|
 | 197 |   Free(buffer, "AddAtomicNumber: buffer");
 | 
|---|
 | 198 | }
 | 
|---|
 | 199 | 
 | 
|---|
 | 200 | /** Adds commentary stuff (needed for further stages) to Sheet xyz files.
 | 
|---|
 | 201 |  * \param *filename file name
 | 
|---|
 | 202 |  * \param *axis array with major, minor and no axis
 | 
|---|
 | 203 |  * \param *chiral pointer to array with both chiral values
 | 
|---|
 | 204 |  * \param *factors pointer to array with length and radius factor
 | 
|---|
 | 205 |  * \param seed random number seed
 | 
|---|
 | 206 |  * \param numbercell number of atoms in unit cell, needed as length of \a *randomness 
 | 
|---|
 | 207 |  * \param *randomness for each atom in unit cell a factor between 0..1, giving its probability of appearance
 | 
|---|
 | 208 |  */
 | 
|---|
 | 209 | void AddSheetInfo(char *filename, int *axis, int *chiral, int *factors, int seed, int numbercell, double *randomness)
 | 
|---|
 | 210 | {
 | 
|---|
 | 211 |   int i;
 | 
|---|
 | 212 |   if ((filename == NULL) || (axis == NULL) || (chiral == NULL) || (factors == NULL)) {
 | 
|---|
 | 213 |     fprintf(stdout, "ERROR: AddSheetInfo - ptr to filename, axis, chiral or factors NULL\n");
 | 
|---|
 | 214 |     exit(255);
 | 
|---|
 | 215 |   }
 | 
|---|
 | 216 |   // open for writing and append
 | 
|---|
 | 217 |   FILE *file2 = fopen(filename,"a");
 | 
|---|
 | 218 |   if (file2 == NULL) {
 | 
|---|
 | 219 |     fprintf(stderr, "ERROR: AddSheetInfo - can't open %s for appending\n", filename);
 | 
|---|
 | 220 |     exit(255);
 | 
|---|
 | 221 |   }
 | 
|---|
 | 222 |   // Add primitive vectors as comment
 | 
|---|
 | 223 |   fprintf(file2,"\n****************************************\n\n");
 | 
|---|
 | 224 |   fprintf(file2,"Axis %d\t%d\t%d\n", axis[0], axis[1], axis[2]);
 | 
|---|
 | 225 |   fprintf(file2,"(n,m) %d\t%d\n", chiral[0], chiral[1]);
 | 
|---|
 | 226 |   fprintf(file2,"factors %d\t%d\n", factors[0], factors[1]);
 | 
|---|
 | 227 |   fprintf(file2,"seed %d\n", seed);
 | 
|---|
 | 228 |   fprintf(file2,"\nRandomness\n");
 | 
|---|
 | 229 |   for (i=0; i<numbercell; i++) {
 | 
|---|
 | 230 |     fprintf(file2,"%d %g\n", i, randomness[i]);
 | 
|---|
 | 231 |   }
 | 
|---|
 | 232 |   fclose(file2);
 | 
|---|
 | 233 | }
 | 
|---|
 | 234 | 
 | 
|---|
 | 235 | 
 | 
|---|
 | 236 | // ================================= Vector functions ==============================
 | 
|---|
 | 237 | 
 | 
|---|
 | 238 | /** Transforms a vector b with a matrix A: Ab = x.
 | 
|---|
 | 239 |  * \param **matrixref reference to NDIMxNDIM matrix A
 | 
|---|
 | 240 |  * \param *vectorref reference to NDIM vector b
 | 
|---|
 | 241 |  * \return reference to resulting NDIM vector Ab = x
 | 
|---|
 | 242 |  */
 | 
|---|
 | 243 | double *MatrixTrafo(double **matrixref, double *vectorref)
 | 
|---|
 | 244 | {
 | 
|---|
 | 245 |   if ((matrixref == NULL) || (vectorref == NULL)) {
 | 
|---|
 | 246 |     fprintf(stderr, "ERROR: MatrixTrafo: ptr to matrixref or vectorref NULL\n");
 | 
|---|
 | 247 |     exit(255);
 | 
|---|
 | 248 |   }
 | 
|---|
 | 249 |   //double *returnvector = Calloc(sizeof(double)*NDIM, 0., "MatrixTrafo: returnvector");
 | 
|---|
 | 250 |   double *returnvector = calloc(sizeof(double)*NDIM, 0.);
 | 
|---|
 | 251 |   if (returnvector == NULL) {
 | 
|---|
 | 252 |     fprintf(stderr, "ERROR: MatrixTrafo - returnvector\n");
 | 
|---|
 | 253 |     exit(255);
 | 
|---|
 | 254 |   }
 | 
|---|
 | 255 |   int i,j;
 | 
|---|
 | 256 |   
 | 
|---|
 | 257 |   for (i=0;i<NDIM;i++)
 | 
|---|
 | 258 |     for (j=0;j<NDIM;j++)
 | 
|---|
 | 259 |       returnvector[j] += matrixref[i][j] * vectorref[i];
 | 
|---|
 | 260 |       
 | 
|---|
 | 261 |   return returnvector;  
 | 
|---|
 | 262 | }
 | 
|---|
 | 263 | double *MatrixTrafoInverse(double *vectorref, double **matrixref)
 | 
|---|
 | 264 | {
 | 
|---|
 | 265 |   if ((matrixref == NULL) || (vectorref == NULL)) {
 | 
|---|
 | 266 |     fprintf(stderr, "ERROR: MatrixTrafo: ptr to matrixref or vectorref NULL\n");
 | 
|---|
 | 267 |     exit(255);
 | 
|---|
 | 268 |   }
 | 
|---|
 | 269 |   //double *returnvector = Calloc(sizeof(double)*NDIM, 0., "MatrixTrafo: returnvector");
 | 
|---|
 | 270 |   double *returnvector = calloc(sizeof(double)*NDIM, 0.);
 | 
|---|
 | 271 |   if (returnvector == NULL) {
 | 
|---|
 | 272 |     fprintf(stderr, "ERROR: MatrixTrafo - returnvector\n");
 | 
|---|
 | 273 |     exit(255);
 | 
|---|
 | 274 |   }
 | 
|---|
 | 275 |   int i,j;
 | 
|---|
 | 276 |   
 | 
|---|
 | 277 |   for (i=0;i<NDIM;i++)
 | 
|---|
 | 278 |     for (j=0;j<NDIM;j++)
 | 
|---|
 | 279 |       returnvector[i] += matrixref[i][j] * vectorref[j];
 | 
|---|
 | 280 |       
 | 
|---|
 | 281 |   return returnvector;  
 | 
|---|
 | 282 | }
 | 
|---|
 | 283 | 
 | 
|---|
 | 284 | /** Inverts a NDIMxNDIM matrix.
 | 
|---|
 | 285 |  * \param **matrix to be inverted
 | 
|---|
 | 286 |  * \param **inverse allocated space for inverse of \a **matrix
 | 
|---|
 | 287 |  */
 | 
|---|
 | 288 | void MatrixInversion(double **matrix, double **inverse) 
 | 
|---|
 | 289 | {
 | 
|---|
 | 290 |   if ((matrix == NULL) || (inverse == NULL)) {
 | 
|---|
 | 291 |     fprintf(stderr, "ERROR: MatrixInversion: ptr to matrix or inverse NULL\n");
 | 
|---|
 | 292 |     exit(255);
 | 
|---|
 | 293 |   }
 | 
|---|
 | 294 |   // determine inverse
 | 
|---|
 | 295 |   double det = Determinant(matrix);
 | 
|---|
 | 296 |   inverse[0][0] = (matrix[1][1]*matrix[2][2] - matrix[1][2]*matrix[2][1])/det;  
 | 
|---|
 | 297 |   inverse[1][0] = (matrix[0][2]*matrix[2][1] - matrix[0][1]*matrix[2][2])/det;  
 | 
|---|
 | 298 |   inverse[2][0] = (matrix[0][1]*matrix[1][2] - matrix[0][2]*matrix[1][1])/det;  
 | 
|---|
 | 299 |   inverse[0][1] = (matrix[1][2]*matrix[2][0] - matrix[1][0]*matrix[2][2])/det;  
 | 
|---|
 | 300 |   inverse[1][1] = (matrix[0][0]*matrix[2][2] - matrix[0][2]*matrix[2][0])/det;  
 | 
|---|
 | 301 |   inverse[2][1] = (matrix[0][2]*matrix[1][0] - matrix[0][0]*matrix[1][2])/det;  
 | 
|---|
 | 302 |   inverse[0][2] = (matrix[1][0]*matrix[2][1] - matrix[1][1]*matrix[2][0])/det;  
 | 
|---|
 | 303 |   inverse[1][2] = (matrix[0][1]*matrix[2][0] - matrix[0][0]*matrix[2][1])/det;  
 | 
|---|
 | 304 |   inverse[2][2] = (matrix[0][0]*matrix[1][1] - matrix[0][1]*matrix[1][0])/det;
 | 
|---|
 | 305 |    
 | 
|---|
 | 306 |   // check inverse
 | 
|---|
 | 307 |   int flag = 0; 
 | 
|---|
 | 308 |   int i,j,k;
 | 
|---|
 | 309 |   double tmp;   
 | 
|---|
 | 310 |   fprintf(stdout, "Checking inverse ... ");
 | 
|---|
 | 311 |   for (i=0;i<NDIM;i++)
 | 
|---|
 | 312 |     for (j=0;j<NDIM;j++) {
 | 
|---|
 | 313 |       tmp = 0.;
 | 
|---|
 | 314 |       for (k=0;k<NDIM;k++)
 | 
|---|
 | 315 |         tmp += matrix[i][k]*inverse[j][k];
 | 
|---|
 | 316 |       if (!flag) {
 | 
|---|
 | 317 |         if (i == j) {
 | 
|---|
 | 318 |           flag = (fabs(1.-tmp) > MYEPSILON) ? 1 : 0;
 | 
|---|
 | 319 |         } else {
 | 
|---|
 | 320 |           flag = (fabs(tmp) > MYEPSILON) ? 1 : 0;
 | 
|---|
 | 321 |         }        
 | 
|---|
 | 322 |       }
 | 
|---|
 | 323 |     }
 | 
|---|
 | 324 |   if (!flag)
 | 
|---|
 | 325 |     fprintf(stdout, "ok\n");
 | 
|---|
 | 326 |   else
 | 
|---|
 | 327 |     fprintf(stdout, "false\n");
 | 
|---|
 | 328 | }
 | 
|---|
 | 329 | 
 | 
|---|
 | 330 | /** Flips to double numbers in place.
 | 
|---|
 | 331 |  * \param *number1 pointer to first double
 | 
|---|
 | 332 |  * \param *number2 pointer to second double
 | 
|---|
 | 333 |  */
 | 
|---|
 | 334 | void flip(double *number1, double *number2)
 | 
|---|
 | 335 | {
 | 
|---|
 | 336 |   if ((number1 == NULL) || (number2 == NULL)) {
 | 
|---|
 | 337 |     fprintf(stderr, "ERROR: flip: ptr to number1 or number2 NULL\n");
 | 
|---|
 | 338 |     exit(255);
 | 
|---|
 | 339 |   }
 | 
|---|
 | 340 |   double tmp = *number1;
 | 
|---|
 | 341 |   *number1 = *number2;
 | 
|---|
 | 342 |   *number2 = tmp;
 | 
|---|
 | 343 | }
 | 
|---|
 | 344 | 
 | 
|---|
 | 345 | /** Transposes a matrix.
 | 
|---|
 | 346 |  * \param **matrix pointer to NDIMxNDIM-matrix array
 | 
|---|
 | 347 |  */
 | 
|---|
 | 348 | void Transpose(double **matrix)
 | 
|---|
 | 349 | {
 | 
|---|
 | 350 |   if (matrix == NULL) {
 | 
|---|
 | 351 |     fprintf(stderr, "ERROR: Transpose: ptr to matrix NULL\n");
 | 
|---|
 | 352 |     exit(255);
 | 
|---|
 | 353 |   }
 | 
|---|
 | 354 |   int i,j;
 | 
|---|
 | 355 |   for (i=0;i<NDIM;i++)
 | 
|---|
 | 356 |     for (j=0;j<i;j++)
 | 
|---|
 | 357 |       flip(&matrix[i][j],&matrix[j][i]);
 | 
|---|
 | 358 | }
 | 
|---|
 | 359 |  
 | 
|---|
 | 360 | 
 | 
|---|
 | 361 | /** Computes the determinant of a NDIMxNDIM matrix.
 | 
|---|
 | 362 |  * \param **matrix pointer to matrix array
 | 
|---|
 | 363 |  * \return det(matrix)
 | 
|---|
 | 364 |  */
 | 
|---|
 | 365 | double Determinant(double **matrix) {
 | 
|---|
 | 366 |   if (matrix == NULL) {
 | 
|---|
 | 367 |     fprintf(stderr, "ERROR: Determinant: ptr to Determinant NULL\n");
 | 
|---|
 | 368 |     exit(255);
 | 
|---|
 | 369 |   }
 | 
|---|
 | 370 |   double det =   matrix[0][0] * (matrix[1][1]*matrix[2][2] - matrix[1][2]*matrix[2][1])
 | 
|---|
 | 371 |                - matrix[1][1] * (matrix[0][0]*matrix[2][2] - matrix[0][2]*matrix[2][0])
 | 
|---|
 | 372 |                + matrix[2][2] * (matrix[0][0]*matrix[1][1] - matrix[0][1]*matrix[1][0]);  
 | 
|---|
 | 373 |   return det;
 | 
|---|
 | 374 | }
 | 
|---|
 | 375 | 
 | 
|---|
 | 376 | /** Adds \a *vector1 onto \a *vector2 coefficient-wise.
 | 
|---|
 | 377 |  * \param *vector1 first vector, on return contains sum
 | 
|---|
 | 378 |  * \param *vector2 vector which is projected
 | 
|---|
 | 379 |  * \return sum of the two vectors
 | 
|---|
 | 380 |  */
 | 
|---|
 | 381 | double * VectorAdd(double *vector1, double *vector2)
 | 
|---|
 | 382 | {
 | 
|---|
 | 383 |   if ((vector1 == NULL) || (vector2 == NULL)) {
 | 
|---|
 | 384 |     fprintf(stderr, "ERROR: VectorAdd: ptr to vector1 or vector2 NULL\n");
 | 
|---|
 | 385 |     exit(255);
 | 
|---|
 | 386 |   }
 | 
|---|
 | 387 |   //double *returnvector = Calloc(sizeof(double)*NDIM, 0., "VectorAdd: returnvector");
 | 
|---|
 | 388 |   double *returnvector = calloc(sizeof(double)*NDIM, 0.);
 | 
|---|
 | 389 |   if (returnvector == NULL) {
 | 
|---|
 | 390 |     fprintf(stderr, "ERROR: VectorAdd - returnvector\n");
 | 
|---|
 | 391 |     exit(255);
 | 
|---|
 | 392 |   }
 | 
|---|
 | 393 |   int i;
 | 
|---|
 | 394 |   
 | 
|---|
 | 395 |   for (i=0;i<NDIM;i++)
 | 
|---|
 | 396 |     returnvector[i] = vector1[i] + vector2[i];
 | 
|---|
 | 397 |     
 | 
|---|
 | 398 |   return returnvector;
 | 
|---|
 | 399 | }
 | 
|---|
 | 400 | 
 | 
|---|
 | 401 | /**  Fixed GramSchmidt-Orthogonalization for NDIM vectors
 | 
|---|
 | 402 |  * \param @orthvector reference to NDIMxNDIM matrix
 | 
|---|
 | 403 |  * \param @orthbetrag reference to NDIM vector with vector magnitudes
 | 
|---|
 | 404 |  * \param @axis major-, minor- and noaxis for specific order for the GramSchmidt procedure
 | 
|---|
 | 405 |  */
 | 
|---|
 | 406 | void Orthogonalize(double **orthvector, int *axis)
 | 
|---|
 | 407 | {
 | 
|---|
 | 408 |   if ((orthvector == NULL) || (axis == NULL)) {
 | 
|---|
 | 409 |     fprintf(stderr, "ERROR: Orthogonalize: ptr to orthvector or axis NULL\n");
 | 
|---|
 | 410 |     exit(255);
 | 
|---|
 | 411 |   }
 | 
|---|
| [1b192d] | 412 |   double betrag;
 | 
|---|
| [a0bcf1] | 413 |   int i;
 | 
|---|
 | 414 |   
 | 
|---|
 | 415 |   // first vector is untouched
 | 
|---|
 | 416 |   // second vector
 | 
|---|
| [1b192d] | 417 |   betrag = Projection(orthvector[axis[1]], orthvector[axis[0]]); 
 | 
|---|
 | 418 |   fprintf(stdout,"%lg\t",betrag);
 | 
|---|
| [a0bcf1] | 419 |   for (i=0;i<NDIM;i++)
 | 
|---|
| [1b192d] | 420 |      orthvector[axis[1]][i] -= orthvector[axis[0]][i] * betrag;
 | 
|---|
| [a0bcf1] | 421 |   // third vector
 | 
|---|
| [1b192d] | 422 |   betrag = Projection(orthvector[axis[0]], orthvector[axis[2]]); 
 | 
|---|
 | 423 |   fprintf(stdout,"%lg\t",betrag);
 | 
|---|
| [a0bcf1] | 424 |   for (i=0;i<NDIM;i++)
 | 
|---|
| [1b192d] | 425 |      orthvector[axis[2]][i] -= orthvector[axis[0]][i] * betrag;
 | 
|---|
 | 426 |   betrag = Projection(orthvector[axis[1]], orthvector[axis[2]]); 
 | 
|---|
 | 427 |   fprintf(stdout,"%lg\n",betrag);
 | 
|---|
 | 428 |   for (i=0;i<NDIM;i++)
 | 
|---|
 | 429 |      orthvector[axis[2]][i] -= orthvector[axis[1]][i] * betrag;
 | 
|---|
| [a0bcf1] | 430 | }
 | 
|---|
 | 431 | 
 | 
|---|
 | 432 | /** Computes projection of \a *vector2 onto \a *vector1.
 | 
|---|
 | 433 |  * \param *vector1 reference vector
 | 
|---|
 | 434 |  * \param *vector2 vector which is projected
 | 
|---|
 | 435 |  * \return projection 
 | 
|---|
 | 436 |  */
 | 
|---|
 | 437 | double Projection(double *vector1, double *vector2)
 | 
|---|
 | 438 | {
 | 
|---|
 | 439 |   if ((vector1 == NULL) || (vector2 == NULL)) {
 | 
|---|
 | 440 |     fprintf(stderr, "ERROR: Projection: ptr to vector1 or vector2 NULL\n");
 | 
|---|
 | 441 |     exit(255);
 | 
|---|
 | 442 |   }
 | 
|---|
 | 443 |   return (ScalarProduct(vector1, vector2)/Norm(vector1)/Norm(vector2));
 | 
|---|
 | 444 | }
 | 
|---|
 | 445 | 
 | 
|---|
 | 446 | /** Determine scalar product between two vectors.
 | 
|---|
 | 447 |  * \param *vector1 first vector
 | 
|---|
 | 448 |  * \param *vector2 second vector
 | 
|---|
 | 449 |  * \return scalar product
 | 
|---|
 | 450 |  */
 | 
|---|
 | 451 | double ScalarProduct(double *vector1, double *vector2)
 | 
|---|
 | 452 | {
 | 
|---|
 | 453 |   if ((vector1 == NULL) || (vector2 == NULL)) {
 | 
|---|
 | 454 |     fprintf(stderr, "ERROR: ScalarProduct: ptr to vector1 or vector2 NULL\n");
 | 
|---|
 | 455 |     exit(255);
 | 
|---|
 | 456 |   }
 | 
|---|
 | 457 |   double scp = 0.;
 | 
|---|
 | 458 |   int i;
 | 
|---|
 | 459 |   
 | 
|---|
 | 460 |   for (i=0;i<NDIM;i++)
 | 
|---|
 | 461 |     scp += vector1[i] * vector2[i];
 | 
|---|
 | 462 |     
 | 
|---|
 | 463 |   return scp;
 | 
|---|
 | 464 | }
 | 
|---|
 | 465 | 
 | 
|---|
 | 466 | /** Computes norm of \a *vector.
 | 
|---|
 | 467 |  * \param *vector pointer to NDIM vector
 | 
|---|
 | 468 |  * \return norm of \a *vector
 | 
|---|
 | 469 |  */
 | 
|---|
 | 470 | double Norm(double *vector) 
 | 
|---|
 | 471 | {
 | 
|---|
 | 472 |   if (vector == NULL) {
 | 
|---|
 | 473 |     fprintf(stderr, "ERROR: Norm: ptr to vector NULL\n");
 | 
|---|
 | 474 |     exit(255);
 | 
|---|
 | 475 |   }
 | 
|---|
 | 476 |   return sqrt(ScalarProduct(vector, vector));
 | 
|---|
 | 477 | }
 | 
|---|
 | 478 | 
 | 
|---|
 | 479 | /** Prints vector to \a *file.
 | 
|---|
 | 480 |  * \param *file file or e.g. stdout
 | 
|---|
 | 481 |  * \param *vector vector to be printed
 | 
|---|
 | 482 |  */
 | 
|---|
 | 483 | void PrintVector(FILE *file, double *vector)
 | 
|---|
 | 484 | {
 | 
|---|
 | 485 |   if ((file == NULL) || (vector == NULL)) {
 | 
|---|
 | 486 |     fprintf(stderr, "ERROR: PrintVector: ptr to file or vector NULL\n");
 | 
|---|
 | 487 |     exit(255);
 | 
|---|
 | 488 |   }
 | 
|---|
 | 489 |   int i;
 | 
|---|
 | 490 |   for (i=0;i<NDIM;i++)
 | 
|---|
 | 491 |     fprintf(file, "%5.5f\t", vector[i]);
 | 
|---|
 | 492 |   fprintf(file, "\n");
 | 
|---|
 | 493 | }
 | 
|---|
 | 494 | 
 | 
|---|
 | 495 | /** Prints matrix to \a *file.
 | 
|---|
 | 496 |  * \param *file file or e.g. stdout
 | 
|---|
 | 497 |  * \param **matrix matrix to be printed
 | 
|---|
 | 498 |  */
 | 
|---|
 | 499 | void PrintMatrix(FILE *file, double **matrix)
 | 
|---|
 | 500 | {
 | 
|---|
 | 501 |   if ((file == NULL) || (matrix == NULL)) {
 | 
|---|
 | 502 |     fprintf(stderr, "ERROR: PrintMatrix: ptr to file or matrix NULL\n");
 | 
|---|
 | 503 |     exit(255);
 | 
|---|
 | 504 |   }
 | 
|---|
 | 505 |   int i,j;
 | 
|---|
 | 506 |   for (i=0;i<NDIM;i++) {
 | 
|---|
 | 507 |     for (j=0;j<NDIM;j++)
 | 
|---|
 | 508 |       fprintf(file, "%5.5f\t", matrix[i][j]);
 | 
|---|
 | 509 |     fprintf(file, "\n");
 | 
|---|
 | 510 |   }
 | 
|---|
 | 511 | }
 | 
|---|
 | 512 | 
 | 
|---|
 | 513 | /** Returns greatest common denominator.
 | 
|---|
 | 514 |  * \param a first integer
 | 
|---|
 | 515 |  * \param b second integer
 | 
|---|
 | 516 |  * \return GCD of a and b
 | 
|---|
 | 517 |  */
 | 
|---|
 | 518 | int GCD(int a, int b)
 | 
|---|
 | 519 | {
 | 
|---|
 | 520 |   int c;
 | 
|---|
 | 521 |   do {
 | 
|---|
 | 522 |     c = a % b;        /* Rest of integer divison */
 | 
|---|
 | 523 |     a = b; b = c;              /* flip the two values */
 | 
|---|
 | 524 |   } while( c != 0);
 | 
|---|
 | 525 |   return a;
 | 
|---|
 | 526 | }
 | 
|---|
 | 527 | 
 | 
|---|
 | 528 | /** Determines the biggest diameter of a sheet.
 | 
|---|
 | 529 |  * \param **matrix reference to NDIMxNDIM matrix with row vectors
 | 
|---|
 | 530 |  * \param *axis reference to NDIM vector with permutation of axis indices [0,1,2]
 | 
|---|
 | 531 |  * \param *factors factorsfor axis[0] and axis[1]
 | 
|---|
 | 532 |  * \return biggest diameter of sheet
 | 
|---|
 | 533 | */
 | 
|---|
 | 534 | double DetermineBiggestDiameter(double **matrix, int *axis, int *factors)
 | 
|---|
 | 535 | {
 | 
|---|
 | 536 |   if ((axis == NULL) || (factors == NULL) || (matrix == NULL)) {
 | 
|---|
 | 537 |     fprintf(stderr, "ERROR: DetermineBiggestDiameter: ptr to factors, axis or matrix NULL\n");
 | 
|---|
 | 538 |     exit(255);
 | 
|---|
 | 539 |   }
 | 
|---|
 | 540 |   double diameter[2] = {0.,0.};
 | 
|---|
 | 541 |   int i, biggest;
 | 
|---|
 | 542 |   
 | 
|---|
 | 543 |   for (i=0;i<NDIM;i++) {
 | 
|---|
 | 544 |     diameter[0] += (matrix[axis[0]][i]*factors[0] - matrix[axis[1]][i]*factors[1]) * (matrix[axis[0]][i]*factors[0] - matrix[axis[1]][i]*factors[1]);
 | 
|---|
 | 545 |     diameter[1] += (matrix[axis[0]][i]*factors[0] + matrix[axis[1]][i]*factors[1]) * (matrix[axis[0]][i]*factors[0] + matrix[axis[1]][i]*factors[1]);
 | 
|---|
 | 546 |   }
 | 
|---|
 | 547 |   if ((diameter[0] - diameter[1]) > MYEPSILON) {
 | 
|---|
 | 548 |     biggest = 0;
 | 
|---|
 | 549 |   } else {
 | 
|---|
 | 550 |     biggest = 1;
 | 
|---|
 | 551 |   }
 | 
|---|
 | 552 |   diameter[0] = sqrt(diameter[0]);
 | 
|---|
 | 553 |   diameter[1] = sqrt(diameter[1]);
 | 
|---|
 | 554 |   fprintf(stdout, "\n\nMajor diameter of the sheet is %5.5f, minor diameter is %5.5f.\n",diameter[biggest],diameter[(biggest+1)%2]);
 | 
|---|
 | 555 | 
 | 
|---|
 | 556 |   return diameter[biggest];
 | 
|---|
 | 557 | } 
 | 
|---|
 | 558 | 
 | 
|---|
 | 559 | /** Determines the center of gravity of atoms in a buffer \a bufptr with given \a number
 | 
|---|
 | 560 |  * \param *bufptr pointer to char buffer with atoms in (name x y z)-manner
 | 
|---|
 | 561 |  * \param number number of atoms/lines to scan
 | 
|---|
 | 562 |  * \return NDIM vector (allocated doubles) pointing back to center of gravity
 | 
|---|
 | 563 |  */
 | 
|---|
 | 564 | double * CenterOfGravity(char *bufptr, int number)
 | 
|---|
 | 565 | {
 | 
|---|
 | 566 |   if (bufptr == NULL) {
 | 
|---|
 | 567 |     fprintf(stderr, "ERROR: CenterOfGravity - bufptr NULL\n");
 | 
|---|
 | 568 |     exit(255);
 | 
|---|
 | 569 |   }
 | 
|---|
 | 570 |   double *cog = calloc(sizeof(double)*NDIM, 0.);
 | 
|---|
 | 571 |   if (cog == NULL) {
 | 
|---|
 | 572 |     fprintf(stderr, "ERROR: CenterOfGravity - cog\n");
 | 
|---|
 | 573 |     exit(255);
 | 
|---|
 | 574 |   }
 | 
|---|
 | 575 |   double *atom = Malloc(sizeof(double)*NDIM, "CenterOfGravity: atom");
 | 
|---|
 | 576 |   char name[255], line[255];
 | 
|---|
 | 577 |   int i,j;
 | 
|---|
 | 578 |   
 | 
|---|
 | 579 |   // Determine center of gravity
 | 
|---|
 | 580 |   for (i=0;i<number;i++) {
 | 
|---|
 | 581 |     bufptr += GetNextline(bufptr, line);
 | 
|---|
 | 582 |     sscanf(line, "%s %lg %lg %lg", name, &atom[0], &atom[1], &atom[2]);
 | 
|---|
 | 583 |     //fprintf(stdout, "Read Atom %s %lg %lg %lg\n", name, atom[0], atom[1], atom[2]);
 | 
|---|
 | 584 |     for (j=0;j<NDIM;j++)
 | 
|---|
 | 585 |       cog[j] += atom[j];
 | 
|---|
 | 586 |   }
 | 
|---|
 | 587 |   for (i=0;i<NDIM;i++)
 | 
|---|
 | 588 |     cog[i] /= -number;
 | 
|---|
 | 589 |     
 | 
|---|
 | 590 |   Free(atom, "CenterOfGravity: atom");
 | 
|---|
 | 591 |   return cog;
 | 
|---|
 | 592 | }
 | 
|---|
 | 593 | 
 | 
|---|
| [1b192d] | 594 | /** Creates orthogonal vectors to directions axis[0] and axis[1], assuming that axis[2] is always orthogonal.
 | 
|---|
 | 595 |  * \param **OrthoVector contains vectors set on return with axis[2] equal to Vector[axis[2]]
 | 
|---|
 | 596 |  * \param **Vector vectors to orthogonalize against
 | 
|---|
 | 597 |  * \param *axis lookup for which direction is which.
 | 
|---|
 | 598 |  */
 | 
|---|
 | 599 | void CreateOrthogonalAxisVectors(double **OrthoVector, double **Vector, int *axis) {
 | 
|---|
 | 600 |   int i,j;
 | 
|---|
 | 601 |   double factor;
 | 
|---|
 | 602 |   // allocate memory
 | 
|---|
 | 603 |   int *TempAxis = (int *) Malloc(sizeof(int)*NDIM, "Main: *TempAxis");
 | 
|---|
 | 604 |   double **TempVectors = (double **) Malloc(sizeof(double *)*NDIM, "Main: *TempVectors");
 | 
|---|
 | 605 |   for (i=0; i<NDIM; i++)
 | 
|---|
 | 606 |     TempVectors[i] = (double *) Malloc(sizeof(double)*NDIM, "Main: TempVectors");
 | 
|---|
 | 607 |   
 | 
|---|
 | 608 |   for (i=0; i<NDIM; i++)
 | 
|---|
 | 609 |     for (j=0; j<NDIM; j++)
 | 
|---|
 | 610 |       TempVectors[i][j] = Vector[i][j];
 | 
|---|
 | 611 |   // GramSchmidt generates Vector[1] orthogonal to Vector[0] and Vector[2] ortho. to Vector[1] and Vector[0]!
 | 
|---|
 | 612 |   TempAxis[0] = axis[2];  // (axis 2 is the orthogonal plane axis)
 | 
|---|
 | 613 |   TempAxis[1] = axis[0];
 | 
|---|
 | 614 |   TempAxis[2] = axis[1];
 | 
|---|
 | 615 |   Orthogonalize(TempVectors, TempAxis);
 | 
|---|
 | 616 |   factor = Norm(Vector[axis[0]])/Norm(TempVectors[TempAxis[2]]);
 | 
|---|
 | 617 |   factor *= (Projection(TempVectors[TempAxis[2]], Vector[axis[0]]) > 0) ? 1. : -1.;
 | 
|---|
 | 618 |   for (i=0; i<NDIM; i++)
 | 
|---|
 | 619 |     OrthoVector[axis[0]][i] = TempVectors[TempAxis[2]][i]*factor;
 | 
|---|
 | 620 |   
 | 
|---|
 | 621 |   TempAxis[1] = axis[1];
 | 
|---|
 | 622 |   TempAxis[2] = axis[0];
 | 
|---|
 | 623 |   for (i=0; i<NDIM; i++)
 | 
|---|
 | 624 |     for (j=0; j<NDIM; j++)
 | 
|---|
 | 625 |       TempVectors[i][j] = Vector[i][j];
 | 
|---|
 | 626 |   Orthogonalize(TempVectors, TempAxis);
 | 
|---|
 | 627 |   factor = Norm(Vector[axis[1]])/Norm(TempVectors[TempAxis[2]]);
 | 
|---|
 | 628 |   factor *= (Projection(TempVectors[TempAxis[2]], Vector[axis[1]]) > 0) ? 1. : -1.;
 | 
|---|
 | 629 |   for (i=0; i<NDIM; i++)
 | 
|---|
 | 630 |     OrthoVector[axis[1]][i] = TempVectors[TempAxis[2]][i]*factor;
 | 
|---|
 | 631 |   
 | 
|---|
 | 632 |   for (i=0; i<NDIM; i++)
 | 
|---|
 | 633 |     OrthoVector[axis[2]][i] = Vector[axis[2]][i];
 | 
|---|
 | 634 |   //print vectors
 | 
|---|
 | 635 |   fprintf(stdout, "Orthogonal vectors are: \n");
 | 
|---|
 | 636 |   for (i=0; i<NDIM; i++) {
 | 
|---|
 | 637 |     for (j=0; j<NDIM; j++) 
 | 
|---|
 | 638 |       fprintf(stdout, "%lg\t", OrthoVector[axis[i]][j]);
 | 
|---|
 | 639 |     fprintf(stdout, "\n");
 | 
|---|
 | 640 |   }
 | 
|---|
 | 641 |   
 | 
|---|
 | 642 |   // free memory
 | 
|---|
 | 643 |   Free(TempAxis, "CreateOrthogonalAxisVectors: *TempAxis");
 | 
|---|
 | 644 |   for (i=0; i<NDIM; i++ )
 | 
|---|
 | 645 |     Free(TempVectors[i], "CreateOrthogonalAxisVectors: TempVectors");
 | 
|---|
 | 646 |   Free(TempVectors, "CreateOrthogonalAxisVectors: *TempVectors");
 | 
|---|
 | 647 | };
 | 
|---|
 | 648 | 
 | 
|---|
| [a0bcf1] | 649 | // ================================= other functions ==============================
 | 
|---|
 | 650 | 
 | 
|---|
| [1b192d] | 651 | /** Prints a debug message.
 | 
|---|
 | 652 |  * \param *msg debug message
 | 
|---|
 | 653 |  */
 | 
|---|
| [a0bcf1] | 654 | void Debug(char *msg)
 | 
|---|
 | 655 | {
 | 
|---|
 | 656 |   if (msg == NULL) {
 | 
|---|
 | 657 |     fprintf(stderr, "ERROR: Debug: ptr to msg NULL\n");
 | 
|---|
 | 658 |     exit(255);
 | 
|---|
 | 659 |   }
 | 
|---|
 | 660 |   fprintf(stdout, "%s", msg);
 | 
|---|
 | 661 | }
 | 
|---|
 | 662 | 
 | 
|---|
| [1b192d] | 663 | 
 | 
|---|
| [a0bcf1] | 664 | // --------------------------------------- M A I N ---------------------------------------------------
 | 
|---|
 | 665 | int main(int argc, char **argv) {
 | 
|---|
 | 666 |         char *filename = NULL; 
 | 
|---|
 | 667 |   char *CellFilename = NULL, *SheetFilename = NULL, *TubeFilename = NULL, *TorusFilename = NULL;
 | 
|---|
 | 668 |   char *SheetFilenameAligned = NULL, *TubeFilenameAligned = NULL;
 | 
|---|
| [1b192d] | 669 |         double **Vector, **OrthoVector, **Recivector = NULL, **Tubevector = NULL, **TubevectorInverse = NULL;
 | 
|---|
| [a0bcf1] | 670 |   double *atom = NULL, *atom_transformed = NULL;
 | 
|---|
 | 671 |   double *x = NULL, *coord = NULL, *tempvector = NULL, *offset = NULL;
 | 
|---|
 | 672 |   //double *cog = NULL, *cog_projected = NULL;
 | 
|---|
 | 673 |   char stage[6];
 | 
|---|
 | 674 |   int axis[NDIM] = {0,1,2}, chiral[2] = {1,1}, factors[NDIM] = {1,1,1};
 | 
|---|
 | 675 |   char name[255], line[255], input = 'n';
 | 
|---|
 | 676 |   char *CellBuffer = NULL, *SheetBuffer = NULL, *TubeBuffer = NULL, *bufptr = NULL;
 | 
|---|
 | 677 |   double *randomness = NULL, percentage; // array with percentages for presence in sheet and beyond
 | 
|---|
 | 678 |   int i,j, ggT;
 | 
|---|
 | 679 |   int length;
 | 
|---|
 | 680 |   
 | 
|---|
 | 681 |         // Read command line arguments  
 | 
|---|
 | 682 |         if (argc <= 2) {
 | 
|---|
 | 683 |                 fprintf(stdout, "Usage: %s <file> <stage>\n\tWhere <file> specifies a file to start from <stage> or a basename\n\t<stage> is either None, Cell, Sheet, Tube, Torus and specifies where to start the rolling up from.\n\tNote: The .Aligned. files can't be used (rotation is essential).\n", argv[0]);
 | 
|---|
 | 684 |                 exit(255);
 | 
|---|
 | 685 |         } else {
 | 
|---|
 | 686 |                 // store variables
 | 
|---|
 | 687 |                 filename = argv[1];
 | 
|---|
 | 688 |                 strncpy(stage, argv[2], 5);
 | 
|---|
 | 689 |     fprintf(stdout, "I will begin at stage %s.\n", stage);
 | 
|---|
 | 690 |                 
 | 
|---|
 | 691 |                 // build filenames
 | 
|---|
 | 692 |     char *ptr = strrchr(filename, '.');
 | 
|---|
| [1f4209] | 693 |     length = strlen(filename);
 | 
|---|
| [a0bcf1] | 694 |     if (ptr != NULL) {
 | 
|---|
 | 695 |       length = ((int)(ptr-filename) >= length-5) ? (int)(ptr-filename) : length;  
 | 
|---|
 | 696 |       filename[length] = '\0'; // eventueller
 | 
|---|
 | 697 |     }
 | 
|---|
 | 698 |     fprintf(stdout, "I will use \'%s' as base for the filenames.\n\n", filename);
 | 
|---|
 | 699 |     CellFilename = Malloc(sizeof(char)*(length+10), "Main: CellFilename");
 | 
|---|
 | 700 |     SheetFilename = Malloc(sizeof(char)*(length+11), "Main: SheetFilename");
 | 
|---|
 | 701 |     TubeFilename = Malloc(sizeof(char)*(length+10), "Main: TubeFilename");
 | 
|---|
 | 702 |     TorusFilename = Malloc(sizeof(char)*(length+11), "Main: TorusFilename");
 | 
|---|
 | 703 |     SheetFilenameAligned = Malloc(sizeof(char)*(length+20), "Main: SheetFilenameAligned");
 | 
|---|
 | 704 |     TubeFilenameAligned = Malloc(sizeof(char)*(length+19), "Main: TubeFilenameAligned");
 | 
|---|
 | 705 |                 sprintf(CellFilename, "%s.Cell.xyz", filename);
 | 
|---|
 | 706 |     sprintf(SheetFilename, "%s.Sheet.xyz", filename);
 | 
|---|
 | 707 |     sprintf(TubeFilename, "%s.Tube.xyz", filename);
 | 
|---|
 | 708 |     sprintf(TorusFilename, "%s.Torus.xyz", filename);
 | 
|---|
 | 709 |     sprintf(SheetFilenameAligned, "%s.Sheet.Aligned.xyz", filename);
 | 
|---|
 | 710 |     sprintf(TubeFilenameAligned, "%s.Tube.Aligned.xyz", filename);
 | 
|---|
 | 711 |         }
 | 
|---|
 | 712 |         
 | 
|---|
 | 713 |   // Allocating memory
 | 
|---|
 | 714 |   Debug ("Allocating memory\n");
 | 
|---|
 | 715 |   atom = (double *) Malloc(sizeof(double)*NDIM, "Main: atom");
 | 
|---|
 | 716 |   Vector = (double **) Malloc(sizeof(double *)*NDIM, "Main: *Vector");
 | 
|---|
| [1b192d] | 717 |   OrthoVector = (double **) Malloc(sizeof(double *)*NDIM, "Main: *OrthoVector");
 | 
|---|
| [a0bcf1] | 718 |   Recivector = (double **) Malloc(sizeof(double *)*NDIM, "Main: *Recivector");
 | 
|---|
 | 719 |   Tubevector = (double **) Malloc(sizeof(double *)*NDIM, "Main: *Tubevector");
 | 
|---|
 | 720 |   TubevectorInverse = (double **) Malloc(sizeof(double *)*NDIM, "Main: *TubevectorInverse");
 | 
|---|
 | 721 |   for (i=0; i<NDIM; i++ )  {
 | 
|---|
 | 722 |     Vector[i] = (double *) Malloc(sizeof(double)*NDIM, "Main: Vector");
 | 
|---|
| [1b192d] | 723 |     OrthoVector[i] = (double *) Malloc(sizeof(double)*NDIM, "Main: OrthoVector");
 | 
|---|
| [a0bcf1] | 724 |     Recivector[i] = (double *) Malloc(sizeof(double)*NDIM, "Main: Recivector");
 | 
|---|
 | 725 |     Tubevector[i] = (double *) Malloc(sizeof(double)*NDIM, "Main: Tubevector");
 | 
|---|
 | 726 |     TubevectorInverse[i] = (double *) Malloc(sizeof(double)*NDIM, "Main: TubevectorInverse");
 | 
|---|
 | 727 |   }
 | 
|---|
 | 728 |   
 | 
|---|
 | 729 |   // ======================== STAGE: Cell ==============================
 | 
|---|
 | 730 |   // The cell is simply created by transforming relative coordinates within the cell
 | 
|---|
 | 731 |   // into cartesian ones using the unit cell vectors.
 | 
|---|
 | 732 |     
 | 
|---|
 | 733 |   double volume;
 | 
|---|
 | 734 |   int numbercell;
 | 
|---|
 | 735 |   FILE *CellFile;
 | 
|---|
 | 736 | 
 | 
|---|
 | 737 |   Debug ("STAGE: None\n");
 | 
|---|
 | 738 |   // Read cell vectors from stdin or from file
 | 
|---|
 | 739 |         if (!strncmp(stage, "Non", 3)) {
 | 
|---|
 | 740 |         fprintf(stdout, "You will give the unit cell of the given substance.\nAfterwards, the programme will create a Sheet, a Tube and a Torus, each with their own xyz-file named accordingly.\n\n");
 | 
|---|
 | 741 |     fprintf(stdout, "Enter 1st primitive vector: ");
 | 
|---|
 | 742 |     fscanf(stdin, "%lg %lg %lg", &Vector[0][0], &Vector[0][1], &Vector[0][2]);  
 | 
|---|
 | 743 |     fprintf(stdout, "Enter 2nd primitive vector: ");
 | 
|---|
 | 744 |     fscanf(stdin, "%lg %lg %lg", &Vector[1][0], &Vector[1][1], &Vector[1][2]);  
 | 
|---|
 | 745 |     fprintf(stdout, "Enter 3rd primitive vector: ");
 | 
|---|
 | 746 |     fscanf(stdin, "%lg %lg %lg", &Vector[2][0], &Vector[2][1], &Vector[2][2]);
 | 
|---|
 | 747 |     fprintf(stdout,"Unit vectors are\n");
 | 
|---|
 | 748 |     PrintMatrix(stdout, Vector);  
 | 
|---|
 | 749 |         } else {
 | 
|---|
 | 750 |     char *ptr = NULL;
 | 
|---|
 | 751 |     char dummy[10];
 | 
|---|
 | 752 |     CellBuffer = bufptr = ReadBuffer(CellFilename, &length);
 | 
|---|
 | 753 |     for (i=0;i<NDIM;i++) {
 | 
|---|
 | 754 |       sprintf(dummy, "a(%i) = ", i+1);
 | 
|---|
 | 755 |       fprintf(stdout, "%s", dummy);
 | 
|---|
 | 756 |       while ((length = GetNextline(bufptr, line)) != -1) {
 | 
|---|
 | 757 |         bufptr += (length)*sizeof(char);
 | 
|---|
 | 758 |         //fprintf(stdout, "LINE at %p: %s\n", bufptr, line);
 | 
|---|
 | 759 |         if ((ptr = strstr(line, dummy)) != NULL)
 | 
|---|
 | 760 |           break;
 | 
|---|
 | 761 |       }
 | 
|---|
 | 762 |       ptr += strlen(dummy);
 | 
|---|
 | 763 |       sscanf(ptr, "%lg %lg %lg", &Vector[i][0], &Vector[i][1], &Vector[i][2]);
 | 
|---|
 | 764 |       fprintf(stdout, "%5.5lg %5.5lg %5.5lg\n", Vector[i][0], Vector[i][1], Vector[i][2]); 
 | 
|---|
 | 765 |     }
 | 
|---|
 | 766 |         }
 | 
|---|
 | 767 | 
 | 
|---|
 | 768 |   volume = Determinant(Vector);
 | 
|---|
 | 769 |   fprintf(stdout,"Volume is %lg\n", volume);
 | 
|---|
 | 770 |   MatrixInversion(Vector, Recivector);  
 | 
|---|
 | 771 |   //Transpose(Recivector);   // inverse's got row vectors if normal matrix' got column ones
 | 
|---|
 | 772 |   fprintf(stdout, "Reciprocal vector is ");
 | 
|---|
 | 773 |   PrintMatrix(stdout, Recivector);
 | 
|---|
 | 774 |   fprintf(stdout, "Reciprocal volume is %lg\n", Determinant(Recivector));
 | 
|---|
| [1b192d] | 775 |   
 | 
|---|
| [a0bcf1] | 776 |   fprintf(stdout, "Vector magnitudes: %5.5lg %5.5lg %5.5lg\n", Norm(Vector[0]), Norm(Vector[1]), Norm(Vector[2]));
 | 
|---|
 | 777 |    
 | 
|---|
 | 778 |   Debug ("STAGE: Cell\n");
 | 
|---|
 | 779 |   if (!strncmp(stage, "Non", 3)) {
 | 
|---|
 | 780 |     fprintf(stdout, "\nHow many atoms are in the unit cell: ");
 | 
|---|
 | 781 |     fscanf(stdin, "%i", &numbercell);
 | 
|---|
 | 782 |     CellFile = fopen(CellFilename, "w");
 | 
|---|
 | 783 |     if (CellFile == NULL) {
 | 
|---|
 | 784 |       fprintf(stderr, "ERROR: main - can't open %s for writing\n", CellFilename);
 | 
|---|
 | 785 |       exit(255);
 | 
|---|
 | 786 |     }
 | 
|---|
 | 787 |     fprintf(stdout, "\nNext, you have to enter each atom in the cell as follows, e.g.\n");
 | 
|---|
 | 788 |     fprintf(stdout, "Enter \'ChemicalSymbol X Y Z\' (relative to primitive vectors): C 0.5 0.25 0.5\n\n");
 | 
|---|
 | 789 |     for (i = 0; i < numbercell; i++) {
 | 
|---|
 | 790 |       fprintf(stdout, "Enter for atom %i \'ChemicalSymbol X Y Z\': ", i+1);
 | 
|---|
 | 791 |       fscanf(stdin, "%s %lg %lg %lg", name, &atom[0], &atom[1], &atom[2]);
 | 
|---|
 | 792 |       tempvector = MatrixTrafo(Vector, atom);
 | 
|---|
 | 793 |       fprintf(stdout, "Atom %i: %s %5.5lg %5.5lg %5.5lg\n", i, name, tempvector[0], tempvector[1], tempvector[2]);
 | 
|---|
 | 794 |       fprintf(stdout, "Probe: %s %5.5lg %5.5lg %5.5lg\n", name,
 | 
|---|
 | 795 |         atom[0]*Vector[0][0]+atom[1]*Vector[1][0]+atom[2]*Vector[2][0],      
 | 
|---|
 | 796 |         atom[0]*Vector[0][1]+atom[1]*Vector[1][1]+atom[2]*Vector[2][1],      
 | 
|---|
 | 797 |         atom[0]*Vector[0][2]+atom[1]*Vector[1][2]+atom[2]*Vector[2][2]    
 | 
|---|
 | 798 |         );
 | 
|---|
 | 799 |       fprintf(CellFile, "%s %lg %lg %lg\n", name, tempvector[0], tempvector[1], tempvector[2]);
 | 
|---|
 | 800 |       Free(tempvector, "Main: At stage Cell - tempvector");
 | 
|---|
 | 801 |     }
 | 
|---|
 | 802 |     fflush(CellFile);
 | 
|---|
 | 803 |     fclose(CellFile);
 | 
|---|
 | 804 |     AddAtomicNumber(CellFilename, numbercell, Vector, Recivector);
 | 
|---|
| [1f4209] | 805 | 
 | 
|---|
| [a0bcf1] | 806 |     CellBuffer = ReadBuffer(CellFilename, &length);
 | 
|---|
| [1f4209] | 807 |         
 | 
|---|
| [a0bcf1] | 808 |     sprintf(stage, "Cell");
 | 
|---|
 | 809 |   } else {
 | 
|---|
 | 810 |     bufptr = CellBuffer;
 | 
|---|
 | 811 |     GetNextline(bufptr, line);
 | 
|---|
 | 812 |     sscanf(line, "%i", &numbercell);
 | 
|---|
 | 813 |   }
 | 
|---|
 | 814 |  
 | 
|---|
 | 815 |   fprintf(stdout, "\nThere are %i atoms in the cell.\n", numbercell);
 | 
|---|
 | 816 |     
 | 
|---|
 | 817 |   // ======================== STAGE: Sheet =============================
 | 
|---|
 | 818 |   // The sheet is a bit more complex. We read the cell in cartesian coordinates
 | 
|---|
 | 819 |   // from the file. Next, we have to rotate the unit cell vectors by the so called
 | 
|---|
 | 820 |   // chiral angle. This gives a slanted and elongated section upon the sheet of
 | 
|---|
 | 821 |   // periodically repeated original unit cells. It only matches up if the factors
 | 
|---|
 | 822 |   // were all integer! (That's why the rotation is discrete and the chiral angle
 | 
|---|
 | 823 |   // specified not as (cos alpha, sin alpha) but as (n,m)) Also, we want this
 | 
|---|
 | 824 |   // section to be rectangular, thus we orthogonalize the original unit vectors
 | 
|---|
 | 825 |   // to gain our (later) tube axis.
 | 
|---|
 | 826 |   // By looking at the biggest possible diameter we know whose original cells to
 | 
|---|
 | 827 |   // look at and check if their respective compounds (contained atoms) still reside
 | 
|---|
 | 828 |   // in the rotated, elongated section we need for the later tube.
 | 
|---|
 | 829 |   // Then in a for loop we go through every cell. By projecting the vector leading
 | 
|---|
 | 830 |   // from the origin to the specific atom down onto the major and minor axis we
 | 
|---|
 | 831 |   // know if it's still within the boundaries spanned by these rotated and elongated
 | 
|---|
 | 832 |   // (radius-, length factor) unit vectors or not. If yes, its coordinates are
 | 
|---|
 | 833 |   // written to file.
 | 
|---|
 | 834 | 
 | 
|---|
 | 835 |   int numbersheet, biggestdiameter, sheetnr[NDIM], tmp, seed;
 | 
|---|
 | 836 |   double x1,x2,x3, angle;
 | 
|---|
 | 837 |   char flag = 'n';
 | 
|---|
 | 838 |   FILE *SheetFile = NULL;
 | 
|---|
 | 839 |   FILE *SheetFileAligned = NULL;
 | 
|---|
 | 840 |   
 | 
|---|
 | 841 |   Debug ("STAGE: Sheet\n");
 | 
|---|
 | 842 |   if (!strncmp(stage, "Cell", 4)) {
 | 
|---|
 | 843 |     fprintf(stdout, "\nEnter seed unequal 0 if any of the bonds shall have a randomness in their being: ");
 | 
|---|
 | 844 |     fscanf(stdin, "%d", &seed);
 | 
|---|
 | 845 |     if (seed != 0) 
 | 
|---|
 | 846 |       input = 'y';
 | 
|---|
 | 847 |     randomness = (double *) Malloc(sizeof(double)*numbercell, "Main: at sheet - randomness");
 | 
|---|
 | 848 |     for(i=0;i<numbercell;i++)
 | 
|---|
 | 849 |       randomness[i] = 0.;
 | 
|---|
 | 850 |     i = 0;
 | 
|---|
 | 851 |     fprintf(stdout, "\n");
 | 
|---|
 | 852 |     while (input == 'y') {
 | 
|---|
 | 853 |       fprintf(stdout, "Enter atom number (-1  0 to end) and percentage (0.0...1.0): ");
 | 
|---|
 | 854 |       fscanf(stdin, "%d %lg", &i, &percentage);
 | 
|---|
 | 855 |       if (i == -1) { input = 'n'; fprintf(stdout, "Breaking\n"); }
 | 
|---|
 | 856 |       else { randomness[i] = 1.-percentage; }
 | 
|---|
 | 857 |     };
 | 
|---|
 | 858 |     
 | 
|---|
 | 859 |     fprintf(stdout, "\nSpecify the axis permutation that is going to be perpendicular to the sheet [tubeaxis, torusaxis, noaxis]: ");
 | 
|---|
 | 860 |     fscanf(stdin, "%d %d %d", &axis[0], &axis[1], &axis[2]);
 | 
|---|
 | 861 |     fprintf(stdout, "axis: %d %d %d\n", axis[0], axis[1], axis[2]);
 | 
|---|
| [1b192d] | 862 |     
 | 
|---|
 | 863 |     // create orthogonal vectors individually for each unit cell vector
 | 
|---|
 | 864 |     CreateOrthogonalAxisVectors(OrthoVector, Vector, axis);
 | 
|---|
 | 865 |     fprintf(stdout, "Orthogonal vector axis[0] %lg\n", Projection(Vector[axis[0]], OrthoVector[axis[0]]));
 | 
|---|
 | 866 |     fprintf(stdout, "Orthogonal vector axis[1] %lg\n", Projection(Vector[axis[1]], OrthoVector[axis[1]]));
 | 
|---|
 | 867 | 
 | 
|---|
| [a0bcf1] | 868 |     do {      
 | 
|---|
 | 869 |       fprintf(stdout, "\nNow specify the two natural numbers (m n) defining the chiral angle, \nif the result is crap, try flipping to (m,n): ");
 | 
|---|
 | 870 |       fscanf(stdin, "%d %d", &chiral[0], &chiral[1]);
 | 
|---|
 | 871 |       ggT = GCD(2*chiral[1]+chiral[0],2*chiral[0]+chiral[1]);
 | 
|---|
 | 872 |       fprintf(stdout, "Greatest Common Denominator of (2n+m, 2m+n) is %d\n", ggT);
 | 
|---|
 | 873 |       fprintf(stdout, "chiral0: %d\tchiral1: %d\n", chiral[0], chiral[1]);
 | 
|---|
 | 874 |       for (i=0;i<NDIM;i++) {
 | 
|---|
| [1b192d] | 875 |         Tubevector[axis[0]][i] = (double)chiral[0] * Vector[axis[0]][i] + (double)chiral[1] * Vector[axis[1]][i];
 | 
|---|
 | 876 |         //Tubevector[axis[0]][i] = chiral[0] * Vector[axis[0]][i] + chiral[1] * Vector[axis[1]][i];
 | 
|---|
| [a0bcf1] | 877 |         //Tubevector[axis[0]][i] = (2.*chiral[0]+chiral[1])/(double)ggT * Vector[axis[0]][i] + (-chiral[0]-2.*chiral[1])/(double)ggT * Vector[axis[1]][i];
 | 
|---|
| [1b192d] | 878 |         //Tubevector[axis[1]][i] = -chiral[1] * Vector[axis[0]][i] + chiral[0] * Vector[axis[1]][i];
 | 
|---|
 | 879 |         Tubevector[axis[1]][i] = (double)chiral[0] * OrthoVector[axis[0]][i] - (double)chiral[1] * OrthoVector[axis[1]][i];
 | 
|---|
| [a0bcf1] | 880 |         //Tubevector[axis[1]][i] = (-chiral[0]-2.*chiral[1])/(double)ggT * Vector[axis[0]][i] + (2.*chiral[0]+chiral[1])/(double)ggT * Vector[axis[1]][i];
 | 
|---|
 | 881 | //        fprintf(stderr, "Tubevector[axis[0]][i] = (double)chiral[0] * Vector[axis[0]][i] + (double)chiral[1] * Vector[axis[1]][i]\n = %lg * %lg + %lg * %lg = %lg + %lg = %lg\n\n", 
 | 
|---|
 | 882 | //          (double)chiral[0], Vector[axis[0]][i], (double)chiral[1], Vector[axis[1]][i], 
 | 
|---|
 | 883 | //          (double)chiral[0] * Vector[axis[0]][i], (double)chiral[1] * Vector[axis[1]][i], 
 | 
|---|
 | 884 | //          Tubevector[axis[0]][i]);
 | 
|---|
 | 885 |         Tubevector[axis[2]][i] = Vector[axis[2]][i];
 | 
|---|
 | 886 |       }
 | 
|---|
| [e2f3fde] | 887 |       // here we assume, that Vector[axis[2]] is along z direction!
 | 
|---|
 | 888 |       gsl_matrix *M = gsl_matrix_alloc(2,2);
 | 
|---|
 | 889 |       gsl_matrix *C = gsl_matrix_alloc(2,2);
 | 
|---|
 | 890 |       gsl_matrix *evec = gsl_matrix_alloc(2,2);
 | 
|---|
 | 891 |       gsl_vector *eval = gsl_vector_alloc(2);
 | 
|---|
 | 892 |       gsl_vector *v = gsl_vector_alloc(2);
 | 
|---|
 | 893 |       gsl_vector *u = gsl_vector_alloc(2);
 | 
|---|
 | 894 |       gsl_eigen_symmv_workspace *w = gsl_eigen_symmv_alloc(2);
 | 
|---|
 | 895 |       gsl_matrix_set(C, 0,0, Vector[axis[0]][0]);
 | 
|---|
 | 896 |       gsl_matrix_set(C, 1,0, Vector[axis[0]][1]);
 | 
|---|
 | 897 |       gsl_matrix_set(C, 0,1, Vector[axis[1]][0]);
 | 
|---|
 | 898 |       gsl_matrix_set(C, 1,1, Vector[axis[1]][1]);
 | 
|---|
 | 899 |       gsl_blas_dgemm(CblasTrans,CblasNoTrans, 1.0, C, C, 0.0, M);
 | 
|---|
 | 900 |       fprintf(stdout, "M: \t%lg\t%lg\n\t%lg\t%lg\n", gsl_matrix_get(M,0,0), gsl_matrix_get(M,0,1), gsl_matrix_get(M,1,0), gsl_matrix_get(M,1,1));
 | 
|---|
 | 901 |       gsl_eigen_symmv(M, eval, evec, w);
 | 
|---|
 | 902 |       gsl_eigen_symmv_sort(eval,evec,GSL_EIGEN_SORT_ABS_DESC);
 | 
|---|
 | 903 |       fprintf(stdout, "Eigenvalues: %lg\t%lg\n", gsl_vector_get(eval,0), gsl_vector_get(eval,1));
 | 
|---|
 | 904 |       fprintf(stdout, "Eigenvectors: \t%lg\t%lg\n\t\t%lg\t%lg\n", gsl_matrix_get(evec,0,0), gsl_matrix_get(evec,0,1), gsl_matrix_get(evec,1,0), gsl_matrix_get(evec,1,1));
 | 
|---|
 | 905 |       gsl_matrix_set(M, 0,0, 0.);
 | 
|---|
 | 906 |       gsl_matrix_set(M, 1,0, 1.);
 | 
|---|
 | 907 |       gsl_matrix_set(M, 0,1, -gsl_vector_get(eval,1)/gsl_vector_get(eval,0));
 | 
|---|
 | 908 |       gsl_matrix_set(M, 1,1, 0.);
 | 
|---|
 | 909 |       gsl_vector_set(v,0,(double)chiral[0]);
 | 
|---|
 | 910 |       gsl_vector_set(v,1,(double)chiral[1]);
 | 
|---|
 | 911 |       gsl_blas_dgemm(CblasNoTrans,CblasNoTrans, 1.0, evec, M, 0.0, C);
 | 
|---|
 | 912 |       gsl_blas_dgemm(CblasNoTrans,CblasTrans, 1.0, C, evec, 0.0, M);
 | 
|---|
 | 913 |       fprintf(stdout, "M: \t%lg\t%lg\n\t%lg\t%lg\n", gsl_matrix_get(M,0,0), gsl_matrix_get(M,0,1), gsl_matrix_get(M,1,0), gsl_matrix_get(M,1,1));
 | 
|---|
 | 914 |       gsl_blas_dgemv(CblasNoTrans, 1.0, M, v, 0.0, u);
 | 
|---|
 | 915 |       fprintf(stdout, "Looking for factor to integer...\n");
 | 
|---|
 | 916 |       for(i=1;i<(chiral[0]+chiral[1])*(chiral[0]+chiral[1]);i++) {
 | 
|---|
 | 917 |         x1 = gsl_vector_get(u,0)*(double)i;
 | 
|---|
 | 918 |         x2 = gsl_vector_get(u,1)*(double)i;
 | 
|---|
 | 919 |         x3 = 
 | 
|---|
 | 920 |         fprintf(stdout, "%d: %d\t%d vs. %lg\t%lg\n",i, ((int)(x1+x1/fabs(x1)*.5)), ((int)(x2+x2/fabs(x2)*.5)), (x1), (x2));
 | 
|---|
| [bd3839] | 921 |         if (( fabs( ((int)(x1+x1/fabs(x1)*.5)) - (x1) ) < 1e-6) && ( fabs( ((int)(x2+x2/fabs(x2)*.5)) - (x2) ) < 1e-6 )) {
 | 
|---|
| [e2f3fde] | 922 |           gsl_blas_dscal((double)i, u);
 | 
|---|
 | 923 |           break;
 | 
|---|
 | 924 |         }
 | 
|---|
 | 925 |       }
 | 
|---|
 | 926 |       fprintf(stdout, "(c,d) = (%lg,%lg)\n",gsl_vector_get(u,0), gsl_vector_get(u,1));
 | 
|---|
 | 927 | 
 | 
|---|
 | 928 |       // get length
 | 
|---|
 | 929 |       double x[NDIM];
 | 
|---|
 | 930 |       for (i=0;i<NDIM;i++)
 | 
|---|
 | 931 |         x[i] = gsl_vector_get(u,0) * Vector[axis[0]][i] + gsl_vector_get(u,1) * Vector[axis[1]][i];
 | 
|---|
 | 932 |       angle = Norm(x)/Norm(Tubevector[axis[1]]) ;//ScalarProduct(x,Tubevector[axis[1]])/Norm(Tubevector[axis[1]]);
 | 
|---|
 | 933 |       fprintf(stdout, "angle is %lg\n", angle);
 | 
|---|
 | 934 |       for (i=0;i<NDIM;i++) {
 | 
|---|
 | 935 |         Tubevector[axis[1]][i] = gsl_vector_get(u,0) * Vector[axis[0]][i] + gsl_vector_get(u,1) * Vector[axis[1]][i];
 | 
|---|
 | 936 |       }
 | 
|---|
 | 937 | 
 | 
|---|
 | 938 |       // Probe
 | 
|---|
 | 939 |       gsl_matrix_set(M, 0,0, Vector[axis[0]][0]);
 | 
|---|
 | 940 |       gsl_matrix_set(M, 1,0, Vector[axis[0]][1]);
 | 
|---|
 | 941 |       gsl_matrix_set(M, 0,1, Vector[axis[1]][0]);
 | 
|---|
 | 942 |       gsl_matrix_set(M, 1,1, Vector[axis[1]][1]);
 | 
|---|
 | 943 |       gsl_vector_set(v,0,(double)chiral[0]);
 | 
|---|
 | 944 |       gsl_vector_set(v,1,(double)chiral[1]);
 | 
|---|
 | 945 |       gsl_blas_dgemv(CblasNoTrans, 1.0, M, u, 0.0, eval);
 | 
|---|
| [bd3839] | 946 |       gsl_blas_dgemv(CblasNoTrans, 1.0, M, v, 0.0, u);
 | 
|---|
| [e2f3fde] | 947 |       x1=1.;
 | 
|---|
 | 948 |       gsl_blas_ddot(u,eval,&x1);
 | 
|---|
 | 949 |       fprintf(stdout, "Testing (c,d): (a,b) M^t M (c,d)^t = 0 ? : %lg\n", x1);
 | 
|---|
 | 950 | 
 | 
|---|
 | 951 |       gsl_matrix_free(M);
 | 
|---|
 | 952 |       gsl_matrix_free(C);
 | 
|---|
 | 953 |       gsl_matrix_free(evec);
 | 
|---|
 | 954 |       gsl_vector_free(eval);
 | 
|---|
 | 955 |       gsl_vector_free(v);
 | 
|---|
 | 956 |       gsl_vector_free(u);
 | 
|---|
 | 957 |       gsl_eigen_symmv_free(w);
 | 
|---|
 | 958 |       
 | 
|---|
| [bd3839] | 959 |       if (fabs(x1) > 1e-6) {
 | 
|---|
 | 960 |         fprintf(stderr,"Resulting TubeVectors of axis %d and %d and not orthogonal, aborting.\n", axis[0], axis[1]);
 | 
|---|
 | 961 |         return(128);
 | 
|---|
 | 962 |       }
 | 
|---|
 | 963 |         
 | 
|---|
 | 964 |       
 | 
|---|
| [e2f3fde] | 965 |       angle = Projection(Tubevector[axis[1]], Vector[axis[0]]);
 | 
|---|
 | 966 |       fprintf(stdout, "Projection Tubevector1 axis[0] %lg %lg\n", angle, 1./angle);
 | 
|---|
 | 967 |       angle = Projection(Tubevector[axis[1]], Vector[axis[1]]);
 | 
|---|
 | 968 |       fprintf(stdout, "Projection Tubevector1 axis[1] %lg %lg\n", angle, 1./angle);
 | 
|---|
| [1b192d] | 969 |       
 | 
|---|
| [a0bcf1] | 970 | /*      fprintf(stdout, "Vector\n");
 | 
|---|
 | 971 |       PrintMatrix(stdout, Vector);
 | 
|---|
 | 972 |       fprintf(stdout, "Tubevector\n");
 | 
|---|
 | 973 |       PrintMatrix(stdout, Tubevector);
 | 
|---|
 | 974 |       for (i=0;i<NDIM;i++) {
 | 
|---|
 | 975 |         fprintf(stdout, "Tubevector %d in Unit cell vectors:\t", axis[i]);
 | 
|---|
 | 976 |         tempvector = MatrixTrafoInverse(Tubevector[axis[i]], Recivector);
 | 
|---|
 | 977 |         PrintVector(stdout, tempvector);
 | 
|---|
 | 978 |         Free(tempvector, "Main:tempvector");
 | 
|---|
 | 979 |       }*/
 | 
|---|
 | 980 | 
 | 
|---|
 | 981 |       // Give info for length and radius factors
 | 
|---|
 | 982 |       fprintf(stdout, "\nThe chiral angle then is %lg degrees with tube radius %5.5f A and length %5.5f A, i.e. torus radius of %5.5f A.\n",
 | 
|---|
 | 983 |         acos(Projection(Vector[axis[0]], Tubevector[axis[0]]))/M_PI*180.,
 | 
|---|
 | 984 |         Norm(Tubevector[axis[0]])/(2.*M_PI),
 | 
|---|
 | 985 |         Norm(Tubevector[axis[1]]),
 | 
|---|
 | 986 |         Norm(Tubevector[axis[1]])/(2.*M_PI)
 | 
|---|
 | 987 |         );
 | 
|---|
 | 988 |       fprintf(stdout, "\nGive integer factors for length and radius of tube (multiple of %d suggested) : ", ggT);
 | 
|---|
 | 989 |       fscanf(stdin, "%d %d", &factors[1], &factors[0]);
 | 
|---|
 | 990 |       fprintf(stdout, "\nThe chiral angle then is %5.5f degrees with tube radius %5.5f A and length %5.5f A, i.e. torus radius of %5.5f A.\n",
 | 
|---|
 | 991 |         acos(Projection(Vector[axis[0]], Tubevector[axis[0]]))/M_PI*180.,
 | 
|---|
 | 992 |         (double)factors[0]*Norm(Tubevector[axis[0]])/(2.*M_PI),
 | 
|---|
 | 993 |         (double)factors[1]*Norm(Tubevector[axis[1]]),
 | 
|---|
 | 994 |         (double)factors[1]*Norm(Tubevector[axis[1]])/(2.*M_PI)
 | 
|---|
 | 995 |         );
 | 
|---|
 | 996 |       fprintf(stdout, "Satisfied? [yn] ");
 | 
|---|
 | 997 |       fscanf(stdin, "%c", &flag);
 | 
|---|
 | 998 |       fscanf(stdin, "%c", &flag);
 | 
|---|
 | 999 |     } while (flag != 'y');
 | 
|---|
 | 1000 |   } else {
 | 
|---|
 | 1001 |     char *ptr = NULL;
 | 
|---|
 | 1002 |     char dummy[10];
 | 
|---|
 | 1003 |     double dummydouble;
 | 
|---|
| [1f4209] | 1004 | 
 | 
|---|
| [a0bcf1] | 1005 |     SheetBuffer = bufptr = ReadBuffer(SheetFilename, &length);
 | 
|---|
 | 1006 |     bufptr += (GetNextline(bufptr, line))*sizeof(char);
 | 
|---|
 | 1007 |     sscanf(line, "%d", &numbersheet);
 | 
|---|
 | 1008 |     
 | 
|---|
 | 1009 |     // retrieve axis permutation
 | 
|---|
 | 1010 |     sprintf(dummy,  "Axis");
 | 
|---|
 | 1011 |     fprintf(stdout, "%s ", dummy);
 | 
|---|
 | 1012 |     while ((length = GetNextline(bufptr, line)) != 0) {
 | 
|---|
 | 1013 |       bufptr += (length)*sizeof(char);
 | 
|---|
 | 1014 |       if ((ptr = strstr(line, dummy)) != NULL)
 | 
|---|
 | 1015 |         break;
 | 
|---|
 | 1016 |     }
 | 
|---|
 | 1017 |     if (length == 0) {
 | 
|---|
 | 1018 |       fprintf(stderr, "ERROR: Main at stage Sheet - could not find %s in %s\n", dummy, SheetFilename);
 | 
|---|
 | 1019 |       exit(255);
 | 
|---|
 | 1020 |     }
 | 
|---|
 | 1021 |     ptr += strlen(dummy);
 | 
|---|
 | 1022 |     sscanf(ptr, "%d %d %d", &axis[0], &axis[1], &axis[2]);
 | 
|---|
 | 1023 |     fprintf(stdout, "%d %d %d\n", axis[0], axis[1], axis[2]); 
 | 
|---|
 | 1024 |     
 | 
|---|
 | 1025 |     // retrieve chiral numbers
 | 
|---|
 | 1026 |     sprintf(dummy,  "(n,m)");
 | 
|---|
 | 1027 |     fprintf(stdout, "%s ", dummy);
 | 
|---|
 | 1028 |     while ((length = GetNextline(bufptr, line)) != 0) {
 | 
|---|
 | 1029 |       bufptr += (length)*sizeof(char);
 | 
|---|
 | 1030 |       if ((ptr = strstr(line, dummy)) != NULL)
 | 
|---|
 | 1031 |         break;
 | 
|---|
 | 1032 |     }
 | 
|---|
 | 1033 |     if (length == 0) {
 | 
|---|
 | 1034 |       fprintf(stderr, "ERROR: Main at stage Sheet - could not find %s in %s\n", dummy, SheetFilename);
 | 
|---|
 | 1035 |       exit(255);
 | 
|---|
 | 1036 |     }      
 | 
|---|
 | 1037 |     ptr += strlen(dummy);
 | 
|---|
 | 1038 |     sscanf(ptr, "%d %d", &chiral[0], &chiral[1]);
 | 
|---|
 | 1039 |     fprintf(stdout, "%d %d\n", chiral[0], chiral[1]); 
 | 
|---|
 | 1040 |     ggT = GCD(2*chiral[1]+chiral[0],2*chiral[0]+chiral[1]);
 | 
|---|
 | 1041 |     fprintf(stdout, "Greatest Common Denominator of (2n+m, 2m+n) is %d\n", ggT);
 | 
|---|
 | 1042 |     
 | 
|---|
 | 1043 |     // retrieve length and radius factors
 | 
|---|
 | 1044 |     sprintf(dummy,  "factors");
 | 
|---|
 | 1045 |     fprintf(stdout, "%s ", dummy);
 | 
|---|
 | 1046 |     while ((length = GetNextline(bufptr, line)) != 0) {
 | 
|---|
 | 1047 |       bufptr += (length)*sizeof(char);
 | 
|---|
 | 1048 |       if ((ptr = strstr(line, dummy)) != NULL)
 | 
|---|
 | 1049 |         break;
 | 
|---|
 | 1050 |     }
 | 
|---|
 | 1051 |     if (length == 0) {
 | 
|---|
 | 1052 |       fprintf(stderr, "ERROR: Main at stage Sheet - could not find %s in %s\n", dummy, SheetFilename);
 | 
|---|
 | 1053 |       exit(255);
 | 
|---|
 | 1054 |     }
 | 
|---|
 | 1055 |     ptr += strlen(dummy);
 | 
|---|
 | 1056 |     sscanf(ptr, "%d %d %d", &factors[0], &factors[1], &factors[2]);
 | 
|---|
 | 1057 |     fprintf(stdout, "%d %d %d\n", factors[0], factors[1], factors[2]); 
 | 
|---|
 | 1058 | 
 | 
|---|
| [1b192d] | 1059 |     // create orthogonal vectors individually for each unit cell vector
 | 
|---|
 | 1060 |     CreateOrthogonalAxisVectors(OrthoVector, Vector, axis);
 | 
|---|
 | 1061 |     fprintf(stdout, "Orthogonal vector axis[0] %lg", Projection(Vector[axis[0]], OrthoVector[axis[0]]));
 | 
|---|
 | 1062 |     fprintf(stdout, "Orthogonal vector axis[1] %lg", Projection(Vector[axis[1]], OrthoVector[axis[1]]));
 | 
|---|
| [a0bcf1] | 1063 |     // create Tubevectors
 | 
|---|
 | 1064 |     for (i=0;i<NDIM;i++) {
 | 
|---|
 | 1065 |       Tubevector[axis[0]][i] = chiral[0] * Vector[axis[0]][i] + chiral[1] * Vector[axis[1]][i];
 | 
|---|
 | 1066 |       //Tubevector[axis[0]][i] = (2.*chiral[0]+chiral[1])/(double)ggT * Vector[axis[0]][i] + (-chiral[0]-2.*chiral[1])/(double)ggT * Vector[axis[1]][i];
 | 
|---|
| [1b192d] | 1067 |       //Tubevector[axis[1]][i] = -chiral[1] * Vector[axis[0]][i] + chiral[0] * Vector[axis[1]][i];
 | 
|---|
 | 1068 |       Tubevector[axis[1]][i] = chiral[0] * OrthoVector[axis[0]][i] + chiral[1] * OrthoVector[axis[1]][i];
 | 
|---|
| [a0bcf1] | 1069 |       //Tubevector[axis[1]][i] = (-chiral[0]-2.*chiral[1])/(double)ggT * Vector[axis[0]][i] + (2.*chiral[0]+chiral[1])/(double)ggT * Vector[axis[1]][i];
 | 
|---|
 | 1070 |       Tubevector[axis[2]][i] = Vector[axis[2]][i];
 | 
|---|
 | 1071 |     }
 | 
|---|
| [e2f3fde] | 1072 |     // here we assume, that Vector[axis[2]] is along z direction!
 | 
|---|
 | 1073 |     gsl_matrix *M = gsl_matrix_alloc(2,2);
 | 
|---|
 | 1074 |     gsl_matrix *C = gsl_matrix_alloc(2,2);
 | 
|---|
 | 1075 |     gsl_matrix *evec = gsl_matrix_alloc(2,2);
 | 
|---|
 | 1076 |     gsl_vector *eval = gsl_vector_alloc(2);
 | 
|---|
 | 1077 |     gsl_vector *v = gsl_vector_alloc(2);
 | 
|---|
 | 1078 |     gsl_vector *u = gsl_vector_alloc(2);
 | 
|---|
 | 1079 |     gsl_eigen_symmv_workspace *w = gsl_eigen_symmv_alloc(2);
 | 
|---|
 | 1080 |     gsl_matrix_set(C, 0,0, Vector[axis[0]][0]);
 | 
|---|
 | 1081 |     gsl_matrix_set(C, 1,0, Vector[axis[0]][1]);
 | 
|---|
 | 1082 |     gsl_matrix_set(C, 0,1, Vector[axis[1]][0]);
 | 
|---|
 | 1083 |     gsl_matrix_set(C, 1,1, Vector[axis[1]][1]);
 | 
|---|
 | 1084 |     gsl_blas_dgemm(CblasTrans,CblasNoTrans, 1.0, C, C, 0.0, M);
 | 
|---|
 | 1085 |     fprintf(stdout, "M: \t%lg\t%lg\n\t%lg\t%lg\n", gsl_matrix_get(M,0,0), gsl_matrix_get(M,0,1), gsl_matrix_get(M,1,0), gsl_matrix_get(M,1,1));
 | 
|---|
 | 1086 |     gsl_eigen_symmv(M, eval, evec, w);
 | 
|---|
 | 1087 |     gsl_eigen_symmv_sort(eval,evec,GSL_EIGEN_SORT_ABS_DESC);
 | 
|---|
 | 1088 |     fprintf(stdout, "Eigenvalues: %lg\t%lg\n", gsl_vector_get(eval,0), gsl_vector_get(eval,1));
 | 
|---|
 | 1089 |     fprintf(stdout, "Eigenvectors: \t%lg\t%lg\n\t\t%lg\t%lg\n", gsl_matrix_get(evec,0,0), gsl_matrix_get(evec,0,1), gsl_matrix_get(evec,1,0), gsl_matrix_get(evec,1,1));
 | 
|---|
 | 1090 |     gsl_matrix_set(M, 0,0, 0.);
 | 
|---|
 | 1091 |     gsl_matrix_set(M, 1,0, 1.);
 | 
|---|
 | 1092 |     gsl_matrix_set(M, 0,1, -gsl_vector_get(eval,1)/gsl_vector_get(eval,0));
 | 
|---|
 | 1093 |     gsl_matrix_set(M, 1,1, 0.);
 | 
|---|
 | 1094 |     gsl_vector_set(v,0,(double)chiral[0]);
 | 
|---|
 | 1095 |     gsl_vector_set(v,1,(double)chiral[1]);
 | 
|---|
 | 1096 |     gsl_blas_dgemm(CblasNoTrans,CblasNoTrans, 1.0, evec, M, 0.0, C);
 | 
|---|
 | 1097 |     gsl_blas_dgemm(CblasNoTrans,CblasTrans, 1.0, C, evec, 0.0, M);
 | 
|---|
 | 1098 |     fprintf(stdout, "M: \t%lg\t%lg\n\t%lg\t%lg\n", gsl_matrix_get(M,0,0), gsl_matrix_get(M,0,1), gsl_matrix_get(M,1,0), gsl_matrix_get(M,1,1));
 | 
|---|
 | 1099 |     gsl_blas_dgemv(CblasNoTrans, 1.0, M, v, 0.0, u);
 | 
|---|
 | 1100 |     fprintf(stdout, "Looking for factor to integer...\n");
 | 
|---|
 | 1101 |     for(i=1;i<(chiral[0]+chiral[1])*(chiral[0]+chiral[1]);i++) {
 | 
|---|
 | 1102 |       x1 = gsl_vector_get(u,0)*(double)i;
 | 
|---|
 | 1103 |       x2 = gsl_vector_get(u,1)*(double)i;
 | 
|---|
 | 1104 |       x3 = 
 | 
|---|
 | 1105 |       fprintf(stdout, "%d: %d\t%d vs. %lg\t%lg\n",i, ((int)(x1+x1/fabs(x1)*.5)), ((int)(x2+x2/fabs(x2)*.5)), (x1), (x2));
 | 
|---|
| [bd3839] | 1106 |       if (( fabs( ((int)(x1+x1/fabs(x1)*.5)) - (x1) ) < 1e-6) && ( fabs( ((int)(x2+x2/fabs(x2)*.5)) - (x2) ) < 1e-6 )) {
 | 
|---|
| [e2f3fde] | 1107 |         gsl_blas_dscal((double)i, u);
 | 
|---|
 | 1108 |         break;
 | 
|---|
 | 1109 |       }
 | 
|---|
 | 1110 |     }
 | 
|---|
 | 1111 |     fprintf(stdout, "(c,d) = (%lg,%lg)\n",gsl_vector_get(u,0), gsl_vector_get(u,1));
 | 
|---|
 | 1112 | 
 | 
|---|
 | 1113 |     // get length
 | 
|---|
 | 1114 |     double x[NDIM];
 | 
|---|
 | 1115 |     for (i=0;i<NDIM;i++)
 | 
|---|
 | 1116 |       x[i] = gsl_vector_get(u,0) * Vector[axis[0]][i] + gsl_vector_get(u,1) * Vector[axis[1]][i];
 | 
|---|
 | 1117 |     angle = Norm(x)/Norm(Tubevector[axis[1]]) ;//ScalarProduct(x,Tubevector[axis[1]])/Norm(Tubevector[axis[1]]);
 | 
|---|
 | 1118 |     fprintf(stdout, "angle is %lg\n", angle);
 | 
|---|
 | 1119 |     for (i=0;i<NDIM;i++) {
 | 
|---|
 | 1120 |       Tubevector[axis[1]][i] = gsl_vector_get(u,0) * Vector[axis[0]][i] + gsl_vector_get(u,1) * Vector[axis[1]][i];
 | 
|---|
 | 1121 |     }
 | 
|---|
 | 1122 | 
 | 
|---|
 | 1123 |     // Probe
 | 
|---|
 | 1124 |     gsl_matrix_set(M, 0,0, Vector[axis[0]][0]);
 | 
|---|
 | 1125 |     gsl_matrix_set(M, 1,0, Vector[axis[0]][1]);
 | 
|---|
 | 1126 |     gsl_matrix_set(M, 0,1, Vector[axis[1]][0]);
 | 
|---|
 | 1127 |     gsl_matrix_set(M, 1,1, Vector[axis[1]][1]);
 | 
|---|
 | 1128 |     gsl_vector_set(v,0,(double)chiral[0]);
 | 
|---|
 | 1129 |     gsl_vector_set(v,1,(double)chiral[1]);
 | 
|---|
 | 1130 |     gsl_blas_dgemv(CblasNoTrans, 1.0, M, u, 0.0, eval);
 | 
|---|
| [bd3839] | 1131 |     gsl_blas_dgemv(CblasNoTrans, 1.0, M, v, 0.0, u);
 | 
|---|
| [e2f3fde] | 1132 |     x1=1.;
 | 
|---|
 | 1133 |     gsl_blas_ddot(u,eval,&x1);
 | 
|---|
 | 1134 |     fprintf(stdout, "Testing (c,d): (a,b) M^t M (c,d)^t = 0 ? : %lg\n", x1);
 | 
|---|
 | 1135 | 
 | 
|---|
 | 1136 |     gsl_matrix_free(M);
 | 
|---|
 | 1137 |     gsl_matrix_free(C);
 | 
|---|
 | 1138 |     gsl_matrix_free(evec);
 | 
|---|
 | 1139 |     gsl_vector_free(eval);
 | 
|---|
 | 1140 |     gsl_vector_free(v);
 | 
|---|
 | 1141 |     gsl_vector_free(u);
 | 
|---|
 | 1142 |     gsl_eigen_symmv_free(w);    
 | 
|---|
| [a0bcf1] | 1143 | 
 | 
|---|
| [bd3839] | 1144 |     if (fabs(x1) > 1e-6) {
 | 
|---|
 | 1145 |       fprintf(stderr,"Resulting TubeVectors of axis %d and %d and not orthogonal, aborting.\n", axis[0], axis[1]);
 | 
|---|
 | 1146 |       return(128);
 | 
|---|
 | 1147 |     }
 | 
|---|
 | 1148 | 
 | 
|---|
| [a0bcf1] | 1149 |     // retrieve seed ... 
 | 
|---|
 | 1150 |     randomness = (double *) Calloc(sizeof(double)*numbercell, 0., "Main: at sheet - randomness");
 | 
|---|
 | 1151 |     sprintf(dummy,  "seed");
 | 
|---|
 | 1152 |     fprintf(stdout, "%s ", dummy);
 | 
|---|
 | 1153 |     while ((length = GetNextline(bufptr, line)) != 0) {
 | 
|---|
 | 1154 |       bufptr += (length)*sizeof(char);
 | 
|---|
 | 1155 |       if ((ptr = strstr(line, dummy)) != NULL)
 | 
|---|
 | 1156 |         break;
 | 
|---|
 | 1157 |     }
 | 
|---|
 | 1158 |     if (length == 0) {
 | 
|---|
 | 1159 |       fprintf(stderr, "ERROR: Main at stage Sheet - could not find %s in %s\n", dummy, SheetFilename);
 | 
|---|
 | 1160 |       exit(255);
 | 
|---|
 | 1161 |     }      
 | 
|---|
 | 1162 |     ptr += strlen(dummy);
 | 
|---|
 | 1163 |     sscanf(ptr, "%d", &seed);
 | 
|---|
 | 1164 |     fprintf(stdout, "%d\n", seed); 
 | 
|---|
 | 1165 | 
 | 
|---|
 | 1166 |     // ... and randomness
 | 
|---|
 | 1167 |     if (seed != 0) {  // only parse for values if a seed, i.e. randomness wanted, was specified
 | 
|---|
 | 1168 |       sprintf(dummy,  "Randomness");
 | 
|---|
 | 1169 |       fprintf(stdout, "%s\n", dummy);
 | 
|---|
 | 1170 |       while ((length = GetNextline(bufptr, line)) != 0) {
 | 
|---|
 | 1171 |         bufptr += (length)*sizeof(char);
 | 
|---|
 | 1172 |         if ((ptr = strstr(line, dummy)) != NULL)
 | 
|---|
 | 1173 |           break;
 | 
|---|
 | 1174 |       }
 | 
|---|
 | 1175 |       if (length == 0) {
 | 
|---|
 | 1176 |         fprintf(stderr, "ERROR: Main at stage Sheet - could not find %s in %s\n", dummy, SheetFilename);
 | 
|---|
 | 1177 |         exit(255);
 | 
|---|
 | 1178 |       }
 | 
|---|
 | 1179 |       sprintf(dummy,  "probability values");
 | 
|---|
 | 1180 |       for (i=0;i<numbercell;i++) {
 | 
|---|
 | 1181 |         length = GetNextline(bufptr, line);
 | 
|---|
 | 1182 |         if (length == 0) {
 | 
|---|
 | 1183 |           fprintf(stderr, "ERROR: Main at stage Sheet - could not find %s in %s\n", dummy, SheetFilename);
 | 
|---|
 | 1184 |           exit(255);
 | 
|---|
 | 1185 |         }
 | 
|---|
 | 1186 |         bufptr += (length)*sizeof(char);
 | 
|---|
 | 1187 |         sscanf(line, "%d %lg", &j, &dummydouble);
 | 
|---|
 | 1188 |         randomness[j] = dummydouble;
 | 
|---|
 | 1189 |         fprintf(stdout, "%d %g\n", j, randomness[j]);      
 | 
|---|
 | 1190 |       }
 | 
|---|
 | 1191 |     }
 | 
|---|
 | 1192 |   }
 | 
|---|
 | 1193 | 
 | 
|---|
| [1b192d] | 1194 |   //int OrthOrder[NDIM] = { axis[2], axis[0], axis[1] };
 | 
|---|
 | 1195 |   //Orthogonalize(Tubevector,OrthOrder);
 | 
|---|
| [a0bcf1] | 1196 |   angle = acos(Projection(Vector[axis[0]], Vector[axis[1]])); // calcs angle between shanks in unit cell
 | 
|---|
| [1b192d] | 1197 |   fprintf(stdout, "The basic angle between the two shanks of the unit cell is %lg %lg\n", angle/M_PI*180., Projection(Vector[axis[0]], Vector[axis[1]]));
 | 
|---|
 | 1198 |   if ( angle/M_PI*180. > 90 ) {
 | 
|---|
 | 1199 |     fprintf(stderr, "There seems to be something wrong with the unit cell! for nanotube the angle should be 60 degrees for example!\n");
 | 
|---|
 | 1200 |     return 1;
 | 
|---|
 | 1201 |   }
 | 
|---|
| [a0bcf1] | 1202 |   angle = acos(Projection(Tubevector[axis[0]], Tubevector[axis[1]])); // calcs angle between shanks in unit cell
 | 
|---|
| [1b192d] | 1203 |   fprintf(stdout, "The basic angle between the two shanks of the tube unit cell is %lg %lg\n", angle/M_PI*180., Projection(Tubevector[axis[0]], Tubevector[axis[1]]));
 | 
|---|
| [a0bcf1] | 1204 |   //angle -= acos(Projection(Vector[axis[0]], Tubevector[axis[0]]));
 | 
|---|
 | 1205 |   //angle = 30./180.*M_PI - acos(Projection(Vector[axis[0]], Tubevector[axis[0]]));
 | 
|---|
| [1b192d] | 1206 |   angle = -acos(Projection(Tubevector[axis[0]], Vector[axis[0]])); 
 | 
|---|
| [a0bcf1] | 1207 |   fprintf(stdout, "The relative alignment rotation angle then is %lg\n", angle/M_PI*180.);
 | 
|---|
| [1b192d] | 1208 |   if (fabs(Tubevector[axis[0]][0]) > MYEPSILON)
 | 
|---|
 | 1209 |     angle = M_PI/2. - acos(Tubevector[axis[0]][0]/Norm(Tubevector[axis[0]]));
 | 
|---|
 | 1210 |   else
 | 
|---|
 | 1211 |     angle = 0.;
 | 
|---|
 | 1212 |   fprintf(stdout, "The absolute alignment rotation angle then is %lg %lg\n", angle/M_PI*180., Tubevector[axis[0]][0]/Norm(Tubevector[axis[0]]));
 | 
|---|
| [73bc6b] | 1213 |   fprintf(stdout, "\nThe chiral angle then is %5.5f degrees with tube radius %5.5f A and length %5.5f A, i.e. final torus radius of %5.5f A.\n",
 | 
|---|
| [a0bcf1] | 1214 |     acos(Projection(Vector[axis[0]], Tubevector[axis[0]]))/M_PI*180.,
 | 
|---|
 | 1215 |     (double)factors[0]*Norm(Tubevector[axis[0]])/(2.*M_PI),
 | 
|---|
 | 1216 |     (double)factors[1]*Norm(Tubevector[axis[1]]),
 | 
|---|
 | 1217 |     (double)factors[1]*Norm(Tubevector[axis[1]])/(2.*M_PI)
 | 
|---|
 | 1218 |     );
 | 
|---|
 | 1219 |   Orthogonalize(Tubevector, axis);   // with correct translational vector, not needed anymore (? what's been done here. Hence, re-inserted)
 | 
|---|
 | 1220 |   fprintf(stdout, "Tubevector magnitudes: %5.5lg %5.5lg %5.5lg\n", Norm(Tubevector[0]), Norm(Tubevector[1]), Norm(Tubevector[2]));
 | 
|---|
| [1b192d] | 1221 |   fprintf(stdout, "Tubevectors are \n");
 | 
|---|
| [a0bcf1] | 1222 |   PrintMatrix(stdout, Tubevector);
 | 
|---|
 | 1223 |   MatrixInversion(Tubevector, TubevectorInverse);
 | 
|---|
 | 1224 |   //Transpose(TubevectorInverse);
 | 
|---|
 | 1225 |       fprintf(stdout, "Vector\n");
 | 
|---|
 | 1226 |       PrintMatrix(stdout, Vector);
 | 
|---|
 | 1227 |       fprintf(stdout, "TubevectorInverse\n");
 | 
|---|
 | 1228 |       PrintMatrix(stdout, TubevectorInverse);
 | 
|---|
 | 1229 |       for (i=0;i<NDIM;i++) {
 | 
|---|
 | 1230 |         fprintf(stdout, "Vector %d in TubeVectorInverse vectors:\t", axis[i]);
 | 
|---|
 | 1231 |         tempvector = MatrixTrafoInverse(Vector[axis[i]], TubevectorInverse);
 | 
|---|
 | 1232 |         PrintVector(stdout, tempvector);
 | 
|---|
 | 1233 |         Free(tempvector, "Main:tempvector");
 | 
|---|
 | 1234 |       }
 | 
|---|
 | 1235 |   fprintf(stdout, "Reciprocal Tubebvectors are \n");
 | 
|---|
 | 1236 |   PrintMatrix(stdout, TubevectorInverse);
 | 
|---|
 | 1237 |   fprintf(stdout, "Tubevector magnitudes: %5.5lg %5.5lg %5.5lg\n", Norm(Tubevector[0]), Norm(Tubevector[1]), Norm(Tubevector[2]));
 | 
|---|
 | 1238 | 
 | 
|---|
 | 1239 |   biggestdiameter = DetermineBiggestDiameter(Tubevector, axis, factors);
 | 
|---|
 | 1240 |   for (i=0;i<NDIM;i++) {
 | 
|---|
 | 1241 |     sheetnr[i] = 0;
 | 
|---|
 | 1242 |   }
 | 
|---|
 | 1243 |   for (i=0;i<NDIM;i++) {
 | 
|---|
 | 1244 |     for (j=0;j<NDIM;j++) {
 | 
|---|
 | 1245 | //      sheetnr[j] =  ceil(biggestdiameter/Norm(Vector[j]));
 | 
|---|
 | 1246 |       if (fabs(Vector[i][j]) > MYEPSILON) {
 | 
|---|
 | 1247 |         tmp = ceil(biggestdiameter/fabs(Vector[i][j]));
 | 
|---|
 | 1248 |       } else {
 | 
|---|
 | 1249 |         tmp = 0;
 | 
|---|
 | 1250 |       }
 | 
|---|
 | 1251 |       sheetnr[j] = sheetnr[j] > tmp ? sheetnr[j] : tmp;
 | 
|---|
 | 1252 |     }
 | 
|---|
 | 1253 |   } 
 | 
|---|
 | 1254 |   fprintf(stdout, "Maximum indices to regard: %d %d %d\n", sheetnr[0], sheetnr[1], sheetnr[2]);
 | 
|---|
 | 1255 |   for (i=0;i<NDIM;i++) {
 | 
|---|
 | 1256 |     fprintf(stdout, "For axis %d: (%5.5lg\t%5.5lg\t%5.5lg) with %5.5lg\n", i, (Vector[i][0]*sheetnr[i]), (Vector[i][1]*sheetnr[i]), (Vector[i][2]*sheetnr[i]), Norm(Vector[i]));
 | 
|---|
 | 1257 |   }
 | 
|---|
 | 1258 | 
 | 
|---|
 | 1259 |   //if (!strncmp(stage, "Cell", 4)) {
 | 
|---|
 | 1260 |     // parse in atoms for quicker processing
 | 
|---|
 | 1261 |     struct Atoms *atombuffer = malloc(sizeof(struct Atoms)*numbercell);
 | 
|---|
 | 1262 |     bufptr = CellBuffer; 
 | 
|---|
 | 1263 |     bufptr += GetNextline(bufptr, line)*sizeof(char);
 | 
|---|
 | 1264 |     bufptr += GetNextline(bufptr, line)*sizeof(char);
 | 
|---|
 | 1265 |     for (i=0;i<numbercell;i++) {
 | 
|---|
 | 1266 |       if ((length = GetNextline(bufptr, line)) != 0) {
 | 
|---|
 | 1267 |         bufptr += length*sizeof(char);
 | 
|---|
 | 1268 |         sscanf(line, "%s %lg %lg %lg", atombuffer[i].name, &(atombuffer[i].x[0]), &(atombuffer[i].x[1]), &(atombuffer[i].x[2]));
 | 
|---|
 | 1269 |         fprintf(stdout, "Read Atombuffer Nr %i: %s %5.5lg %5.5lg %5.5lg\n", i+1, atombuffer[i].name, atombuffer[i].x[0], atombuffer[i].x[1], atombuffer[i].x[2]);
 | 
|---|
 | 1270 |       } else {
 | 
|---|
 | 1271 |         fprintf(stdout, "Error reading Atom Nr. %i\n", i+1);
 | 
|---|
 | 1272 |         break;
 | 
|---|
 | 1273 |       }
 | 
|---|
 | 1274 |     }
 | 
|---|
 | 1275 |     SheetFile = fopen(SheetFilename, "w");
 | 
|---|
 | 1276 |     if (SheetFile == NULL) {
 | 
|---|
 | 1277 |       fprintf(stderr, "ERROR: main - can't open %s for writing\n", SheetFilename);
 | 
|---|
 | 1278 |       exit(255);
 | 
|---|
 | 1279 |     }
 | 
|---|
 | 1280 |     SheetFileAligned = fopen(SheetFilenameAligned, "w");
 | 
|---|
 | 1281 |     if (SheetFile == NULL) {
 | 
|---|
 | 1282 |       fprintf(stderr, "ERROR: main - can't open %s for writing\n", SheetFilenameAligned);
 | 
|---|
 | 1283 |       exit(255);
 | 
|---|
 | 1284 |     }
 | 
|---|
 | 1285 |     // Now create the sheet
 | 
|---|
 | 1286 |     double index[NDIM];
 | 
|---|
 | 1287 |     int nr;//, nummer = 0;
 | 
|---|
 | 1288 |     numbersheet = 0;
 | 
|---|
 | 1289 |     index[axis[2]] = 0;
 | 
|---|
 | 1290 |     // initialise pseudo random number generator with given seed
 | 
|---|
 | 1291 |     fprintf(stdout, "Initialising pseudo random number generator with given seed %d.\n", seed);
 | 
|---|
 | 1292 |     srand(seed);
 | 
|---|
 | 1293 |     //for (index[axis[0]] = 0; index[axis[0]] <= sheetnr[axis[0]]; index[axis[0]]++) { // NOTE: minor axis may start from 0! Check on this later ...
 | 
|---|
 | 1294 |     for (index[axis[0]] = -sheetnr[axis[0]]+1; index[axis[0]] < sheetnr[axis[0]]; index[axis[0]]++) { // NOTE: minor axis may start from 0! Check on this later ...
 | 
|---|
 | 1295 |       //for (index[axis[1]] = 0; index[axis[1]] <= sheetnr[axis[1]]; index[axis[1]]++) {  // These are all the cells that need be checked on
 | 
|---|
 | 1296 |       for (index[axis[1]] = -sheetnr[axis[1]]+1; index[axis[1]] < sheetnr[axis[1]]; index[axis[1]]++) {  // These are all the cells that need be checked on
 | 
|---|
 | 1297 |         // Calculate offset in cartesian coordinates
 | 
|---|
 | 1298 |         offset = MatrixTrafo(Vector, index);
 | 
|---|
 | 1299 | 
 | 
|---|
 | 1300 |         //fprintf(stdout, "Now dealing with numbercell atoms in unit cell at R = (%lg,%lg,%lg)\n", offset[0], offset[1], offset[2]);
 | 
|---|
 | 1301 |         for (nr = 0; nr < numbercell; nr++) {
 | 
|---|
 | 1302 |           percentage = rand()/(RAND_MAX+1.0);
 | 
|---|
 | 1303 |           //fprintf(stdout, "Lucky number for %d is %lg >? %lg\n", nr, percentage, randomness[nr]); 
 | 
|---|
 | 1304 |           if (percentage >= randomness[nr]) {
 | 
|---|
 | 1305 |             // Create coordinates at atom site
 | 
|---|
 | 1306 |             coord = VectorAdd(atombuffer[nr].x, offset);
 | 
|---|
 | 1307 |             //fprintf(stdout, "Atom Nr. %i: ", (numbersheet+1));         
 | 
|---|
 | 1308 |             //PrintVector(stdout, coord);
 | 
|---|
 | 1309 |             // project down on major and minor Tubevectors and check for length if out of sheet
 | 
|---|
| [e2f3fde] | 1310 |             tempvector = MatrixTrafoInverse(coord, TubevectorInverse);
 | 
|---|
 | 1311 |             if (((tempvector[axis[0]] + MYEPSILON) > 0) && ((factors[0] - tempvector[axis[0]]) > MYEPSILON) &&
 | 
|---|
 | 1312 |                 ((tempvector[axis[1]] + MYEPSILON) > 0) && ((factors[1] - tempvector[axis[1]]) > MYEPSILON) &&
 | 
|---|
 | 1313 |                 ((tempvector[axis[2]] + MYEPSILON) > 0) && ((factors[2] - tempvector[axis[2]]) > MYEPSILON)) { // check if within rotated cell          numbersheet++;
 | 
|---|
| [a0bcf1] | 1314 |               //if (nummer >= 2)  strcpy(atombuffer[nr].name, "O");
 | 
|---|
 | 1315 |               //nummer++;
 | 
|---|
 | 1316 |               fprintf(SheetFile, "%s\t%5.5lg\t%5.5lg\t%5.5lg\n", atombuffer[nr].name, coord[0], coord[1], coord[2]);
 | 
|---|
 | 1317 |               // rotate to align the sheet in xy plane
 | 
|---|
 | 1318 |               x1 = coord[0]*cos(-angle) + coord[1] * sin(-angle);
 | 
|---|
 | 1319 |               x2 = coord[0]*(-sin(-angle)) + coord[1] * cos(-angle);
 | 
|---|
 | 1320 |               x3 = coord[2];
 | 
|---|
 | 1321 |               fprintf(SheetFileAligned, "%s\t%5.5lg\t%5.5lg\t%5.5lg\n", atombuffer[nr].name, x1, x2, x3);
 | 
|---|
 | 1322 |               //fprintf(SheetFile, "O\t%5.5lg\t%5.5lg\t%5.5lg\n", coord[0], coord[1], coord[2]);
 | 
|---|
 | 1323 |               //fprintf(stdout, "%s/%d\t(%lg\t%lg\t%lg)\t", atombuffer[nr].name, numbersheet+1, coord[0], coord[1], coord[2]);
 | 
|---|
 | 1324 |               //PrintVector(stdout, tempvector);
 | 
|---|
 | 1325 |               numbersheet++;
 | 
|---|
 | 1326 |               //fprintf(stdout, "%i,", nr);
 | 
|---|
 | 1327 |             } //else {
 | 
|---|
 | 1328 |               //numbersheet++;
 | 
|---|
 | 1329 |               //fprintf(SheetFile, "B\t%lg\t%lg\t%lg\n", coord[0], coord[1], coord[2]);
 | 
|---|
 | 1330 |               //fprintf(stdout, "O \t(%lg\t%lg\t%lg)\n", coord[0], coord[1], coord[2]);
 | 
|---|
 | 1331 |               //fprintf(stdout, "!!%i!!, ", nr);
 | 
|---|
 | 1332 |             //}
 | 
|---|
 | 1333 |             Free(tempvector, "Main: At stage Sheet - tempvector");
 | 
|---|
 | 1334 |             Free(coord, "Main: At stage Sheet - coord");
 | 
|---|
 | 1335 |           }
 | 
|---|
 | 1336 |         }
 | 
|---|
 | 1337 |         Free(offset, "Main: At stage Sheet - offset");
 | 
|---|
 | 1338 |       }
 | 
|---|
 | 1339 |       //fprintf(stdout, "\n";
 | 
|---|
 | 1340 |     }
 | 
|---|
 | 1341 | 
 | 
|---|
 | 1342 |     fclose(SheetFile);
 | 
|---|
 | 1343 |     fclose(SheetFileAligned);
 | 
|---|
 | 1344 |     AddAtomicNumber(SheetFilename,numbersheet, Vector, Recivector); // prepend atomic number and comment
 | 
|---|
 | 1345 |     AddAtomicNumber(SheetFilenameAligned,numbersheet, Vector, Recivector); // prepend atomic number and comment
 | 
|---|
 | 1346 |     AddSheetInfo(SheetFilename,axis,chiral, factors, seed, numbercell, randomness);
 | 
|---|
 | 1347 |     fprintf(stdout, "\nThere are %i atoms in the created sheet.\n", numbersheet);
 | 
|---|
 | 1348 | 
 | 
|---|
 | 1349 |     strncpy(stage, "Sheet", 5);
 | 
|---|
 | 1350 |   //}
 | 
|---|
 | 1351 |   SheetBuffer = ReadBuffer(SheetFilename, &length);
 | 
|---|
 | 1352 |   
 | 
|---|
 | 1353 |   
 | 
|---|
 | 1354 |   // ======================== STAGE: Tube ==============================
 | 
|---|
 | 1355 |   // The tube starts with the rectangular (due to the orthogonalization) sheet
 | 
|---|
 | 1356 |   // just created (or read). Along the minor axis it is rolled up, i.e. projected
 | 
|---|
 | 1357 |   // from a 2d surface onto a cylindrical surface (x,y,z <-> r,alpha,z). The only
 | 
|---|
 | 1358 |   // thing that's a bit complex is that the sheet it not aligned along the cartesian
 | 
|---|
 | 1359 |   // axis but along major and minor. That's why we have to transform the atomic
 | 
|---|
 | 1360 |   // cartesian coordinates into the orthogonal tubevector base, do the rolling up
 | 
|---|
 | 1361 |   // there (and regard that minor and major axis must not necessarily be of equal
 | 
|---|
 | 1362 |   // length) and afterwards transform back again (where we need the $halfaxis due to
 | 
|---|
 | 1363 |   // the above possible inequality).
 | 
|---|
 | 1364 | 
 | 
|---|
 | 1365 |   FILE *TubeFile = NULL;
 | 
|---|
 | 1366 |   FILE *TubeFileAligned = NULL;
 | 
|---|
 | 1367 |   
 | 
|---|
 | 1368 |   Debug ("STAGE: Tube\n");
 | 
|---|
 | 1369 |   if (!strncmp(stage, "Sheet", 4)) {
 | 
|---|
 | 1370 |     TubeFile = fopen(TubeFilename, "w");
 | 
|---|
 | 1371 |     if (TubeFile == NULL) {
 | 
|---|
 | 1372 |       fprintf(stderr, "ERROR: Main - can't open %s for writing\n", TubeFilename);
 | 
|---|
 | 1373 |       exit(255);
 | 
|---|
 | 1374 |     }
 | 
|---|
 | 1375 |     TubeFileAligned = fopen(TubeFilenameAligned, "w");
 | 
|---|
 | 1376 |     if (TubeFile == NULL) {
 | 
|---|
 | 1377 |       fprintf(stderr, "ERROR: Main - can't open %s for writing\n", TubeFilenameAligned);
 | 
|---|
 | 1378 |       exit(255);
 | 
|---|
 | 1379 |     }
 | 
|---|
 | 1380 |     bufptr = SheetBuffer;
 | 
|---|
 | 1381 |     bufptr += GetNextline(bufptr, line);  // write numbers to file
 | 
|---|
 | 1382 |     bufptr += GetNextline(bufptr, line);  // write comment to file
 | 
|---|
 | 1383 | 
 | 
|---|
 | 1384 |     //cog = CenterOfGravity(bufptr, numbersheet);
 | 
|---|
 | 1385 |     //cog_projected = MatrixTrafoInverse(cog, TubevectorInverse);
 | 
|---|
 | 1386 |     //fprintf(stdout, "\nCenter of Gravity at (%5.5lg\t%5.5lg\t%5.5lg) and projected at (%5.5lg\t%5.5lg\t%5.5lg)\n", cog[0], cog[1], cog[2], cog_projected[0], cog_projected[1], cog_projected[2]);
 | 
|---|
 | 1387 |     
 | 
|---|
 | 1388 |     // restart
 | 
|---|
 | 1389 |     bufptr = SheetBuffer;
 | 
|---|
 | 1390 |     bufptr += GetNextline(bufptr, line);  // write numbers to file
 | 
|---|
 | 1391 |     bufptr += GetNextline(bufptr, line);  // write numbers to file
 | 
|---|
 | 1392 | 
 | 
|---|
 | 1393 |     // determine half axis as tube vector not necessarily have the same length
 | 
|---|
 | 1394 |     double halfaxis[NDIM];
 | 
|---|
 | 1395 |     for (i=0;i<NDIM;i++)
 | 
|---|
 | 1396 |       halfaxis[i] = factors[0]*Norm(Tubevector[axis[0]])/Norm(Tubevector[i]);
 | 
|---|
 | 1397 |       
 | 
|---|
 | 1398 |     double arg, radius;  
 | 
|---|
 | 1399 |     for (i=0;i<numbersheet;i++) {
 | 
|---|
 | 1400 |       // scan next atom 
 | 
|---|
 | 1401 |       bufptr += GetNextline(bufptr, line);
 | 
|---|
 | 1402 |       sscanf(line, "%s %lg %lg %lg", name, &atom[0], &atom[1], &atom[2]);
 | 
|---|
 | 1403 | 
 | 
|---|
 | 1404 |       //  transform atom coordinates in cartesian system to the axis eigensystem
 | 
|---|
 | 1405 |       x =  MatrixTrafoInverse(atom, TubevectorInverse);
 | 
|---|
 | 1406 |       //x = VectorAdd(y, cog_projected);
 | 
|---|
 | 1407 |       //free(y);
 | 
|---|
 | 1408 |       
 | 
|---|
 | 1409 |       // roll up (project (x,y,z) on cylindrical coordinates (radius,arg,z))
 | 
|---|
 | 1410 |       arg = 2.*M_PI*x[axis[0]]/(factors[0]) - M_PI;  // is angle
 | 
|---|
 | 1411 |       radius = 1./(2.*M_PI);  // is length of sheet in units of axis vector, divide by pi to get radius (from circumference)
 | 
|---|
 | 1412 |       // fprintf(stdout, "arg: %5.2f (c%2.2f,s%2.2f)\t",$arg, cos($arg), sin($arg));
 | 
|---|
 | 1413 |       x[axis[0]] = cos(arg)*halfaxis[axis[0]]*radius; //(radius+x[axis[2]]/halfaxis[axis[2]]); // as both vectors are not normalized additional betrag has to be taken into account!
 | 
|---|
 | 1414 |       x[axis[2]] = sin(arg)*halfaxis[axis[2]]*radius; //(radius+x[axis[2]]/halfaxis[axis[2]]); // due to the back-transformation from eigensystem to cartesian one
 | 
|---|
 | 1415 |       //fprintf(stdout, "rotated: (%5.2f,%5.2f,%5.2f)\n",x[0],x[1],x[2]);
 | 
|---|
 | 1416 |       atom_transformed = MatrixTrafo(Tubevector, x);
 | 
|---|
 | 1417 |       fprintf(TubeFile, "%s\t%lg\t%lg\t%lg\n", name, atom_transformed[0], atom_transformed[1], atom_transformed[2]);
 | 
|---|
 | 1418 |       // rotate and flip to align tube in z-direction
 | 
|---|
| [1b192d] | 1419 |       x1 = atom_transformed[0]*cos(-angle) + atom_transformed[1] * sin(-angle);
 | 
|---|
 | 1420 |       x2 = atom_transformed[0]*(-sin(-angle)) + atom_transformed[1] * cos(-angle);
 | 
|---|
| [a0bcf1] | 1421 |       x3 = atom_transformed[2];
 | 
|---|
| [1b192d] | 1422 |       fprintf(TubeFileAligned, "%s\t%lg\t%lg\t%lg\n", name, x3, x2, x1);  // order so that symmetry is along z axis
 | 
|---|
| [a0bcf1] | 1423 |       //fprintf(stdout, "%s\t%5.5lg\t%5.5lg\t%5.5lg\n", name, atom_transformed[0], atom_transformed[1] ,atom_transformed[2]);
 | 
|---|
 | 1424 | 
 | 
|---|
 | 1425 |       Free(x, "Main: at stage Tube - x"); 
 | 
|---|
 | 1426 |       Free(atom_transformed, "Main: at stage Tube - atom_transformed");
 | 
|---|
 | 1427 |     }
 | 
|---|
 | 1428 | 
 | 
|---|
 | 1429 |     
 | 
|---|
 | 1430 |     fclose(TubeFile);
 | 
|---|
 | 1431 |     fclose(TubeFileAligned);
 | 
|---|
 | 1432 |     //free(cog);
 | 
|---|
 | 1433 |     //free(cog_projected);
 | 
|---|
 | 1434 |     AddAtomicNumber(TubeFilename,numbersheet, Vector, Recivector); // prepend atomic number and comment
 | 
|---|
 | 1435 |     AddAtomicNumber(TubeFilenameAligned,numbersheet, Vector, Recivector); // prepend atomic number and comment
 | 
|---|
 | 1436 |     AddSheetInfo(TubeFilename,axis,chiral, factors, seed, numbercell, randomness);
 | 
|---|
 | 1437 |     fprintf(stdout, "\nThere are %i atoms in the created tube.\n", numbersheet);
 | 
|---|
 | 1438 |     
 | 
|---|
 | 1439 |     strncpy(stage, "Tube", 4);
 | 
|---|
 | 1440 |   } else {
 | 
|---|
 | 1441 |   }
 | 
|---|
 | 1442 | 
 | 
|---|
 | 1443 |   TubeBuffer = ReadBuffer(TubeFilename, &length);
 | 
|---|
 | 1444 | 
 | 
|---|
 | 1445 |   // ======================== STAGE: Torus =============================
 | 
|---|
 | 1446 |   // The procedure for the torus is very much alike to the one used to make the
 | 
|---|
 | 1447 |   // tube. Only the projection is not from 2d surface onto a cylindrical one but
 | 
|---|
 | 1448 |   // from a cylindrial onto a torus surface
 | 
|---|
 | 1449 |   // (x,y,z) <-> (cos(s)*(R+r*cos(t)), sin(s)*(R+rcos(t)), r*sin(t)).
 | 
|---|
 | 1450 |   // Here t is the angle within the tube with radius r, s is the torus angle with
 | 
|---|
 | 1451 |   // radius R. We get R from the tubelength (that's why we need lengthfactor to
 | 
|---|
 | 1452 |   // make it long enough). And due to fact that we have it already upon a cylindrical
 | 
|---|
 | 1453 |   // surface, r*cos(t) and r*sin(t) already reside in $minoraxis and $noaxis.
 | 
|---|
 | 1454 | 
 | 
|---|
 | 1455 |   FILE *TorusFile;
 | 
|---|
 | 1456 |   
 | 
|---|
 | 1457 |   Debug ("STAGE: Torus\n");
 | 
|---|
 | 1458 |   if (!strncmp(stage, "Tube", 4)) {
 | 
|---|
 | 1459 |     TorusFile = fopen(TorusFilename, "w");
 | 
|---|
 | 1460 |     if (TorusFile == NULL) {
 | 
|---|
 | 1461 |       fprintf(stderr, "ERROR: main - can't open %s for writing\n", TorusFilename);
 | 
|---|
 | 1462 |       exit(255);
 | 
|---|
 | 1463 |     }
 | 
|---|
 | 1464 |     bufptr = TubeBuffer;
 | 
|---|
 | 1465 |     bufptr += GetNextline(bufptr, line);  // write numbers to file
 | 
|---|
 | 1466 |     bufptr += GetNextline(bufptr, line);  // write comment to file
 | 
|---|
 | 1467 |     
 | 
|---|
 | 1468 |     //cog = CenterOfGravity(bufptr, numbersheet);
 | 
|---|
 | 1469 |     //cog_projected = MatrixTrafoInverse(cog, TubevectorInverse);
 | 
|---|
 | 1470 |     //fprintf(stdout, "\nCenter of Gravity at (%5.5lg\t%5.5lg\t%5.5lg) and projected at (%5.5lg\t%5.5lg\t%5.5lg)\n", cog[0], cog[1], cog[2], cog_projected[0], cog_projected[1], cog_projected[2]);
 | 
|---|
 | 1471 |     
 | 
|---|
 | 1472 |     // determine half axis as tube vectors not necessarily have same length
 | 
|---|
 | 1473 |     double halfaxis[NDIM];
 | 
|---|
 | 1474 |     for (i=0;i<NDIM;i++)
 | 
|---|
 | 1475 |       halfaxis[i] = Norm(Tubevector[axis[1]])/Norm(Tubevector[i]);
 | 
|---|
 | 1476 |       
 | 
|---|
 | 1477 |     double arg, radius;  
 | 
|---|
 | 1478 |     for (i=0;i<numbersheet;i++) {
 | 
|---|
 | 1479 |       // scan next atom 
 | 
|---|
 | 1480 |       bufptr += GetNextline(bufptr, line);
 | 
|---|
 | 1481 |       sscanf(line, "%s %lg %lg %lg", name, &atom[0], &atom[1], &atom[2]);
 | 
|---|
 | 1482 | 
 | 
|---|
 | 1483 |       //  transform atom coordinates in cartesian system to the axis eigensystem
 | 
|---|
 | 1484 |       x = MatrixTrafoInverse(atom, TubevectorInverse);
 | 
|---|
 | 1485 |       //x = VectorAdd(y, cog_projected);
 | 
|---|
 | 1486 |       //free(y);
 | 
|---|
 | 1487 |       
 | 
|---|
 | 1488 |       // roll up (project (x,y,z) on cylindrical coordinates (radius,arg,z))
 | 
|---|
 | 1489 |       arg = 2.*M_PI*x[axis[1]]/(factors[1]) - M_PI;  // is angle
 | 
|---|
 | 1490 |       radius = (factors[1])/(2.*M_PI) + x[axis[0]]/halfaxis[axis[0]];  // is length of sheet in units of axis vector, divide by pi to get radius (from circumference)
 | 
|---|
 | 1491 |       // fprintf(stdout, "arg: %5.2f (c%2.2f,s%2.2f)\t",$arg, cos($arg), sin($arg));
 | 
|---|
 | 1492 |       x[axis[0]] = cos(arg)*halfaxis[axis[0]]*radius; // as both vectors are not normalized additional betrag has to be taken into account!
 | 
|---|
 | 1493 |       x[axis[1]] = sin(arg)*halfaxis[axis[1]]*radius; // due to the back-transformation from eigensystem to cartesian one
 | 
|---|
 | 1494 |       //fprintf(stdout, "rotated: (%5.2f,%5.2f,%5.2f)\n",x[0],x[1],x[2]);
 | 
|---|
 | 1495 |       atom_transformed = MatrixTrafo(Tubevector, x);
 | 
|---|
 | 1496 |       fprintf(TorusFile, "%s\t%lg\t%lg\t%lg\n", name, atom_transformed[0], atom_transformed[1] ,atom_transformed[2]);
 | 
|---|
 | 1497 |       //fprintf(stdout, "%s\t%5.5lg\t%5.5lg\t%5.5lg\n", name, atom_transformed[0], atom_transformed[1] ,atom_transformed[2]);
 | 
|---|
 | 1498 | 
 | 
|---|
 | 1499 |       Free(x, "Main: at stage Torus - x"); 
 | 
|---|
 | 1500 |       Free(atom_transformed, "Main: at stage Torus - atom_transformed");
 | 
|---|
 | 1501 |     }
 | 
|---|
 | 1502 |     
 | 
|---|
 | 1503 |     fclose(TorusFile);
 | 
|---|
 | 1504 |     //free(cog);
 | 
|---|
 | 1505 |     //free(cog_projected);
 | 
|---|
 | 1506 |     AddAtomicNumber(TorusFilename,numbersheet, Vector, Recivector); // prepend atomic number and comment
 | 
|---|
 | 1507 |     AddSheetInfo(TorusFilename,axis,chiral, factors, seed, numbercell, randomness);
 | 
|---|
 | 1508 |     fprintf(stdout, "\nThere are %i atoms in the created torus.\n", numbersheet);
 | 
|---|
 | 1509 | 
 | 
|---|
 | 1510 |     strncpy(stage, "Torus", 5);
 | 
|---|
 | 1511 |   } else {
 | 
|---|
 | 1512 |   }
 | 
|---|
 | 1513 | 
 | 
|---|
 | 1514 |   // Free memory
 | 
|---|
 | 1515 |   for (i=0; i<NDIM; i++ )  {
 | 
|---|
 | 1516 |     Free(Vector[i], "Main: end of stages - *Vector");
 | 
|---|
 | 1517 |     Free(Recivector[i], "Main: end of stages - *Recivector");
 | 
|---|
 | 1518 |     Free(Tubevector[i], "Main: end of stages - *Tubevector");
 | 
|---|
 | 1519 |     Free(TubevectorInverse[i], "Main: end of stages - *TubevectorInverse");
 | 
|---|
 | 1520 |   }
 | 
|---|
 | 1521 |   Free(atom, "Main: end of stages - atom");
 | 
|---|
 | 1522 |   Free(Vector, "Main: end of stages - Vector");
 | 
|---|
 | 1523 |   Free(Recivector, "Main: end of stages - Recivector");
 | 
|---|
 | 1524 |   Free(Tubevector, "Main: end of stages - Tubevector");
 | 
|---|
 | 1525 |   Free(TubevectorInverse, "Main: end of stages - TubevectorInverse");
 | 
|---|
 | 1526 |   Free(randomness, "Main: at stage Sheet - randomness");
 | 
|---|
 | 1527 | 
 | 
|---|
 | 1528 |   if (CellBuffer != NULL) Free(CellBuffer, "Main: end of stages - CellBuffer");
 | 
|---|
 | 1529 |   if (SheetBuffer != NULL) Free(SheetBuffer, "Main: end of stages - SheetBuffer");
 | 
|---|
 | 1530 |   if (TubeBuffer != NULL) Free(TubeBuffer, "Main: end of stages - TubeBuffer");
 | 
|---|
 | 1531 | 
 | 
|---|
 | 1532 |   Free(CellFilename, "Main: end of stafes - CellFilename");
 | 
|---|
 | 1533 |   Free(SheetFilename, "Main: end of stafes - CellFilename");
 | 
|---|
 | 1534 |   Free(TubeFilename, "Main: end of stafes - CellFilename");
 | 
|---|
 | 1535 |   Free(TorusFilename, "Main: end of stafes - CellFilename");
 | 
|---|
 | 1536 |   Free(SheetFilenameAligned, "Main: end of stafes - CellFilename");
 | 
|---|
 | 1537 |   Free(TubeFilenameAligned, "Main: end of stafes - CellFilename");
 | 
|---|
 | 1538 |   
 | 
|---|
 | 1539 |   // exit
 | 
|---|
 | 1540 |   exit(0);
 | 
|---|
 | 1541 | }
 | 
|---|