Skip to main content

Post-processing tools 2023 R2

test_dvs_client_cxx.cpp

Last update: 17.04.2023
Go to the documentation of this file.
1 /* *************************************************************
2  * Copyright 2017-2018 ANSYS, Inc.
3  * All Rights Reserved.
4  *
5  * Restricted Rights Legend
6  *
7  * Use, duplication, or disclosure of this
8  * software and its documentation by the
9  * Government is subject to restrictions as
10  * set forth in subdivision [(b)(3)(ii)] of
11  * the Rights in Technical Data and Computer
12  * Software clause at 52.227-7013.
13  * *************************************************************
14  */
15 
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdint.h>
28 #include <stdarg.h>
29 
30 #include "dvs_client_interface.h"
31 #include "dvs_server_interface.h"
33 #include "logger.h"
34 #include "test_dynamic_data.h"
35 
36 #include <vector>
37 
38 #ifdef _WIN32
39 #include <Windows.h>
40 #else
41 #include <unistd.h>
42 #endif
43 
44 static void logging_function(void* user_data, const char* message)
45 {
46  fprintf(stderr, message);
47 }
48 
56 int main(int argc, char** argv)
57 {
58  uint32_t port = 50055;
59  uint32_t msec_delay = 0;
60  char host[512] = {0};
61  strcpy(host, "127.0.0.1");
62  char protocol[10] = {0};
63  strcpy(protocol, "grpc");
64  uint32_t width = 50;
65  uint32_t height = 50;
66  uint32_t depth = 50;
67  uint32_t max_timesteps = 10;
68  uint32_t current_rank = 0;
69  uint32_t total_ranks = 1;
70  uint8_t create_ghosts = 1;
71  uint8_t block_for_server = 1;
72  uint32_t starting_timestep = 0;
73  uint32_t dedup = 1;
74  bool send_case_vars = true;
75  bool send_structured_parts = false;
76  char dataset_id[255] = {0};
77  strcpy(dataset_id, "Test-C++-API");
78  char secret[255] = {0};
79  uint32_t plot_rank = 0;
80  uint32_t server_number = 0;
81  uint32_t server_verbosity = 0;
82  uint32_t local_ranks = 0;
83  uint32_t all_defs = false;
84  char cache_uri[512] = {0};
85  bool log_all = false;
86  uint32_t debug_wait = 0;
87  bool start_server = false;
88  bool test_delete = false;
89 
90  uint32_t i = 1;
91  while (i < argc)
92  {
93  if ((strcmp(argv[i], "-p") == 0 ) && (i < argc - 1))
94  {
95  i++;
96  port = atoi(argv[i]);
97  }
98  else if ((strcmp(argv[i], "-h") == 0) && (i < argc - 1))
99  {
100  i++;
101  strncpy(host, argv[i], 255);
102  }
103  else if ((strcmp(argv[i], "-protocol") == 0) && (i < argc - 1))
104  {
105  i++;
106  strncpy(protocol, argv[i], 10);
107  if (strcmp(protocol, "grpc") != 0 && strcmp(protocol, "null") != 0 )
108  {
109  fprintf(stderr, "protocol: %s invalid\n", protocol);
110  exit(1);
111  }
112  }
113  else if ((strcmp(argv[i], "-d") == 0) && (i < argc - 1))
114  {
115  i++;
116  msec_delay = atoi(argv[i]);
117  }
118  else if ((strcmp(argv[i], "-s") == 0) && (i < argc - 3))
119  {
120  i++;
121  width = atoi(argv[i++]);
122  height = atoi(argv[i++]);
123  depth = atoi(argv[i]);
124  }
125  else if ((strcmp(argv[i], "-t") == 0) && (i < argc - 1))
126  {
127  i++;
128  max_timesteps = atoi(argv[i]);
129  }
130  else if ((strcmp(argv[i], "-r") == 0) && (i < argc - 2))
131  {
132  i++;
133  current_rank = atoi(argv[i++]);
134  total_ranks = atoi(argv[i]);
135  }
136  else if (strcmp(argv[i], "-noghost") == 0)
137  {
138  create_ghosts = 0;
139  }
140  else if (strcmp(argv[i], "-nowait") == 0)
141  {
142  block_for_server = 0;
143  }
144  else if ((strcmp(argv[i], "-start") == 0) && (i < argc - 1))
145  {
146  i++;
147  starting_timestep = atoi(argv[i]);
148  }
149  else if (strcmp(argv[i], "-nodedup") == 0)
150  {
151  dedup = 0;
152  }
153  else if (strcmp(argv[i], "-id") == 0)
154  {
155  i++;
156  memset(dataset_id, 0, 255);
157  strncpy(dataset_id, argv[i], 255);
158  }
159  else if (strcmp(argv[i], "-secret") == 0)
160  {
161  i++;
162  strncpy(secret, argv[i], 255);
163  }
164  else if (strcmp(argv[i], "-case_constants") == 0)
165  {
166  send_case_vars = true;
167  }
168  else if (strcmp(argv[i], "-structured") == 0)
169  {
170  send_structured_parts = true;
171  }
172  else if (strcmp(argv[i], "-plot_rank") == 0)
173  {
174  i++;
175  plot_rank = atoi(argv[i]);
176  }
177  else if (strcmp(argv[i], "-server") == 0 && (i < argc - 3))
178  {
179  i++;
180  start_server = true;
181  server_number = atoi(argv[i++]);
182  local_ranks = atoi(argv[i++]);
183  server_verbosity = atoi(argv[i]);
184  }
185  else if (strcmp(argv[i], "-cache_uri") == 0)
186  {
187  i++;
188  strncpy(cache_uri, argv[i], 512);
189  }
190  else if (strcmp(argv[i], "-all_defs") == 0)
191  {
192  all_defs = true;
193  }
194  else if (strcmp(argv[i], "-log_all") == 0)
195  {
196  log_all = true;
197  }
198  else if (strcmp(argv[i], "-debug_wait") == 0)
199  {
200  i++;
201  debug_wait = atoi(argv[i]);
202  }
203  else if (strcmp(argv[i], "-test_delete") == 0)
204  {
205  test_delete = true;
206  }
207  else
208  {
209  fprintf(stderr, "Unknown option: %s\n", argv[i]);
210  fprintf(stderr, "Usage: %s [-p port] [-h host] [-d msec_delay] [-t num_timesteps] [-s dx dy dz] [-noghost] [-nowait] [-start t]\n", argv[0]);
211  fprintf(stderr, "Options:\n");
212  fprintf(stderr, " -t timesteps Number of timesteps to generate. Default: %u\n", max_timesteps);
213  fprintf(stderr, " -p port Server port to connect to. Default: %u\n", port);
214  fprintf(stderr, " -h host Server hostname to connect to. Default: %s\n", host);
215  fprintf(stderr, " -protocol str Server protocol. I.E. grpc or null. Default: grpc");
216  fprintf(stderr, " -d delay Number of milliseconds to delay between timestep pushes. Default: %u\n", msec_delay);
217  fprintf(stderr, " -s dx dy dz Size of 3D hex grid (width height depth) Default: %u %u %u\n", width, height, depth);
218  fprintf(stderr, " -r x y Rank information x=current rank (0 based), y=total number of ranks. Default: %u %u\n", current_rank, total_ranks);
219  fprintf(stderr, " -noghost Do not create ghost elements\n");
220  fprintf(stderr, " -nowait Do not wait for server to be available\n");
221  fprintf(stderr, " -start t Begin timesteps with timestep Default: %u\n", starting_timestep);
222  fprintf(stderr, " -nodedup Do not de-duplicate data on the client side Default: deduplicate\n");
223  fprintf(stderr, " -id string Set an id/name for the dataset Default: TestID\n");
224  fprintf(stderr, " -secret string Shared secret to use when talking with server Default: no shared secret\n");
225  fprintf(stderr, " -case_constants Turn on sending case constants Defaults: Don't send case constants\n");
226  fprintf(stderr, " -structured Turn on sending structured part data Default: Don't send structured part data\n");
227  fprintf(stderr, " -plot_rank Set the rank which should send plot data to EnSight (zero based) Default: %u\n", plot_rank);
228  fprintf(stderr, " -server n r v Start a server using server number [n], expecting [r] local ranks for DVS connections to connect to with verbosity [v]. Local Rank Min/Max: 1/1000\n");
229  fprintf(stderr, " -cache_uri str The URI for the server to use for the cache. Default: No cache\n");
230  fprintf(stderr, " -all_defs Send all part/var definitions no matter the current rank. Default: No\n");
231  fprintf(stderr, " -log_all Print out all client logging information\n. Default: No client logs");
232  fprintf(stderr, " -debug_wait ms Wait for [ms] for debugging\n");
233  fprintf(stderr, " -test_delete Test deleting all timesteps before each update Default: Do not test\n");
234  exit(1);
235  }
236  i++;
237  }
238 
239  if (debug_wait > 0)
240  {
241  #ifdef _WIN32
242  Sleep(debug_wait);
243  #else
244  usleep(debug_wait*1000);
245  #endif
246  }
247 
248  char uri[512] = {0};
249  sprintf(uri, "%s://%s:%u", protocol, host, port);
250  fprintf(stderr, "Connecting to: %s\n", uri);
251  fprintf(stderr, "Timestep delay: %u\n", msec_delay);
252 
253  uint32_t send_vars = 1;
254  uint32_t send_elems = 1;
255  uint32_t send_hex_elems = 1;
256  uint32_t send_nfaced_elems = 1;
257  uint32_t send_pnt_elems = 1;
258  uint32_t send_tri_quad_elems = 1;
259  uint32_t send_nsided_elems = 0;
260  uint32_t send_plots = 1;
261 
262  dvs_client_flags flags;
263  if (block_for_server) flags = static_cast<dvs_client_flags>(flags | dvs_client_flags::BLOCK_FOR_SERVER);
264  if (dedup) flags = static_cast<dvs_client_flags>(flags | dvs_client_flags::DEDUP);
265 
266  fprintf(stderr, "Client Flags: Blocking: %d, Dedup: %u\n", (BLOCK_FOR_SERVER & flags) > 0, (DEDUP & flags) > 0);
267 
268  DVS::IServer* server = DVS::CREATE_SERVER_INSTANCE(uri);
269  if (server == nullptr)
270  {
271  fprintf(stderr, "Failed to create server\n");
272  exit(1);
273  }
274  if (start_server)
275  {
276  char temp[10];
277  snprintf(temp, 10, "%u", server_verbosity);
278  server->set_option("VERBOSE",temp);
279  if (strlen(cache_uri) > 0) server->set_option("CACHE_URI",cache_uri);
280  server->startup(server_number, local_ranks);
281  }
282 
283  DVS::IClient* client = nullptr;
284  client = DVS::CREATE_CLIENT_INSTANCE(server, flags, secret);
285  fprintf(stderr, "Current Client Version: %s\n", client->get_version());
286  if (client == nullptr)
287  {
288  fprintf(stderr, "Failed to create client\n");
289  exit(1);
290  }
292  client->set_logger(new DVS::Logger(nullptr, log_flags, logging_function));
293  {
294  if (part_info_num != 7 || var_info_num != 7)
295  {
296  fprintf(stderr, "This pseudo client code relies on part infos == 7 and var infos == 7, needs modified otherwise\n");
297  exit(1);
298  }
299 
300  struct TestDynamicData test;
301  test_dynamic_data_init(&test, 0, current_rank, total_ranks);
302  client->begin_init(dataset_id, test.current_rank, test.total_ranks, test.num_chunks);
303  client->set_unit_system(test.unit_system);
304  client->add_metadata(test.metadata_keys, test.metadata_vals, test.metadata_num_pairs);
305  //TODO: Have this done in only the 0th rank once merging definitions is finished
306  if (send_plots && current_rank == plot_rank) client->add_plot_info(test.plots, plot_info_num);
307 
308  if ((total_ranks == 1) || (total_ranks == 2) || all_defs)
309  {
310  //If one rank or two ranks and first rank send everything (tests second rank having no definitions)
311  if (current_rank == 0 || all_defs)
312  {
313  client->add_part_info(test.parts, part_info_num);
314  client->add_var_info(test.vars, send_case_vars ? var_info_num : var_info_num - 1);
315  }
316  }
317  else if (total_ranks == 3)
318  {
319  //If 3 ranks splitup definition data between first 2 ranks
320  //the last rank will not have any (will receive data from others)
321  if (current_rank == 0)
322  {
323  //Send part 0
324  client->add_part_info(test.parts, 1);
325  //Send vars 0->1
326  client->add_var_info(test.vars, 2);
327  }
328  else if (current_rank == 1)
329  {
330  //Send parts 1->2
331  client->add_part_info(&test.parts[1], part_info_num-1);
332  //Send vars 2->5
333  client->add_var_info(&test.vars[2], send_case_vars ? 5 : 4);
334  }
335  //Third rank will have empty definitions which should be filled in
336  }
337  else if (total_ranks > 3)
338  {
339  //If more than 3 ranks splitup data between first 3 ranks
340  //other 3 ranks will not have any (will receive data from others)
341  if (current_rank == 0)
342  {
343  //Send part 0
344  client->add_part_info(test.parts, 1);
345  //Send vars 0->1
346  client->add_var_info(test.vars, 2);
347  }
348  else if (current_rank == 1)
349  {
350  //Send part 1
351  client->add_part_info(&test.parts[1], 1);
352  //Send parts 2->3
353  client->add_var_info(&test.vars[2], 2);
354  }
355  else if (current_rank == 2)
356  {
357  //Send part 2
358  client->add_part_info(&test.parts[2], part_info_num-2);
359  //Send parts 4->5
360  client->add_var_info(&test.vars[4], send_case_vars ? 3 : 2);
361  }
362  }
363  else
364  {
365  //Situation not currently handled exit out
366  fprintf(stderr, "Bad Initialization of Ranks\n");
367  exit(1);
368  }
369 
370  client->end_init();
371  }
372 
373  uint32_t update_num = 0; // Keep a running update number for this session
374  for (uint32_t i = starting_timestep; i < max_timesteps; i++)
375  {
376  if (i > 1 + starting_timestep && msec_delay)
377  {
378  #ifdef _WIN32
379  Sleep(msec_delay);
380  #else
381  usleep(msec_delay*1000);
382  #endif
383  }
384  if (test_delete && i != starting_timestep) {
385  fprintf(stderr, "Rank: %i of %i Deleting Item\n", (current_rank+1), total_ranks);
386  client->delete_item(update_num++, current_rank, "/timestep.time/gte/0.0");
387  }
388  fprintf(stderr, "Rank: %i of %i Sending Timestep: %i of %i\n", (current_rank+1), total_ranks, (i+1), max_timesteps);
389 
390  struct TestDynamicData test;
391  test_dynamic_data_init(&test, i, current_rank, total_ranks);
392  test.ghosts = create_ghosts;
393  test_dynamic_data_create_mesh_and_elements(&test, width, height, depth);
394 
395  client->begin_update(update_num++, current_rank, test.current_chunk, test.time);
396 
397  if (send_structured_parts)
398  {
400  (
401  test.parts[5]._id,
402  test.pp_global_ijk_max,
403  test.pp_local_ijk_min,
404  test.pp_local_ijk_max,
405  test.pp_origin,
406  test.pp_unit_vec_i,
407  test.pp_unit_vec_j,
408  test.pp_unit_vec_k,
409  test.pp_i_vals,
410  test.pp_j_vals,
411  test.pp_k_vals
412  );
413 
415  (
416  test.parts[6]._id,
417  test.curv_global_ijk_max,
418  test.curv_local_ijk_min,
419  test.curv_local_ijk_max,
420  test.curv_x_vals,
421  test.curv_y_vals,
422  test.curv_z_vals
423  );
424  }
425 
426  if (send_hex_elems) client->update_nodes(test.parts[0]._id, test.mesh_x_coords, test.mesh_y_coords, test.mesh_z_coords, test.mesh_coords_size);
427  if (send_pnt_elems) client->update_nodes(test.parts[1]._id, test.mesh_x_coords, test.mesh_y_coords, test.mesh_z_coords, test.mesh_coords_size);
428  if (send_nfaced_elems) client->update_nodes(test.parts[2]._id, test.mesh_x_coords, test.mesh_y_coords, test.mesh_z_coords, test.mesh_coords_size);
429  if (send_tri_quad_elems) client->update_nodes(test.parts[3]._id, test.mesh_x_coords, test.mesh_y_coords, test.mesh_z_coords, test.mesh_coords_size);
430  if (send_nsided_elems) client->update_nodes(test.parts[4]._id, test.polymesh_x_coords, test.polymesh_y_coords, test.polymesh_z_coords, test.polymesh_coords_size);
431 
432  if (send_elems)
433  {
434  if (send_hex_elems)
435  {
436  client->update_elements(test.parts[0]._id, HEXAHEDRON, test.mesh_hex_elem_coords, test.mesh_hex_elem_coords_size);
437  if (test.mesh_hex_ghost_elem_coords_size > 0)
438  {
439  client->update_elements(test.parts[0]._id, HEXAHEDRON_GHOST, test.mesh_hex_ghost_elem_coords, test.mesh_hex_ghost_elem_coords_size);
440  }
441  }
442 
443  if (send_nfaced_elems)
444  {
446  (
447  test.parts[2]._id,
448  CONVEX_POLYHEDRON,
449  test.mesh_nfaced_hex_elem_faces_per_elem,
450  test.mesh_nfaced_hex_elem_faces_per_elem_size,
451  test.mesh_nfaced_hex_elem_nodes_per_face,
452  test.mesh_nfaced_hex_elem_nodes_per_face_size,
453  test.mesh_nfaced_hex_elem_coords,
454  test.mesh_nfaced_hex_elem_coords_size
455  );
456  if (test.mesh_nfaced_hex_ghost_elem_coords_size > 0)
457  {
459  (
460  test.parts[2]._id,
461  CONVEX_POLYHEDRON_GHOST,
462  test.mesh_nfaced_hex_ghost_elem_faces_per_elem,
463  test.mesh_nfaced_hex_ghost_elem_faces_per_elem_size,
464  test.mesh_nfaced_hex_ghost_elem_nodes_per_face,
465  test.mesh_nfaced_hex_ghost_elem_nodes_per_face_size,
466  test.mesh_nfaced_hex_ghost_elem_coords,
467  test.mesh_nfaced_hex_ghost_elem_coords_size
468  );
469  }
470  }
471 
472  if (send_nsided_elems && current_rank == 0)
473  {
474  //Only send if current rank is 0 as we aren't
475  //splitting this part up based on rank
477  (
478  test.parts[4]._id,
479  N_SIDED_POLYGON,
480  test.polymesh_elem_nodes_per_face,
481  test.polymesh_elem_nodes_per_face_size,
482  test.polymesh_elem_nodes,
483  test.polymesh_elem_nodes_size
484  );
485  }
486 
487  if (send_pnt_elems) client->update_elements(test.parts[1]._id, PNT, test.mesh_point_elem_coords, test.mesh_point_elem_coords_size);
488 
489  if (send_tri_quad_elems)
490  {
491  client->update_elements(test.parts[3]._id, QUADRANGLE, test.mesh_quad_elem_coords, test.mesh_quad_elem_coords_size);
492  client->update_elements(test.parts[3]._id, TRIANGLE, test.mesh_tri_elem_coords, test.mesh_tri_elem_coords_size);
493  }
494  }
495 
496  if (send_vars)
497  {
498  //Case vars not working correctly with DVS
499  if (send_case_vars) client->update_var_case(dvs_var_type::SCALAR, test.vars[6]._id, &test.case_var_value, 1);
500  client->update_var_part(dvs_var_type::SCALAR, test.vars[4]._id, test.parts[0]._id, &test.part_scalar[0], 1);
501  client->update_var_part(dvs_var_type::SCALAR, test.vars[4]._id, test.parts[1]._id, &test.part_scalar[1], 1);
502  if (send_hex_elems) client->update_var_element(HEXAHEDRON, dvs_var_type::SCALAR, test.vars[2]._id, test.parts[0]._id, test.mesh_hex_elem_var_scalar, test.mesh_hex_elem_var_scalar_size);
503  if (send_hex_elems) client->update_var_element(HEXAHEDRON, dvs_var_type::SCALAR, test.vars[5]._id, test.parts[0]._id, test.mesh_hex_elem_var_rank_scalar, test.mesh_hex_elem_var_rank_scalar_size);
504 
505  //N-FACED Elements use the same elemental vars for now as hex elements
506  if (send_nfaced_elems) client->update_var_element(CONVEX_POLYHEDRON, dvs_var_type::SCALAR, test.vars[2]._id, test.parts[2]._id, test.mesh_hex_elem_var_scalar, test.mesh_hex_elem_var_scalar_size);
507  if (send_nfaced_elems) client->update_var_element(CONVEX_POLYHEDRON, dvs_var_type::SCALAR, test.vars[5]._id, test.parts[2]._id, test.mesh_hex_elem_var_rank_scalar, test.mesh_hex_elem_var_rank_scalar_size);
508 
509  if (send_structured_parts)
510  {
511  client->update_var_element(STRUCTURED, dvs_var_type::SCALAR, test.vars[2]._id, test.parts[5]._id, test.structured_elem_var_scalar, test.structured_elem_var_scalar_size);
512  client->update_var_element(STRUCTURED, dvs_var_type::SCALAR, test.vars[5]._id, test.parts[5]._id, test.structured_elem_var_scalar_rank, test.structured_elem_var_scalar_rank_size);
513 
514  client->update_var_element(STRUCTURED, dvs_var_type::SCALAR, test.vars[2]._id, test.parts[6]._id, test.structured_elem_var_scalar, test.structured_elem_var_scalar_size);
515  client->update_var_element(STRUCTURED, dvs_var_type::SCALAR, test.vars[5]._id, test.parts[6]._id, test.structured_elem_var_scalar_rank, test.structured_elem_var_scalar_rank_size);
516  }
517 
518  if (test.mesh_hex_ghost_elem_var_scalar_size > 0)
519  {
520  if (send_hex_elems) client->update_var_element(HEXAHEDRON_GHOST, dvs_var_type::SCALAR, test.vars[2]._id, test.parts[0]._id, test.mesh_hex_ghost_elem_var_scalar, test.mesh_hex_ghost_elem_var_scalar_size);
521  //N-FACED Elements use the same elemental vars for now as hex elements
522  if (send_nfaced_elems) client->update_var_element(CONVEX_POLYHEDRON_GHOST, dvs_var_type::SCALAR, test.vars[2]._id, test.parts[2]._id, test.mesh_hex_ghost_elem_var_scalar, test.mesh_hex_ghost_elem_var_scalar_size);
523  }
524  if (test.mesh_hex_ghost_elem_var_rank_scalar_size > 0)
525  {
526  if (send_hex_elems) client->update_var_element(HEXAHEDRON_GHOST, dvs_var_type::SCALAR, test.vars[5]._id, test.parts[0]._id, test.mesh_hex_ghost_elem_var_rank_scalar, test.mesh_hex_ghost_elem_var_rank_scalar_size);
527  //N-FACED Elements use the same elemental vars for now as hex elements
528  if (send_nfaced_elems) client->update_var_element(CONVEX_POLYHEDRON_GHOST, dvs_var_type::SCALAR, test.vars[5]._id, test.parts[2]._id, test.mesh_hex_ghost_elem_var_rank_scalar, test.mesh_hex_ghost_elem_var_rank_scalar_size);
529  }
530 
531  if (send_pnt_elems) client->update_var_element(PNT, dvs_var_type::SCALAR, test.vars[5]._id, test.parts[1]._id, test.mesh_point_elem_var_rank_scalar, test.mesh_point_elem_var_rank_scalar_size);
532 
533  if (send_nfaced_elems) client->update_var_element(HEXAHEDRON, dvs_var_type::VECTOR, test.vars[3]._id, test.parts[0]._id, test.mesh_hex_elem_var_vector, test.mesh_hex_elem_var_vector_size);
534  if (test.mesh_hex_ghost_elem_var_vector_size > 0)
535  {
536  if (send_nfaced_elems) client->update_var_element(HEXAHEDRON_GHOST, dvs_var_type::VECTOR, test.vars[3]._id, test.parts[0]._id, test.mesh_hex_ghost_elem_var_vector, test.mesh_hex_ghost_elem_var_vector_size);
537  }
538 
539  if (send_tri_quad_elems)
540  {
541  client->update_var_element(QUADRANGLE, dvs_var_type::SCALAR, test.vars[2]._id, test.parts[3]._id, test.mesh_quad_elem_var_scalar, test.mesh_quad_elem_var_scalar_size);
542  client->update_var_element(QUADRANGLE, dvs_var_type::SCALAR, test.vars[5]._id, test.parts[3]._id, test.mesh_quad_elem_var_rank_scalar, test.mesh_quad_elem_var_rank_scalar_size);
543  client->update_var_element(TRIANGLE, dvs_var_type::SCALAR, test.vars[2]._id, test.parts[3]._id, test.mesh_tri_elem_var_scalar, test.mesh_tri_elem_var_scalar_size);
544  client->update_var_element(TRIANGLE, dvs_var_type::SCALAR, test.vars[5]._id, test.parts[3]._id, test.mesh_tri_elem_var_rank_scalar, test.mesh_tri_elem_var_rank_scalar_size);
545  }
546 
547  client->update_var_node(dvs_var_type::SCALAR, test.vars[0]._id, test.parts[0]._id, test.mesh_node_var_scalar, test.mesh_node_var_scalar_size);
548  client->update_var_node(dvs_var_type::VECTOR, test.vars[1]._id, test.parts[0]._id, test.mesh_node_var_vector, test.mesh_node_var_vector_size);
549  client->update_var_node(dvs_var_type::SCALAR, test.vars[0]._id, test.parts[2]._id, test.mesh_node_var_scalar, test.mesh_node_var_scalar_size);
550  client->update_var_node(dvs_var_type::VECTOR, test.vars[1]._id, test.parts[2]._id, test.mesh_node_var_vector, test.mesh_node_var_vector_size);
551 
552  if (send_structured_parts)
553  {
554  client->update_var_node(dvs_var_type::SCALAR, test.vars[0]._id, test.parts[5]._id, test.structured_nodal_scalar, test.structured_nodal_scalar_size);
555  client->update_var_node(dvs_var_type::SCALAR, test.vars[0]._id, test.parts[6]._id, test.structured_nodal_scalar, test.structured_nodal_scalar_size);
556  }
557  }
558 
559  if (send_plots && current_rank == plot_rank)
560  {
561  client->update_plot(test.plots[0]._id, test.plot_x_values[0], test.plot_y_values[0], test.plot_num_values);
562  client->update_plot(test.plots[1]._id, test.plot_x_values[1], test.plot_y_values[1], test.plot_num_values);
563  client->update_plot(test.plots[2]._id, test.plot_x_values[2], test.plot_y_values[2], test.plot_num_values);
564  }
565  client->end_update();
566 
567  test_dynamic_data_free(&test);
568  }
569  DVS::DESTROY_CLIENT_INSTANCE(client);
570 
571  if (start_server)
572  {
573  //If we started our own server wait for the pending timesteps to clear before tearing everything down
574  //in case it was writing stuff.
575 
576  //Not waiting isn't a problem but if we had another process connecting to this
577  //process' server and sending data we might lose the last timestep since it won't be
578  //fully complete and we would not have written it yet.
579  uint32_t num_pending = 1;
580  uint32_t num_complete = 0;
581  while (num_pending > 0) {
582  dvs_ret error = server->get_timestep_count(num_pending, num_complete);
583  if (error != DVS_NONE) break;
584  // Avoid burning up a CPU waiting for the I/O to complete
585  const uint32_t temp_delay_ms = 50;
586 #ifdef _WIN32
587  Sleep(temp_delay_ms);
588 #else
589  usleep(temp_delay_ms * 1000);
590 #endif
591  }
592  }
593  DVS::DESTROY_SERVER_INSTANCE(server);
594 
595  return 0;
596 }
API for solvers to use to send data to EnSight servers.
virtual void set_logger(ILogger *logger)=0
Set the logger interface to use.
virtual dvs_ret update_nodes_structured(uint32_t part_id, const uint32_t global_ijk_max[3], const uint32_t local_ijk_min[3], const uint32_t local_ijk_max[3], const float origin[3], const float dir_i[3], const float dir_j[3], const float dir_k[3], const float *i_vals, const float *j_vals, const float *k_vals)=0
Update the nodes for a parallelepiped structured part.
virtual dvs_ret add_plot_info(const dvs_plot_info *plot_info, uint32_t num_plots)=0
Add plot information for session.
virtual dvs_ret set_unit_system(const char *system)=0
Set the unit system we are using for this session (optional)
virtual dvs_ret update_elements(uint32_t part_id, dvs_element_type type, const uint32_t *indices, uint32_t num_indices)=0
Update elements for a specific part and element type.
virtual dvs_ret delete_item(uint32_t update_num, uint32_t rank, const char *filter)=0
Delete an item.
virtual dvs_ret add_part_info(const dvs_part_info *part_info, uint32_t num_parts)=0
Add part information for session.
virtual dvs_ret end_update()=0
Call to end the update for this timestep/rank/chunk.
virtual dvs_ret update_elements_polyhedral(uint32_t part_id, dvs_element_type type, const uint32_t *faces_per_element, uint32_t faces_per_element_size, const uint32_t *nodes_per_face, uint32_t nodes_per_face_size, const uint32_t *indices, uint32_t indices_size)=0
Update N-FACED Elements.
virtual dvs_ret add_var_info(const dvs_var_info *var_info, uint32_t num_vars)=0
Add variable information for session.
virtual dvs_ret update_nodes(uint32_t part_id, const float *x, const float *y, const float *z, uint32_t num_values)=0
Update nodes for a specific part.
virtual dvs_ret update_var_case(dvs_var_type var_type, uint32_t var_id, const float *values, uint32_t num_values)=0
Update case variable.
virtual dvs_ret end_init()=0
Finish initialization for this rank.
virtual dvs_ret update_var_part(dvs_var_type var_type, uint32_t var_id, uint32_t part_id, const float *values, uint32_t num_values)=0
Update part vector variable.
virtual dvs_ret add_metadata(const char *const keys[], const char *const vals[], uint32_t num_metadata_pairs)=0
Add metadata for the current dataset.
virtual dvs_ret begin_update(uint32_t update_num, uint32_t rank, uint32_t chunk, float time)=0
Method to begin an update.
virtual const char * get_version()=0
Get the version of the client API.
virtual dvs_ret update_elements_polygon(uint32_t part_id, dvs_element_type type, const uint32_t *nodes_per_polygon, uint32_t nodes_per_polygon_size, const uint32_t *indices, uint32_t indices_size)=0
Update N-SIDED elements.
virtual dvs_ret update_var_node(dvs_var_type var_type, uint32_t var_id, uint32_t part_id, const float *values, uint32_t num_values)=0
Update nodal variable values.
virtual dvs_ret update_var_element(dvs_element_type elem_type, dvs_var_type var_type, uint32_t var_id, uint32_t part_id, const float *values, uint32_t num_values)=0
Update elemental scalar variable values.
virtual dvs_ret update_plot(uint32_t plot_id, const float *x_values, const float *y_values, uint32_t num_values)=0
Update plot data for plot.
virtual dvs_ret begin_init(const char *dataset_name, uint32_t current_rank, uint32_t total_ranks, uint32_t num_chunks)=0
Begins initialization for this rank.
Interface class used to run a dynamic data server in a thread accepting incoming client connections.
virtual void set_option(const char *key, const char *value)=0
Set a specific option on the server, these are used during startup See See Server Options.
virtual dvs_ret startup(uint32_t server_number, uint32_t local_ranks)=0
Start the server.
virtual dvs_ret get_timestep_count(uint32_t &num_pending, uint32_t &num_complete) const =0
return the current number of pending and complete timesteps in the server
C++ Client API for using the Dynamic Visualization Store.
C++ Server API for using Dynamic Visualization Store Server.
Contains enums used in C/C++ API.
dvs_log_flags
Flags to control logging filters.
@ LOG_UPDATE_BEG_END
Log messages related to begin and end of updates.
@ LOG_ALL
Log all messages.
dvs_client_flags
Flags for specific server setup.
@ DEDUP
Do not send duplicate data to server.
@ BLOCK_FOR_SERVER
Clients should block for servers to be initialized before sending data.
@ VECTOR
XYZ Coordinates.
int32_t dvs_ret
Return value of methods, TODO.
#define DVS_NONE
No detected error has occurred.
int main(int argc, char **argv)
Main method of test client application.