void nc_put_var(TYPE type,int ncid,int varid,const void *dp){ switch(type){ case(BYTE): nc_put_var_uchar(ncid,varid,(const unsigned char *)dp); break; case(SHORT): nc_put_var_short(ncid,varid,(const short *)dp); break; case(INT): nc_put_var_int(ncid,varid,(const int *)dp); break; case(LONG): nc_put_var_long(ncid,varid,(const long *)dp); break; case(FLOAT): nc_put_var_float(ncid,varid,(const float *)dp); break; case(DOUBLE): nc_put_var_double(ncid,varid,(const double *)dp); break; default: printf("unkown types nc_put_var()!\n"); } }
int main(int argc, char ** argv) { GetPot cl(argc, argv); // Command line parsing if(!cl.search("--input")) { std::cerr << "No --input argument found!" << std::endl; usage_error(argv[0]); } const char * meshname = cl.next(""); if(!cl.search("--oldid")) { std::cerr << "No --oldid argument found!" << std::endl; usage_error(argv[0]); } long oldid = cl.next(0); if(!cl.search("--newid")) { std::cerr << "No --newid argument found!" << std::endl; usage_error(argv[0]); } long newid = cl.next(0); unsigned char flags = 0; if (cl.search("--nodesetonly")) flags |= NODES; if (cl.search("--sidesetonly")) flags |= SIDES; if (cl.search("--blockonly")) flags |= BLOCKS; if (cl.search("--dim")) flags |= EXODUS_DIM; // No command line flags were set, turn on NODES, SIDES, and BLOCKS if (!flags) flags = NODES | SIDES | BLOCKS; // ALL except EXODUS_DIM on // flags are exclusive if (flags != NODES && flags != SIDES && flags != BLOCKS && flags != EXODUS_DIM && flags != (NODES | SIDES | BLOCKS)) { std::cerr << "Only one of the following options may be active [--nodesetonly | --sidesetonly | --blockonly | --dim]!" << std::endl; usage_error(argv[0]); } // Processing std::string var_name, dim_name; int status; int nc_id, var_id, dim_id; size_t dim_len; status = nc_open (meshname, NC_WRITE, &nc_id); if (status != NC_NOERR) handle_error(status, "Error while opening file."); for (unsigned char mask = 8; mask; mask/=2) { // These are char *'s #defined in exodsuII_int.h switch (flags & mask) { case BLOCKS: dim_name = DIM_NUM_EL_BLK; var_name = VAR_ID_EL_BLK; break; case SIDES: dim_name = DIM_NUM_SS; var_name = VAR_SS_IDS; break; case NODES: dim_name = DIM_NUM_NS; var_name = VAR_NS_IDS; break; case EXODUS_DIM: dim_name = DIM_NUM_DIM; // var_name not used for setting dimension break; default: // We don't match this flag, so go to the next mask continue; } // Get the ID and length of the variable in question - stored in a dimension field status = nc_inq_dimid (nc_id, dim_name.c_str(), &dim_id); if (status != NC_NOERR) handle_error(status, "Error while inquiring about a dimension's ID."); status = nc_inq_dimlen (nc_id, dim_id, &dim_len); if (status != NC_NOERR) handle_error(status, "Error while inquiring about a dimension's length."); if ( (flags & mask) != EXODUS_DIM) { // Now get the variable values themselves std::vector<long> var_vals(dim_len); status = nc_inq_varid (nc_id, var_name.c_str(), &var_id); if (status != NC_NOERR) handle_error(status, "Error while inquiring about a variable's ID."); status = nc_get_var_long (nc_id, var_id, &var_vals[0]); if (status != NC_NOERR) handle_error(status, "Error while retrieving a variable's values."); // Update the variable value specified on the command line for (unsigned int i=0; i<dim_len; ++i) if (var_vals[i] == oldid) var_vals[i] = newid; // Save that value back to the NetCDF database status = nc_put_var_long (nc_id, var_id, &var_vals[0]); if (status != NC_NOERR) handle_error(status, "Error while writing a variable's values."); } // Redefine the dimension else { // The value stored in dim_len is actually the dimension? if (dim_len == (size_t)oldid) { // Trying to change def's always raises // Error -38: /* Operation not allowed in data mode */ // unless you are in "define" mode. So let's go there now. // Try to put the file into define mode status = nc_redef(nc_id); if (status != NC_NOERR) handle_error(status, "Error while putting file into define mode."); // Rename the "num_dim" dimension. Note: this will fail if there is already a dimension // which has the name you are trying to use. This can happen, for example if you have already // changed the dimension of this exodus file once using this very script. There appears // to be no way to delete a dimension using basic NetCDF interfaces, so to workaround this // we just rename it to an arbitrary unique string that Exodus will ignore. // Construct a string with 6 random alpha-numeric characters at the end. std::string random_dim_name; gen_random_string(random_dim_name, 6); random_dim_name = std::string("ignored_num_dim_") + random_dim_name; // Rename the old dimension variable to our randomly-chosen name status = nc_rename_dim(nc_id, dim_id, random_dim_name.c_str()); if (status != NC_NOERR) handle_error(status, "Error while trying to rename num_dim."); // Now define a new "num_dim" value of newid int dummy=0; status = nc_def_dim (nc_id, dim_name.c_str(), newid, &dummy); if (status != NC_NOERR) handle_error(status, "Error while trying to define num_dim."); // Leave define mode status = nc_enddef(nc_id); if (status != NC_NOERR) handle_error(status, "Error while leaving define mode."); } } } // end for // Write out the dataset status = nc_close(nc_id); return (status != NC_NOERR); }