The FARGO_THORIN code developer's guide
 All Data Structures Files Functions Variables Typedefs Macros
commbound.c
Go to the documentation of this file.
1 /** \file commbound.c
2 
3 Contains the functions used to synchronize buffer zones on all
4 processes. In addition to the main function that allows the
5 synchronization (note that even processes first send their inner zones
6 to the previous process, then receive their inner buffer from this
7 process, while odd processes first receive their outer buffer from the
8 next process, then send their outer zones to the next process. This
9 file also contains the function that allocates the memory for the
10 communication (once for all the run).
11 
12 @author THORIN modifications by
13 Ondřej Chrenko <chrenko@sirrah.troja.mff.cuni.cz>, Copyright (C) 2017;
14 original code by Frédéric Masset
15 
16 */
17 
18 #include "fargo.h"
19 
24 
25 static int allocated_com = 0;
26 static int size_com;
27 
28 void AllocateComm () { /* #THORIN */
29  size_com = 3;
30  if (EnergyEq == YES) size_com++; /* #THORIN */
31  if (AdvecteLabel == YES) size_com++;
33  SendInnerBoundary = malloc (size_com * sizeof(real));
34  SendOuterBoundary = malloc (size_com * sizeof(real));
35  RecvInnerBoundary = malloc (size_com * sizeof(real));
36  RecvOuterBoundary = malloc (size_com * sizeof(real));
37  if ((SendInnerBoundary == NULL) ||\
38  (SendOuterBoundary == NULL) ||\
39  (RecvInnerBoundary == NULL) ||\
40  (RecvOuterBoundary == NULL)) {
41  fprintf (stderr, "CPU %d had not enough memory to allocate communicators.\n", CPU_Rank);
42  prs_exit(0);
43  }
44  allocated_com = 1;
45 }
46 
47 void CommunicateBoundaries (Density, Vrad, Vtheta, Energy, Label) /* #THORIN */
48  PolarGrid *Density, *Vrad, *Vtheta, *Energy, *Label;
49 {
50  MPI_Request req1, req2, req3, req4;
51  int l, prev, next, oo, o, nr, shift; /* #THORIN shift is new */
52  if (!allocated_com) AllocateComm ();
53  prev = CPU_Rank-1;
54  next = CPU_Rank+1;
55  l = CPUOVERLAP*NSEC;
56  nr = Density->Nrad;
57  oo = (nr-CPUOVERLAP)*NSEC;
58  o = (nr-2*CPUOVERLAP)*NSEC;
59  memcpy (SendInnerBoundary, Density->Field+l, l*sizeof(real));
60  memcpy (SendInnerBoundary+l, Vrad->Field+l, l*sizeof(real));
61  memcpy (SendInnerBoundary+2*l, Vtheta->Field+l, l*sizeof(real));
62  memcpy (SendOuterBoundary, Density->Field+o, l*sizeof(real));
63  memcpy (SendOuterBoundary+l, Vrad->Field+o, l*sizeof(real));
64  memcpy (SendOuterBoundary+2*l, Vtheta->Field+o, l*sizeof(real));
65  /* #THORIN ---> */
66  shift = 3;
67  if (EnergyEq == YES) {
68  memcpy (SendInnerBoundary+shift*l, Energy->Field+l, l*sizeof(real));
69  memcpy (SendOuterBoundary+shift*l, Energy->Field+o, l*sizeof(real));
70  shift++;
71  }
72  if (AdvecteLabel == YES) {
73  memcpy (SendInnerBoundary+shift*l, Label->Field+l, l*sizeof(real));
74  memcpy (SendOuterBoundary+shift*l, Label->Field+o, l*sizeof(real));
75  }
76  /* <--- */
77  if (CPU_Rank % 2 == 0) {
78  if (CPU_Rank > 0) {
81  }
82  if (CPU_Rank < CPU_Number-1) {
85  }
86  } else {
87  if (CPU_Rank < CPU_Number-1) {
90  }
91  if (CPU_Rank > 0) {
94  }
95  }
96  if (CPU_Rank > 0) {
97  MPI_Wait (&req1, &fargostat);
98  MPI_Wait (&req2, &fargostat);
99  memcpy (Density->Field, RecvInnerBoundary, l*sizeof(real));
100  memcpy (Vrad->Field, RecvInnerBoundary+l, l*sizeof(real));
101  memcpy (Vtheta->Field, RecvInnerBoundary+2*l, l*sizeof(real));
102  /* #THORIN --> */
103  shift=3;
104  if (EnergyEq) {
105  memcpy (Energy->Field, RecvInnerBoundary+shift*l, l*sizeof(real));
106  shift++;
107  }
108  if (AdvecteLabel == YES) {
109  memcpy (Label->Field, RecvInnerBoundary+shift*l, l*sizeof(real));
110  }
111  /* <--- */
112  }
113  if (CPU_Rank < CPU_Number-1) {
114  MPI_Wait (&req3, &fargostat);
115  MPI_Wait (&req4, &fargostat);
116  memcpy (Density->Field+oo, RecvOuterBoundary, l*sizeof(real));
117  memcpy (Vrad->Field+oo, RecvOuterBoundary+l, l*sizeof(real));
118  memcpy (Vtheta->Field+oo, RecvOuterBoundary+2*l, l*sizeof(real));
119  /* #THORIN ---> */
120  shift=3;
121  if (EnergyEq) {
122  memcpy (Energy->Field+oo, RecvOuterBoundary+shift*l, l*sizeof(real));
123  shift++;
124  }
125  if (AdvecteLabel == YES) {
126  memcpy (Label->Field+oo, RecvOuterBoundary+shift*l, l*sizeof(real));
127  }
128  /* <--- */
129  }
130 }
double real
Definition of the type 'real' used throughout the code.
Definition: types.h:20
MPI_Status fargostat
Definition: global.h:32
int CPU_Number
Definition: global.h:2
#define YES
Definition: types.h:46
#define MPI_DOUBLE
Definition: mpi_dummy.h:11
A structure used to store any scalar fied on the computational domain.
Definition: types.h:37
static int allocated_com
Definition: commbound.c:25
boolean EnergyEq
Definition: global.h:24
static int size_com
Definition: commbound.c:26
void MPI_Irecv()
Definition: mpi_dummy.c:52
#define CPUOVERLAP
Definition: fondam.h:13
boolean AdvecteLabel
Definition: global.h:29
int NSEC
Definition: param_noex.h:19
void AllocateComm()
Definition: commbound.c:28
static real * SendInnerBoundary
Definition: commbound.c:20
void MPI_Isend()
Definition: mpi_dummy.c:48
static real * SendOuterBoundary
Definition: commbound.c:21
int MPI_Request
Definition: mpi_dummy.h:19
static real * RecvInnerBoundary
Definition: commbound.c:22
Contains all the include directives requested by the code.
int CPU_Rank
Definition: global.h:1
real Energy()
void CommunicateBoundaries(PolarGrid *Density, PolarGrid *Vrad, PolarGrid *Vtheta, PolarGrid *Energy, PolarGrid *Label)
Definition: commbound.c:47
void MPI_Wait()
Definition: mpi_dummy.c:68
static real * RecvOuterBoundary
Definition: commbound.c:23
#define MPI_COMM_WORLD
Definition: mpi_dummy.h:10
void prs_exit(int numb)
Definition: LowTasks.c:33