1 /*
2  * Copyright(C) 1999-2020 National Technology & Engineering Solutions
3  * of Sandia, LLC (NTESS).  Under the terms of Contract DE-NA0003525 with
4  * NTESS, the U.S. Government retains certain rights in this software.
5  *
6  * See packages/seacas/LICENSE for details
7  */
8 /*****************************************************************************/
9 /*****************************************************************************/
10 /* Function(s) contained in this file:
11  *      ex_get_loadbal_param()
12  *****************************************************************************
13  * This function retrieves the load balance parameters.
14  *****************************************************************************
15  *  Variable Index:
16  *      exoid             - The NetCDF ID of an already open NemesisI file.
17  *      num_int_nodes    - The number of internal FEM nodes.
18  *      num_bor_nodes    - The number of border FEM nodes.
19  *      num_ext_nodes    - The number of external FEM nodes.
20  *      num_int_elems    - The number of internal FEM elements.
21  *      num_bor_elems    - The number of border FEM elements.
22  *      num_node_cmaps   - The number of nodal communication maps.
23  *      num_elem_cmaps   - The number of elemental communication maps.
24  *      processor        - The processor the file being read was written for.
25  */
26 /*****************************************************************************/
27 /*****************************************************************************/
28 /*****************************************************************************/
29 
30 #include "exodusII.h"     // for ex_err, etc
31 #include "exodusII_int.h" // for EX_FATAL, DIM_NUM_BOR_ELEMS, etc
32 
33 /*!
34  * \ingroup ModelDescription
35  * \undoc
36  */
ex_get_loadbal_param(int exoid,void_int * num_int_nodes,void_int * num_bor_nodes,void_int * num_ext_nodes,void_int * num_int_elems,void_int * num_bor_elems,void_int * num_node_cmaps,void_int * num_elem_cmaps,int processor)37 int ex_get_loadbal_param(int exoid, void_int *num_int_nodes, void_int *num_bor_nodes,
38                          void_int *num_ext_nodes, void_int *num_int_elems, void_int *num_bor_elems,
39                          void_int *num_node_cmaps, void_int *num_elem_cmaps, int processor)
40 {
41   int     dimid, varid, status;
42   size_t  start[1];
43   size_t  nin, nbn, nen, nie, nbe, nncm, necm;
44   int64_t varidx[2];
45   char    ftype[2];
46   int     nmstat;
47 
48   char errmsg[MAX_ERR_LENGTH];
49   /*-----------------------------Execution begins-----------------------------*/
50   EX_FUNC_ENTER();
51   if (ex__check_valid_file_id(exoid, __func__) == EX_FATAL) {
52     EX_FUNC_LEAVE(EX_FATAL);
53   }
54 
55   if (ex_int64_status(exoid) & EX_BULK_INT64_API) {
56     *(int64_t *)num_int_nodes  = 0;
57     *(int64_t *)num_bor_nodes  = 0;
58     *(int64_t *)num_ext_nodes  = 0;
59     *(int64_t *)num_int_elems  = 0;
60     *(int64_t *)num_bor_elems  = 0;
61     *(int64_t *)num_node_cmaps = 0;
62     *(int64_t *)num_elem_cmaps = 0;
63   }
64   else {
65     *(int *)num_int_nodes  = 0;
66     *(int *)num_bor_nodes  = 0;
67     *(int *)num_ext_nodes  = 0;
68     *(int *)num_int_elems  = 0;
69     *(int *)num_bor_elems  = 0;
70     *(int *)num_node_cmaps = 0;
71     *(int *)num_elem_cmaps = 0;
72   }
73 
74   /* Check the file version information */
75   if ((dimid = ne__check_file_version(exoid)) != EX_NOERR) {
76     EX_FUNC_LEAVE(dimid);
77   }
78 
79   /* Get the file type */
80   if (ex__get_file_type(exoid, ftype) != EX_NOERR) {
81     snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: unable to find file type for file ID %d", exoid);
82     ex_err_fn(exoid, __func__, errmsg, EX_LASTERR);
83 
84     EX_FUNC_LEAVE(EX_FATAL);
85   }
86 
87   /* Get the status for this node map */
88   if ((status = nc_inq_varid(exoid, VAR_INT_N_STAT, &varid)) != NC_NOERR) {
89     snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to find variable ID for \"%s\" from file ID %d",
90              VAR_INT_N_STAT, exoid);
91     ex_err_fn(exoid, __func__, errmsg, status);
92 
93     EX_FUNC_LEAVE(EX_FATAL);
94   }
95 
96   if (ftype[0] == 's') {
97     start[0] = processor;
98   }
99   else {
100     start[0] = 0;
101   }
102 
103   if ((status = nc_get_var1_int(exoid, varid, start, &nmstat)) != NC_NOERR) {
104     snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get status for \"%s\" from file ID %d",
105              VAR_INT_N_STAT, exoid);
106     ex_err_fn(exoid, __func__, errmsg, status);
107     EX_FUNC_LEAVE(EX_FATAL);
108   }
109 
110   if (nmstat == 1) {
111     if (ex_get_idx(exoid, VAR_NODE_MAP_INT_IDX, varidx, processor) == -1) {
112       snprintf(errmsg, MAX_ERR_LENGTH,
113                "ERROR: failed to find index variable, \"%s\", in file ID %d", VAR_NODE_MAP_INT_IDX,
114                exoid);
115       ex_err_fn(exoid, __func__, errmsg, status);
116 
117       EX_FUNC_LEAVE(EX_FATAL);
118     }
119 
120     /* check if I need to get the dimension of the internal node map */
121     if (varidx[1] == -1) {
122       /* Get the dimension ID for the number of internal nodes */
123       if ((status = nc_inq_dimid(exoid, DIM_NUM_INT_NODES, &dimid)) != NC_NOERR) {
124         snprintf(errmsg, MAX_ERR_LENGTH,
125                  "ERROR: failed to find dimension ID for \"%s\" in file ID %d", DIM_NUM_INT_NODES,
126                  exoid);
127         ex_err_fn(exoid, __func__, errmsg, status);
128 
129         EX_FUNC_LEAVE(EX_FATAL);
130       }
131 
132       /*
133        * Get the value of the dimension representing the total number of
134        * internal FEM nodes.
135        */
136       if ((status = nc_inq_dimlen(exoid, dimid, &nin)) != NC_NOERR) {
137         snprintf(errmsg, MAX_ERR_LENGTH,
138                  "ERROR: failed to find length of dimension \"%s\" in file ID %d",
139                  DIM_NUM_INT_NODES, exoid);
140         ex_err_fn(exoid, __func__, errmsg, status);
141 
142         EX_FUNC_LEAVE(EX_FATAL);
143       }
144 
145       /* set the end value for the node map */
146       varidx[1] = nin;
147     } /* End "if (varidx[1] = -1)" */
148 
149     /* now get the number of nodes */
150     if (ex_int64_status(exoid) & EX_BULK_INT64_API) {
151       *(int64_t *)num_int_nodes = varidx[1] - varidx[0];
152     }
153     else {
154       *(int *)num_int_nodes = varidx[1] - varidx[0];
155     }
156   }
157 
158   /* Get the status for this node map */
159   if ((status = nc_inq_varid(exoid, VAR_BOR_N_STAT, &varid)) != NC_NOERR) {
160     snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to find variable ID for \"%s\" from file ID %d",
161              VAR_BOR_N_STAT, exoid);
162     ex_err_fn(exoid, __func__, errmsg, status);
163 
164     EX_FUNC_LEAVE(EX_FATAL);
165   }
166 
167   if (ftype[0] == 's') {
168     start[0] = processor;
169   }
170   else {
171     start[0] = 0;
172   }
173 
174   if ((status = nc_get_var1_int(exoid, varid, start, &nmstat)) != NC_NOERR) {
175     snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get status for \"%s\" from file ID %d",
176              VAR_BOR_N_STAT, exoid);
177     ex_err_fn(exoid, __func__, errmsg, status);
178     EX_FUNC_LEAVE(EX_FATAL);
179   }
180 
181   if (nmstat == 1) {
182     if (ex_get_idx(exoid, VAR_NODE_MAP_BOR_IDX, varidx, processor) == -1) {
183       snprintf(errmsg, MAX_ERR_LENGTH,
184                "ERROR: failed to find index variable, \"%s\", in file ID %d", VAR_NODE_MAP_BOR_IDX,
185                exoid);
186       ex_err_fn(exoid, __func__, errmsg, status);
187 
188       EX_FUNC_LEAVE(EX_FATAL);
189     }
190 
191     /* check if I need to get the dimension of the border node map */
192     if (varidx[1] == -1) {
193       /* Get the dimension ID for the number of border nodes */
194       if ((status = nc_inq_dimid(exoid, DIM_NUM_BOR_NODES, &dimid)) != NC_NOERR) {
195         snprintf(errmsg, MAX_ERR_LENGTH,
196                  "ERROR: failed to find dimension ID for \"%s\" in file ID %d", DIM_NUM_BOR_NODES,
197                  exoid);
198         ex_err_fn(exoid, __func__, errmsg, status);
199 
200         EX_FUNC_LEAVE(EX_FATAL);
201       }
202 
203       /*
204        * Get the value of the dimension representing the number of border
205        * FEM nodes.
206        */
207       if ((status = nc_inq_dimlen(exoid, dimid, &nbn)) != NC_NOERR) {
208         snprintf(errmsg, MAX_ERR_LENGTH,
209                  "ERROR: failed to find length of dimension \"%s\" in file ID %d",
210                  DIM_NUM_BOR_NODES, exoid);
211         ex_err_fn(exoid, __func__, errmsg, status);
212 
213         EX_FUNC_LEAVE(EX_FATAL);
214       }
215 
216       /* set the end value for the node map */
217       varidx[1] = nbn;
218     } /* End "if (varidx[1] == -1)" */
219 
220     /* now calculate the number of nodes */
221     if (ex_int64_status(exoid) & EX_BULK_INT64_API) {
222       *(int64_t *)num_bor_nodes = varidx[1] - varidx[0];
223     }
224     else {
225       *(int *)num_bor_nodes = varidx[1] - varidx[0];
226     }
227   }
228 
229   /* Get the status for this node map */
230   if ((status = nc_inq_varid(exoid, VAR_EXT_N_STAT, &varid)) != NC_NOERR) {
231     snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to find variable ID for \"%s\" from file ID %d",
232              VAR_EXT_N_STAT, exoid);
233     ex_err_fn(exoid, __func__, errmsg, status);
234 
235     EX_FUNC_LEAVE(EX_FATAL);
236   }
237 
238   if (ftype[0] == 's') {
239     start[0] = processor;
240   }
241   else {
242     start[0] = 0;
243   }
244 
245   if ((status = nc_get_var1_int(exoid, varid, start, &nmstat)) != NC_NOERR) {
246     snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get status for \"%s\" from file ID %d",
247              VAR_EXT_N_STAT, exoid);
248     ex_err_fn(exoid, __func__, errmsg, status);
249     EX_FUNC_LEAVE(EX_FATAL);
250   }
251 
252   if (nmstat == 1) {
253     if (ex_get_idx(exoid, VAR_NODE_MAP_EXT_IDX, varidx, processor) == -1) {
254       snprintf(errmsg, MAX_ERR_LENGTH,
255                "ERROR: failed to find index variable, \"%s\", in file ID %d", VAR_NODE_MAP_EXT_IDX,
256                exoid);
257       ex_err_fn(exoid, __func__, errmsg, status);
258 
259       EX_FUNC_LEAVE(EX_FATAL);
260     }
261 
262     /* check if I need to get the dimension of the external node map */
263     if (varidx[1] == -1) {
264       /* Get the dimension ID for the number of external nodes */
265       if ((status = nc_inq_dimid(exoid, DIM_NUM_EXT_NODES, &dimid)) != NC_NOERR) {
266         snprintf(errmsg, MAX_ERR_LENGTH,
267                  "ERROR: failed to find dimension ID for \"%s\" in file ID %d", DIM_NUM_EXT_NODES,
268                  exoid);
269         ex_err_fn(exoid, __func__, errmsg, status);
270 
271         EX_FUNC_LEAVE(EX_FATAL);
272       }
273 
274       /*
275        * Get the value of the dimension representing the number of external
276        * FEM nodes.
277        */
278       if ((status = nc_inq_dimlen(exoid, dimid, &nen)) != NC_NOERR) {
279         snprintf(errmsg, MAX_ERR_LENGTH,
280                  "ERROR: failed to find length of dimension \"%s\" in file ID %d",
281                  DIM_NUM_EXT_NODES, exoid);
282         ex_err_fn(exoid, __func__, errmsg, status);
283 
284         EX_FUNC_LEAVE(EX_FATAL);
285       }
286       /* set the end value for the node map */
287       varidx[1] = nen;
288     } /* End "if (varidx[1] == -1)" */
289 
290     /* now get the number of nodes */
291     if (ex_int64_status(exoid) & EX_BULK_INT64_API) {
292       *(int64_t *)num_ext_nodes = varidx[1] - varidx[0];
293     }
294     else {
295       *(int *)num_ext_nodes = varidx[1] - varidx[0];
296     }
297   }
298 
299   /* Get the status for this element map */
300   if ((status = nc_inq_varid(exoid, VAR_INT_E_STAT, &varid)) != NC_NOERR) {
301     snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to find variable ID for \"%s\" from file ID %d",
302              VAR_INT_E_STAT, exoid);
303     ex_err_fn(exoid, __func__, errmsg, status);
304     EX_FUNC_LEAVE(EX_FATAL);
305   }
306 
307   if (ftype[0] == 's') {
308     start[0] = processor;
309   }
310   else {
311     start[0] = 0;
312   }
313 
314   if ((status = nc_get_var1_int(exoid, varid, start, &nmstat)) != NC_NOERR) {
315     snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get status for \"%s\" from file ID %d",
316              VAR_INT_E_STAT, exoid);
317     ex_err_fn(exoid, __func__, errmsg, status);
318     EX_FUNC_LEAVE(EX_FATAL);
319   }
320 
321   if (nmstat == 1) {
322     if (ex_get_idx(exoid, VAR_ELEM_MAP_INT_IDX, varidx, processor) == -1) {
323       snprintf(errmsg, MAX_ERR_LENGTH,
324                "ERROR: failed to find index variable, \"%s\", in file ID %d", VAR_ELEM_MAP_INT_IDX,
325                exoid);
326       ex_err_fn(exoid, __func__, errmsg, status);
327 
328       EX_FUNC_LEAVE(EX_FATAL);
329     }
330 
331     /* check if I need to get the dimension of the internal element map */
332     if (varidx[1] == -1) {
333       /* Get the dimension ID for the number of internal elements */
334       if ((status = nc_inq_dimid(exoid, DIM_NUM_INT_ELEMS, &dimid)) != NC_NOERR) {
335         snprintf(errmsg, MAX_ERR_LENGTH,
336                  "ERROR: failed to find dimension ID for \"%s\" from file ID %d", DIM_NUM_INT_ELEMS,
337                  exoid);
338         ex_err_fn(exoid, __func__, errmsg, status);
339 
340         EX_FUNC_LEAVE(EX_FATAL);
341       }
342 
343       /*
344        * Get the value of the dimension representing the number of internal
345        * FEM elements.
346        */
347       if ((status = nc_inq_dimlen(exoid, dimid, &nie)) != NC_NOERR) {
348         snprintf(errmsg, MAX_ERR_LENGTH,
349                  "ERROR: failed to find length of dimension \"%s\" in file ID %d",
350                  DIM_NUM_INT_ELEMS, exoid);
351         ex_err_fn(exoid, __func__, errmsg, status);
352         EX_FUNC_LEAVE(EX_FATAL);
353       }
354 
355       /* set the end value for the node map */
356       varidx[1] = nie;
357     } /* End "if (varidx[1] == -1)" */
358 
359     /* now get the number of elements */
360     if (ex_int64_status(exoid) & EX_BULK_INT64_API) {
361       *(int64_t *)num_int_elems = varidx[1] - varidx[0];
362     }
363     else {
364       *(int *)num_int_elems = varidx[1] - varidx[0];
365     }
366   }
367 
368   /* Get the status for this element map */
369   if ((status = nc_inq_varid(exoid, VAR_BOR_E_STAT, &varid)) != NC_NOERR) {
370     snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to find variable ID for \"%s\" from file ID %d",
371              VAR_BOR_E_STAT, exoid);
372     ex_err_fn(exoid, __func__, errmsg, status);
373     EX_FUNC_LEAVE(EX_FATAL);
374   }
375 
376   if (ftype[0] == 's') {
377     start[0] = processor;
378   }
379   else {
380     start[0] = 0;
381   }
382 
383   if ((status = nc_get_var1_int(exoid, varid, start, &nmstat)) != NC_NOERR) {
384     snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get status for \"%s\" from file ID %d",
385              VAR_BOR_E_STAT, exoid);
386     ex_err_fn(exoid, __func__, errmsg, status);
387     EX_FUNC_LEAVE(EX_FATAL);
388   }
389 
390   if (nmstat == 1) {
391     if (ex_get_idx(exoid, VAR_ELEM_MAP_BOR_IDX, varidx, processor) == -1) {
392       snprintf(errmsg, MAX_ERR_LENGTH,
393                "ERROR: failed to find index variable, \"%s\", in file ID %d", VAR_ELEM_MAP_BOR_IDX,
394                exoid);
395       ex_err_fn(exoid, __func__, errmsg, status);
396 
397       EX_FUNC_LEAVE(EX_FATAL);
398     }
399 
400     /* check if I need to get the dimension of the border element map */
401     if (varidx[1] == -1) {
402       /* Get the dimension ID for the number of border elements */
403       if ((status = nc_inq_dimid(exoid, DIM_NUM_BOR_ELEMS, &dimid)) != NC_NOERR) {
404         snprintf(errmsg, MAX_ERR_LENGTH,
405                  "ERROR: failed to find dimension ID for \"%s\" from file ID %d", DIM_NUM_BOR_ELEMS,
406                  exoid);
407         ex_err_fn(exoid, __func__, errmsg, status);
408 
409         EX_FUNC_LEAVE(EX_FATAL);
410       }
411 
412       /*
413        * Get the value of the dimension representing the number of border
414        * FEM elements.
415        */
416       if ((status = nc_inq_dimlen(exoid, dimid, &nbe)) != NC_NOERR) {
417         snprintf(errmsg, MAX_ERR_LENGTH,
418                  "ERROR: failed to find length of dimension \"%s\" in file ID %d",
419                  DIM_NUM_BOR_ELEMS, exoid);
420         ex_err_fn(exoid, __func__, errmsg, status);
421         EX_FUNC_LEAVE(EX_FATAL);
422       }
423 
424       /* set the end value for the node map */
425       varidx[1] = nbe;
426     } /* End "if (varidx[1] == -1)" */
427 
428     /* now get the number of nodes */
429     if (ex_int64_status(exoid) & EX_BULK_INT64_API) {
430       *(int64_t *)num_bor_elems = varidx[1] - varidx[0];
431     }
432     else {
433       *(int *)num_bor_elems = varidx[1] - varidx[0];
434     }
435   } /* End "if (nmstat == 1)" */
436 
437   if (ex_get_idx(exoid, VAR_N_COMM_INFO_IDX, varidx, processor) == -1) {
438     snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to find index variable, \"%s\", in file ID %d",
439              VAR_N_COMM_INFO_IDX, exoid);
440     ex_err_fn(exoid, __func__, errmsg, status);
441 
442     EX_FUNC_LEAVE(EX_FATAL);
443   }
444 
445   /* check if I need to get the dimension of the nodal comm map */
446   if (varidx[1] == -1) {
447     /* Get the nodal comm map information */
448     if ((status = nc_inq_dimid(exoid, DIM_NUM_N_CMAPS, &dimid)) != NC_NOERR) {
449       varidx[1] = 0;
450     }
451     else {
452       if ((status = nc_inq_dimlen(exoid, dimid, &nncm)) != NC_NOERR) {
453         snprintf(errmsg, MAX_ERR_LENGTH,
454                  "ERROR: failed to find length of dimension \"%s\" in file ID %d", DIM_NUM_N_CMAPS,
455                  exoid);
456         ex_err_fn(exoid, __func__, errmsg, status);
457         EX_FUNC_LEAVE(EX_FATAL);
458       }
459       /* set the end value for the node map */
460       varidx[1] = nncm;
461     }
462   } /* End "if (varidx[1] == -1)" */
463 
464   if (ex_int64_status(exoid) & EX_BULK_INT64_API) {
465     *(int64_t *)num_node_cmaps = varidx[1] - varidx[0];
466   }
467   else {
468     *(int *)num_node_cmaps = varidx[1] - varidx[0];
469   }
470 
471   if (ex_get_idx(exoid, VAR_E_COMM_INFO_IDX, varidx, processor) == -1) {
472     snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to find index variable, \"%s\", in file ID %d",
473              VAR_E_COMM_INFO_IDX, exoid);
474     ex_err_fn(exoid, __func__, errmsg, status);
475 
476     EX_FUNC_LEAVE(EX_FATAL);
477   }
478 
479   /* check if I need to get the dimension of the elemental comm map */
480   if (varidx[1] == -1) {
481     /* Get the elemental comm map information */
482     if ((status = nc_inq_dimid(exoid, DIM_NUM_E_CMAPS, &dimid)) != NC_NOERR) {
483       varidx[1] = 0;
484     }
485     else {
486       if ((status = nc_inq_dimlen(exoid, dimid, &necm)) != NC_NOERR) {
487         snprintf(errmsg, MAX_ERR_LENGTH,
488                  "ERROR: failed to find length of dimension \"%s\" in file ID %d", DIM_NUM_E_CMAPS,
489                  exoid);
490         ex_err_fn(exoid, __func__, errmsg, status);
491         EX_FUNC_LEAVE(EX_FATAL);
492       }
493 
494       /* set the end value for the node map */
495       varidx[1] = necm;
496     }
497   } /* End "if (varidx[1] == -1)" */
498 
499   if (ex_int64_status(exoid) & EX_BULK_INT64_API) {
500     *(int64_t *)num_elem_cmaps = varidx[1] - varidx[0];
501   }
502   else {
503     *(int *)num_elem_cmaps = varidx[1] - varidx[0];
504   }
505 
506   EX_FUNC_LEAVE(EX_NOERR);
507 }
508