Sierra Toolkit  Version of the Day
FieldRepository.cpp
1 /*------------------------------------------------------------------------*/
2 /* Copyright 2010 Sandia Corporation. */
3 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */
4 /* license for use of this work by or on behalf of the U.S. Government. */
5 /* Export of this program may require a license from the */
6 /* United States Government. */
7 /*------------------------------------------------------------------------*/
8 
9 #include <stk_mesh/base/Trace.hpp>
10 
11 #include <stk_mesh/baseImpl/FieldRepository.hpp>
12 
13 #include <stk_util/util/string_case_compare.hpp>
14 
15 #include <cstring>
16 #include <sstream>
17 #include <stdexcept>
18 
19 namespace stk_classic {
20 namespace mesh {
21 namespace impl {
22 
23 namespace {
24 
25 std::string print_field_type(const DataTraits & arg_traits ,
26  unsigned arg_rank ,
27  const shards::ArrayDimTag * const * arg_tags )
28 {
29  std::ostringstream oss;
30  oss << "FieldBase<" ;
31  oss << arg_traits.name ;
32  for ( unsigned i = 0 ; i < arg_rank ; ++i ) {
33  oss << "," << arg_tags[i]->name();
34  }
35  oss << ">" ;
36  return oss.str();
37 }
38 
39 // Check for compatibility:
40 // 1) Scalar type must match
41 // 2) Number of states must match
42 // 3) Dimension must be different by at most one rank,
43 // where the tags match for the smaller rank.
44 void verify_field_type( const char * arg_method ,
45  const FieldBase & arg_field ,
46  const DataTraits & arg_traits ,
47  unsigned arg_rank ,
48  const shards::ArrayDimTag * const * arg_dim_tags ,
49  unsigned arg_num_states )
50 {
51 
52  const bool ok_traits = arg_traits.is_void
53  || & arg_traits == & arg_field.data_traits();
54 
55  const bool ok_number_states =
56  ! arg_num_states || arg_num_states == arg_field.number_of_states();
57 
58  bool ok_dimension = ! arg_rank || arg_rank == arg_field.rank() ||
59  arg_rank + 1 == arg_field.rank() ||
60  arg_rank - 1 == arg_field.rank() ;
61 
62  const unsigned check_rank = arg_rank < arg_field.rank() ?
63  arg_rank : arg_field.rank() ;
64 
65  for ( unsigned i = 0 ; i < check_rank && ok_dimension ; ++i ) {
66  ok_dimension = arg_dim_tags[i] == arg_field.dimension_tags()[i] ;
67  }
68 
69  ThrowErrorMsgIf( ! ok_traits || ! ok_number_states || ! ok_dimension,
70  arg_method << " FAILED: Existing field = " <<
71  print_field_type( arg_field.data_traits() ,
72  arg_field.rank() ,
73  arg_field.dimension_tags() ) <<
74  "[ name = \"" << arg_field.name() <<
75  "\" , #states = " << arg_field.number_of_states() << " ]" <<
76  " Expected field info = " <<
77  print_field_type( arg_traits , arg_rank , arg_dim_tags ) <<
78  "[ #states = " << arg_num_states << " ]");
79 }
80 
81 } //unamed namespace
82 
83 //----------------------------------------------------------------------
84 
85 FieldBase * FieldRepository::get_field(
86  const char * arg_method ,
87  const std::string & arg_name ,
88  const DataTraits & arg_traits ,
89  unsigned arg_rank ,
90  const shards::ArrayDimTag * const * arg_dim_tags ,
91  unsigned arg_num_states ) const
92 {
93  FieldBase * f = NULL ;
94 
95  for ( std::vector<FieldBase*>::const_iterator
96  j = m_fields.begin() ;
97  j != m_fields.end() && NULL == f ; ++j ) {
98  if ( equal_case( (*j)->name() , arg_name ) ) {
99 
100  f = *j ;
101 
102  verify_field_type( arg_method , *f , arg_traits ,
103  arg_rank , arg_dim_tags , arg_num_states );
104  }
105  }
106  return f ;
107 }
108 
109 FieldBase * FieldRepository::declare_field(
110  const std::string & arg_name ,
111  const DataTraits & arg_traits ,
112  unsigned arg_rank ,
113  const shards::ArrayDimTag * const * arg_dim_tags ,
114  unsigned arg_num_states ,
115  MetaData * arg_meta_data )
116 {
117  TraceIf("stk_classic::mesh::impl::FieldRepository::declare_field", LOG_FIELD);
118 
119  static const char* reserved_state_suffix[6] = {
120  "_STKFS_OLD",
121  "_STKFS_N",
122  "_STKFS_NM1",
123  "_STKFS_NM2",
124  "_STKFS_NM3",
125  "_STKFS_NM4"
126  };
127 
128  // Check that the name does not have a reserved suffix
129 
130  for ( unsigned i = 0 ; i < 6 ; ++i ) {
131  const int len_name = arg_name.size();
132  const int len_suffix = std::strlen( reserved_state_suffix[i] );
133  const int offset = len_name - len_suffix ;
134  if ( 0 <= offset ) {
135  const char * const name_suffix = arg_name.c_str() + offset ;
136  ThrowErrorMsgIf( equal_case( name_suffix , reserved_state_suffix[i] ),
137  "For name = \"" << name_suffix <<
138  "\" CANNOT HAVE THE RESERVED STATE SUFFIX \"" <<
139  reserved_state_suffix[i] << "\"" );
140  }
141  }
142 
143  // Check that the field of this name has not already been declared
144 
145  FieldBase * f[ MaximumFieldStates ] ;
146 
147  f[0] = get_field(
148  "FieldRepository::declare_field" ,
149  arg_name ,
150  arg_traits ,
151  arg_rank ,
152  arg_dim_tags ,
153  arg_num_states
154  );
155 
156  if ( NULL != f[0] ) {
157  for ( unsigned i = 1 ; i < arg_num_states ; ++i ) {
158  f[i] = f[0]->m_impl.field_state(static_cast<FieldState>(i));
159  }
160  }
161  else {
162  // Field does not exist then create it
163 
164  std::string field_names[ MaximumFieldStates ];
165 
166  field_names[0] = arg_name ;
167 
168  if ( 2 == arg_num_states ) {
169  field_names[1] = arg_name ;
170  field_names[1].append( reserved_state_suffix[0] );
171  }
172  else {
173  for ( unsigned i = 1 ; i < arg_num_states ; ++i ) {
174  field_names[i] = arg_name ;
175  field_names[i].append( reserved_state_suffix[i] );
176  }
177  }
178 
179  for ( unsigned i = 0 ; i < arg_num_states ; ++i ) {
180 
181  f[i] = new FieldBase(
182  arg_meta_data ,
183  m_fields.size() ,
184  field_names[i] ,
185  arg_traits ,
186  arg_rank,
187  arg_dim_tags,
188  arg_num_states ,
189  static_cast<FieldState>(i)
190  );
191 
192  m_fields.push_back( f[i] );
193  }
194 
195  for ( unsigned i = 0 ; i < arg_num_states ; ++i ) {
196  f[i]->m_impl.set_field_states( f );
197  }
198  }
199 
200  return f[0] ;
201 }
202 
203 void FieldRepository::verify_and_clean_restrictions(
204  const char * arg_method ,
205  const Part& superset, const Part& subset,
206  const PartVector & arg_all_parts )
207 {
208  TraceIf("stk_classic::mesh::impl::FieldRepository::verify_and_clean_restrictions", LOG_FIELD);
209 
210  for ( FieldVector::iterator f = m_fields.begin() ; f != m_fields.end() ; ++f ) {
211  (*f)->m_impl.verify_and_clean_restrictions( arg_method, superset, subset, arg_all_parts );
212  }
213 }
214 
215 FieldRepository::~FieldRepository() {
216  try {
217  FieldVector::iterator j = m_fields.begin();
218  for ( ; j != m_fields.end() ; ++j ) { delete *j ; }
219  m_fields.clear();
220  } catch(...) {}
221 }
222 
223 } // namespace impl
224 } // namespace mesh
225 } // namespace stk_classic
const stk_classic::mesh::FieldBase * get_field(const FieldIdMap &field_id_map, int field_id)
Definition: ImplDetails.cpp:51
Sierra Toolkit.
bool equal_case(const char *lhs, const char *rhs)
Case-insensitive equality compare.
std::vector< Part *> PartVector
Collections of parts are frequently maintained as a vector of Part pointers.
Definition: Types.hpp:31
FieldState
Enumeration of states for multi-state fields.
Definition: FieldState.hpp:34