1 /*
2  * Copyright (c) 2005-2017 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  * 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 NTESS 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  * exgotv - ex_get_object_truth_vector
38  *
39  * revision history -
40  *
41  *
42  *****************************************************************************/
43 
44 #include "exodusII.h"     // for ex_err, etc
45 #include "exodusII_int.h" // for ex_get_dimension, EX_FATAL, etc
46 #include "vtk_netcdf.h"       // for nc_inq_varid, NC_NOERR, etc
47 #include <inttypes.h>     // for PRId64
48 #include <stddef.h>       // for size_t
49 #include <stdio.h>
50 #include <stdlib.h> // for NULL
51 
52 /*!
53  * reads the EXODUS specified variable truth vector from the database
54  */
55 
ex_get_object_truth_vector(int exoid,ex_entity_type obj_type,ex_entity_id entity_id,int num_var,int * var_vec)56 int ex_get_object_truth_vector(int exoid, ex_entity_type obj_type, ex_entity_id entity_id,
57                                int num_var, int *var_vec)
58 {
59   int    statust;
60   int    varid, tabid, i, status, ent_ndx;
61   size_t num_var_db = 0;
62   size_t start[2], count[2];
63   char   errmsg[MAX_ERR_LENGTH];
64 
65   /*
66    * The ent_type and the var_name are used to build the netcdf
67    * variables name.  Normally this is done via a macro defined in
68    * exodusII_int.h
69    */
70   const char *ent_type = NULL;
71   const char *var_name = NULL;
72 
73   EX_FUNC_ENTER();
74   ex_check_valid_file_id(exoid, __func__);
75 
76   switch (obj_type) {
77   case EX_EDGE_BLOCK:
78     status =
79         ex_get_dimension(exoid, DIM_NUM_EDG_VAR, "edge variables", &num_var_db, &varid, __func__);
80     statust  = nc_inq_varid(exoid, VAR_EBLK_TAB, &tabid);
81     var_name = "vals_edge_var";
82     ent_type = "eb";
83     break;
84   case EX_FACE_BLOCK:
85     status =
86         ex_get_dimension(exoid, DIM_NUM_FAC_VAR, "face variables", &num_var_db, &varid, __func__);
87     statust  = nc_inq_varid(exoid, VAR_FBLK_TAB, &tabid);
88     var_name = "vals_face_var";
89     ent_type = "fb";
90     break;
91   case EX_ELEM_BLOCK:
92     status   = ex_get_dimension(exoid, DIM_NUM_ELE_VAR, "element variables", &num_var_db, &varid,
93                               __func__);
94     statust  = nc_inq_varid(exoid, VAR_ELEM_TAB, &tabid);
95     var_name = "vals_elem_var";
96     ent_type = "eb";
97     break;
98   case EX_NODE_SET:
99     status   = ex_get_dimension(exoid, DIM_NUM_NSET_VAR, "nodeset variables", &num_var_db, &varid,
100                               __func__);
101     statust  = nc_inq_varid(exoid, VAR_NSET_TAB, &tabid);
102     var_name = "vals_nset_var";
103     ent_type = "ns";
104     break;
105   case EX_EDGE_SET:
106     status   = ex_get_dimension(exoid, DIM_NUM_ESET_VAR, "edgeset variables", &num_var_db, &varid,
107                               __func__);
108     statust  = nc_inq_varid(exoid, VAR_ESET_TAB, &tabid);
109     var_name = "vals_eset_var";
110     ent_type = "es";
111     break;
112   case EX_FACE_SET:
113     status   = ex_get_dimension(exoid, DIM_NUM_FSET_VAR, "faceset variables", &num_var_db, &varid,
114                               __func__);
115     statust  = nc_inq_varid(exoid, VAR_FSET_TAB, &tabid);
116     var_name = "vals_fset_var";
117     ent_type = "fs";
118     break;
119   case EX_SIDE_SET:
120     status   = ex_get_dimension(exoid, DIM_NUM_SSET_VAR, "sideset variables", &num_var_db, &varid,
121                               __func__);
122     statust  = nc_inq_varid(exoid, VAR_SSET_TAB, &tabid);
123     var_name = "vals_sset_var";
124     ent_type = "ss";
125     break;
126   case EX_ELEM_SET:
127     status   = ex_get_dimension(exoid, DIM_NUM_ELSET_VAR, "elemset variables", &num_var_db, &varid,
128                               __func__);
129     statust  = nc_inq_varid(exoid, VAR_ELSET_TAB, &tabid);
130     var_name = "vals_elset_var";
131     ent_type = "es";
132     break;
133   default:
134     snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: Invalid variable type %d specified in file id %d",
135              obj_type, exoid);
136     ex_err(__func__, errmsg, EX_BADPARAM);
137     EX_FUNC_LEAVE(EX_WARN);
138   }
139 
140   if (status != NC_NOERR) {
141     EX_FUNC_LEAVE(EX_WARN);
142   }
143 
144   /* Determine index of entity_id in id array */
145   ent_ndx = ex_id_lkup(exoid, obj_type, entity_id);
146   if (ent_ndx <= 0) {
147     ex_get_err(NULL, NULL, &status);
148     if (status != 0) {
149       if (status != EX_NULLENTITY) {
150         snprintf(errmsg, MAX_ERR_LENGTH,
151                  "ERROR: failed to locate %s id %" PRId64 " in id variable in file id %d",
152                  ex_name_of_object(obj_type), entity_id, exoid);
153         ex_err(__func__, errmsg, status);
154         EX_FUNC_LEAVE(EX_FATAL);
155       }
156     }
157   }
158   /* If this is a null entity, then 'ent_ndx' will be negative.
159    * We don't care in this __func__, so make it positive and continue...
160    */
161   if (ent_ndx < 0) {
162     ent_ndx = -ent_ndx;
163   }
164 
165   if ((int)num_var_db != num_var) {
166     snprintf(errmsg, MAX_ERR_LENGTH,
167              "ERROR: # of variables doesn't match those defined in file id %d", exoid);
168     ex_err(__func__, errmsg, EX_BADPARAM);
169     EX_FUNC_LEAVE(EX_FATAL);
170   }
171 
172   if (statust != NC_NOERR) {
173     /* since truth vector isn't stored in the data file, derive it dynamically
174      */
175     for (i = 0; i < num_var; i++) {
176       /* NOTE: names are 1-based */
177       if (nc_inq_varid(exoid, ex_catstr2(var_name, i + 1, ent_type, ent_ndx), &tabid) != NC_NOERR) {
178         /* variable doesn't exist; put a 0 in the truth vector */
179         var_vec[i] = 0;
180       }
181       else {
182         /* variable exists; put a 1 in the truth vector */
183         var_vec[i] = 1;
184       }
185     }
186   }
187   else {
188 
189     /* read in the truth vector */
190 
191     start[0] = ent_ndx - 1;
192     start[1] = 0;
193 
194     count[0] = 1;
195     count[1] = num_var;
196 
197     status = nc_get_vara_int(exoid, tabid, start, count, var_vec);
198 
199     if (status != NC_NOERR) {
200       snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get truth vector from file id %d", exoid);
201       ex_err(__func__, errmsg, status);
202       EX_FUNC_LEAVE(EX_FATAL);
203     }
204   }
205   EX_FUNC_LEAVE(EX_NOERR);
206 }
207