1 /*
2 * Copyright (c) 2006 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 #include "exodusII.h"
37 #include "exodusII_int.h"
38 #include <stdlib.h> /* for free() */
39
40 /*! write out the connectivity array */
41 #define EX_WRITE_CONN(TNAME,VARCONN,VARCONNVAL) \
42 if (ex_int64_status(exoid) & EX_BULK_INT64_API) { \
43 status = nc_put_var_longlong(exoid, VARCONN, VARCONNVAL); \
44 } else { \
45 status = nc_put_var_int(exoid, VARCONN, VARCONNVAL); \
46 } \
47 if (status != NC_NOERR) { \
48 exerrval = status; \
49 sprintf(errmsg, \
50 "Error: failed to write connectivity array for %s block %"PRId64" in file id %d", \
51 TNAME,blk_id,exoid); \
52 ex_err("ex_put_conn",errmsg, exerrval); \
53 return(EX_FATAL); \
54 }
55
56 /*!
57 * writes the connectivity array for a block
58 * \param exoid exodus file id
59 * \param blk_type type of block
60 * \param blk_id id of block
61 * \param node_conn node-element connectivity
62 * \param elem_edge_conn element-edge connectivity (NULL if none)
63 * \param elem_face_conn element-face connectivity (NULL if none)
64 */
65
ex_put_conn(int exoid,ex_entity_type blk_type,ex_entity_id blk_id,const void_int * node_conn,const void_int * elem_edge_conn,const void_int * elem_face_conn)66 int ex_put_conn (int exoid,
67 ex_entity_type blk_type,
68 ex_entity_id blk_id,
69 const void_int *node_conn,
70 const void_int *elem_edge_conn,
71 const void_int *elem_face_conn)
72 {
73 int connid=-1, blk_id_ndx, status;
74 char errmsg[MAX_ERR_LENGTH];
75
76 exerrval = 0; /* clear error code */
77
78 blk_id_ndx = ex_id_lkup(exoid,blk_type,blk_id);
79 if (exerrval != 0) {
80 if (exerrval == EX_NULLENTITY) {
81 sprintf(errmsg,
82 "Warning: connectivity array not allowed for NULL %s block %"PRId64" in file id %d",
83 ex_name_of_object(blk_type),blk_id,exoid);
84 ex_err("ex_put_conn",errmsg,EX_MSG);
85 return (EX_WARN);
86 }
87 else {
88 sprintf(errmsg,
89 "Error: failed to locate %s block id %"PRId64" in id array in file id %d",
90 ex_name_of_object(blk_type),blk_id, exoid);
91 ex_err("ex_put_conn",errmsg,exerrval);
92 return (EX_FATAL);
93 }
94 }
95
96 /* inquire id's of previously defined dimensions */
97 if (node_conn) {
98 switch (blk_type) {
99 case EX_ELEM_BLOCK:
100 status = nc_inq_varid (exoid, VAR_CONN(blk_id_ndx), &connid);
101 break;
102 case EX_FACE_BLOCK:
103 status = nc_inq_varid (exoid, VAR_FBCONN(blk_id_ndx), &connid);
104 break;
105 case EX_EDGE_BLOCK:
106 status = nc_inq_varid (exoid, VAR_EBCONN(blk_id_ndx), &connid);
107 break;
108 default:
109 exerrval = 1005;
110 sprintf(errmsg,
111 "Internal Error: unrecognized block type in switch: %d in file id %d",
112 blk_type,exoid);
113 ex_err("ex_putt_conn",errmsg,EX_MSG);
114 return (EX_FATAL);
115 }
116 if (status != NC_NOERR) {
117 exerrval = status;
118 sprintf(errmsg,
119 "Error: failed to locate connectivity array for %s block %"PRId64" in file id %d",
120 ex_name_of_object(blk_type),blk_id,exoid);
121 ex_err("ex_put_conn",errmsg, exerrval);
122 return(EX_FATAL);
123 }
124
125 EX_WRITE_CONN(ex_name_of_object(blk_type),connid,node_conn);
126 }
127
128 /* If there are edge and face connectivity arrays that belong with the element
129 * block, write them now. Warn if they are required but not specified or
130 * specified but not required.
131 */
132 if ( blk_type == EX_ELEM_BLOCK ) {
133 int nedpereldim, nfapereldim;
134 size_t num_ed_per_elem, num_fa_per_elem;
135
136 status = nc_inq_dimid (exoid, DIM_NUM_EDG_PER_EL(blk_id_ndx), &nedpereldim);
137 if (status != NC_NOERR && elem_edge_conn != 0)
138 {
139 exerrval = status;
140 sprintf(errmsg,
141 "Error: edge connectivity specified but failed to "
142 "locate number of edges/element in block %"PRId64" in file id %d",
143 blk_id,exoid);
144 ex_err("ex_put_conn",errmsg,exerrval);
145 return(EX_FATAL);
146 }
147
148 status = nc_inq_dimid (exoid, DIM_NUM_FAC_PER_EL(blk_id_ndx), &nfapereldim);
149 if (status != NC_NOERR && elem_face_conn != 0)
150 {
151 exerrval = status;
152 sprintf(errmsg,
153 "Error: face connectivity specified but failed to "
154 "locate number of faces/element in block %"PRId64" in file id %d",
155 blk_id,exoid);
156 ex_err("ex_put_conn",errmsg,exerrval);
157 return(EX_FATAL);
158 }
159
160 num_ed_per_elem = 0;
161 if ((elem_edge_conn != 0) &&
162 (status = nc_inq_dimlen(exoid, nedpereldim, &num_ed_per_elem) != NC_NOERR))
163 {
164 exerrval = status;
165 sprintf(errmsg,
166 "Error: failed to get number of edges/elem in block %"PRId64" in file id %d",
167 blk_id,exoid);
168 ex_err("ex_put_conn",errmsg,exerrval);
169 return(EX_FATAL);
170 }
171
172 num_fa_per_elem = 0;
173 if ((elem_face_conn != 0) &&
174 (status = nc_inq_dimlen(exoid, nfapereldim, &num_fa_per_elem) != NC_NOERR))
175 {
176 exerrval = status;
177 sprintf(errmsg,
178 "Error: failed to get number of faces/elem in block %"PRId64" in file id %d",
179 blk_id,exoid);
180 ex_err("ex_put_conn",errmsg,exerrval);
181 return(EX_FATAL);
182 }
183
184 if ( (num_ed_per_elem == 0 && elem_edge_conn != 0) ||
185 (num_ed_per_elem != 0 && elem_edge_conn == 0) )
186 {
187 exerrval = (EX_FATAL);
188 sprintf(errmsg,
189 "Error: number of edges per element (%ld) doesn't "
190 "agree with elem_edge_conn (0x%p)",
191 (long)num_ed_per_elem, (void*)elem_edge_conn );
192 ex_err("ex_put_conn",errmsg,exerrval);
193 return (EX_FATAL);
194 }
195
196 if ( (num_fa_per_elem == 0 && elem_face_conn != 0) ||
197 (num_fa_per_elem != 0 && elem_face_conn == 0) )
198 {
199 exerrval = (EX_FATAL);
200 sprintf(errmsg,
201 "Error: number of faces per element (%ld) doesn't "
202 "agree with elem_face_conn (0x%p)",
203 (long)num_fa_per_elem, (void*)elem_face_conn );
204 ex_err("ex_put_conn",errmsg,exerrval);
205 return (EX_FATAL);
206 }
207
208 if ( num_ed_per_elem != 0 ) {
209 status = nc_inq_varid(exoid, VAR_ECONN(blk_id_ndx), &connid);
210 if (status != NC_NOERR)
211 {
212 exerrval = status;
213 sprintf(errmsg,
214 "Error: failed to locate connectivity array for "
215 "element edge block %"PRId64" in file id %d",
216 blk_id,exoid);
217 ex_err("ex_put_conn",errmsg, exerrval);
218 return(EX_FATAL);
219 }
220 EX_WRITE_CONN("element edge",connid,elem_edge_conn);
221 }
222
223 if ( num_fa_per_elem != 0 ) {
224 status = nc_inq_varid (exoid, VAR_FCONN(blk_id_ndx), &connid);
225 if (status != NC_NOERR)
226 {
227 exerrval = status;
228 sprintf(errmsg,
229 "Error: failed to locate connectivity array for "
230 "element face block %"PRId64" in file id %d",
231 blk_id,exoid);
232 ex_err("ex_put_conn",errmsg, exerrval);
233 return(EX_FATAL);
234 }
235 EX_WRITE_CONN("element face",connid,elem_face_conn);
236 }
237 }
238
239 return (EX_NOERR);
240
241 }
242