📄 excopy.c
字号:
/* * Copyright (c) 2005 Sandia Corporation. Under the terms of Contract * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Governement * retains certain rights in this software. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * * Neither the name of Sandia Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *//******************************************************************************* excopy - ex_copy** entry conditions - * input parameters:* int in_exoid input exodus file id** exit conditions - * int out_exoid output exodus file id** revision history - *******************************************************************************/#include <assert.h>#include <stdlib.h>#include <string.h>#include "exodusII.h"#include "exodusII_int.h"struct ncdim { /* dimension */ char name[MAX_STR_LENGTH]; size_t size;};struct ncvar { /* variable */ char name[MAX_STR_LENGTH]; nc_type type; int ndims; int dims[NC_MAX_VAR_DIMS]; int natts;};struct ncatt { /* attribute */ int var; char name[MAX_STR_LENGTH]; nc_type type; size_t len; void *val;};static size_t type_size(nc_type type);static int cpy_att (int, int, int, int);static int cpy_var_def(int, int, int, char*);static int cpy_var_val(int, int, char*);static int cpy_coord_def(int in_id,int out_id,int rec_dim_id, char *var_nm, int in_large, int out_large);static int cpy_coord_val(int in_id,int out_id,char *var_nm, int in_large, int out_large);static void update_internal_structs( int, ex_inquiry, struct list_item** );/*! * efficiently copies all non-transient information (attributes, * dimensions, and variables from an opened EXODUS file to another * opened EXODUS file. Will not overwrite a dimension or variable * already defined in the new file. * \param in_exoid exodus file id for input file * \param out_exoid exodus file id for output file */int ex_copy (int in_exoid, int out_exoid){ int status; int ndims; /* number of dimensions */ int nvars; /* number of variables */ int ngatts; /* number of global attributes */ int recdimid; /* id of unlimited dimension */ int dimid; /* dimension id */ int dim_out_id; /* dimension id */ int varid; /* variable id */ int var_out_id; /* variable id */ struct ncvar var; /* variable */ struct ncatt att; /* attribute */ int i; size_t numrec; size_t dim_sz; char dim_nm[NC_MAX_NAME]; int in_large, out_large; exerrval = 0; /* clear error code */ /* * Get exodus_large_model setting on both input and output * databases so know how to handle coordinates. */ in_large = ex_large_model(in_exoid); out_large = ex_large_model(out_exoid); /* * get number of dimensions, number of variables, number of global * atts, and dimension id of unlimited dimension, if any */ nc_inq(in_exoid, &ndims, &nvars, &ngatts, &recdimid); nc_inq_dimlen(in_exoid, recdimid, &numrec); /* put output file into define mode */ nc_redef(out_exoid); /* copy global attributes */ for (i = 0; i < ngatts; i++) { nc_inq_attname(in_exoid, NC_GLOBAL, i, att.name); /* if attribute exists in output file, don't overwrite it; compute * word size, I/O word size etc. are global attributes stored when * file is created with ex_create; we don't want to overwrite those */ if ((status = nc_inq_att(out_exoid, NC_GLOBAL, att.name, &att.type, &att.len)) != NC_NOERR) { /* The "last_written_time" attribute is a special attribute used by the Sierra IO system to determine whether a timestep has been fully written to the database in order to try to detect a database crash that happens in the middle of a database output step. Don't want to copy that attribute. */ if (strcmp(att.name,"last_written_time") != 0) { /* attribute doesn't exist in new file so OK to create it */ nc_copy_att(in_exoid,NC_GLOBAL,att.name,out_exoid,NC_GLOBAL); } } } /* copy dimensions */ /* Get the dimension sizes and names */ for(dimid = 0; dimid < ndims; dimid++){ nc_inq_dim(in_exoid,dimid,dim_nm,&dim_sz); /* If the dimension isn't one we specifically don't want * to copy (ie, number of QA or INFO records) and it * hasn't been defined, copy it */ if ( ( strcmp(dim_nm,DIM_NUM_QA) != 0) && ( strcmp(dim_nm,DIM_NUM_INFO) != 0) && ( strcmp(dim_nm,DIM_NUM_NOD_VAR) != 0) && ( strcmp(dim_nm,DIM_NUM_EDG_VAR) != 0) && ( strcmp(dim_nm,DIM_NUM_FAC_VAR) != 0) && ( strcmp(dim_nm,DIM_NUM_ELE_VAR) != 0) && ( strcmp(dim_nm,DIM_NUM_NSET_VAR) != 0) && ( strcmp(dim_nm,DIM_NUM_ESET_VAR) != 0) && ( strcmp(dim_nm,DIM_NUM_FSET_VAR) != 0) && ( strcmp(dim_nm,DIM_NUM_SSET_VAR) != 0) && ( strcmp(dim_nm,DIM_NUM_ELSET_VAR) != 0) && ( strcmp(dim_nm,DIM_NUM_GLO_VAR) != 0) ) { /* See if the dimension has already been defined */ status = nc_inq_dimid(out_exoid, dim_nm, &dim_out_id); if(status != NC_NOERR) { if(dimid != recdimid) { status = nc_def_dim(out_exoid, dim_nm, dim_sz, &dim_out_id); } else { status = nc_def_dim(out_exoid, dim_nm, NC_UNLIMITED, &dim_out_id); } /* end else */ } /* end if */ } /* end if */ } /* end loop over dim */ /* copy variable definitions and variable attributes */ for (varid = 0; varid < nvars; varid++) { nc_inq_var(in_exoid, varid, var.name, &var.type, &var.ndims, var.dims, &var.natts); /* we don't want to copy some variables because there is not a * simple way to add to them; * QA records, info records and all results variables (nodal * element, and global results) are examples */ if ( ( strcmp(var.name,VAR_QA_TITLE) != 0) && ( strcmp(var.name,VAR_INFO) != 0) && ( strcmp(var.name,VAR_EBLK_TAB) != 0) && ( strcmp(var.name,VAR_FBLK_TAB) != 0) && ( strcmp(var.name,VAR_ELEM_TAB) != 0) && ( strcmp(var.name,VAR_ELSET_TAB) != 0) && ( strcmp(var.name,VAR_SSET_TAB) != 0) && ( strcmp(var.name,VAR_FSET_TAB) != 0) && ( strcmp(var.name,VAR_ESET_TAB) != 0) && ( strcmp(var.name,VAR_NSET_TAB) != 0) && ( strcmp(var.name,VAR_NAME_GLO_VAR) != 0) && ( strcmp(var.name,VAR_GLO_VAR) != 0) && ( strcmp(var.name,VAR_NAME_NOD_VAR) != 0) && ( strcmp(var.name,VAR_NOD_VAR) != 0) && ( strcmp(var.name,VAR_NAME_EDG_VAR) != 0) && ( strcmp(var.name,VAR_NAME_FAC_VAR) != 0) && ( strcmp(var.name,VAR_NAME_ELE_VAR) != 0) && ( strcmp(var.name,VAR_NAME_NSET_VAR) != 0) && ( strcmp(var.name,VAR_NAME_ESET_VAR) != 0) && ( strcmp(var.name,VAR_NAME_FSET_VAR) != 0) && ( strcmp(var.name,VAR_NAME_SSET_VAR) != 0) && ( strcmp(var.name,VAR_NAME_ELSET_VAR) != 0)&& ( strncmp(var.name,"vals_elset_var", 14) != 0) && ( strncmp(var.name,"vals_sset_var", 13) != 0) && ( strncmp(var.name,"vals_fset_var", 13) != 0) && ( strncmp(var.name,"vals_eset_var", 13) != 0) && ( strncmp(var.name,"vals_nset_var", 13) != 0) && ( strncmp(var.name,"vals_nod_var", 12) != 0) && ( strncmp(var.name,"vals_edge_var", 13) != 0) && ( strncmp(var.name,"vals_face_var", 13) != 0) && ( strncmp(var.name,"vals_elem_var", 13) != 0) ) { if (strncmp(var.name,VAR_COORD,5) == 0) { var_out_id = cpy_coord_def (in_exoid, out_exoid, recdimid, var.name, in_large, out_large); } else { var_out_id = cpy_var_def (in_exoid, out_exoid, recdimid, var.name); } /* copy the variable's attributes */ (void) cpy_att (in_exoid, out_exoid, varid, var_out_id); } } /* take the output file out of define mode */ nc_enddef (out_exoid); /* output variable data */ for (varid = 0; varid < nvars; varid++) { nc_inq_var(in_exoid, varid, var.name, &var.type, &var.ndims, var.dims, &var.natts); /* we don't want to copy some variable values; * QA records and info records shouldn't be copied because there * isn't an easy way to add to them; * the time value array ("time_whole") and any results variables * (nodal, elemental, or global) shouldn't be copied */ if ( ( strcmp(var.name,VAR_QA_TITLE) != 0) && ( strcmp(var.name,VAR_INFO) != 0) && ( strcmp(var.name,VAR_EBLK_TAB) != 0) && ( strcmp(var.name,VAR_FBLK_TAB) != 0) && ( strcmp(var.name,VAR_ELEM_TAB) != 0) && ( strcmp(var.name,VAR_ELSET_TAB) != 0) && ( strcmp(var.name,VAR_SSET_TAB) != 0) && ( strcmp(var.name,VAR_FSET_TAB) != 0) && ( strcmp(var.name,VAR_ESET_TAB) != 0) && ( strcmp(var.name,VAR_NSET_TAB) != 0) && ( strcmp(var.name,VAR_NAME_GLO_VAR) != 0) && ( strcmp(var.name,VAR_GLO_VAR) != 0) && ( strcmp(var.name,VAR_NAME_NOD_VAR) != 0) && ( strcmp(var.name,VAR_NOD_VAR) != 0) && ( strcmp(var.name,VAR_NAME_EDG_VAR) != 0) && ( strcmp(var.name,VAR_NAME_FAC_VAR) != 0) && ( strcmp(var.name,VAR_NAME_ELE_VAR) != 0) && ( strcmp(var.name,VAR_NAME_NSET_VAR) != 0) && ( strcmp(var.name,VAR_NAME_ESET_VAR) != 0) && ( strcmp(var.name,VAR_NAME_FSET_VAR) != 0) && ( strcmp(var.name,VAR_NAME_SSET_VAR) != 0) && ( strcmp(var.name,VAR_NAME_ELSET_VAR) != 0) && ( strncmp(var.name,"vals_elset_var", 14) != 0)&& ( strncmp(var.name,"vals_sset_var", 13) != 0)&& ( strncmp(var.name,"vals_fset_var", 13) != 0)&& ( strncmp(var.name,"vals_eset_var", 13) != 0)&& ( strncmp(var.name,"vals_nset_var", 13) != 0)&& ( strncmp(var.name,"vals_nod_var", 12) != 0) && ( strncmp(var.name,"vals_edge_var",13) != 0) && ( strncmp(var.name,"vals_face_var",13) != 0) && ( strncmp(var.name,"vals_elem_var",13) != 0) && ( strcmp(var.name,VAR_WHOLE_TIME) != 0) ) { if (strncmp(var.name,VAR_COORD,5) == 0) { (void) cpy_coord_val (in_exoid, out_exoid, var.name, in_large, out_large); } else { (void) cpy_var_val (in_exoid, out_exoid, var.name); } } } /* ensure internal data structures are updated */ /* if number of blocks > 0 */ update_internal_structs( out_exoid, EX_INQ_EDGE_BLK, ex_get_counter_list(EX_EDGE_BLOCK)); update_internal_structs( out_exoid, EX_INQ_FACE_BLK, ex_get_counter_list(EX_FACE_BLOCK)); update_internal_structs( out_exoid, EX_INQ_ELEM_BLK, ex_get_counter_list(EX_ELEM_BLOCK)); /* if number of sets > 0 */ update_internal_structs( out_exoid, EX_INQ_NODE_SETS, ex_get_counter_list(EX_NODE_SET)); update_internal_structs( out_exoid, EX_INQ_EDGE_SETS, ex_get_counter_list(EX_EDGE_SET)); update_internal_structs( out_exoid, EX_INQ_FACE_SETS, ex_get_counter_list(EX_FACE_SET)); update_internal_structs( out_exoid, EX_INQ_SIDE_SETS, ex_get_counter_list(EX_SIDE_SET)); update_internal_structs( out_exoid, EX_INQ_ELEM_SETS, ex_get_counter_list(EX_ELEM_SET)); /* if number of maps > 0 */ update_internal_structs( out_exoid, EX_INQ_NODE_MAP, ex_get_counter_list(EX_NODE_MAP)); update_internal_structs( out_exoid, EX_INQ_EDGE_MAP, ex_get_counter_list(EX_EDGE_MAP)); update_internal_structs( out_exoid, EX_INQ_FACE_MAP, ex_get_counter_list(EX_FACE_MAP)); update_internal_structs( out_exoid, EX_INQ_ELEM_MAP, ex_get_counter_list(EX_ELEM_MAP)); return(EX_NOERR);}int cpy_att(int in_id,int out_id,int var_in_id,int var_out_id)/* int in_id: input netCDF input-file ID int out_id: input netCDF output-file ID int var_in_id: input netCDF input-variable ID int var_out_id: input netCDF output-variable ID */{ /* Routine to copy all the attributes from the input netCDF file to the output netCDF file. If var_in_id == NC_GLOBAL, then the global attributes are copied. Otherwise the variable's attributes are copied. */ int idx; int nbr_att; if(var_in_id == NC_GLOBAL) { nc_inq_natts(in_id,&nbr_att); } else { nc_inq_varnatts(in_id, var_in_id, &nbr_att); } /* Get the attributes names, types, lengths, and values */ for (idx=0; idx<nbr_att; idx++) { char att_nm[MAX_STR_LENGTH]; nc_inq_attname(in_id, var_in_id, idx, att_nm); nc_copy_att(in_id, var_in_id, att_nm, out_id, var_out_id); } return(EX_NOERR);} int cpy_coord_def(int in_id,int out_id,int rec_dim_id,char *var_nm, int in_large, int out_large)/* int in_id: input netCDF input-file ID int out_id: input netCDF output-file ID int rec_dim_id: input input-file record dimension ID char *var_nm: input variable name int in_large: large file setting for input file int out_large: large file setting for output file int cpy_var_def(): output output-file variable ID */{ const char *routine = NULL; int status; size_t spatial_dim; int nbr_dim; int temp; int dim_out_id[2]; int var_out_id = -1; /* Handle easiest situation first: in_large matches out_large */ if (in_large == out_large) { return cpy_var_def(in_id, out_id, rec_dim_id, var_nm); } /* At this point, know that in_large != out_large, so some change to the coord variable definition is needed. Also will need the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -