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