/[escript]/trunk/weipa/src/VisItControl.cpp
ViewVC logotype

Contents of /trunk/weipa/src/VisItControl.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3365 - (show annotations)
Thu Nov 18 10:49:40 2010 UTC (10 years, 3 months ago) by caltinay
File size: 8781 byte(s)
Fixed compilation without VisIt.

1
2 /*******************************************************
3 *
4 * Copyright (c) 2003-2010 by University of Queensland
5 * Earth Systems Science Computational Center (ESSCC)
6 * http://www.uq.edu.au/esscc
7 *
8 * Primary Business: Queensland, Australia
9 * Licensed under the Open Software License version 3.0
10 * http://www.opensource.org/licenses/osl-3.0.php
11 *
12 *******************************************************/
13
14 #include <weipa/VisItControl.h>
15 #include <weipa/EscriptDataset.h>
16
17 #ifdef USE_VISIT
18 #include <weipa/VisItData.h>
19
20 #include <VisItControlInterface_V2.h>
21
22 #include <cstring>
23 #include <iostream>
24
25 #define VISIT_COMMAND_PROCESS 0
26 #define VISIT_COMMAND_SUCCESS 1
27 #define VISIT_COMMAND_FAILURE 2
28 #endif
29
30 namespace weipa {
31
32 namespace VisItControl {
33
34 bool initialized = false;
35
36 #ifdef USE_VISIT
37
38 weipa::VisItData_ptr visitData(new VisItData());
39 int mpiRank = 0;
40 int mpiSize = 1;
41 bool runFlag = true;
42 bool connected = false;
43
44 // Helper function for processVisItCommand()
45 static void broadcastSlaveCommand(int* command)
46 {
47 #if HAVE_MPI
48 MPI_Bcast(command, 1, MPI_INT, 0, MPI_COMM_WORLD);
49 #endif
50 }
51
52 // Processes commands from the VisIt viewer on all processors
53 static int processVisItCommand()
54 {
55 if (mpiRank == 0) {
56 int success = VisItProcessEngineCommand();
57 int command;
58
59 if (success) {
60 command = VISIT_COMMAND_SUCCESS;
61 broadcastSlaveCommand(&command);
62 return 1;
63 } else {
64 command = VISIT_COMMAND_FAILURE;
65 broadcastSlaveCommand(&command);
66 return 0;
67 }
68 } else {
69 // Note: Only through the SlaveProcessCallback() function
70 // can rank 0 send VISIT_COMMAND_PROCESS to non-zero ranks
71 while (1) {
72 int command=VISIT_COMMAND_SUCCESS;
73 broadcastSlaveCommand(&command);
74 switch (command) {
75 case VISIT_COMMAND_PROCESS:
76 VisItProcessEngineCommand();
77 break;
78 case VISIT_COMMAND_SUCCESS:
79 return 1;
80 case VISIT_COMMAND_FAILURE:
81 return 0;
82 }
83 }
84 }
85 }
86
87 // Callback involved in command communication
88 static void slaveProcessCallback()
89 {
90 int command = VISIT_COMMAND_PROCESS;
91 broadcastSlaveCommand(&command);
92 }
93
94 #if HAVE_MPI
95 static int broadcastIntCallback(int* value, int sender)
96 {
97 return MPI_Bcast(value, 1, MPI_INT, sender, MPI_COMM_WORLD);
98 }
99
100 static int broadcastStringCallback(char* str, int len, int sender)
101 {
102 return MPI_Bcast(str, len, MPI_CHAR, sender, MPI_COMM_WORLD);
103 }
104 #endif
105
106 // Processes a control command
107 static void controlCommandCallback(const char* cmd, const char* sdata,
108 void* cb_data)
109 {
110 #ifdef _DEBUG
111 std::cout << "Control Command: " << cmd << std::endl;
112 #endif
113
114 if (strstr(cmd, "pause")) {
115 runFlag = !runFlag;
116 } else if (strstr(cmd, "update_plots")) {
117 VisItUpdatePlots();
118 }
119 }
120
121 // Callback that returns metadata for this dataset
122 visit_handle VisItGetMetaData(void* cbdata)
123 {
124 #ifdef _DEBUG
125 std::cout << "VisItGetMetaData()" << std::endl;
126 #endif
127 return visitData->getSimMetaData();
128 }
129
130 // Callback that returns the domain list for this dataset
131 visit_handle VisItGetDomainList(const char* name, void* cbdata)
132 {
133 #ifdef _DEBUG
134 std::cout << "VisItGetDomainList(" << name << ")" << std::endl;
135 #endif
136 return visitData->getDomainList();
137 }
138
139 // Callback that returns mesh data
140 visit_handle VisItGetMesh(int domain, const char* name, void* cbdata)
141 {
142 #ifdef _DEBUG
143 std::cout << "VisItGetMesh(" << domain << ", '" << name << "')" << std::endl;
144 #endif
145 if (mpiRank != domain) {
146 #ifdef _DEBUG
147 std::cout << "I don't have data for domain " << domain << std::endl;
148 #endif
149 return VISIT_INVALID_HANDLE;
150 }
151 return visitData->getMesh(name);
152 }
153
154 // Callback that returns variable data
155 visit_handle VisItGetVariable(int domain, const char* name, void* cbdata)
156 {
157 #ifdef _DEBUG
158 std::cout << "VisItGetVariable(" << domain << ", '" << name << "')" << std::endl;
159 #endif
160 if (mpiRank != domain) {
161 #ifdef _DEBUG
162 std::cout << "I don't have data for domain " << domain << std::endl;
163 #endif
164 return VISIT_INVALID_HANDLE;
165 }
166 return visitData->getVariable(name);
167 }
168
169 #endif // USE_VISIT
170
171 /****************************************************************************/
172
173 // Initializes libsim and the communication to VisIt
174 bool initialize(const std::string& simFile, const std::string& comment)
175 {
176 #ifdef USE_VISIT
177 if (connected) {
178 VisItDisconnect();
179 connected = false;
180 std::cout << "VisIt client disconnected." << std::endl;
181 }
182
183 if (!initialized) {
184 //VisItOpenTraceFile("/tmp/simV2trace.txt");
185 if (!VisItSetupEnvironment()) {
186 std::cerr << "Error setting up VisIt environment" << std::endl;
187 return false;
188 }
189
190 #if HAVE_MPI
191 MPI_Comm_rank(MPI_COMM_WORLD, &mpiRank);
192 MPI_Comm_size(MPI_COMM_WORLD, &mpiSize);
193
194 // Install callback functions for global communication
195 VisItSetBroadcastIntFunction(broadcastIntCallback);
196 VisItSetBroadcastStringFunction(broadcastStringCallback);
197
198 // Tell libsim whether the simulation is parallel
199 VisItSetParallel(mpiSize > 1);
200 VisItSetParallelRank(mpiRank);
201 #endif
202 std::vector<std::string> cmdNames;
203 cmdNames.push_back("pause");
204 cmdNames.push_back("update_plots");
205 visitData->setCommandNames(cmdNames);
206 initialized = true;
207 }
208
209 if (mpiRank == 0) {
210 std::string filename(simFile);
211 if (filename.rfind(".sim2") != filename.length()-5) {
212 filename += ".sim2";
213 }
214 VisItInitializeSocketAndDumpSimFile("escript", comment.c_str(),
215 NULL, NULL, NULL, filename.c_str());
216 }
217 #endif // USE_VISIT
218 return initialized;
219 }
220
221 // Main entry point that checks for client input and publishes new data
222 bool publishData(EscriptDataset_ptr dataset)
223 {
224 if (!initialized || dataset->getConvertedDomain().size()==0) {
225 return false;
226 }
227
228 #ifdef USE_VISIT
229 int visitState = 0, err = 0;
230
231 if (connected) {
232 visitData->publishData(dataset);
233 visitData->setSimulationStatus(runFlag);
234 VisItTimeStepChanged();
235 }
236
237 do {
238 // Get input from VisIt or timeout so the simulation can continue
239 if (mpiRank == 0) {
240 int blocking = (connected && !runFlag) ? 1 : 0;
241 visitState = VisItDetectInput(blocking, -1);
242 }
243
244 #if HAVE_MPI
245 MPI_Bcast(&visitState, 1, MPI_INT, 0, dataset->getMPIComm());
246 #endif
247
248 // visitState values:
249 // 0: there was no input from VisIt so nothing to do
250 // 1: VisIt is trying to connect
251 // 2: VisIt sent a command which should be processed
252 // < 0: an unrecoverable error occurred
253 if (visitState < 0) {
254 std::cerr << "VisItControl: Can't recover from error! State="
255 << visitState << std::endl; fflush(stderr);
256 err = 1;
257 } else if (visitState == 1) {
258 if (VisItAttemptToCompleteConnection() == VISIT_OKAY) {
259 std::cout << "VisIt client connected." << std::endl;
260 // publish latest data
261 visitData->publishData(dataset);
262 visitData->setSimulationStatus(runFlag);
263 void* cbdata = NULL;
264 VisItSetCommandCallback(controlCommandCallback, cbdata);
265 VisItSetSlaveProcessCallback(slaveProcessCallback);
266
267 VisItSetGetMetaData(VisItGetMetaData, cbdata);
268 VisItSetGetMesh(VisItGetMesh, cbdata);
269 VisItSetGetVariable(VisItGetVariable, cbdata);
270 VisItSetGetDomainList(VisItGetDomainList, cbdata);
271 VisItTimeStepChanged();
272 connected = true;
273 } else {
274 char *errorString = VisItGetLastError();
275 if (mpiRank == 0) {
276 if (strlen(errorString) > 0) {
277 std::cerr << errorString << std::endl;
278 } else {
279 std::cerr << "VisIt failed to connect successfully."
280 << std::endl;
281 }
282 }
283 free(errorString);
284 }
285 } else if (visitState == 2) {
286 if (!processVisItCommand()) {
287 VisItDisconnect();
288 connected = false;
289 std::cout << "VisIt client disconnected." << std::endl;
290 }
291 }
292 } while (visitState != 0);
293
294 return err==0;
295 #else // USE_VISIT
296
297 return false;
298 #endif
299 }
300
301 } // namespace VisItControl
302
303 } // namespace weipa
304

  ViewVC Help
Powered by ViewVC 1.1.26