SoundSim
main.c
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdbool.h>
4 #include <string.h>
5 #include "main.h"
6 #include "soundwavefunction.h"
7 #include "collision.h"
8 #include "extras.h"
9 #include <time.h>
10 #include <sys/types.h>
11 #include <signal.h>
12 #include <mpi.h>
13 #include <stddef.h>
15 int visuStep = 1;
20 int j, k, l, i;
23 int myrank;
24 int size;
25 const int nitems = 18;
26 int rows = 5;
28 int realcountleft = 0;
29 int cols = 18;
36 
42 {
43  if (room == NULL) {
44  allElements = malloc(x_format * y_format * z_format * sizeof(item_node));
45  room = malloc(x_format * sizeof(item_node **));
46  if (room == NULL) {
47  return NULL;
48  }
49  for (int i = 0; i < x_format; i++)
50  {
51  room[i] = malloc(y_format * sizeof(item_node *));
52  if (room[i] == NULL) {
53  return NULL;
54  }
55  for (int j = 0; j < y_format; j++)
56  {
57  room[i][j] = allElements + (i * y_format * z_format) + (j * z_format);
58  if (room[i][j] == NULL) {
59  return NULL;
60  }
61  }
62  }
63  for (j = 0; j < x_format; j++) {
64  for (k = 0; k < y_format; k++) {
65  for (l = 0; l < z_format; l++) {
66  room[j][k][l].id = 3;
67  room[j][k][l].next = NULL;
68  }
69  }
70  }
71  }
72  return room;
73 }
77 void allocRoom() {
78  if (room == NULL) {
79  allElements = malloc(x_format * y_format * z_format * sizeof(item_node));
80  room = malloc(x_format * sizeof(item_node **));
81  if (room == NULL) {
82  printf("No Mem Bro!");
83  }
84  for (int i = 0; i < x_format; i++)
85  {
86  room[i] = malloc(y_format * sizeof(item_node *));
87  if (room[i] == NULL) {
88  printf("No Mem Bro!");
89  }
90  for (int j = 0; j < y_format; j++)
91  {
92  room[i][j] = allElements + (i * y_format * z_format) + (j * z_format);
93  if (room[i][j] == NULL) {
94  printf("No Mem Bro!");
95  }
96  }
97  }
98 
99  }
100 }
106 {
107  room_new = NULL;
108  if (room_new == NULL) {
109  allElementsNew = malloc(x_format * y_format * z_format * sizeof(item_node));
110  room_new = malloc(x_format * sizeof(item_node **));
111  if (room_new == NULL) {
112  //return NULL;
113  }
114  for (int i = 0; i < x_format; i++)
115  {
116  room_new[i] = malloc(y_format * sizeof(item_node *));
117  if (room_new[i] == NULL) {
118  //return NULL;
119  }
120  for (int j = 0; j < y_format; j++)
121  {
122  room_new[i][j] = allElementsNew + (i * y_format * z_format) + (j * z_format);
123  if (room_new[i][j] == NULL) {
124  //return NULL;
125  }
126  }
127  }
128  }
129  //schöner machen!
130  for (j = 0; j < x_format; j++) {
131  for (k = 0; k < y_format; k++) {
132  for (l = 0; l < z_format; l++) {
133  //printf("x: %d, y: %d, z: %d, id: %d\n",j,k,l,getFieldID(j,k,l));
134 
135  if ((room[j][k][l].next) != NULL) {
136  if ((room[j][k][l].next->id) == 1) {
137  room_new[j][k][l] = room[j][k][l];
138  //printf("WAND:! x: %d, y: %d, z: %d, id: %d\n",j,k,l,getFieldID(j,k,l));
139  } else {
140  room_new[j][k][l].id = 3;
141  room_new[j][k][l].next = NULL;
142  //return NULL;
143  }
144  }
145  else {
146  //printf("keine wand:! x: %d, y: %d, z: %d, id: %d\n",j,k,l,getFieldID(j,k,l));
147 
148  room_new[j][k][l].id = 3;
149  room_new[j][k][l].next = NULL;
150  //return NULL;
151 
152  }
153  }
154  }
155  }
156  return room_new;
157 }
162 void changeRoom(item_node *** newRoom)
163 {
164  if (room != NULL) {
165  free(allElements);
166  for (int i = 0; i < x_format; i++)
167  {
168  free(room[i]);
169  }
170  free (room);
171  room = NULL;
172  }
173  //free(room);
174  //free(allElements);
175  room = newRoom;
176  allElements = allElementsNew;
177  //memmove(room,room_new, 200 * sizeof(item_node **));
178  //memmove(allElements,allElementsNew, 200 * 200 * 200 * sizeof(item_node));
179 }
185 int getItemID(item_node * node ) {
186  if (node != NULL)
187  {
188  return node->id;
189  } else return 2;
190 }
196 void setItemID(item_node * node, int id)
197 {
198  node->id = id;
199 }
207 int getFieldID(int x, int y, int z)
208 {
209  int returnvalue = 2;
210  if (x < x_format && y < y_format && z < z_format && x >= 0 && y >= 0 && z >= 0)
211  {
212  if (room[x][y][z].next != NULL) {
213  //0 oder 1
214  returnvalue = room[x][y][z].next->id;
215  }
216  else returnvalue = 3;
217  //ohne jeglicher Belegung
218  }
219  return returnvalue;
220 }
221 //den Raum zurückgeben
227  return *** room;
228 }
236 bool isObstacle(int x, int y, int z)
237 {
238  bool returnvalue = false;
239  if (room[x][y][z].next != NULL) {
240  if (room[x][y][z].next->id == 1)
241  {
242  //dann Hinderniss
243  returnvalue = true;
244  }
245  }
246  return returnvalue;
247 
248 }
250 void setFreq20b40(item_node * node, int value)
251 {
252  if (getItemID(node) == 0) {
253  node->data.Sound.freq_20_40 = value;
254  }
255 }
256 void setFreq40b100(item_node * node, int value)
257 {
258  if (getItemID(node) == 0) {
259  node->data.Sound.freq_40_100 = value;
260  }
261 }
262 void setFreq100b150(item_node * node, int value)
263 {
264  if (getItemID(node) == 0) {
265  node->data.Sound.freq_100_150 = value;
266  }
267 }
268 void setFreq150b400(item_node * node, int value)
269 {
270  if (getItemID(node) == 0) {
271  node->data.Sound.freq_150_400 = value;
272  }
273 }
274 void setFreq400b1000(item_node * node, int value)
275 {
276  if (getItemID(node) == 0) {
277  node->data.Sound.freq_400_1000 = value;
278  }
279 }
280 void setFreq1000b2000(item_node * node, int value)
281 {
282  if (getItemID(node) == 0) {
283  node->data.Sound.freq_1000_2000 = value;
284  }
285 }
286 void setFreq2000b3500(item_node * node, int value)
287 {
288  if (getItemID(node) == 0) {
289  node->data.Sound.freq_2000_3500 = value;
290  }
291 }
292 void setFreq3500b6000(item_node * node, int value)
293 {
294  if (getItemID(node) == 0) {
295  node->data.Sound.freq_3500_6000 = value;
296  }
297 }
298 void setFreq6000b10000(item_node * node, int value)
299 {
300  if (getItemID(node) == 0) {
301  node->data.Sound.freq_6000_10000 = value;
302  }
303 }
304 void setFreq10000b20000(item_node * node, int value)
305 {
306  if (getItemID(node) == 0) {
307  node->data.Sound.freq_10000_20000 = value;
308  }
309 }
311 
313 {
314  if (getItemID(node) == 0) {
315  return node->data.Sound.freq_20_40;
316  } else {
317  return 99999;
318  }
319 }
321 {
322  if (getItemID(node) == 0) {
323  return node->data.Sound.freq_40_100;
324  } else {
325  return 99999;
326  }
327 }
329 {
330  if (getItemID(node) == 0) {
331  return node->data.Sound.freq_100_150;
332  } else {
333  return 99999;
334  }
335 }
337 {
338  if (getItemID(node) == 0) {
339  return node->data.Sound.freq_150_400;
340  } else {
341  return 99999;
342  }
343 }
345 {
346  if (getItemID(node) == 0) {
347  return node->data.Sound.freq_400_1000;
348  } else {
349  return 99999;
350  }
351 }
353 {
354  if (getItemID(node) == 0) {
355  return node->data.Sound.freq_1000_2000;
356  } else {
357  return 99999;
358  }
359 }
361 {
362  if (getItemID(node) == 0) {
363  return node->data.Sound.freq_2000_3500;
364  } else {
365  return 99999;
366  }
367 }
369 {
370  if (getItemID(node) == 0) {
371  return node->data.Sound.freq_3500_6000;
372  } else {
373  return 99999;
374  }
375 }
377 {
378  if (getItemID(node) == 0) {
379  return node->data.Sound.freq_6000_10000;
380  } else {
381  return 99999;
382  }
383 }
385 {
386  if (getItemID(node) == 0) {
387  return node->data.Sound.freq_10000_20000;
388  } else {
389  return 99999;
390  }
391 }
392 
394 
399 void setDirectionID(item_node * node, int value)
400 {
401  if (getItemID(node) == 0) {
402  node->data.Sound.direction_id = value;
403  }
404 }
411 {
412  if (getItemID(node) == 0) {
413  return node->data.Sound.direction_id;
414  } else return -1;
415 }
421 int getReboundID(int currentDirectionID)
422 {
423  switch (currentDirectionID)
424  {
425  case 1: return 5; break;
426  case 2: return 4; break;
427  case 3: return 7; break;
428  case 4: return 2; break;
429  case 5: return 1; break;
430  case 6: return 8; break;
431  case 7: return 3; break;
432  case 8: return 6; break;
433  default: return 0; break;
434  }
435 
436 }
438 {
439  //Absicherung fehlt
440  return *node;
441 }
443 {
444  //Absicherung fehlt
445  return *node;
446 }
454 item_node *getItem_Root(int x, int y, int z)
455 {
456  if (x < x_format && y < y_format && z < z_format && x >= 0 && y >= 0 && z >= 0)
457  {
458  return &room[x][y][z];
459  } else {
460  item_node* newNode = malloc(sizeof(item_node));
461  newNode->id = 2;
462  newNode->next = NULL;
463  return newNode;
464  //Element erstellen mit id 2 -> ungültig und wird dann entfernt
465  }
466 }
467 //Create Item
476 item_node* createItem (int x, int y, int z, int id)
477 {
478  item_node* selected = getItem_Root(x, y, z);
479  //printf("Passt?: %d\n", getItemID(selected) );
480  //prüfen ob Element überhaupt Gültig ist!
481  if (getItemID(selected) != 2)
482  {
483  while (selected->next != NULL)
484  selected = selected->next;
485  selected->next = malloc(sizeof(item_node));
486  selected->next->prev = selected;
487  selected = selected->next;
488  selected->id = id;
489  selected->next = NULL;
490  if (selected->id == 0) {
491  setMovement(selected, 0);
492  }
493  }
494  return selected;
495 }
500 void removeItem(item_node * node) {
501  if (node->next == NULL) {
502  //letztes item: vorletztes next->NULL
503  if (node->prev == NULL) {
504  //bedeutet: er versucht den head zu löschen, dieser hat kein prev pfeil und darum geht das hier kaputt!
505  //hier ist aber nicht das problem, sondern hier taucht das problem nur in erscheinung
506  //irgendwo wird also der head als id = sound beschrieben, sodass z,b in collision dieser aufruf überhaupt erfolgen kann.
507  }
508  node->prev->next = NULL;
509  }
510  else {
511  node->prev->next = node->next;
512  node->next->prev = node->prev;
513  }
514 }
523 item_node* addItem (item_node * node, int x, int y, int z)
524 {
525  item_node* selected = getItem_Root(x, y, z);
526  if (getItemID(selected) != 2)
527  {
528  removeItem(node);
529  while (selected->next != NULL)
530  selected = selected->next;
531  selected->next = node;
532  selected->next->prev = selected;
533  selected = selected->next;
534  selected->next = NULL;
535  }
536  return selected;
537 }
545 item_node *getItem_RootNewRoom(int x, int y, int z)
546 {
547  if (x < x_format && y < y_format && z < z_format && x >= 0 && y >= 0 && z >= 0)
548  {
549  return &room_new[x][y][z];
550  } else {
551  item_node* newNode = malloc(sizeof(item_node));
552  newNode->id = 2;
553  newNode->next = NULL;
554  return newNode;
555  //Element erstellen mit id 2 -> ungültig und wird dann entfernt
556  }
557 }
565 void addItemNewRoom (item_node * node, int x, int y, int z)
566 {
567  item_node* selected = getItem_RootNewRoom(x, y, z);
568  if (getItemID(selected) != 2)
569  {
570  removeItem(node);
571  while (selected->next != NULL)
572  selected = selected->next;
573  selected->next = node;
574  selected->next->prev = selected;
575  selected = selected->next;
576  selected->next = NULL;
577  }
578 }
586 int isSoundField(int x, int y, int z)
587 {
588  int returnvalue = 0;
589  if (x < x_format && y < y_format && z < z_format && x >= 0 && y >= 0 && z >= 0)
590  {
591  if (room[x][y][z].next != NULL) {
592  //0 oder 1
593  if (room[x][y][z].next->id == 0)
594  {
595  returnvalue = 1;
596  }
597  }
598  else returnvalue = 1;
599  //ohne jeglicher Belegung
600  }
601  return returnvalue;
602 }
603 
604 void createReceipt(int (*roomtrans)[cols], int var, int x) {
605  if (isSoundField(x, roomtrans[var][16], roomtrans[var][17]) == 1) {
606 
607  item_node *poo = createItem(x, roomtrans[var][16], roomtrans[var][17], 0);
608  setFreq20b40(poo, roomtrans[var][1]);
609  setFreq40b100(poo, roomtrans[var][2]);
610  setFreq100b150(poo, roomtrans[var][3]);
611  setFreq150b400(poo, roomtrans[var][4]);
612  setFreq400b1000(poo, roomtrans[var][5]);
613  setFreq1000b2000(poo, roomtrans[var][6]);
614  setFreq2000b3500(poo, roomtrans[var][7]);
615  setFreq3500b6000(poo, roomtrans[var][8]);
616  setFreq6000b10000(poo, roomtrans[var][9]);
617  setFreq10000b20000(poo, roomtrans[var][10]);
618  setTouche(poo);
619  setDirectionID(poo, roomtrans[var][12]);
620  setMovement(poo, roomtrans[var][13]);
621  setSideOfWave(poo, roomtrans[var][14]);
622  }
623  else {
624  item_node *puh = createItem(x, roomtrans[var][16], roomtrans[var][17], 0);
625  setFreq20b40(puh, roomtrans[var][1]);
626  setFreq40b100(puh, roomtrans[var][2]);
627  setFreq100b150(puh, roomtrans[var][3]);
628  setFreq150b400(puh, roomtrans[var][4]);
629  setFreq400b1000(puh, roomtrans[var][5]);
630  setFreq1000b2000(puh, roomtrans[var][6]);
631  setFreq2000b3500(puh, roomtrans[var][7]);
632  setFreq3500b6000(puh, roomtrans[var][8]);
633  setFreq6000b10000(puh, roomtrans[var][9]);
634  setFreq10000b20000(puh, roomtrans[var][10]);
635  setTouche(puh);
636  setDirectionID(puh, getReboundID(roomtrans[var][12]));
637  setMovement(puh, roomtrans[var][13]);
638  setSideOfWave(puh, roomtrans[var][14]);
639  absorption(puh, 0.76);
640  }
641 }
642 int* prepareArrays(item_node *node, int side) {
643  int *sarray = malloc(cols * sizeof(int));
644  if (side == 1) {
645 
646  sarray[0] = getItemID(node);
647  sarray[1] = getFreq20b40(node);
648  sarray[2] = getFreq40b100(node);
649  sarray[3] = getFreq100b150(node);
650  sarray[4] = getFreq150b400(node);
651  sarray[5] = getFreq400b1000(node);
652  sarray[6] = getFreq1000b2000(node);
653  sarray[7] = getFreq2000b3500(node);
654  sarray[8] = getFreq3500b6000(node);
655  sarray[9] = getFreq6000b10000(node);
656  sarray[10] = getFreq10000b20000(node);
657  sarray[11] = getTouch(node);
658  sarray[12] = getDirectionID(node);
659  sarray[13] = getMovement(node);
660  sarray[14] = getSideOfWave(node);
661  sarray[15] = j;
662  sarray[16] = k;
663  sarray[17] = l;
664  }
665  else if (side == 2) {
666 
667  sarray[0] = getItemID(node);
668  sarray[1] = getFreq20b40(node);
669  sarray[2] = getFreq40b100(node);
670  sarray[3] = getFreq100b150(node);
671  sarray[4] = getFreq150b400(node);
672  sarray[5] = getFreq400b1000(node);
673  sarray[6] = getFreq1000b2000(node);
674  sarray[7] = getFreq2000b3500(node);
675  sarray[8] = getFreq3500b6000(node);
676  sarray[9] = getFreq6000b10000(node);
677  sarray[10] = getFreq10000b20000(node);
678  sarray[11] = getTouch(node);
679  sarray[12] = getDirectionID(node);
680  sarray[13] = getMovement(node);
681  sarray[14] = getSideOfWave(node);
682  sarray[15] = j;
683  sarray[16] = k;
684  sarray[17] = l;
685  }
686  return sarray;
687 }
691 void saveVisualisation(int x_offset)
692 {
695  if (myrank > 1)
696  {
697  int rows = 5;
698  int cols = 4;
699  int realcount = 0;
700  int (*sendarray)[cols] = malloc(sizeof * sendarray * rows);
701  for (int j = 0; j < x_format; ++j)
702  {
703  for (int k = 0; k < y_format; ++k)
704  {
705  for (int l = 0; l < z_format; ++l)
706  {
707  if (realcount == rows) {
708  int newnum = (rows + 2) * 2;
709  int (*newptr)[cols] = realloc(sendarray, sizeof * newptr * newnum);
710  rows = newnum;
711  sendarray = newptr;
712  }
713 
714  if (isObstacle(j, k, l)) {
715  //Hinderniss mit Value 0 markieren
716  sendarray[realcount][0] = j + x_offset;
717  sendarray[realcount][1] = k;
718  sendarray[realcount][2] = l;
719  sendarray[realcount][3] = 0;
720  ++realcount;
721  } else {
722  item_node *temp;
723  temp = getItem_Root(j, k, l);
724  int max = 0;
725  int count = 0;
726  while (temp != NULL)
727  {
728  int itemID = getItemID(temp);
729  if (itemID == 0)
730  {
731  if (getFreq150b400(temp) > max) {
732  max = getFreq150b400(temp);
733  }
734  }
735  temp = temp->next;
736  }
737  if (max > 0) {
738  sendarray[realcount][0] = j + x_offset;
739  sendarray[realcount][1] = k;
740  sendarray[realcount][2] = l;
741  sendarray[realcount][3] = max;
742  ++realcount;
743  }
744  }
745  }
746  }
747  }
748  MPI_Request req;
749  MPI_Isend(sendarray, realcount * cols, MPI_INT, 1, 1, MPI_COMM_WORLD, &req);
750  MPI_Wait(&req, MPI_STATUS_IGNORE);
751  //freen
752  free(sendarray);
753  }
754 }
755 int main (int argc, char *argv[])
756 {
757  double start_t, end_t, total_t;
758  MPI_Request *request;
759  MPI_Request *request_ready;
760  MPI_Status status;
761  MPI_Init(&argc, &argv); // bytes in 1 blocks are definitely lost in loss record 1,382 of 3,539
762  MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
763  MPI_Comm_size(MPI_COMM_WORLD, &size);
764  int NSimulations = size - 2;
765  if (myrank == 0) {
767  x_format = 200;
768  y_format = 200;
769  z_format = 200;
770  int setting_runs = 100;
771  start_t = MPI_Wtime(); //Startzeit
772  printf("%s\n", "-----STARTING THE ENGINE-----" );
773  printf("X:%d & Y:%d & Z:%d\n", x_format, y_format, z_format);
774  //-V & -Visu
775  //für jeden Slave Process wird festgehalten wie viele Zahlen er am Ende zugewiesen bekommt
776  int * paraarray = malloc(NSimulations * sizeof(int));
777  //array nullen
778  for (int j = 0; j < NSimulations; j++) {
779  paraarray[j] = 0;
780  }
781  //um die Zahlen gleichmäßig zu verteilen werden alle Summanden durchlaufen und nacheinander auf die Prozesse 2 bis size-1 aufgeteilt
782  int new_process_rank = 0;
783  for (int i = 0; i < x_format; i++)
784  {
785  paraarray[new_process_rank] = paraarray[new_process_rank] + 1;
786  //wenn alle Ranks durchlaufen wurden wird wieder auf den 0. gesprungen
787  if (new_process_rank + 1 >= NSimulations) {
788  new_process_rank = 0;
789  } else
790  {
791  ++new_process_rank;
792  }
793  }
794  //Wird gleichmäßig verteilt! :)
795  for (int var = 2; var < NSimulations + 2; ++var) {
796  printf("Rank: %d, Values: %d\n", var, paraarray[var - 2]);
797  }
798  //Offset berechnen
799  //Info Array berechnen
800  int * SimSetting = malloc(5 * sizeof(int));
801  request = malloc(sizeof(MPI_Request) * NSimulations);
802  for (int t = 0; t < NSimulations; ++t) {
803  //berechneter X Wert, Y_Format, Z_Format, berechneter Offset neben X
804  int offset = 0;
805  for (int j = 0; j < t; ++j) {
806  offset = offset + paraarray[j];
807  }
808  SimSetting[0] = paraarray[t];
809  SimSetting[1] = y_format;
810  SimSetting[2] = z_format;
811  SimSetting[3] = offset;
812  SimSetting[4] = setting_runs;
813  //1. Senden der Array Größe, da diese dem Empfänger bekannt sein muss
814  //t+2 weil wir ja einen offset von 2 reservierten T haben
815  MPI_Isend(SimSetting, 5, MPI_INT, t + 2, t + 2, MPI_COMM_WORLD, &request[t]);
816  //MPI_Send(&paraarray[p], 1, MPI_INT, p, tag, MPI_COMM_WORLD);
817  printf("Offset: %d\n", offset);
818  }
819  MPI_Waitall(NSimulations, request, MPI_STATUSES_IGNORE);
820  printf("Tasks wurden verteilt!\n");
822  int go = 1;
823  for (int i = 1; i <= setting_runs; ++i)
824  {
825  MPI_Request visuGo;
826  MPI_Isend(&NSimulations, 1, MPI_INT, 1, 1, MPI_COMM_WORLD, &visuGo);
827  //wir erwarten keine Antwort
828  MPI_Request_free(&visuGo);
829  for (int t = 0; t < NSimulations; ++t) {
830  MPI_Isend(&go, 1, MPI_INT, t + 2, t + 2, MPI_COMM_WORLD, &request[t]);
831  }
832  //Synchronisieren
833  MPI_Waitall(NSimulations, request, MPI_STATUSES_IGNORE);
834  int sum_tasks = 0;
835  for (int t = 0; t < NSimulations; ++t) {
836  int add = 0;
837  MPI_Recv(&add, 1, MPI_INT, t + 2, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
838  sum_tasks = sum_tasks + add;
839  }
840  }
841  //Iterationen beenden
842  go = 0;
843  MPI_Request visuGo;
844  MPI_Isend(&go, 1, MPI_INT, 1, 1, MPI_COMM_WORLD, &visuGo);
845  //wir erwarten keine Antwort
846  MPI_Request_free(&visuGo);
847  for (int t = 0; t < NSimulations; ++t) {
848  MPI_Isend(&go, 1, MPI_INT, t + 2, t + 2, MPI_COMM_WORLD, &request[t]);
849  }
850  //bruchen wir vlt nicht mehr
851  MPI_Waitall(NSimulations, request, MPI_STATUSES_IGNORE);
852  } else if (myrank == 1) {
853  //alten output.json löschen
854  remove("output");
855  //Visualisation starten
856  FILE *fp;
857  fp = fopen("output", "a");
858  fprintf(fp, "{" );
859  //go bekommt die anzahl der tasks die ihn aufrufen
860  int go = 0;
861  int run = 1;
862  MPI_Recv(&go, 1, MPI_INT, 0, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
863  while (go != 0) {
864  fprintf(fp, "\"soundarray%d\": [", run );
865  //besser mit MPI Probe?
866  for (i = 2; i < go + 2; ++i) {
867  int amount = 0;
868  MPI_Status status;
869  MPI_Probe(i, 1, MPI_COMM_WORLD, &status);
870  MPI_Get_count(&status, MPI_INT, &amount);
871  int cols = 4;
872  int (*recv_buf)[cols] = malloc(sizeof * recv_buf * amount / 4);
873  MPI_Recv(recv_buf, amount, MPI_INT, i, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
874  for (int var = 0; var < amount / 4; ++var) {
875  fprintf(fp, "{ \"x\": %d, \"y\": %d, \"z\": %d, \"value\": %d },", recv_buf[var][0], recv_buf[var][1], recv_buf[var][2], recv_buf[var][3]);
876  }
877  free(recv_buf);
878  }
879  fprintf(fp, "]," );
880  ++run;
881  MPI_Recv(&go, 1, MPI_INT, 0, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
882  }
883  fclose(fp);
884  } else if (myrank > 1) {
885  int * mySimSetting = malloc(5 * sizeof(int));
886  MPI_Recv(mySimSetting, 5, MPI_INT, 0, myrank, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
887  x_format = mySimSetting[0];
888  y_format = mySimSetting[1];
889  z_format = mySimSetting[2];
890  //Ticks von T0 bekommen
891  int x_offset = mySimSetting[3];
892  int runs = mySimSetting[4];
893  int go = 0;
894  int run = 1;
895  MPI_Recv(&go, 1, MPI_INT, 0, myrank, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
896  while (go) {
897  //solange durchgehen
898  createRoom();
899  //createItem(1, 1, 1, 1);
900  if (myrank == 2 && run == 1) {
901  loudspeaker();
902  //createItem(10,10,20,1);
903  //createWall();
904  }
905  if (myrank == (size - 2) / 2 && run == 1) {
906  door();
907  }
908  unToucheAll();
909  saveVisualisation(x_offset);
910  createRoomNew();
911  //printf("Durchgang: %d, Task: %d\n", run, myrank);
912  int sendrowsleft = 5;
913  int sendrowsright = 5;
914  int (*sendarrayleft)[cols] = malloc(sizeof * sendarrayleft * sendrowsleft);
915  int (*sendarrayright)[cols] = malloc(sizeof * sendarrayright * sendrowsright);
916 
917  if (myrank != 2 && myrank != size - 1 && run > 1) {
918  // von links empfangen
919  int amountleft = 0;
920  int sourceleft = myrank - 1;
921  MPI_Status status;
922  MPI_Probe(sourceleft, 14, MPI_COMM_WORLD, &status);
923  MPI_Get_count(&status, MPI_INT, &amountleft);
924  int (*recv_bufl)[cols] = malloc(sizeof * recv_bufl * amountleft / cols);
925  MPI_Recv(recv_bufl, amountleft, MPI_INT, sourceleft, 14, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
926  for (int var = 0; var < amountleft / cols; ++var) {
927  createReceipt(recv_bufl, var, 0);
928  }
929  free(recv_bufl);
930  // von rechts empfangen
931  int amountright = 0;
932  int sourceright = myrank + 1;
933  MPI_Probe(sourceright, 14, MPI_COMM_WORLD, &status);
934  MPI_Get_count(&status, MPI_INT, &amountright);
935  int (*recv_bufr)[cols] = malloc(sizeof * recv_bufr * amountright / cols);
936  MPI_Recv(recv_bufr, amountright, MPI_INT, sourceright, 14, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
937  for (int var = 0; var < amountright / cols; ++var) {
938  createReceipt(recv_bufr, var, x_format-1);
939  }
940  free(recv_bufr);
941  }
942  else if (myrank == 2 && run > 1) {
943  // darf nur von rechts Empfangen
944  int amount = 0;
945  int source = myrank + 1;
946  MPI_Status status;
947  MPI_Probe(source, 14, MPI_COMM_WORLD, &status);
948  MPI_Get_count(&status, MPI_INT, &amount);
949  int (*recv_buf)[cols] = malloc(sizeof * recv_buf * amount / cols);
950  MPI_Recv(recv_buf, amount, MPI_INT, source, 14, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
951  for (int var = 0; var < amount / cols; ++var) {
952  createReceipt(recv_buf, var, x_format-1);
953  }
954  free(recv_buf);
955 
956  } else if (myrank == size - 2 && run > 1) {
957  // darf nur von links empfangen
958  int amount = 0;
959  int source = myrank - 1;
960  MPI_Status status;
961  MPI_Probe(source, 14, MPI_COMM_WORLD, &status);
962  MPI_Get_count(&status, MPI_INT, &amount);
963  int (*recv_buf)[cols] = malloc(sizeof * recv_buf * amount / cols);
964  MPI_Recv(recv_buf, amount, MPI_INT, source, 14, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
965  for (int var = 0; var < amount / cols; ++var) {
966  createReceipt(recv_buf, var, 0);
967  }
968  free(recv_buf);
969  }
970 
971  for (j = 0; j < x_format; ++j)
972  {
973  for (k = 0; k < y_format; ++k)
974  {
975  for (l = 0; l < z_format; ++l) {
976 
977  if (isObstacle(j, k, l) == false)
978  {
979  //kein Hinderniss -> fortfahren
980  item_node *temp;
981  temp = getItem_Root(j, k, l);
982  while (temp != NULL) {
983  //Richtung prüfen
984  increaseMovement(temp);
985  checkSoundValid(temp, j, k, l);
986  if (checkSoundValid(temp, j, k, l) == true && getTouch(temp) == false) { // Damit er keine 0dB Elemente zu Wellen macht
987  addWave(temp, j, k , l);
988  } // Sprung in die Waveunktion
989  int direction_id = getDirectionID(temp);
990  //TODO: Besser nur bei Sound Objekten
991  if (direction_id == 1) {
992  int next_itemID = getFieldID(j, k + 1, l);
993  if (next_itemID == 0 || next_itemID == 3) {
994  //ist Sound Feld
995  addItemNewRoom(temp, j, k + 1, l);
996  } else if (next_itemID == 1) {
997  //TODO Wenn Kollsion mit itemID 2
998  absorption(temp, 0.78);
999  //1. Sound an die Folgestelle schieben
1000  //2. Attribut der Richtung anpassen
1001  temp->data.Sound.direction_id = getReboundID(direction_id);
1003  addItemNewRoom(temp, j, k, l);
1004  } else if (next_itemID == 2)
1005  {
1006  removeItem(temp);
1007  }
1008  }
1009  else if (direction_id == 2) {
1010  int next_itemID = getFieldID(j + 1, k + 1 , l);
1011  if (next_itemID == 0 || next_itemID == 3) {
1012  addItemNewRoom(temp, j + 1, k + 1, l);
1013  }
1014  else if (next_itemID == 1) {
1015  absorption(temp, 0.78);
1016  temp->data.Sound.direction_id = getReboundID(direction_id);
1018  addItemNewRoom(temp, j, k, l);
1019  } else if (next_itemID == 2 && j == x_format - 1 && myrank != size - 1) {
1020  if (realcountright == sendrowsright) {
1021  int newnum = (sendrowsright + 2) * 2;
1022  int (*newptr)[cols] = realloc(sendarrayright, sizeof * newptr * newnum);
1023  sendrowsright = newnum;
1024  sendarrayright = newptr;
1025  }
1026  int *sendarrayright_new = prepareArrays(temp, 2);
1027  for (int var = 0; var < cols; ++var) {
1028  sendarrayright[realcountright][var] = sendarrayright_new[var];
1029  }
1030  free(sendarrayright_new);
1031  ++realcountright;
1032  removeItem(temp);
1033  }
1034  else {
1035  removeItem(temp);
1036  }
1037  }
1038  else if (direction_id == 3) {
1039  int next_itemID = getFieldID(j + 1, k, l);
1040  if (next_itemID == 0 || next_itemID == 3) {
1041  addItemNewRoom(temp, j + 1, k, l);
1042  }
1043  else if (next_itemID == 1) {
1044  absorption(temp, 0.78);
1045  temp->data.Sound.direction_id = getReboundID(direction_id);
1047  addItemNewRoom(temp, j, k, l);
1048  } else if (next_itemID == 2 && j == x_format - 1 && myrank != size - 1) {
1049  if (realcountright == sendrowsright) {
1050  int newnum = (sendrowsright + 2) * 2;
1051  int (*newptr)[cols] = realloc(sendarrayright, sizeof * newptr * newnum);
1052  sendrowsright = newnum;
1053  sendarrayright = newptr;
1054  }
1055  int *sendarrayright_new = prepareArrays(temp, 2);
1056  for (int var = 0; var < cols; ++var) {
1057  sendarrayright[realcountright][var] = sendarrayright_new[var];
1058  }
1059  free(sendarrayright_new);
1060  ++realcountright;
1061  removeItem(temp);
1062  }
1063  else {
1064  removeItem(temp);
1065  }
1066  }
1067  else if (direction_id == 4) {
1068  int next_itemID = getFieldID(j + 1, k - 1 , l);
1069  if (next_itemID == 0 || next_itemID == 3) {
1070  addItemNewRoom(temp, j + 1, k - 1, l);
1071  }
1072  else if (next_itemID == 1) {
1073  absorption(temp, 0.78);
1074  temp->data.Sound.direction_id = getReboundID(direction_id);
1076  addItemNewRoom(temp, j, k, l);
1077  } else if (next_itemID == 2 && j == x_format - 1 && myrank != size - 1) {
1078  if (realcountright == sendrowsright) {
1079  int newnum = (sendrowsright + 2) * 2;
1080  int (*newptr)[cols] = realloc(sendarrayright, sizeof * newptr * newnum);
1081  sendrowsright = newnum;
1082  sendarrayright = newptr;
1083  }
1084  int *sendarrayright_new = prepareArrays(temp, 2);
1085  for (int var = 0; var < cols; ++var) {
1086  sendarrayright[realcountright][var] = sendarrayright_new[var];
1087  }
1088  free(sendarrayright_new);
1089  ++realcountright;
1090  removeItem(temp);
1091  } else {
1092  removeItem(temp);
1093  }
1094  }
1095  else if (direction_id == 5)
1096  {
1097  //nächstes Feld prüfen
1098  int next_itemID = getFieldID(j, k - 1, l);
1099  if (next_itemID == 0 || next_itemID == 3) {
1100  addItemNewRoom(temp, j, k - 1, l);
1101  //room_new[j-1][k] = getSound(j,k);
1102  } else if (next_itemID == 1) {
1103 
1104  //TODO: Winkel Abprall, Schalldämmung durch Hinderniss
1105  //1. Sound an die Folgestelle schieben
1106  absorption(temp, 0.78);
1107  //2. Attribut der Richtung anpassen
1108  temp->data.Sound.direction_id = getReboundID(direction_id);
1110  addItemNewRoom(temp, j, k, l);
1111  } else if (next_itemID == 2)
1112  {
1113  removeItem(temp);
1114  }
1115  }
1116  else if (direction_id == 6) {
1117  int next_itemID = getFieldID(j - 1, k - 1 , l);
1118  if (next_itemID == 0 || next_itemID == 3) {
1119  addItemNewRoom(temp, j - 1, k - 1, l);
1120  }
1121  else if (next_itemID == 1) {
1122  absorption(temp, 0.78);
1123  temp->data.Sound.direction_id = getReboundID(direction_id);
1125  addItemNewRoom(temp, j, k, l);
1126  } else if (next_itemID == 2 && j == 0 && myrank != 2) {
1127  if (realcountleft == sendrowsleft) {
1128  int newnum = (sendrowsleft + 2) * 2;
1129  int (*newptr)[cols] = realloc(sendarrayleft, sizeof * newptr * newnum);
1130  sendrowsleft = newnum;
1131  sendarrayleft = newptr;
1132  }
1133  int *sendarrayleft_new = prepareArrays(temp, 2);
1134  for (int var = 0; var < cols; ++var) {
1135  sendarrayleft[realcountleft][var] = sendarrayleft_new[var];
1136  }
1137  free(sendarrayleft_new);
1138  ++realcountleft;
1139  removeItem(temp);
1140  } else {
1141  removeItem(temp);
1142  }
1143  }
1144  else if (direction_id == 7) {
1145  int next_itemID = getFieldID(j - 1, k , l);
1146  if (next_itemID == 0 || next_itemID == 3) {
1147  addItemNewRoom(temp, j - 1, k, l);
1148  }
1149  else if (next_itemID == 1) {
1150  absorption(temp, 0.78);
1151  temp->data.Sound.direction_id = getReboundID(direction_id);
1153  addItemNewRoom(temp, j, k, l);
1154  } else if (next_itemID == 2 && j == 0 && myrank != 2) {
1155  if (realcountleft == sendrowsleft) {
1156  int newnum = (sendrowsleft + 2) * 2;
1157  int (*newptr)[cols] = realloc(sendarrayleft, sizeof * newptr * newnum);
1158  sendrowsleft = newnum;
1159  sendarrayleft = newptr;
1160  }
1161  int *sendarrayleft_new = prepareArrays(temp, 1);
1162  for (int var = 0; var < cols; ++var) {
1163  sendarrayleft[realcountleft][var] = sendarrayleft_new[var];
1164  }
1165  ++realcountleft;
1166  removeItem(temp);
1167  } else {
1168  removeItem(temp);
1169  }
1170  }
1171  else if (direction_id == 8) {
1172  int next_itemID = getFieldID(j - 1, k + 1 , l);
1173  if (next_itemID == 0 || next_itemID == 3) {
1174  addItemNewRoom(temp, j - 1, k + 1, l);
1175  }
1176  else if (next_itemID == 1) {
1177  absorption(temp, 0.78);
1178  temp->data.Sound.direction_id = getReboundID(direction_id);
1180  addItemNewRoom(temp, j, k, l);
1181  } else if (next_itemID == 2 && j == 0 && myrank != 2) {
1182  if (realcountleft == sendrowsleft) {
1183  int newnum = (sendrowsleft + 2) * 2;
1184  int (*newptr)[cols] = realloc(sendarrayleft, sizeof * newptr * newnum);
1185  sendrowsleft = newnum;
1186  sendarrayleft = newptr;
1187  }
1188  int *sendarrayleft_new = prepareArrays(temp, 1);
1189  for (int var = 0; var < cols; ++var) {
1190  sendarrayleft[realcountleft][var] = sendarrayleft_new[var];
1191  }
1192  ++realcountleft;
1193  removeItem(temp);
1194  } else {
1195  removeItem(temp);
1196  }
1197  }
1198  decSoundWithMovement(temp);
1199  checkSoundValid(temp, j, k, l);
1200  temp = temp->next;
1201  }
1202  }
1203  if (getFieldID(j, k, l) == 0) {
1204  interference(j, k, l); // nach allen verschiebungen überlappungen verrechnen.
1205  }
1206  }
1207  }
1208  }
1209  if (run < runs && myrank != 2 && myrank != size - 1) {
1210 
1211  int desti = myrank + 1;
1212  MPI_Request reqr;
1213  MPI_Isend(sendarrayright, realcountright * cols, MPI_INT, desti, 14, MPI_COMM_WORLD, &reqr);
1214  MPI_Wait(&reqr, MPI_STATUS_IGNORE);
1215 
1216  desti = myrank - 1;
1217  MPI_Request reql;
1218  MPI_Isend(sendarrayleft, realcountleft * cols, MPI_INT, desti, 14, MPI_COMM_WORLD, &reql);
1219  MPI_Wait(&reql, MPI_STATUS_IGNORE);
1220 
1221  }
1222  else if (run < runs && myrank == 2) {
1223  int desti = myrank + 1;
1224  MPI_Request reqr;
1225  MPI_Isend(sendarrayright, realcountright * cols, MPI_INT, desti, 14, MPI_COMM_WORLD, &reqr);
1226  MPI_Wait(&reqr, MPI_STATUS_IGNORE);
1227  }
1228  else if (run < runs && myrank == size - 1) {
1229  int desti = myrank - 1;
1230  MPI_Request reql;
1231  MPI_Isend(sendarrayleft, realcountleft * cols, MPI_INT, desti, 14, MPI_COMM_WORLD, &reql);
1232  MPI_Wait(&reql, MPI_STATUS_IGNORE);
1233  }
1234  free(sendarrayleft);
1235  free(sendarrayright);
1236  realcountright = 0;
1237  realcountleft = 0;
1238  changeRoom(room_new);
1239  ++run;
1240  //Sync
1241  int sendready = 1;
1242  MPI_Send(&sendready, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
1243  //Takt
1244  MPI_Recv(&go, 1, MPI_INT, 0, myrank, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
1245  }
1246  }
1247  MPI_Barrier(MPI_COMM_WORLD);
1248  if (myrank == 0) {
1249  end_t = MPI_Wtime();
1250  total_t = end_t - start_t;
1251  printf("Time for executing were: %f seconds\n " , total_t);
1252  printf("The Matrix was %d * %d * %d\n", x_format, y_format, z_format);
1253  printf("%s\n", "-----ENGINE STOPPED-----" );
1254  } else if (myrank == 1) {
1255  //Visualisation beenden
1256  FILE *fp;
1257  fp = fopen("output", "a");
1258  fprintf(fp, "}" );
1259  fclose(fp);
1260  }
1261  MPI_Finalize();
1262 }
1263 
int myrank
Definition: main.c:23
void setTouche(item_node *node)
void interference(int x, int y, int z)
Definition: collision.c:35
int main(int argc, char *argv[])
Definition: main.c:755
int l
Definition: main.c:20
void absorption(item_node *temp, float coeff)
Definition: collision.c:16
int * prepareArrays(item_node *node, int side)
Definition: main.c:642
void setSideOfWave(item_node *node, int side)
int z_format
Definition: main.c:19
int y_format
Definition: main.c:18
void setFreq100b150(item_node *node, int value)
Definition: main.c:262
item_node getSound(item_node *node)
Definition: main.c:437
item_node *** room_new
Definition: main.c:33
void changeRoom(item_node ***newRoom)
Definition: main.c:162
item_node * allElementsNew
Definition: main.c:34
void setFreq1000b2000(item_node *node, int value)
Definition: main.c:280
struct item_node * next
Definition: main.h:13
int getFreq400b1000(item_node *node)
Definition: main.c:344
item_node getObstacle(item_node *node)
Definition: main.c:442
int getFieldID(int x, int y, int z)
Definition: main.c:207
void setDirectionID(item_node *node, int value)
Definition: main.c:399
struct item_node * prev
Definition: main.h:14
void setFreq6000b10000(item_node *node, int value)
Definition: main.c:298
int size
Definition: main.c:24
int i
Definition: main.c:20
int j
Definition: main.c:20
item_node * createItem(int x, int y, int z, int id)
Definition: main.c:476
int id
Definition: main.h:12
int visuStep
Step Counter für Visualisierung.
Definition: main.c:15
void setFreq10000b20000(item_node *node, int value)
Definition: main.c:304
item_node *** room
Definition: main.c:32
void setItemID(item_node *node, int id)
Definition: main.c:196
union item_node::@0 data
int x_format
Raum Formate.
Definition: main.c:17
void saveVisualisation(int x_offset)
Definition: main.c:691
int cols
Definition: main.c:29
void createReceipt(int(*roomtrans)[cols], int var, int x)
Definition: main.c:604
int getFreq20b40(item_node *node)
Definition: main.c:312
void setFreq40b100(item_node *node, int value)
Definition: main.c:256
void setFreq3500b6000(item_node *node, int value)
Definition: main.c:292
item_node * addItem(item_node *node, int x, int y, int z)
Definition: main.c:523
void setMovement(item_node *node, int m)
int realcountright
Definition: main.c:27
bool getTouch(item_node *node)
int realcountleft
Definition: main.c:28
void increaseMovement(item_node *node)
int getItemID(item_node *node)
Definition: main.c:185
void setFreq20b40(item_node *node, int value)
Definition: main.c:250
int rows
Definition: main.c:26
int getFreq150b400(item_node *node)
Definition: main.c:336
int getFreq100b150(item_node *node)
Definition: main.c:328
int getFreq10000b20000(item_node *node)
Definition: main.c:384
struct item_node::@0::@1 Sound
int getFreq6000b10000(item_node *node)
Definition: main.c:376
Definition: main.h:10
int getSideOfWave(item_node *node)
const int nitems
Definition: main.c:25
item_node getRoom()
Definition: main.c:226
void removeItem(item_node *node)
Definition: main.c:500
void addWave(item_node *temp, int x, int y, int z)
int getFreq1000b2000(item_node *node)
Definition: main.c:352
void unToucheAll()
void addItemNewRoom(item_node *node, int x, int y, int z)
Definition: main.c:565
item_node * roomtrans
Modelierung eines Fragments !
Definition: main.c:31
int getFreq3500b6000(item_node *node)
Definition: main.c:368
int getDirectionID(item_node *node)
Definition: main.c:410
item_node *** createRoom()
Definition: main.c:41
int getFreq2000b3500(item_node *node)
Definition: main.c:360
int getReboundID(int currentDirectionID)
Definition: main.c:421
void decSoundWithMovement(item_node *node)
void changeReboundSideOfWave(item_node *node)
void loudspeaker()
Definition: extras.c:64
int isSoundField(int x, int y, int z)
Definition: main.c:586
void setFreq2000b3500(item_node *node, int value)
Definition: main.c:286
int getFreq40b100(item_node *node)
Definition: main.c:320
int k
Definition: main.c:20
void allocRoom()
Definition: main.c:77
bool checkSoundValid(item_node *temp, int x, int y, int z)
Definition: collision.c:167
item_node * allElements
Definition: main.c:35
void setFreq150b400(item_node *node, int value)
Definition: main.c:268
item_node * getItem_Root(int x, int y, int z)
Definition: main.c:454
item_node *** createRoomNew()
Definition: main.c:105
void setFreq400b1000(item_node *node, int value)
Definition: main.c:274
item_node * getItem_RootNewRoom(int x, int y, int z)
Definition: main.c:545
bool isObstacle(int x, int y, int z)
Definition: main.c:236
void door()
Definition: extras.c:24
int getMovement(item_node *node)