|
Sierra Toolkit
Version of the Day
|
00001 /*------------------------------------------------------------------------*/ 00002 /* Copyright 2010 Sandia Corporation. */ 00003 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */ 00004 /* license for use of this work by or on behalf of the U.S. Government. */ 00005 /* Export of this program may require a license from the */ 00006 /* United States Government. */ 00007 /*------------------------------------------------------------------------*/ 00008 00009 #include <stk_mesh/base/Trace.hpp> 00010 00011 #include <stk_mesh/baseImpl/FieldRepository.hpp> 00012 00013 #include <stk_util/util/string_case_compare.hpp> 00014 00015 #include <cstring> 00016 #include <sstream> 00017 #include <stdexcept> 00018 00019 namespace stk_classic { 00020 namespace mesh { 00021 namespace impl { 00022 00023 namespace { 00024 00025 std::string print_field_type(const DataTraits & arg_traits , 00026 unsigned arg_rank , 00027 const shards::ArrayDimTag * const * arg_tags ) 00028 { 00029 std::ostringstream oss; 00030 oss << "FieldBase<" ; 00031 oss << arg_traits.name ; 00032 for ( unsigned i = 0 ; i < arg_rank ; ++i ) { 00033 oss << "," << arg_tags[i]->name(); 00034 } 00035 oss << ">" ; 00036 return oss.str(); 00037 } 00038 00039 // Check for compatibility: 00040 // 1) Scalar type must match 00041 // 2) Number of states must match 00042 // 3) Dimension must be different by at most one rank, 00043 // where the tags match for the smaller rank. 00044 void verify_field_type( const char * arg_method , 00045 const FieldBase & arg_field , 00046 const DataTraits & arg_traits , 00047 unsigned arg_rank , 00048 const shards::ArrayDimTag * const * arg_dim_tags , 00049 unsigned arg_num_states ) 00050 { 00051 00052 const bool ok_traits = arg_traits.is_void 00053 || & arg_traits == & arg_field.data_traits(); 00054 00055 const bool ok_number_states = 00056 ! arg_num_states || arg_num_states == arg_field.number_of_states(); 00057 00058 bool ok_dimension = ! arg_rank || arg_rank == arg_field.rank() || 00059 arg_rank + 1 == arg_field.rank() || 00060 arg_rank - 1 == arg_field.rank() ; 00061 00062 const unsigned check_rank = arg_rank < arg_field.rank() ? 00063 arg_rank : arg_field.rank() ; 00064 00065 for ( unsigned i = 0 ; i < check_rank && ok_dimension ; ++i ) { 00066 ok_dimension = arg_dim_tags[i] == arg_field.dimension_tags()[i] ; 00067 } 00068 00069 ThrowErrorMsgIf( ! ok_traits || ! ok_number_states || ! ok_dimension, 00070 arg_method << " FAILED: Existing field = " << 00071 print_field_type( arg_field.data_traits() , 00072 arg_field.rank() , 00073 arg_field.dimension_tags() ) << 00074 "[ name = \"" << arg_field.name() << 00075 "\" , #states = " << arg_field.number_of_states() << " ]" << 00076 " Expected field info = " << 00077 print_field_type( arg_traits , arg_rank , arg_dim_tags ) << 00078 "[ #states = " << arg_num_states << " ]"); 00079 } 00080 00081 } //unamed namespace 00082 00083 //---------------------------------------------------------------------- 00084 00085 FieldBase * FieldRepository::get_field( 00086 const char * arg_method , 00087 const std::string & arg_name , 00088 const DataTraits & arg_traits , 00089 unsigned arg_rank , 00090 const shards::ArrayDimTag * const * arg_dim_tags , 00091 unsigned arg_num_states ) const 00092 { 00093 FieldBase * f = NULL ; 00094 00095 for ( std::vector<FieldBase*>::const_iterator 00096 j = m_fields.begin() ; 00097 j != m_fields.end() && NULL == f ; ++j ) { 00098 if ( equal_case( (*j)->name() , arg_name ) ) { 00099 00100 f = *j ; 00101 00102 verify_field_type( arg_method , *f , arg_traits , 00103 arg_rank , arg_dim_tags , arg_num_states ); 00104 } 00105 } 00106 return f ; 00107 } 00108 00109 FieldBase * FieldRepository::declare_field( 00110 const std::string & arg_name , 00111 const DataTraits & arg_traits , 00112 unsigned arg_rank , 00113 const shards::ArrayDimTag * const * arg_dim_tags , 00114 unsigned arg_num_states , 00115 MetaData * arg_meta_data ) 00116 { 00117 TraceIf("stk_classic::mesh::impl::FieldRepository::declare_field", LOG_FIELD); 00118 00119 static const char* reserved_state_suffix[6] = { 00120 "_STKFS_OLD", 00121 "_STKFS_N", 00122 "_STKFS_NM1", 00123 "_STKFS_NM2", 00124 "_STKFS_NM3", 00125 "_STKFS_NM4" 00126 }; 00127 00128 // Check that the name does not have a reserved suffix 00129 00130 for ( unsigned i = 0 ; i < 6 ; ++i ) { 00131 const int len_name = arg_name.size(); 00132 const int len_suffix = std::strlen( reserved_state_suffix[i] ); 00133 const int offset = len_name - len_suffix ; 00134 if ( 0 <= offset ) { 00135 const char * const name_suffix = arg_name.c_str() + offset ; 00136 ThrowErrorMsgIf( equal_case( name_suffix , reserved_state_suffix[i] ), 00137 "For name = \"" << name_suffix << 00138 "\" CANNOT HAVE THE RESERVED STATE SUFFIX \"" << 00139 reserved_state_suffix[i] << "\"" ); 00140 } 00141 } 00142 00143 // Check that the field of this name has not already been declared 00144 00145 FieldBase * f[ MaximumFieldStates ] ; 00146 00147 f[0] = get_field( 00148 "FieldRepository::declare_field" , 00149 arg_name , 00150 arg_traits , 00151 arg_rank , 00152 arg_dim_tags , 00153 arg_num_states 00154 ); 00155 00156 if ( NULL != f[0] ) { 00157 for ( unsigned i = 1 ; i < arg_num_states ; ++i ) { 00158 f[i] = f[0]->m_impl.field_state(static_cast<FieldState>(i)); 00159 } 00160 } 00161 else { 00162 // Field does not exist then create it 00163 00164 std::string field_names[ MaximumFieldStates ]; 00165 00166 field_names[0] = arg_name ; 00167 00168 if ( 2 == arg_num_states ) { 00169 field_names[1] = arg_name ; 00170 field_names[1].append( reserved_state_suffix[0] ); 00171 } 00172 else { 00173 for ( unsigned i = 1 ; i < arg_num_states ; ++i ) { 00174 field_names[i] = arg_name ; 00175 field_names[i].append( reserved_state_suffix[i] ); 00176 } 00177 } 00178 00179 for ( unsigned i = 0 ; i < arg_num_states ; ++i ) { 00180 00181 f[i] = new FieldBase( 00182 arg_meta_data , 00183 m_fields.size() , 00184 field_names[i] , 00185 arg_traits , 00186 arg_rank, 00187 arg_dim_tags, 00188 arg_num_states , 00189 static_cast<FieldState>(i) 00190 ); 00191 00192 m_fields.push_back( f[i] ); 00193 } 00194 00195 for ( unsigned i = 0 ; i < arg_num_states ; ++i ) { 00196 f[i]->m_impl.set_field_states( f ); 00197 } 00198 } 00199 00200 return f[0] ; 00201 } 00202 00203 void FieldRepository::verify_and_clean_restrictions( 00204 const char * arg_method , 00205 const Part& superset, const Part& subset, 00206 const PartVector & arg_all_parts ) 00207 { 00208 TraceIf("stk_classic::mesh::impl::FieldRepository::verify_and_clean_restrictions", LOG_FIELD); 00209 00210 for ( FieldVector::iterator f = m_fields.begin() ; f != m_fields.end() ; ++f ) { 00211 (*f)->m_impl.verify_and_clean_restrictions( arg_method, superset, subset, arg_all_parts ); 00212 } 00213 } 00214 00215 FieldRepository::~FieldRepository() { 00216 try { 00217 FieldVector::iterator j = m_fields.begin(); 00218 for ( ; j != m_fields.end() ; ++j ) { delete *j ; } 00219 m_fields.clear(); 00220 } catch(...) {} 00221 } 00222 00223 } // namespace impl 00224 } // namespace mesh 00225 } // namespace stk_classic