| [a0bcf1] | 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 | } | 
|---|