1 /*
2  * Copyright (c) 1998 Sandia Corporation. Under the terms of Contract
3  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Governement
4  * retains certain rights in this software.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are
8  * met:
9  *
10  *     * Redistributions of source code must retain the above copyright
11  *       notice, this list of conditions and the following disclaimer.
12  *
13  *     * Redistributions in binary form must reproduce the above
14  *       copyright notice, this list of conditions and the following
15  *       disclaimer in the documentation and/or other materials provided
16  *       with the distribution.
17  *
18  *     * Neither the name of Sandia Corporation nor the names of its
19  *       contributors may be used to endorse or promote products derived
20  *       from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34  */
35 /*****************************************************************************/
36 /*****************************************************************************/
37 /*****************************************************************************/
38 /* Function(s) contained in this file:
39  *     ne_get_cmap_params()
40  *****************************************************************************
41  * This function outputs the communication map parameters.
42  *****************************************************************************
43  *  Variable Index:
44  *      neid                - The NetCDF ID of an already open NemesisI file.
45  *      node_cmap_ids       - Pointer to vector of nodal communication
46  *                            set IDs.
47  *      node_cmap_node_cnts - Pointer to a vector which contains a count of
48  *                            the number of FEM nodes for each nodal
49  *                            communication map.
50  *      elem_cmap_ids       - Pointer to vector for retrieval of elemental
51  *                            communication set IDs.
52  *      elem_cmap_elem_cnts - Pointer to a vector which contains a count of
53  *                            the number of FEM elements for each elemental
54  *                            communication map.
55  *      processor           - The processor the file being read was written
56  *                            for.
57  */
58 /*****************************************************************************/
59 /*****************************************************************************/
60 /*****************************************************************************/
61 
62 #include <stdio.h>
63 #include <stdlib.h>
64 
65 #include "netcdf.h"
66 
67 #include "exodusII.h"
68 #include "exodusII_int.h"
69 
70 #include "ne_nemesisI_int.h"
71 #include "ne_nemesisI.h"
72 
ne_get_cmap_params(int neid,int * node_cmap_ids,int * node_cmap_node_cnts,int * elem_cmap_ids,int * elem_cmap_elem_cnts,int processor)73 int ne_get_cmap_params(int  neid,
74                        int *node_cmap_ids,
75                        int *node_cmap_node_cnts,
76                        int *elem_cmap_ids,
77                        int *elem_cmap_elem_cnts,
78                        int  processor
79 		       )
80 {
81   char   *func_name="ne_get_cmap_params";
82 
83   size_t  cnt, num_n_comm_maps, num_e_comm_maps, start[1], count[1];
84   size_t  cmap_info_idx[2], cmap_data_idx[2];
85   int     nmstat;
86   int     status, map_idx, varid, dimid;
87 
88   char    errmsg[MAX_ERR_LENGTH];
89   /*-----------------------------Execution begins-----------------------------*/
90 
91   exerrval = 0;	/* clear error code */
92 
93   /*****************************************************************************/
94   /*****************************************************************************/
95   /*                    Nodal communication map(s)                             */
96   /*****************************************************************************/
97   /*****************************************************************************/
98 
99   /* get the cmap information variables index */
100   if (ne_get_idx(neid, VAR_N_COMM_INFO_IDX, cmap_info_idx, processor) == -1) {
101     sprintf(errmsg,
102             "Error: failed to find index variable, \"%s\", in file ID %d",
103             VAR_N_COMM_INFO_IDX, neid);
104     ex_err(func_name, errmsg, exerrval);
105 
106     return (EX_FATAL);
107   }
108 
109   /* Get the number of nodal communications maps in the file */
110   if ((status = nc_inq_dimid(neid, DIM_NUM_N_CMAPS, &dimid)) == NC_NOERR) {
111     /* check if I need to get the dimension of the nodal comm map */
112     if (cmap_info_idx[1] == -1) {
113       if ((status = nc_inq_dimlen(neid, dimid, count)) != NC_NOERR) {
114         exerrval = status;
115         sprintf(errmsg,
116 		"Error: failed to find length of dimension \"%s\" in file ID %d",
117                 DIM_NUM_N_CMAPS, neid);
118         ex_err(func_name, errmsg, exerrval);
119         return (EX_FATAL);
120       }
121 
122       /* set the end value for the node map */
123       cmap_info_idx[1] = count[0];
124     }  /* End "if (cmap_info_idx[1] == -1) */
125 
126     num_n_comm_maps = cmap_info_idx[1] - cmap_info_idx[0];
127 
128     if (num_n_comm_maps > 0) {
129       count[0] = num_n_comm_maps;
130 
131       /* Get the variable ID for the vector of nodal comm map IDs */
132       if ((status = nc_inq_varid(neid, VAR_N_COMM_IDS, &varid)) != NC_NOERR) {
133         exerrval = status;
134         sprintf(errmsg,
135                 "Error: failed to get variable ID for \"%s\" in file ID %d",
136                 VAR_N_COMM_IDS, neid);
137         ex_err(func_name, errmsg, exerrval);
138         return (EX_FATAL);
139       }
140 
141       /* Get the vector of nodal communication map IDs */
142       if (node_cmap_ids != NULL) {
143         start[0] = cmap_info_idx[0];
144 	status = nc_get_vara_int(neid, varid, start, count, node_cmap_ids);
145 
146         if (status != NC_NOERR) {
147           exerrval = status;
148           sprintf(errmsg,
149                   "Error: failed to get variable \"%s\" from file ID %d",
150                   VAR_N_COMM_IDS, neid);
151           ex_err(func_name, errmsg, exerrval);
152           return (EX_FATAL);
153         }
154 
155         if ((status = nc_inq_varid(neid, VAR_N_COMM_STAT, &varid)) != NC_NOERR) {
156           exerrval = status;
157           sprintf(errmsg,
158 		  "Error: failed to find variable ID for \"%s\" from file ID %d",
159                   VAR_N_COMM_STAT, neid);
160           ex_err(func_name, errmsg, exerrval);
161           return (EX_FATAL);
162         }
163 
164         if (node_cmap_node_cnts != NULL) {
165 
166           /* Get the node counts in each of the nodal communication maps */
167           for(cnt=0; cnt < num_n_comm_maps; cnt++) {
168 
169             if ((map_idx=ne_id_lkup(neid, VAR_N_COMM_IDS, cmap_info_idx,
170 				    node_cmap_ids[cnt])) < 0) {
171               exerrval = EX_MSG;
172               sprintf(errmsg,
173 		      "Error: failed to find nodal comm map with ID %d in file ID %d",
174                       node_cmap_ids[cnt], neid);
175               ex_err(func_name, errmsg, exerrval);
176               return (EX_FATAL);
177             }
178 
179             /* Check the status of the node map */
180             start[0] = map_idx;
181             if ((status = nc_get_var1_int(neid, varid, start, &nmstat)) != NC_NOERR) {
182               exerrval = status;
183               sprintf(errmsg,
184 		      "Error: failed to get status for \"%s\" from file ID %d",
185                       VAR_N_COMM_STAT, neid);
186               ex_err(func_name, errmsg, exerrval);
187               return (EX_FATAL);
188             }
189 
190             if (nmstat == 1) {
191 
192               /* get the cmap information variables index */
193               if (ne_get_idx(neid, VAR_N_COMM_DATA_IDX, cmap_data_idx,
194                              map_idx) == -1) {
195                 exerrval = status;
196                 sprintf(errmsg,
197 			"Error: failed to find index variable, \"%s\", in file ID %d",
198                         VAR_N_COMM_DATA_IDX, neid);
199                 ex_err(func_name, errmsg, exerrval);
200 
201                 return (EX_FATAL);
202               }
203 
204               if (cmap_data_idx[1] == -1) {
205                 /*
206                  * Find the dimension ID of the variable containing the
207                  * node count
208                  */
209                 if ((status = nc_inq_dimid(neid, DIM_NCNT_CMAP, &dimid)) != NC_NOERR) {
210                   exerrval = status;
211                   sprintf(errmsg,
212 			  "Error: failed to find dimension ID for \"%s\" in file ID %d",
213                           DIM_NCNT_CMAP, neid);
214                   ex_err(func_name, errmsg, exerrval);
215                   return (EX_FATAL);
216                 }
217 
218 		/* Find the value of the number of nodes in this nodal comm map */
219                 if ((status = nc_inq_dimlen(neid, dimid, count)) != NC_NOERR) {
220                   exerrval = status;
221                   sprintf(errmsg,
222 			  "Error: failed to find length of dimension \"%s\" in file ID %d",
223                           DIM_NCNT_CMAP, neid);
224                   ex_err(func_name, errmsg, exerrval);
225                   return (EX_FATAL);
226                 }
227 
228                 cmap_data_idx[1] = count[0];
229               }
230 
231               node_cmap_node_cnts[cnt] = cmap_data_idx[1] - cmap_data_idx[0];
232             }
233             else
234               node_cmap_node_cnts[cnt] = 0;
235           }  /* "for(cnt=0; cnt < num_n_comm_maps; cnt++)" */
236         }  /* "if (node_cmap_node_cnts != NULL)" */
237       }  /* "if (node_cmap_ids != NULL)" */
238     }  /* "if (num_n_comm_maps > 0)" */
239   } /* End "if ((dimid = nc_inq_dimid(neid, DIM_NUM_N_CMAPS)) != -1)" */
240 
241   /*****************************************************************************/
242   /*****************************************************************************/
243   /*                Elemental communication map(s)                             */
244   /*****************************************************************************/
245   /*****************************************************************************/
246 
247   /* get the cmap information variables index */
248   if (ne_get_idx(neid, VAR_E_COMM_INFO_IDX, cmap_info_idx, processor) == -1) {
249     exerrval = status;
250     sprintf(errmsg,
251             "Error: failed to find index variable, \"%s\", in file ID %d",
252             VAR_E_COMM_INFO_IDX, neid);
253     ex_err(func_name, errmsg, exerrval);
254 
255     return (EX_FATAL);
256   }
257 
258   /* Get the number of elemental communications maps in the file */
259   if ((status = nc_inq_dimid(neid, DIM_NUM_E_CMAPS, &dimid)) == NC_NOERR) {
260     /* check if I need to get the dimension of the nodal comm map */
261     if (cmap_info_idx[1] == -1) {
262       if ((status = nc_inq_dimlen(neid, dimid, count)) != NC_NOERR) {
263         exerrval = status;
264         sprintf(errmsg,
265 		"Error: failed to find length of dimension \"%s\" in file ID %d",
266                 DIM_NUM_E_CMAPS, neid);
267         ex_err(func_name, errmsg, exerrval);
268         return (EX_FATAL);
269       }
270 
271       /* set the end value for the node map */
272       cmap_info_idx[1] = count[0];
273     }  /* End "if (cmap_info_idx[1] == -1) */
274 
275     num_e_comm_maps = cmap_info_idx[1] - cmap_info_idx[0];
276 
277     if (num_e_comm_maps > 0) {
278       count[0] = num_e_comm_maps;
279 
280       /* Get the variable ID for the vector of nodal comm map IDs */
281       if ((status = nc_inq_varid(neid, VAR_E_COMM_IDS, &varid)) != NC_NOERR) {
282         exerrval = status;
283         sprintf(errmsg,
284                 "Error: failed to get variable ID for \"%s\" in file ID %d",
285                 VAR_E_COMM_IDS, neid);
286         ex_err(func_name, errmsg, exerrval);
287         return (EX_FATAL);
288       }
289 
290       /* Get the vector of elemental communication map IDs */
291       if (elem_cmap_ids != NULL) {
292         start[0] = cmap_info_idx[0];
293 	status = nc_get_vara_int(neid, varid, start, count, elem_cmap_ids);
294         if (status != NC_NOERR) {
295           exerrval = status;
296           sprintf(errmsg,
297                   "Error: failed to get variable \"%s\" from file ID %d",
298                   VAR_E_COMM_IDS, neid);
299           ex_err(func_name, errmsg, exerrval);
300           return (EX_FATAL);
301         }
302 
303         if ((status = nc_inq_varid(neid, VAR_E_COMM_STAT, &varid)) != NC_NOERR) {
304           exerrval = status;
305           sprintf(errmsg,
306 		  "Error: failed to find variable ID for \"%s\" from file ID %d",
307                   VAR_E_COMM_STAT, neid);
308           ex_err(func_name, errmsg, exerrval);
309           return (EX_FATAL);
310         }
311 
312         if (elem_cmap_elem_cnts != NULL) {
313           /*
314            * Get the element counts in each of the elemental
315            * communication maps
316            */
317           for(cnt=0; cnt < num_e_comm_maps; cnt++) {
318 
319             if ((map_idx=ne_id_lkup(neid, VAR_E_COMM_IDS, cmap_info_idx,
320 				    elem_cmap_ids[cnt])) < 0) {
321               exerrval = EX_MSG;
322               sprintf(errmsg,
323 		      "Error: failed to find elemental comm map with ID %d in file ID %d",
324                       elem_cmap_ids[cnt], neid);
325               ex_err(func_name, errmsg, exerrval);
326               return (EX_FATAL);
327             }
328 
329             /* Check the status of the requested elemental map */
330             start[0] = map_idx;
331             if ((status = nc_get_var1_int(neid, varid, start, &nmstat)) != NC_NOERR) {
332               exerrval = status;
333               sprintf(errmsg,
334                       "Error: failed to get status for \"%s\" from file ID %d",
335                       VAR_E_COMM_STAT, neid);
336               ex_err(func_name, errmsg, exerrval);
337               return (EX_FATAL);
338             }
339 
340             if (nmstat == 1) {
341 
342               /* get the cmap information variables index */
343               if (ne_get_idx(neid, VAR_E_COMM_DATA_IDX, cmap_data_idx,
344                              map_idx) == -1) {
345                 exerrval = status;
346                 sprintf(errmsg,
347 			"Error: failed to find index variable, \"%s\", in file ID %d",
348 			VAR_E_COMM_DATA_IDX, neid);
349                 ex_err(func_name, errmsg, exerrval);
350 
351                 return (EX_FATAL);
352               }
353 
354               if (cmap_data_idx[1] == -1) {
355                 /*
356                  * Find the dimension ID of the variable containing the
357                  * element count
358                  */
359                 if ((status = nc_inq_dimid(neid, DIM_ECNT_CMAP, &dimid)) != NC_NOERR) {
360                   exerrval = status;
361                   sprintf(errmsg,
362 			  "Error: failed to find dimension ID for \"%s\" in file ID %d",
363                           DIM_ECNT_CMAP, neid);
364                   ex_err(func_name, errmsg, exerrval);
365                   return (EX_FATAL);
366                 }
367 
368                 /*
369                  * Find the value of the number of elements in this elemental
370                  * comm map
371                  */
372                 if ((status = nc_inq_dimlen(neid, dimid, count)) != NC_NOERR) {
373                   exerrval = status;
374                   sprintf(errmsg,
375 			  "Error: failed to find length of dimension \"%s\" in file ID %d",
376                           DIM_ECNT_CMAP, neid);
377                   ex_err(func_name, errmsg, exerrval);
378                   return (EX_FATAL);
379                 }
380                 cmap_data_idx[1] = count[0];
381               }
382               elem_cmap_elem_cnts[cnt] = cmap_data_idx[1] - cmap_data_idx[0];
383             }
384             else
385               elem_cmap_elem_cnts[cnt] = 0;
386           }  /* "for(cnt=0; cnt < num_e_comm_maps; cnt++)" */
387         }  /* "if (elem_cmap_elem_cnts != NULL)" */
388       }  /* "if (elem_cmap_ids != NULL)" */
389     }  /* "if (num_e_comm_maps > 0)" */
390   } /* End "if ((dimid = nc_inq_dimid(neid, DIM_NUM_E_CMAPS(processor))) != -1)" */
391   return (EX_NOERR);
392 }
393