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