libMesh
Loading...
Searching...
No Matches
Functions
meshid.C File Reference

Go to the source code of this file.

Functions

void handle_error (int error, std::string message)
 
void usage_error (const char *progname)
 
void gen_random_string (std::string &s, const int len)
 
int main (int argc, char **argv)
 

Function Documentation

◆ gen_random_string()

void gen_random_string ( std::string &  s,
const int  len 
)

Definition at line 246 of file meshid.C.

247{
248 static const char alphanum[] =
249 "0123456789"
250 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
251 "abcdefghijklmnopqrstuvwxyz";
252
253 // Seed the random number generator with the current time
254 srand( static_cast<unsigned>(time(nullptr)) );
255
256 s.resize(len);
257 for (int i = 0; i < len; ++i)
258 {
259 unsigned int alphai = static_cast<unsigned int>
260 (rand() / (RAND_MAX+1.0) * (sizeof(alphanum)-1));
261 s[i] = alphanum[alphai];
262 }
263}

Referenced by main().

◆ handle_error()

void handle_error ( int  error,
std::string  message 
)

Definition at line 226 of file meshid.C.

227{
228 std::cout << "Error " << error << " occurred while working with the netCDF API" << std::endl;
229 std::cout << message << std::endl;
230
231 exit(1);
232}

Referenced by main().

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 55 of file meshid.C.

56{
57 GetPot cl(argc, argv);
58
59 // Command line parsing
60 if (!cl.search("--input"))
61 {
62 std::cerr << "No --input argument found!" << std::endl;
63 usage_error(argv[0]);
64 }
65 const char * meshname = cl.next("");
66
67 if (!cl.search("--oldid"))
68 {
69 std::cerr << "No --oldid argument found!" << std::endl;
70 usage_error(argv[0]);
71 }
72 long oldid = cl.next(0);
73
74 if (!cl.search("--newid"))
75 {
76 std::cerr << "No --newid argument found!" << std::endl;
77 usage_error(argv[0]);
78 }
79 long newid = cl.next(0);
80
81 unsigned char flags = 0;
82 if (cl.search("--nodesetonly"))
83 flags |= NODES;
84 if (cl.search("--sidesetonly"))
85 flags |= SIDES;
86 if (cl.search("--blockonly"))
87 flags |= BLOCKS;
88 if (cl.search("--dim"))
89 flags |= EXODUS_DIM;
90
91 // No command line flags were set, turn on NODES, SIDES, and BLOCKS
92 if (!flags)
93 flags = NODES | SIDES | BLOCKS; // ALL except EXODUS_DIM on
94
95 // flags are exclusive
96 if (flags != NODES &&
97 flags != SIDES &&
98 flags != BLOCKS &&
99 flags != EXODUS_DIM &&
100 flags != (NODES | SIDES | BLOCKS))
101 {
102 std::cerr << "Only one of the following options may be active [--nodesetonly | --sidesetonly | --blockonly | --dim]!" << std::endl;
103 usage_error(argv[0]);
104 }
105
106 // Processing
107 std::string var_name, dim_name;
108 int status;
109 int nc_id, var_id, dim_id;
110 size_t dim_len;
111
112 status = nc_open (meshname, NC_WRITE, &nc_id);
113 if (status != NC_NOERR) handle_error(status, "Error while opening file.");
114
115 for (unsigned char mask = 8; mask; mask/=2)
116 {
117 // These are char *'s #defined in exodusII_int.h
118 switch (flags & mask)
119 {
120 case BLOCKS:
121 dim_name = DIM_NUM_EL_BLK;
122 var_name = VAR_ID_EL_BLK;
123 break;
124 case SIDES:
125 dim_name = DIM_NUM_SS;
126 var_name = VAR_SS_IDS;
127 break;
128 case NODES:
129 dim_name = DIM_NUM_NS;
130 var_name = VAR_NS_IDS;
131 break;
132 case EXODUS_DIM:
133 dim_name = DIM_NUM_DIM;
134 // var_name not used for setting dimension
135 break;
136 default:
137 // We don't match this flag, so go to the next mask
138 continue;
139 }
140
141 // Get the ID and length of the variable in question - stored in a dimension field
142 status = nc_inq_dimid (nc_id, dim_name.c_str(), &dim_id);
143 if (status != NC_NOERR) handle_error(status, "Error while inquiring about a dimension's ID.");
144
145 status = nc_inq_dimlen (nc_id, dim_id, &dim_len);
146 if (status != NC_NOERR) handle_error(status, "Error while inquiring about a dimension's length.");
147
148 if ((flags & mask) != EXODUS_DIM)
149 {
150 // Now get the variable values themselves
151 std::vector<long> var_vals(dim_len);
152
153 status = nc_inq_varid (nc_id, var_name.c_str(), &var_id);
154 if (status != NC_NOERR) handle_error(status, "Error while inquiring about a variable's ID.");
155
156 status = nc_get_var_long (nc_id, var_id, var_vals.data());
157 if (status != NC_NOERR) handle_error(status, "Error while retrieving a variable's values.");
158
159 // Update the variable value specified on the command line
160 for (unsigned int i=0; i<dim_len; ++i)
161 if (var_vals[i] == oldid)
162 var_vals[i] = newid;
163
164 // Save that value back to the NetCDF database
165 status = nc_put_var_long (nc_id, var_id, var_vals.data());
166 if (status != NC_NOERR) handle_error(status, "Error while writing a variable's values.");
167 }
168
169 // Redefine the dimension
170 else
171 {
172 // The value stored in dim_len is actually the dimension?
173 if (dim_len == (size_t)oldid)
174 {
175 // Trying to change def's always raises
176 // Error -38: /* Operation not allowed in data mode */
177 // unless you are in "define" mode. So let's go there now.
178
179 // Try to put the file into define mode
180 status = nc_redef(nc_id);
181 if (status != NC_NOERR) handle_error(status, "Error while putting file into define mode.");
182
183 // Rename the "num_dim" dimension. Note: this will fail if there is already a dimension
184 // which has the name you are trying to use. This can happen, for example if you have already
185 // changed the dimension of this exodus file once using this very script. There appears
186 // to be no way to delete a dimension using basic NetCDF interfaces, so to workaround this
187 // we just rename it to an arbitrary unique string that Exodus will ignore.
188
189 // Construct a string with 6 random alpha-numeric characters at the end.
190 std::string random_dim_name;
191 gen_random_string(random_dim_name, 6);
192 random_dim_name = std::string("ignored_num_dim_") + random_dim_name;
193
194 // Rename the old dimension variable to our randomly-chosen name
195 status = nc_rename_dim(nc_id, dim_id, random_dim_name.c_str());
196 if (status != NC_NOERR) handle_error(status, "Error while trying to rename num_dim.");
197
198 // Now define a new "num_dim" value of newid
199 int dummy=0;
200 status = nc_def_dim (nc_id, dim_name.c_str(), newid, &dummy);
201 if (status != NC_NOERR) handle_error(status, "Error while trying to define num_dim.");
202
203 // Leave define mode
204 status = nc_enddef(nc_id);
205 if (status != NC_NOERR) handle_error(status, "Error while leaving define mode.");
206 }
207 }
208 } // end for
209
210 // Write out the dataset
211 status = nc_close(nc_id);
212
213 return (status != NC_NOERR);
214}
void gen_random_string(std::string &s, const int len)
Definition meshid.C:246
void handle_error(int error, std::string message)
Definition meshid.C:226
void usage_error(const char *progname)
Definition meshid.C:236
MPI_Status status

References gen_random_string(), handle_error(), main(), and usage_error().

◆ usage_error()

void usage_error ( const char *  progname)

Definition at line 236 of file meshid.C.

237{
238 std::cout << "Usage: " << progname
239 << " --input inputmesh --oldid <n> --newid <n> [--nodesetonly | --sidesetonly | --blockonly]"
240 << std::endl;
241 exit(1);
242}

Referenced by main().