-
Notifications
You must be signed in to change notification settings - Fork 24
/
asynchdist.c
151 lines (125 loc) · 4.35 KB
/
asynchdist.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#include <stdio.h>
#include <unistd.h>
#include "mpi.h"
#include "asynch_interface.h"
int my_rank;
int np;
int Output_Linkid(double t,VEC* y_i,VEC* global_params,VEC* params,int state,void* user);
void Set_Output_User_LinkID(asynchsolver* asynch);
int main(int argc,char* argv[])
{
//Initialize MPI stuff
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);
MPI_Comm_size(MPI_COMM_WORLD,&np);
//Parse input
if(argc < 2)
{
if(my_rank == 0)
{
printf("Command line parameter required: A universal variable file (.gbl).\n");
printf("\n");
}
MPI_Finalize();
return 1;
}
//Declare variables
time_t start,stop;
double total_time;
asynchsolver* asynch;
if(my_rank == 0)
printf("\nBeginning initialization...\n*****************************\n");
MPI_Barrier(MPI_COMM_WORLD);
start = time(NULL);
//Init asynch object and the river network
asynch = Asynch_Init(MPI_COMM_WORLD,&argc,&argv);
if(my_rank == 0) printf("Reading global file...\n");
Asynch_Parse_GBL(asynch,argv[1]);
if(my_rank == 0) printf("Loading network...\n");
Asynch_Load_Network(asynch);
if(my_rank == 0) printf("Partitioning network...\n");
Asynch_Partition_Network(asynch);
if(my_rank == 0) printf("Loading parameters...\n");
Asynch_Load_Network_Parameters(asynch,0);
if(my_rank == 0) printf("Reading dam and reservoir data...\n");
Asynch_Load_Dams(asynch);
if(my_rank == 0) printf("Setting up numerical error data...\n");
Asynch_Load_Numerical_Error_Data(asynch);
if(my_rank == 0) printf("Initializing model...\n");
Asynch_Initialize_Model(asynch);
if(my_rank == 0) printf("Loading initial conditions...\n");
Asynch_Load_Initial_Conditions(asynch);
if(my_rank == 0) printf("Loading forcings...\n");
Asynch_Load_Forcings(asynch);
if(my_rank == 0) printf("Loading output data information...\n");
Asynch_Load_Save_Lists(asynch);
if(my_rank == 0) printf("Finalizing network...\n");
Asynch_Finalize_Network(asynch);
if(my_rank == 0) printf("Calculating initial step sizes...\n");
Asynch_Calculate_Step_Sizes(asynch);
if(my_rank == 0)
{
printf("\nModel type is %u.\nGlobal parameters are:\n",asynch->GlobalVars->type);
Print_Vector(asynch->GlobalVars->global_params);
printf("\n");
}
//Setup output for link id, if needed
int id_setup = Asynch_Check_Output(asynch,"LinkID");
if(id_setup != -1)
{
Set_Output_User_LinkID(asynch);
Asynch_Set_Output(asynch,"LinkID",ASYNCH_INT,(void (*)(double,VEC*,VEC*,VEC*,int,void*)) &Output_Linkid,NULL,0);
}
//Prepare output files
Asynch_Prepare_Temp_Files(asynch);
Asynch_Write_Current_Step(asynch); //!!!! Wow, this sucks. Is there a way to get rid of it? !!!!
Asynch_Prepare_Peakflow_Output(asynch);
Asynch_Prepare_Output(asynch);
//Make sure everyone is good before getting down to it...
printf("Process %i (%i total) is good to go with %i links.\n",my_rank,np,asynch->my_N);
sleep(1);
MPI_Barrier(MPI_COMM_WORLD);
if(my_rank == 0)
{
stop = time(NULL);
total_time = difftime(stop,start);
printf("Finished initialization. Total time: %f\n\n\nComputing solution at each link...\n************************************\n",total_time);
}
fflush(stdout);
MPI_Barrier(MPI_COMM_WORLD);
//Perform the calculations
time(&start);
Asynch_Advance(asynch,1);
MPI_Barrier(MPI_COMM_WORLD);
time(&stop);
//Out information
total_time += difftime(stop,start);
if(my_rank == 0) printf("\nComputations complete. Total time for calculations: %f\n",difftime(stop,start));
if(asynch->sys[asynch->my_sys[0]]->c == NULL)
{
printf("[%i]: The solution at ID %i at time %.12f is\n",my_rank,asynch->sys[asynch->my_sys[0]]->ID,asynch->sys[asynch->my_sys[0]]->last_t);
Print_Vector(asynch->sys[asynch->my_sys[0]]->list->tail->y_approx);
}
//Take a snapshot
Asynch_Take_System_Snapshot(asynch,NULL);
//Create output files
Asynch_Create_Output(asynch,NULL);
Asynch_Create_Peakflows_Output(asynch);
//Clean up
Asynch_Delete_Temporary_Files(asynch);
Asynch_Free(asynch);
MPI_Finalize();
return 0;
}
int Output_Linkid(double t,VEC* y_i,VEC* global_params,VEC* params,int state,void* user)
{
return ((Link*)user)->ID;
}
//!!!! Gross, but not sure how else to handle this. Maybe with a lot of interface functions? !!!!
void Set_Output_User_LinkID(asynchsolver* asynch)
{
unsigned int i,my_N = asynch->my_N,*my_sys = asynch->my_sys;
Link** sys = asynch->sys;
for(i=0;i<my_N;i++)
sys[my_sys[i]]->output_user = (void*) sys[my_sys[i]];
}