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 *
37 * expoea - ex_put_n_one_attr
38 *
39 * entry conditions -
40 *   input parameters:
41 *       int     exoid                   exodus file id
42 *       int     obj_type                object type (edge, face, elem block)
43 *       int     obj_id                  object id (edge, face, elem block ID)
44 *       int     attrib_index            index of attribute to write
45 *       float*  attrib                  array of attributes
46 *
47 * exit conditions -
48 *
49 *
50 *****************************************************************************/
51 
52 #include "exodusII.h"
53 #include "exodusII_int.h"
54 
55 /*!
56  * writes the specified attribute for a block
57  * \param      exoid         exodus file id
58  * \param      obj_type      object type (edge, face, elem block)
59  * \param      obj_id        object id (edge, face, elem block ID)
60  * \param      start_num     the starting index of the attributes to be written
61  * \param      num_ent       the number of entities to write attributes for.
62  * \param      attrib_index  index of attribute to write
63  * \param      attrib        array of attributes
64  */
65 
ex_put_n_one_attr(int exoid,ex_entity_type obj_type,int obj_id,int start_num,int num_ent,int attrib_index,const void * attrib)66 int ex_put_n_one_attr( int   exoid,
67 		       ex_entity_type obj_type,
68 		       int   obj_id,
69 		       int   start_num,
70 		       int   num_ent,
71 		       int   attrib_index,
72 		       const void *attrib )
73 {
74   int status;
75   int attrid, obj_id_ndx, temp;
76   size_t num_entries_this_obj, num_attr;
77   size_t start[2], count[2];
78   ptrdiff_t stride[2];
79   char errmsg[MAX_ERR_LENGTH];
80   const char* dnumobjent;
81   const char* dnumobjatt;
82   const char* vattrbname;
83 
84   exerrval = 0; /* clear error code */
85 
86   /* Determine index of obj_id in id array */
87   if (obj_type != EX_NODAL) {
88     obj_id_ndx = ex_id_lkup(exoid,obj_type,obj_id);
89     if (exerrval != 0) {
90       if (exerrval == EX_NULLENTITY) {
91 	sprintf(errmsg,
92 		"Warning: no attributes allowed for NULL %s %d in file id %d",
93 		ex_name_of_object(obj_type),obj_id,exoid);
94 	ex_err("ex_put_n_one_attr",errmsg,EX_MSG);
95 	return (EX_WARN);              /* no attributes for this element block */
96       } else {
97 	sprintf(errmsg,
98 		"Error: no %s id %d in id array in file id %d",
99 		ex_name_of_object(obj_type), obj_id, exoid);
100 	ex_err("ex_put_n_one_attr",errmsg,exerrval);
101 	return (EX_FATAL);
102       }
103     }
104   }
105 
106   switch (obj_type) {
107   case EX_SIDE_SET:
108     dnumobjent = DIM_NUM_SIDE_SS(obj_id_ndx);
109     dnumobjatt = DIM_NUM_ATT_IN_SS(obj_id_ndx);
110     vattrbname = VAR_SSATTRIB(obj_id_ndx);
111     break;
112   case EX_NODE_SET:
113     dnumobjent = DIM_NUM_NOD_NS(obj_id_ndx);
114     dnumobjatt = DIM_NUM_ATT_IN_NS(obj_id_ndx);
115     vattrbname = VAR_NSATTRIB(obj_id_ndx);
116     break;
117   case EX_EDGE_SET:
118     dnumobjent = DIM_NUM_EDGE_ES(obj_id_ndx);
119     dnumobjatt = DIM_NUM_ATT_IN_ES(obj_id_ndx);
120     vattrbname = VAR_ESATTRIB(obj_id_ndx);
121     break;
122   case EX_FACE_SET:
123     dnumobjent = DIM_NUM_FACE_FS(obj_id_ndx);
124     dnumobjatt = DIM_NUM_ATT_IN_FS(obj_id_ndx);
125     vattrbname = VAR_FSATTRIB(obj_id_ndx);
126     break;
127   case EX_ELEM_SET:
128     dnumobjent = DIM_NUM_ELE_ELS(obj_id_ndx);
129     dnumobjatt = DIM_NUM_ATT_IN_ELS(obj_id_ndx);
130     vattrbname = VAR_ELSATTRIB(obj_id_ndx);
131     break;
132   case EX_NODAL:
133     dnumobjent = DIM_NUM_NODES;
134     dnumobjatt = DIM_NUM_ATT_IN_NBLK;
135     vattrbname = VAR_NATTRIB;
136     break;
137   case EX_EDGE_BLOCK:
138     dnumobjent = DIM_NUM_ED_IN_EBLK(obj_id_ndx);
139     dnumobjatt = DIM_NUM_ATT_IN_EBLK(obj_id_ndx);
140     vattrbname = VAR_EATTRIB(obj_id_ndx);
141     break;
142   case EX_FACE_BLOCK:
143     dnumobjent = DIM_NUM_FA_IN_FBLK(obj_id_ndx);
144     dnumobjatt = DIM_NUM_ATT_IN_FBLK(obj_id_ndx);
145     vattrbname = VAR_FATTRIB(obj_id_ndx);
146     break;
147   case EX_ELEM_BLOCK:
148     dnumobjent = DIM_NUM_EL_IN_BLK(obj_id_ndx);
149     dnumobjatt = DIM_NUM_ATT_IN_BLK(obj_id_ndx);
150     vattrbname = VAR_ATTRIB(obj_id_ndx);
151     break;
152   default:
153     exerrval = 1005;
154     sprintf(errmsg,
155 	    "Internal Error: unrecognized object type in switch: %d in file id %d",
156 	    obj_type,exoid);
157     ex_err("ex_putt_n_one_attr",errmsg,EX_MSG);
158     return (EX_FATAL);
159   }
160 
161   /* inquire id's of previously defined dimensions  */
162   if (ex_get_dimension(exoid, dnumobjent,"entries", &num_entries_this_obj, &temp, "ex_put_n_one_attr") != NC_NOERR)
163     return EX_FATAL;
164 
165   if (start_num + num_ent -1 > (int)num_entries_this_obj) {
166     exerrval = EX_BADPARAM;
167     sprintf(errmsg,
168 	    "Error: start index (%d) + count (%d) is larger than total number of entities (%d) in file id %d",
169 	    start_num, num_ent, (int)num_entries_this_obj, exoid);
170     ex_err("ex_put_n_one_attr",errmsg,exerrval);
171     return (EX_FATAL);
172   }
173 
174   if (ex_get_dimension(exoid, dnumobjatt,"attributes", &num_attr, &temp, "ex_put_n_one_attr") != NC_NOERR)
175     return EX_FATAL;
176 
177   if (attrib_index < 1 || attrib_index > (int)num_attr) {
178     exerrval = EX_FATAL;
179     sprintf(errmsg,
180             "Error: Invalid attribute index specified: %d.  Valid range is 1 to %d for %s %d in file id %d",
181             attrib_index, (int)num_attr, ex_name_of_object(obj_type), obj_id, exoid);
182     ex_err("ex_put_n_one_attr",errmsg,exerrval);
183     return (EX_FATAL);
184   }
185 
186   if ((status = nc_inq_varid(exoid, vattrbname, &attrid)) != NC_NOERR) {
187     exerrval = status;
188     sprintf(errmsg,
189 	    "Error: failed to locate attribute variable for %s %d in file id %d",
190 	    ex_name_of_object(obj_type),obj_id,exoid);
191     ex_err("ex_put_n_one_attr",errmsg,exerrval);
192     return (EX_FATAL);
193   }
194 
195   /* write out the attributes  */
196 
197   start[0] = start_num-1;
198   start[1] = attrib_index-1;
199 
200   count[0] = num_ent;
201   count[1] = 1;
202 
203   stride[0] = 1;
204   stride[1] = num_attr;
205 
206   if (ex_comp_ws(exoid) == 4) {
207     status = nc_put_vars_float(exoid, attrid, start, count, stride, attrib);
208   } else {
209     status = nc_put_vars_double(exoid, attrid, start, count, stride, attrib);
210   }
211 
212   if (status != NC_NOERR) {
213     exerrval = status;
214     sprintf(errmsg,
215             "Error: failed to put attribute %d for %s %d in file id %d",
216             attrib_index, ex_name_of_object(obj_type), obj_id, exoid);
217     ex_err("ex_put_n_one_attr",errmsg,exerrval);
218     return (EX_FATAL);
219   }
220   return(EX_NOERR);
221 }
222