10 #define PROTON_MASS 1836
11 #define NEUTRON_MASS 1839
12 #define ELECTRON_MASS 1
15 #define TPL_PROB_GRAN 100000
16 #define TPL_MASS_SHIFT 0
17 #define TPL_CHARGE_SHIFT 0
18 #define TPL_LOCATION_SHIFT (-16)
19 //#define NUM_INIT_PARTICLES 32
20 //#define NUM_INIT_PARTICLES 64
21 //#define NUM_INIT_PARTICLES 256
22 #define NUM_INIT_PARTICLES 1024
23 //#define NUM_INIT_PARTICLES 0x10000
26 extern void Visualiser_Initialise(void);
27 extern void Update_DoTimestep(void);
28 extern void Visualiser_Update(void);
31 void SaveUniverse(int signal);
34 const struct sPartTpl {
37 int Probability; // per `TPL_PROB_GRAN`
39 {PROTON_MASS, 1, TPL_PROB_GRAN/4}, // Proton-Like
40 {NEUTRON_MASS, 0, TPL_PROB_GRAN/4}, // Neutron-Like
41 {ELECTRON_MASS, -1, TPL_PROB_GRAN/2}, // Electron-Like
43 const int giNumTemplates = (sizeof(gaTemplates)/sizeof(gaTemplates[0]));
44 tParticle gaParticles[NUM_INIT_PARTICLES];
45 tParticle *gpParticles = gaParticles;
46 int giNumParticles = NUM_INIT_PARTICLES;
47 int giCurrentTimestamp = 0;
48 volatile int giUpdatePos;
52 int main(int argc, char *argv[])
58 signal(SIGINT, SaveUniverse);
60 printf("Mathematical Universe Simulator\n");
61 printf(" By John Hodge (thePowersGang)\n");
64 if( argc > 1 && (fp = fopen(argv[1], "rb")) )
67 len = fread(&tmp, 2, 1, fp);
68 if(tmp != sizeof(tLargeInt)) {
69 fprintf(stderr, "Unable to restore from '%s', largeint size does not match (%i != %i)\n",
70 argv[1], tmp, sizeof(tLargeInt));
73 len = fread(&tmp, 2, 1, fp);
74 if(tmp != sizeof(tVector)/sizeof(tLargeInt)) {
75 fprintf(stderr, "Unable to restore from '%s', vector order does not match (%i != %i)\n",
76 argv[1], tmp, sizeof(tVector)/sizeof(tLargeInt));
80 len = fread(&tmp, 4, 1, fp);
81 if( tmp > NUM_INIT_PARTICLES ) {
82 fprintf(stderr, "Unable to restore from '%s', there is not enough static space allocated (%i > %i)\n",
83 argv[1], tmp, NUM_INIT_PARTICLES);
87 printf("giNumParticles = %i\n", tmp);
90 tmp = giNumParticles*(sizeof(tLargeInt)*2+sizeof(tVector));
91 fseek(fp, 0, SEEK_END);
92 if( (ftell(fp) - 8) % tmp ) {
94 "Warning: File has trailing bytes (0x%x), may have been an unclean close (Len 0x%x)\n",
95 (ftell(fp) - 8) % tmp, ftell(fp)
99 giCurrentTimestamp = (ftell(fp) - 8) / tmp;
100 printf("giCurrentTimestamp = %i\n", giCurrentTimestamp);
101 fseek(fp, 8 + (giCurrentTimestamp-1) * tmp, SEEK_SET);
102 for( i = 0; i < giNumParticles; i++ )
104 len = fread(&gaParticles[i].Location, sizeof(tVector), 1, fp);
105 len = fread(&gaParticles[i].Mass, sizeof(tLargeInt), 1, fp);
106 len = fread(&gaParticles[i].Charge, sizeof(tLargeInt), 1, fp);
111 printf("Restored from '%s' (%i particles)\n", argv[1], giNumParticles);
112 printf("WARNING: Restoring a universe state can lead to errors\n");
118 int aCounts[giNumTemplates];
119 for( j = 0; j < giNumTemplates; j++ ) aCounts[j] = 0;
121 printf("Initialising with %i atomic particles\n", giNumParticles);
122 printf(" Basing off %i templates\n", giNumTemplates);
126 seed = atoi(argv[1]);
127 printf(" Seeding random number generator with %i\n", seed);
131 printf("Generating particles...\n");
132 for( i = 0; i < giNumParticles; i ++ )
134 val = rand() % TPL_PROB_GRAN;
135 for( j = 0; j < giNumTemplates; j++ )
137 if( val < gaTemplates[j].Probability ) break;
138 val -= gaTemplates[j].Probability;
140 if( j == giNumTemplates ) {
141 fprintf(stderr, "ERROR: Templates do not add up to %i\n", TPL_PROB_GRAN);
145 #if TPL_LOCATION_SHIFT < 0
146 if( i == 0 ) printf("Setting coords for #0\n");
147 LargeInt_SetNative(&gaParticles[i].Location.C[0], rand()>>(-TPL_LOCATION_SHIFT), 0);
148 LargeInt_SetNative(&gaParticles[i].Location.C[1], rand()>>(-TPL_LOCATION_SHIFT), 0);
149 //LargeInt_SetNative(&gaParticles[i].Location.C[2], rand()>>(-TPL_LOCATION_SHIFT), 0);
151 LargeInt_SetNative(&gaParticles[i].Location.C[0], rand(), TPL_LOCATION_SHIFT);
152 LargeInt_SetNative(&gaParticles[i].Location.C[1], rand(), TPL_LOCATION_SHIFT);
153 LargeInt_SetNative(&gaParticles[i].Location.C[2], rand(), TPL_LOCATION_SHIFT);
156 LargeInt_SetNative(&gaParticles[i].Mass, gaTemplates[j].Mass, TPL_MASS_SHIFT);
157 LargeInt_SetNative(&gaParticles[i].Charge, gaTemplates[j].Charge, TPL_CHARGE_SHIFT);
158 printf("%2i%%\r", i*100/giNumParticles);
162 printf("Final counts of particles:\n");
163 for( j = 0; j < giNumTemplates; j++ )
165 printf("%i: %i\n", j, aCounts[j]);
169 printf("Starting simulation.\n");
171 Visualiser_Initialise();
175 gLogFile = fopen("universe.blg", "ab");
176 if( giCurrentTimestamp ) {
177 // fseek(gLogFile, giCurrentTimestamp*giNumParticles*(sizeof(tLargeInt)*2+sizeof(tVector)), SEEK_SET);
180 tmp = sizeof(tLargeInt); fwrite(&tmp, 2, 1, gLogFile);
181 tmp = sizeof(tVector)/sizeof(tLargeInt); fwrite(&tmp, 2, 1, gLogFile);
182 tmp = giNumParticles; fwrite(&tmp, 4, 1, gLogFile);
185 giUpdatePos = giNumParticles;
186 for(;;giCurrentTimestamp++)
188 printf("Iteration %i\n", giCurrentTimestamp);
191 for(i=0,giUpdatePos=0;i<giNumParticles;i++,giUpdatePos++)
193 fwrite(&gaParticles[i].Location, sizeof(tVector), 1, gLogFile);
194 fwrite(&gaParticles[i].Mass, sizeof(tLargeInt), 1, gLogFile);
195 fwrite(&gaParticles[i].Charge, sizeof(tLargeInt), 1, gLogFile);
202 void SaveUniverse(int signal)
204 // Detect an interrupt during update
205 if(giUpdatePos < giNumParticles) return;