ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/ripple/dp.c
Revision: 1185
Committed: Fri May 21 20:07:10 2004 UTC (20 years, 1 month ago) by xsun
Content type: text/plain
File size: 27288 byte(s)
Log Message:
this is the ripple codes

File Contents

# Content
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <math.h>
5 #include <unistd.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <sys/time.h>
9 #include <time.h>
10 #include "mkl_vsl.h"
11
12 // inlined functions (for periodic box wrapping)
13
14 inline double roundMe( double x ){
15 return ( x >= 0 ) ? floor( x + 0.5 ) : ceil( x - 0.5 );
16 }
17
18 // Structures to store our data:
19
20 // coords holds the data for a single tethered dipole:
21 struct coords{
22 double pos[3]; // cartesian coords
23 double theta; // orientational angle relative to z axis
24 double phi; // orientational angle in x-y plane
25 double mu; // dipole strength
26 char name[30]; // an identifier for the type of atom
27 };
28
29 // state holds the current "configuration" of the entire system
30 struct system {
31 int nAtoms; // Number of Atoms in this configuration
32 struct coords *r; // The set of coordinates for all atoms
33 double beta; // beta = 1 /(kb*T)
34 double strength; // strength of the dipoles (Debye)
35 double z0; // default z axis position
36 double theta0; // default theta angle
37 double kz; // force constant for z displacement
38 double ktheta; // force constant for theta displacement
39 int nCycles; // How many cycles to do in total
40 int iCycle; // How many cycles have we done?
41 int nMoves; // How many MC moves in each cycle
42 int nSample; // How many cycles between samples
43 double Hmat[2][2]; // The information about the size of the per. box
44 double HmatI[2][2]; // The inverse box
45 double energy; // The current Energy
46 double dtheta; // maximum size of a theta move
47 double deltaz; // maximum size of a z move
48 double deltaphi; // maximum size of a phi move
49 int nAttempts; // number of MC moves that have been attempted
50 int nAccepts; // number of MC moves that have been accepted
51 int nx; // number of unit cells in x direction
52 int ny; // number of unit cells in y direction
53 };
54
55 char *program_name; /* the name of the program */
56
57 // Function prototypes:
58 void usage(void);
59 double toterg(struct system* state);
60 void getmag(struct system* state, double mag[3]);
61 double eneri(struct system* state, struct coords iTemp, int i, int jb);
62 void adjust(struct system* state);
63 void mcmove(struct system* state, VSLStreamStatePtr stream, double *en);
64 void store(struct system* state, FILE* out_file);
65 void invertMat2(double a[2][2], double b[2][2]);
66 void wrapVector( double thePos[2], double Hmat[2][2], double HmatI[2][2]);
67
68 // Defines for the MKL random Number generator:
69 #define SEED 1
70 #define BRNG VSL_BRNG_MCG31
71 #define METHOD 0
72 #define N 1
73
74 int main(argc, argv)
75 int argc;
76 char *argv[];
77 {
78
79 FILE *in_file; /* the input file */
80 FILE *out_file; /* the output file */
81 char *out_prefix = NULL; /* the prefix of the output file
82 (if different from the root_name) */
83 char out_name[500]; /* the output name */
84 char in_name[500]; // the input file name
85 char *root_name = NULL; /* the root name */
86
87 int have_outName = 0;
88 int have_inName = 0;
89 int have_rootName = 0;
90 int restart_from_file = 0;
91
92 int i, j, k, imove;
93
94 char temp_name[500];
95 int lineCount = 0; // the line number
96 char read_buffer[1000]; /* the line buffer for reading */
97 char *eof_test; /* ptr to see when we reach the end of the file */
98 char *foo; /* the pointer to the current string token */
99 char atomName[10];
100
101 double aLat;
102 double bLat;
103 int cells;
104
105 int haveAlat = 0;
106 int haveBlat = 0;
107 int haveCells = 0;
108
109 struct system* state;
110 struct coords* r;
111
112 int done;
113 char current_flag;
114
115 double dx, dy, uxi, uyi, uzi, myran, en, ent, magmag;
116 double mag[3];
117 int which;
118
119 // Other useful defines:
120
121 double twopi = 2.0 * M_PI;
122 double kb = 0.0019872198;
123 strcpy(atomName, "Ar");
124
125 state = (struct system *)malloc(sizeof(struct system));
126
127 // The parameters for the simulation:
128
129 state->strength = 7.0;
130 state->z0 = 0.0;
131 state->kz = kb;
132 state->theta0 = M_PI / 2.0;
133 state->ktheta = 0.0;
134 state->dtheta = 0.3;
135 state->deltaz = 1.0;
136 state->deltaphi = 0.5;
137 state->beta = 1.0 / (kb * 300.0);
138
139 // these three should really be given as command line arguments, but we'll
140 // set defaults here just in case:
141
142 state->nCycles = 1000000;
143 state->nMoves = 100;
144
145 // Store roughly 100 frames while we are testing
146 state->nSample = state->nCycles / 100;
147
148 // Stuff for initializing the random number generator:
149 struct timeval now_time_val;
150 struct timezone time_zone;
151 struct tm *now_tm;
152 time_t now;
153 int mySeed;
154 VSLStreamStatePtr stream;
155
156 // First, initialize the random number generator:
157 gettimeofday(&now_time_val, &time_zone); /* get the time now */
158 now = now_time_val.tv_sec; /* convert to epoch time */
159 mySeed = (int) now;
160 vslNewStream(&stream, BRNG, mySeed);
161
162 // Now handle the arguments to the program:
163
164 program_name = argv[0]; // save the program name in case we need it
165
166 for( i = 1; i < argc; i++){
167
168 if(argv[i][0] =='-'){
169
170 // parse single character options
171
172 done =0;
173 j = 1;
174 current_flag = argv[i][j];
175 while( (current_flag != '\0') && (!done) ){
176
177 switch(current_flag){
178
179 case 'o':
180 // -o <filename> => the output
181
182 i++;
183 strcpy( out_name, argv[i] );
184 have_outName = 1;
185 done = 1;
186 break;
187
188 case 'i':
189 // -i <filename> => the input
190
191 i++;
192 strcpy( in_name, argv[i] );
193 have_inName = 1;
194 done = 1;
195 break;
196
197 case 'r':
198 // -r <root> => root Name
199
200 i++;
201 strcpy( root_name, argv[i] );
202 have_rootName = 1;
203 done = 1;
204 break;
205
206 case 'n':
207 // -n <#> => do Cycle MC cycles
208
209 i++;
210 state->nCycles = atoi(argv[i]);
211 done = 1;
212 break;
213
214 case 's':
215 // -s <#> => write out every nSample MC cycles
216 printf("setting nSample\n");
217 i++;
218 state->nSample = atoi(argv[i]);
219 printf("setting nSample to %d\n", state->nSample);
220 done = 1;
221 break;
222
223 case 'm':
224 // -m <#> => each MC cycle consists of nMoves atomic moves
225
226 i++;
227 state->nMoves = atoi(argv[i]);
228 done = 1;
229 break;
230
231 case 'k':
232 // -k kz sets the value of kz in units of kb
233 i++;
234 state->kz = kb * atof( argv[i] );
235 done = 1;
236 break;
237
238 case 'h':
239 // -h hexSpace set the inter-atomic spacing for a regular
240 // hexagonal lattice
241 haveAlat = 1;
242 haveBlat = 1;
243 i++;
244 bLat = atof( argv[i] );
245 aLat = sqrt(3.0) * bLat;
246 done = 1;
247 break;
248
249 case 'a':
250 // -a aLat set the x lattice spacing for the distorted hexagonal
251 // lattice
252 haveAlat = 1;
253 i++;
254 aLat = atof( argv[i] );
255 done = 1;
256 break;
257
258 case 'b':
259 // -b bLat set the y lattice spacing for the distorted hexagonal
260 // lattice when initializing the system
261 haveBlat = 1;
262 i++;
263 bLat = atof( argv[i] );
264 done = 1;
265 break;
266
267 case 'c':
268 // -c cells sets the number of unit cells along the x axis
269 // to use when initializing the system
270 haveCells = 1;
271 i++;
272 cells = atoi( argv[i] );
273 done = 1;
274 break;
275
276 case 'x':
277 usage();
278 done = 1;
279 break;
280
281 default:
282
283 (void)fprintf(stderr, "Bad option \"-%s\"\n", current_flag);
284 usage();
285 }
286 j++;
287 current_flag = argv[i][j];
288 }
289 } else {
290
291 if( root_name != NULL ){
292 fprintf( stderr,
293 "The root name has already been set with an argument to -r\n"
294 "But another argument looks like the root name. Whassup?\n");
295 usage();
296 }
297
298 root_name = argv[i];
299 }
300 }
301
302 if ( !have_outName && root_name == NULL) {
303 fprintf( stderr, "No output or root filename was set, so look for your data in dp.dump!\n");
304 strcpy(out_name, "dp.dump");
305 have_outName=1;
306 }
307
308
309 // Figure out if we are starting from an input file:
310
311 if (have_inName) {
312
313 restart_from_file = 1;
314
315 in_file = fopen(in_name, "r");
316 if(in_file == NULL){
317 printf("Cannot open file \"%s\" for reading.\n", in_name);
318 exit(8);
319 }
320
321 // start reading the first frame
322 eof_test = fgets(read_buffer, sizeof(read_buffer), in_file);
323 lineCount++;
324
325 while(eof_test != NULL){
326
327 (void)sscanf(read_buffer, "%d", &state->nAtoms);
328 state->r =
329 (struct coords *)calloc(state->nAtoms, sizeof(struct coords));
330
331 // read and the comment line and grab the time and box dimensions
332
333 eof_test = fgets(read_buffer, sizeof(read_buffer), in_file);
334 lineCount++;
335 if(eof_test == NULL){
336 printf("error in reading file at line: %d\n", lineCount);
337 exit(8);
338 }
339
340 foo = strtok( read_buffer, " ,;\t" );
341 (void)sscanf( read_buffer, "%d", &state->iCycle );
342
343 foo = strtok(NULL, " ,;\t");
344 if(foo == NULL){
345 printf("error in reading file at line: %d\n", lineCount);
346 exit(8);
347 }
348 (void)sscanf(foo, "%d", &state->nx);
349
350 foo = strtok(NULL, " ,;\t");
351 if(foo == NULL){
352 printf("error in reading file at line: %d\n", lineCount);
353 exit(8);
354 }
355 (void)sscanf(foo, "%d", &state->ny);
356
357 foo = strtok(NULL, " ,;\t");
358 if(foo == NULL){
359 printf("error in reading file at line: %d\n", lineCount);
360 exit(8);
361 }
362 (void)sscanf(foo, "%lf",&state->Hmat[0][0]);
363
364 foo = strtok(NULL, " ,;\t");
365 if(foo == NULL){
366 printf("error in reading file at line: %d\n", lineCount);
367 exit(8);
368 }
369 (void)sscanf(foo, "%lf",&state->Hmat[1][0]);
370
371
372 foo = strtok(NULL, " ,;\t");
373 if(foo == NULL){
374 printf("error in reading file at line: %d\n", lineCount);
375 exit(8);
376 }
377 (void)sscanf(foo, "%lf",&state->Hmat[0][1]);
378
379 foo = strtok(NULL, " ,;\t");
380 if(foo == NULL){
381 printf("error in reading file at line: %d\n", lineCount);
382 exit(8);
383 }
384 (void)sscanf(foo, "%lf",&state->Hmat[1][1]);
385
386 // Length of the two box vectors:
387
388 dx = sqrt(pow(state->Hmat[0][0], 2) + pow(state->Hmat[1][0], 2));
389 dy = sqrt(pow(state->Hmat[0][1], 2) + pow(state->Hmat[1][1], 2));
390
391 aLat = dx / (double)(state->nx);
392 bLat = dy / (double)(state->ny);
393
394 // Find HmatI:
395
396 invertMat2(state->Hmat, state->HmatI);
397
398 for( i=0; i < state->nAtoms; i++){
399
400 eof_test = fgets(read_buffer, sizeof(read_buffer), in_file);
401 lineCount++;
402 if(eof_test == NULL){
403 printf("error in reading file at line: %d\n", lineCount);
404 exit(8);
405 }
406
407 foo = strtok(read_buffer, " ,;\t");
408 (void)strcpy(state->r[i].name, foo); //copy the atom name
409
410 // next we grab the positions
411
412 foo = strtok(NULL, " ,;\t");
413 if(foo == NULL){
414 printf("error in reading postition x from %s\n"
415 "natoms = %d, line = %d\n",
416 in_name, state->nAtoms, lineCount );
417 exit(8);
418 }
419 (void)sscanf( foo, "%lf", &state->r[i].pos[0] );
420
421 foo = strtok(NULL, " ,;\t");
422 if(foo == NULL){
423 printf("error in reading postition y from %s\n"
424 "natoms = %d, line = %d\n",
425 in_name, state->nAtoms, lineCount );
426 exit(8);
427 }
428 (void)sscanf( foo, "%lf", &state->r[i].pos[1] );
429
430 foo = strtok(NULL, " ,;\t");
431 if(foo == NULL){
432 printf("error in reading postition z from %s\n"
433 "natoms = %d, line = %d\n",
434 in_name, state->nAtoms, lineCount );
435 exit(8);
436 }
437 (void)sscanf( foo, "%lf", &state->r[i].pos[2] );
438
439 foo = strtok(NULL, " ,;\t");
440 if(foo == NULL){
441 printf("error in reading angle phi from %s\n"
442 "natoms = %d, line = %d\n",
443 in_name, state->nAtoms, lineCount );
444 exit(8);
445 }
446 (void)sscanf( foo, "%lf", &state->r[i].phi );
447
448 foo = strtok(NULL, " ,;\t");
449 if(foo == NULL){
450 printf("error in reading unit vector x from %s\n"
451 "natoms = %d, line = %d\n",
452 in_name, state->nAtoms, lineCount );
453 exit(8);
454 }
455 (void)sscanf( foo, "%lf", &uxi );
456
457 foo = strtok(NULL, " ,;\t");
458 if(foo == NULL){
459 printf("error in reading unit vector y from %s\n"
460 "natoms = %d, line = %d\n",
461 in_name, state->nAtoms, lineCount );
462 exit(8);
463 }
464 (void)sscanf( foo, "%lf", &uyi );
465
466 foo = strtok(NULL, " ,;\t");
467 if(foo == NULL){
468 printf("error in reading unit vector z from %s\n"
469 "natoms = %d, line = %d\n",
470 in_name, state->nAtoms, lineCount );
471 exit(8);
472 }
473 (void)sscanf( foo, "%lf", &uzi );
474
475 state->r[i].theta = acos(uzi);
476
477 // The one parameter not stored in the dump file is the dipole strength
478 state->r[i].mu = state->strength;
479
480 }
481 eof_test = fgets(read_buffer, sizeof(read_buffer), in_file);
482 lineCount++;
483 }
484 (void)fclose(in_file);
485
486 } else {
487
488 // not restarting from file, so use data we've got!
489
490 if (!haveAlat) {
491 printf("aLat has not been set!\n");
492 exit(8);
493 }
494
495 if (!haveBlat) {
496 printf("bLat has not been set!\n");
497 exit(8);
498 }
499
500 if (!haveCells) {
501 printf("The number of cells has not been set!\n");
502 exit(8);
503 }
504
505 // Create lattice here:
506
507 // Domains should be roughly square:
508
509 state->nx = cells;
510 state->ny = (int) ((double)cells * aLat / bLat );
511
512 // each cell has 2 atoms (one at (0,0) and one at (a/2 , b/2))
513 state->nAtoms = 2 * state->nx * state->ny;
514
515 state->r =
516 (struct coords *)calloc(state->nAtoms, sizeof(struct coords));
517
518 which = 0;
519 for(i=0; i < state->nx; i++) {
520 for(j=0; j < state->ny; j++) {
521
522 // First atom is at (0,0)
523
524 (void)strcpy(state->r[which].name, atomName);
525 state->r[which].pos[0] = i * aLat;
526 state->r[which].pos[1] = j * bLat;
527
528 vdRngUniform( METHOD, stream, N, &myran, 0.0, 1.0);
529 state->r[which].phi = myran * twopi;
530
531 vdRngUniform( METHOD, stream, N, &myran, 0.0, 1.0);
532 state->r[which].theta = acos(2.0*myran - 1.0);
533
534 vdRngUniform( METHOD, stream, N, &myran, 0.0, 1.0);
535 state->r[which].pos[2] = state->z0 + (2.0*myran-1.0) * state->deltaz;
536
537 state->r[which].mu = state->strength;
538
539 which++;
540 // Second atom is at (a/2, b/2)
541
542 state->r[which].pos[0] = aLat * (2.0 * i + 1.0) / 2.0;
543 state->r[which].pos[1] = bLat * (2.0 * j + 1.0) / 2.0;
544
545 vdRngUniform( METHOD, stream, N, &myran, 0.0, 1.0);
546 state->r[which].phi = myran * twopi;
547
548 vdRngUniform( METHOD, stream, N, &myran, 0.0, 1.0);
549 state->r[which].theta = acos(2.0*myran - 1.0);
550
551 vdRngUniform( METHOD, stream, N, &myran, 0.0, 1.0);
552 state->r[which].pos[2] = state->z0 + (2.0*myran-1.0)*state->deltaz;
553
554 state->r[which].mu = state->strength;
555 which++;
556 }
557 }
558 state->Hmat[0][0] = state->nx * aLat;
559 state->Hmat[0][1] = 0.0;
560 state->Hmat[1][0] = 0.0;
561 state->Hmat[1][1] = state->ny * bLat;
562
563 // Find HmatI:
564
565 invertMat2(state->Hmat, state->HmatI);
566
567 }
568
569 // Open the dump file for writing:
570
571 if( !have_outName ) sprintf( out_name, "%s.dump", root_name );
572
573 out_file = fopen( out_name, "w" );
574 if( out_file == NULL ){
575 printf("Cannot open file \"%s\" for writing.\n", out_name);
576 exit(8);
577 }
578
579 if (state->iCycle >= state->nCycles) {
580 printf("This configuration has already gone past the requested number\n"
581 "of MC cycles! Use the -n flag to request more MC cycles!\n");
582 exit(8);
583 }
584
585 // Do the MC simulation (finally!)
586
587 en = toterg(state);
588
589 printf("MC simulation starting for %d cycles\n", state->nCycles);
590 printf("MC simulation starting with %d moves per cycle\n", state->nMoves);
591 printf("MC simulation starting with sampling done every %d cycles\n", state->nSample);
592
593 printf("The initial Energy is : \t%f\n\n", en);
594
595 state->nAttempts = 0;
596 state->nAccepts = 0;
597
598 adjust(state);
599
600 for(state->iCycle = 0; state->iCycle < state->nCycles; state->iCycle++) {
601 for(imove=0; imove < state->nMoves; imove++) {
602 mcmove(state, stream, &en);
603 }
604
605 if(((state->iCycle)%state->nSample) == 0) {
606 store(state, out_file);
607 /* Don't bother with the magnetization for now */
608 /*
609 getmag(state, mag);
610 magmag = sqrt(pow(mag[0],2) + pow(mag[1],2) + pow(mag[2],2));
611 printf("mag=%f\t%f\t%f\t%f\n", mag[0], mag[1], mag[2], magmag);
612 */
613 }
614
615 if( ((state->iCycle+1)%(state->nCycles / 5)) ==0) {
616 printf("\n=====> Completed\t%d\tout of\t%d cycles\n",
617 state->iCycle + 1,
618 state->nCycles);
619 adjust(state);
620 }
621 }
622
623 if(state->nCycles != 0) {
624 if(state->nAttempts !=0) {
625 printf("Number of attempts to modify a particle :%d\n"
626 "Number of successful modifications: %d (=%lf%)\n\n",
627 state->nAttempts, state->nAccepts,
628 100*(double)(state->nAccepts)/(double)(state->nAttempts));
629 }
630
631 ent = toterg(state);
632
633 if ( fabs(ent-en) > 1e-6) {
634 printf("\n###### ENERGY PROBLEMS ###############\n\n");
635 printf("Total Energy end of simulation : %lf\n"
636 "Running Energy : %lf\n"
637 "Energy Difference : %lf\n\n", ent, en, ent-en);
638 }
639 }
640 fclose(out_file);
641 vslDeleteStream( &stream );
642 return 0;
643 }
644
645 double toterg(struct system* state) {
646
647 struct coords iTemp;
648
649 int i, jb;
650 double ener;
651 double eni;
652
653 ener = 0.0;
654
655 for(i = 0; i < state->nAtoms; i++) {
656
657 // Copy atom i's values into iTemp:
658
659 iTemp.pos[0] = state->r[i].pos[0];
660 iTemp.pos[1] = state->r[i].pos[1];
661 iTemp.pos[2] = state->r[i].pos[2];
662 iTemp.phi = state->r[i].phi;
663 iTemp.theta = state->r[i].theta;
664 iTemp.mu = state->r[i].mu;
665
666 // Pointer for eneri loop start is set to i
667 // We'll skip the i->i pairing in the eneri routine
668
669 jb = i;
670
671 eni = eneri(state, iTemp, i, jb);
672 ener += eni;
673 }
674 state->energy = ener;
675 return ener;
676 }
677
678 void getmag(struct system* state, double mag[3]) {
679
680 double thetai, phii, mui, magmag;
681 int i;
682
683 mag[0] = 0.0;
684 mag[1] = 0.0;
685 mag[2] = 0.0;
686
687 for(i = 0; i < state->nAtoms; i++) {
688 phii = state->r[i].phi;
689 thetai = state->r[i].theta;
690 mui = state->r[i].mu;
691 mag[0] += mui * cos(phii) * sin(thetai);
692 mag[1] += mui * sin(phii) * sin(thetai);
693 mag[2] += mui * cos(thetai);
694 }
695
696 mag[0] /= (double)(state->nAtoms);
697 mag[1] /= (double)(state->nAtoms);
698 mag[2] /= (double)(state->nAtoms);
699
700 }
701
702 double eneri(struct system *state, struct coords iTemp, int i, int jb) {
703
704 double uxi, uyi, uzi, r, r2, r3, r5, uxj, uyj, uzj, rcut;
705 double udotu, rdotui, rdotuj, vij, pre, vint;
706 double eni, dz;
707 double d[2];
708 int j;
709
710 pre = 14.38362;
711
712 rcut = 30.0;
713
714 eni = 0.0;
715 uxi = iTemp.mu * cos(iTemp.phi) * sin(iTemp.theta);
716 uyi = iTemp.mu * sin(iTemp.phi) * sin(iTemp.theta);
717 uzi = iTemp.mu * cos(iTemp.theta);
718
719 for(j = jb; j < state->nAtoms; j++) {
720 if(j != i) {
721
722 // 2-d wrapping on x and y:
723
724 d[0] = state->r[j].pos[0] - iTemp.pos[0];
725 d[1] = state->r[j].pos[1] - iTemp.pos[1];
726
727 wrapVector(d, state->Hmat, state->HmatI);
728
729 // z is unwrapped!
730
731 dz = state->r[j].pos[2] - iTemp.pos[2];
732
733 r2 = pow(d[0], 2) + pow(d[1], 2) + pow(dz, 2);
734 r = sqrt(r2);
735
736 if(r < rcut) {
737
738 r3 = r2*r;
739 r5 = r2*r3;
740
741 uxj = state->r[j].mu * cos(state->r[j].phi) * sin(state->r[j].theta);
742 uyj = state->r[j].mu * sin(state->r[j].phi) * sin(state->r[j].theta);
743 uzj = state->r[j].mu * cos(state->r[j].theta);
744 udotu = uxi*uxj + uyi*uyj + uzi*uzj;
745 rdotui = d[0]*uxi + d[1]*uyi + dz*uzi;
746 rdotuj = d[0]*uxj + d[1]*uyj + dz*uzj;
747
748 vij = pre*(udotu/r3 - 3.0*rdotui*rdotuj/r5);
749 eni += vij;
750 }
751 }
752 }
753
754 vint = 0.5 * state->kz * pow((iTemp.pos[2] - state->z0), 2);
755 vint += 0.5 * state->ktheta * pow((iTemp.theta - state->theta0), 2);
756 eni += vint;
757 return eni;
758 }
759
760 void adjust(struct system* state) {
761
762 static int attempp, naccp;
763 double dzo, dphio, dthetao, frac;
764
765 if((state->nAttempts == 0) || (attempp >= state->nAttempts)) {
766 naccp = state->nAccepts;
767 attempp = state->nAttempts;
768 } else {
769 frac = (double)(state->nAccepts - naccp) /
770 (double)(state->nAttempts - attempp);
771
772 dthetao = state->dtheta;
773 dzo = state->deltaz;
774 dphio = state->deltaphi;
775
776 state->dtheta *= fabs(frac/0.5);
777 state->deltaz *= fabs(frac/0.5);
778 state->deltaphi *= fabs(frac/0.5);
779
780 if((state->dtheta/dthetao)>1.5) state->dtheta = dthetao*1.5;
781 if((state->dtheta/dthetao)<0.5) state->dtheta = dthetao*0.5;
782
783 if((state->deltaz/dzo)>1.5) state->deltaz = dzo * 1.5;
784 if((state->deltaz/dzo)<0.5) state->deltaz = dzo * 0.5;
785 if((state->deltaphi/dphio)>1.5) state->deltaphi = dphio * 1.5;
786 if((state->deltaphi/dphio)<0.5) state->deltaphi = dphio * 0.5;
787 printf("Max. displ. set to :\t%lf\t%lf\t%lf\n"
788 " (old was:\t%lf\t%lf\t%lf)\n"
789 "Fractional acceptance:\t%lf\n"
790 "nAttempts:\t%d\n"
791 "nSuccesses:\t%d\n\n",
792 state->deltaz, state->deltaphi, state->dtheta,
793 dzo, dphio, dthetao,
794 frac,
795 state->nAttempts - attempp,
796 state->nAccepts - naccp);
797 naccp = state->nAccepts;
798 attempp=state->nAttempts;
799 }
800 }
801
802 void mcmove(struct system* state, VSLStreamStatePtr stream, double *en) {
803
804 int o, jb;
805 struct coords oTemp;
806 double eno, enn, myran;
807
808 state->nAttempts++;
809
810 jb = 0;
811
812 vdRngUniform( METHOD, stream, N, &myran, 0.0, 1.0);
813
814 o = (int)(state->nAtoms * myran);
815 oTemp.pos[0] = state->r[o].pos[0];
816 oTemp.pos[1] = state->r[o].pos[1];
817 oTemp.pos[2] = state->r[o].pos[2];
818 oTemp.phi = state->r[o].phi;
819 oTemp.theta = state->r[o].theta;
820 oTemp.mu = state->r[o].mu;
821
822 eno = eneri(state, oTemp, o, jb);
823
824 vdRngUniform( METHOD, stream, N, &myran, 0.0, 1.0);
825
826 oTemp.pos[2] += (2.0*myran-1.0) * state->deltaz;
827
828 vdRngUniform( METHOD, stream, N, &myran, 0.0, 1.0);
829
830 oTemp.phi += (2.0*myran-1.0) * state->deltaphi;
831
832 vdRngUniform( METHOD, stream, N, &myran, 0.0, 1.0);
833
834 oTemp.theta += (2.0*myran-1.0) * state->dtheta;
835
836 enn = eneri(state, oTemp, o, jb);
837
838
839 vdRngUniform( METHOD, stream, N, &myran, 0.0, 1.0);
840
841 if(myran <= (exp(- state->beta * (enn-eno)))) {
842 state->nAccepts++;
843 *en += (enn-eno);
844 state->r[o].pos[2] = oTemp.pos[2];
845 state->r[o].phi = oTemp.phi;
846 state->r[o].theta = oTemp.theta;
847 }
848 }
849
850
851 void store(struct system* state, FILE* out_file) {
852
853 double uxi, uyi, uzi;
854 int i;
855
856 fprintf(out_file,"%d\n",state->nAtoms);
857
858 fprintf(out_file, "%d;\t%d\t%d;\t%f\t%f;\t%f\t%f;\n",
859 state->iCycle,
860 state->nx,
861 state->ny,
862 state->Hmat[0][0],
863 state->Hmat[1][0],
864 state->Hmat[0][1],
865 state->Hmat[1][1]);
866
867 for(i=0; i < state->nAtoms; i++) {
868 uxi = cos(state->r[i].phi)*sin(state->r[i].theta);
869 uyi = sin(state->r[i].phi)*sin(state->r[i].theta);
870 uzi = cos(state->r[i].theta);
871 fprintf(out_file, "%s\t%f\t%f\t%f\t%f\t%f\t%f\t%f\n",
872 "Ar",
873 state->r[i].pos[0],
874 state->r[i].pos[1],
875 state->r[i].pos[2],
876 state->r[i].phi,
877 uxi,
878 uyi,
879 uzi);
880 }
881
882 fflush(out_file);
883 }
884
885 double matDet2(double a[2][2]) {
886
887 double determinant;
888
889 determinant = (a[0][0] * a[1][1]) - (a[0][1] * a[1][0]);
890
891 return determinant;
892 }
893
894
895 void invertMat2(double a[2][2], double b[2][2]) {
896
897 double determinant;
898
899 determinant = matDet2( a );
900
901 if (determinant == 0.0) {
902 printf("Can't invert a matrix with a zero determinant!\n");
903 }
904
905 b[0][0] = a[1][1] / determinant;
906 b[0][1] = -a[0][1] / determinant;
907 b[1][0] = -a[1][0] / determinant;
908 b[1][1] = a[0][0] / determinant;
909 }
910
911 void matVecMul2(double m[2][2], double inVec[2], double outVec[2]) {
912 double a0, a1, a2;
913
914 a0 = inVec[0]; a1 = inVec[1];
915
916 outVec[0] = m[0][0]*a0 + m[0][1]*a1;
917 outVec[1] = m[1][0]*a0 + m[1][1]*a1;
918 }
919
920 void wrapVector( double thePos[2], double Hmat[2][2], double HmatInv[2][2]){
921
922 int i;
923 double scaled[2];
924
925 // calc the scaled coordinates.
926
927 matVecMul2(HmatInv, thePos, scaled);
928
929 for(i=0; i<2; i++)
930 scaled[i] -= roundMe(scaled[i]);
931
932 // calc the wrapped real coordinates from the wrapped scaled coordinates
933
934 matVecMul2(Hmat, scaled, thePos);
935
936 }
937
938 /***************************************************************************
939 * prints out the usage for the command line arguments, then exits.
940 ***************************************************************************/
941
942 void usage(){
943 (void)fprintf(stderr,
944 "The proper usage is: %s [options]\n"
945 "\n"
946 "Options:\n"
947 "\n"
948 " -x Display this message\n"
949 " -o <out_name> The output file (Defaults to <root>.dump)\n"
950 " -i <in_name> The input file (no default)\n"
951 " -r <root> The root (Defaults to dp)\n"
952 " -n nCycles The number of MC cycles to do\n"
953 " -s nSample The number of MC cycles between samples\n"
954 " -m nMoves The number of particle moves in each MC cycle\n"
955 " -a aLat Set the lattice spacing along x axis\n"
956 " -b bLat Set the lattice spacing along y axis\n"
957 " -c cells Set the number of cells along x direction\n"
958 " (Domains are kept nearly square)\n"
959 " -h hexSpace Set up a hexagonal lattice\n"
960 " aLat = sqrt(3) hexSpace\n"
961 " bLat = hexSpace\n"
962 " -k kz Sets the value of kz in units of kb\n"
963 "\n",
964
965 program_name);
966 exit(8);
967 }