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  * exgvtt - ex_get_truth_table
11  *
12  * entry conditions -
13  *   input parameters:
14  *       int     exoid              exodus file id
15  *       int     num_blk            number of blocks
16  *       int     num_var            number of variables
17  *
18  * exit conditions -
19  *       int*    var_tab            element variable truth table array
20  *
21  *
22  *****************************************************************************/
23 
24 #include "exodusII.h"     // for ex_err, etc
25 #include "exodusII_int.h" // for ex__get_dimension, EX_FATAL, etc
26 
27 /*!
28  * \ingroup ResultsData
29  * reads the EXODUS specified variable truth table from the database
30  * \param[in]       exoid              exodus file id
31  * \param[in]       obj_type           object type
32  * \param[in]       num_blk            number of blocks or sets
33  * \param[in]       num_var            number of variables
34  * \param[out]     *var_tab            variable truth table array
35  */
36 
ex_get_truth_table(int exoid,ex_entity_type obj_type,int num_blk,int num_var,int * var_tab)37 int ex_get_truth_table(int exoid, ex_entity_type obj_type, int num_blk, int num_var, int *var_tab)
38 {
39   int    dimid, varid, tabid, i, j, status, status1;
40   size_t num_entity = 0;
41   size_t num_var_db = 0;
42   char   errmsg[MAX_ERR_LENGTH];
43 
44   /*
45    * The ent_type and the var_name are used to build the netcdf
46    * variables name.  Normally this is done via a macro defined in
47    * exodusII_int.h
48    */
49   const char *ent_type = NULL;
50   const char *var_name = NULL;
51 
52   EX_FUNC_ENTER();
53   if (ex__check_valid_file_id(exoid, __func__) == EX_FATAL) {
54     EX_FUNC_LEAVE(EX_FATAL);
55   }
56 
57   switch (obj_type) {
58   case EX_EDGE_BLOCK:
59     status =
60         ex__get_dimension(exoid, DIM_NUM_EDG_VAR, "edge variables", &num_var_db, &varid, __func__);
61     status1  = nc_inq_varid(exoid, VAR_EBLK_TAB, &tabid);
62     var_name = "vals_edge_var";
63     ent_type = "eb";
64     break;
65   case EX_FACE_BLOCK:
66     status =
67         ex__get_dimension(exoid, DIM_NUM_FAC_VAR, "face variables", &num_var_db, &varid, __func__);
68     status1  = nc_inq_varid(exoid, VAR_FBLK_TAB, &tabid);
69     var_name = "vals_face_var";
70     ent_type = "fb";
71     break;
72   case EX_ELEM_BLOCK:
73     status   = ex__get_dimension(exoid, DIM_NUM_ELE_VAR, "element variables", &num_var_db, &varid,
74                                __func__);
75     status1  = nc_inq_varid(exoid, VAR_ELEM_TAB, &tabid);
76     var_name = "vals_elem_var";
77     ent_type = "eb";
78     break;
79   case EX_NODE_SET:
80     status   = ex__get_dimension(exoid, DIM_NUM_NSET_VAR, "nodeset variables", &num_var_db, &varid,
81                                __func__);
82     status1  = nc_inq_varid(exoid, VAR_NSET_TAB, &tabid);
83     var_name = "vals_nset_var";
84     ent_type = "ns";
85     break;
86   case EX_EDGE_SET:
87     status   = ex__get_dimension(exoid, DIM_NUM_ESET_VAR, "edgeset variables", &num_var_db, &varid,
88                                __func__);
89     status1  = nc_inq_varid(exoid, VAR_ESET_TAB, &tabid);
90     var_name = "vals_eset_var";
91     ent_type = "es";
92     break;
93   case EX_FACE_SET:
94     status   = ex__get_dimension(exoid, DIM_NUM_FSET_VAR, "faceset variables", &num_var_db, &varid,
95                                __func__);
96     status1  = nc_inq_varid(exoid, VAR_FSET_TAB, &tabid);
97     var_name = "vals_fset_var";
98     ent_type = "fs";
99     break;
100   case EX_SIDE_SET:
101     status   = ex__get_dimension(exoid, DIM_NUM_SSET_VAR, "sideset variables", &num_var_db, &varid,
102                                __func__);
103     status1  = nc_inq_varid(exoid, VAR_SSET_TAB, &tabid);
104     var_name = "vals_sset_var";
105     ent_type = "ss";
106     break;
107   case EX_ELEM_SET:
108     status   = ex__get_dimension(exoid, DIM_NUM_ELSET_VAR, "elemset variables", &num_var_db, &varid,
109                                __func__);
110     status1  = nc_inq_varid(exoid, VAR_ELSET_TAB, &tabid);
111     var_name = "vals_elset_var";
112     ent_type = "es";
113     break;
114   case EX_BLOB:
115     status =
116         ex__get_dimension(exoid, DIM_NUM_BLOB_VAR, "blob variables", &num_var_db, &varid, __func__);
117     status1  = nc_inq_varid(exoid, VAR_BLOB_TAB, &tabid);
118     var_name = "vals_blob_var";
119     ent_type = "blob";
120     break;
121   default:
122     snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: Invalid variable type %d specified in file id %d",
123              obj_type, exoid);
124     ex_err_fn(exoid, __func__, errmsg, EX_BADPARAM);
125     EX_FUNC_LEAVE(EX_WARN);
126   }
127 
128   if (status != NC_NOERR) {
129     EX_FUNC_LEAVE(EX_WARN);
130   }
131 
132   if (obj_type == EX_BLOB) {
133     num_entity = ex_inquire_int(exoid, EX_INQ_BLOB);
134   }
135   else {
136     status = ex__get_dimension(exoid, ex__dim_num_objects(obj_type), ex_name_of_object(obj_type),
137                                &num_entity, &dimid, __func__);
138     if (status != NC_NOERR) {
139       EX_FUNC_LEAVE(EX_FATAL);
140     }
141   }
142 
143   if (num_entity != (size_t)num_blk) {
144     snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: # of %s doesn't match those defined in file id %d",
145              ex_name_of_object(obj_type), exoid);
146     ex_err_fn(exoid, __func__, errmsg, EX_BADPARAM);
147     EX_FUNC_LEAVE(EX_FATAL);
148   }
149 
150   if (num_var_db != (size_t)num_var) {
151     snprintf(errmsg, MAX_ERR_LENGTH,
152              "ERROR: # of %s variables doesn't match those defined in file id %d",
153              ex_name_of_object(obj_type), exoid);
154     ex_err_fn(exoid, __func__, errmsg, EX_BADPARAM);
155     EX_FUNC_LEAVE(EX_FATAL);
156   }
157 
158   if (status1 != NC_NOERR) {
159     /* since truth table isn't stored in the data file, derive it dynamically */
160     for (j = 0; j < num_blk; j++) {
161 
162       for (i = 0; i < num_var; i++) {
163         /* NOTE: names are 1-based */
164         if (nc_inq_varid(exoid, ex__catstr2(var_name, i + 1, ent_type, j + 1), &tabid) ==
165             NC_NOERR) {
166           /* variable exists; put a 1 in the truth table */
167           var_tab[j * num_var + i] = 1;
168         }
169         else {
170           /* variable doesn't exist; put a 0 in the truth table */
171           var_tab[j * num_var + i] = 0;
172         }
173       }
174     }
175   }
176   else {
177     /* read in the truth table */
178     status = nc_get_var_int(exoid, tabid, var_tab);
179 
180     if (status != NC_NOERR) {
181       snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get %s truth table from file id %d",
182                ex_name_of_object(obj_type), exoid);
183       ex_err_fn(exoid, __func__, errmsg, status);
184       EX_FUNC_LEAVE(EX_FATAL);
185     }
186   }
187   EX_FUNC_LEAVE(EX_NOERR);
188 }
189