|
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 #ifndef stk_algsup_AlgorithmRunSimple_hpp 00010 #define stk_algsup_AlgorithmRunSimple_hpp 00011 00012 #include <string> 00013 00014 #include <Shards_ArrayVector.hpp> 00015 00016 #include <stk_mesh/base/Types.hpp> 00017 #include <stk_mesh/base/FieldData.hpp> 00018 #include <stk_algsup/AlgorithmRunner.hpp> 00019 00020 namespace stk_classic { 00021 namespace mesh { 00026 template< class F, class R > 00027 class GatherField 00028 : public Field<typename FieldTraits<F>::data_type *, R> 00029 { 00030 #ifndef DOXYGEN_COMPILE 00031 00032 public: 00033 typedef Field<typename FieldTraits<F>::data_type *, R> PtrField; 00034 00035 typedef F RelatedField; 00036 typedef R Relation; 00037 00038 private: 00039 00040 ~GatherField(); 00041 GatherField(); 00042 GatherField( const GatherField & ); 00043 GatherField & operator = ( const GatherField & ); 00044 00045 #endif /* DOXYGEN_COMPILE */ 00046 }; 00047 } // namespace mesh 00048 00049 struct AlgField 00050 { 00051 virtual ~AlgField() 00052 {} 00053 00054 virtual void set(const stk_classic::mesh::Bucket &bucket) = 0; 00055 }; 00056 00057 00058 typedef std::vector<AlgField *> AlgFieldVector; 00059 00060 00061 class Algorithm 00062 { 00063 public: 00064 Algorithm(stk_classic::mesh::MetaData &meta_data) 00065 : m_metaData(meta_data) 00066 {} 00067 00068 virtual ~Algorithm() 00069 {} 00070 00071 void add_field(AlgField *field) { 00072 m_fieldVector.push_back(field); 00073 } 00074 00075 virtual void apply( const AlgorithmWork & ) = 0 ; 00076 00077 // static void number_cruncher(.....); 00078 00079 00080 // void run(const stk_classic::mesh::Bucket& bucket, int begin, int end ) { 00081 // run(bucket, begin, end); 00082 // } 00083 00084 public: 00085 const stk_classic::mesh::MetaData & m_metaData; 00086 00087 private: 00088 AlgFieldVector m_fieldVector; 00089 }; 00090 00091 00092 template <class T> 00093 struct AlgFieldPtr : public AlgField 00094 { 00095 typedef typename stk_classic::mesh::FieldTraits<T>::data_type Scalar; 00096 00097 AlgFieldPtr(Algorithm *algorithm, const char *name) 00098 : m_field(*algorithm->m_metaData.get_field<T>(name)) 00099 { 00100 algorithm->add_field(this); 00101 } 00102 00103 AlgFieldPtr(Algorithm *algorithm, const char *name, stk_classic::mesh::FieldState field_state) 00104 : m_field(algorithm->m_metaData.get_field<T>(name)->field_of_state(field_state)) 00105 { 00106 algorithm->add_field(this); 00107 } 00108 00109 AlgFieldPtr(Algorithm *algorithm, T &field) 00110 : m_field(field) 00111 { 00112 algorithm->add_field(this); 00113 } 00114 00115 AlgFieldPtr(Algorithm *algorithm, T &field, stk_classic::mesh::FieldState field_state) 00116 : m_field(field.field_of_state(field_state)) 00117 { 00118 algorithm->add_field(this); 00119 } 00120 00121 virtual ~AlgFieldPtr() 00122 {} 00123 00124 virtual void set(const stk_classic::mesh::Bucket &bucket) { 00125 m_ptr = stk_classic::mesh::field_data<T>(m_field, bucket.begin()); 00126 } 00127 00128 T & m_field; 00129 Scalar * m_ptr; 00130 }; 00131 00132 00133 template< class ArrayType > 00134 struct ToArrayVector 00135 {}; 00136 00137 00138 template< typename Scalar , shards::ArrayOrder Order , 00139 class Tag1 , class Tag2 , class Tag3 , class Tag4 , 00140 class Tag5 , class Tag6 , class Tag7> 00141 struct ToArrayVector< shards::Array<Scalar,Order,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,void> > 00142 { 00143 typedef shards::ArrayVector<Scalar,Order,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,void> ArrayVectorType; 00144 }; 00145 00146 00147 template <class T> 00148 struct DimTagInfo; 00149 00150 00151 template <> 00152 struct DimTagInfo<stk_classic::mesh::Cartesian> 00153 { 00154 static unsigned value(const stk_classic::mesh::Bucket &bucket) { 00155 return 3; 00156 } 00157 }; 00158 00159 00160 template <> 00161 struct DimTagInfo<void> 00162 { 00163 static unsigned value(const stk_classic::mesh::Bucket &bucket) { 00164 return 0; 00165 } 00166 }; 00167 00168 00169 template <class RelationField> 00170 class AlgFieldGather; 00171 00172 00173 template< typename Scalar , 00174 class Tag1 , class Tag2 , class Tag3 , class Tag4 , 00175 class Tag5 , class Tag6 , class Tag7, class Relation> 00176 struct AlgFieldGather< stk_classic::mesh::GatherField <stk_classic::mesh::Field<Scalar,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7>, Relation> > : public AlgField 00177 { 00178 typedef stk_classic::mesh::Field<Scalar,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7> T; 00179 typedef typename stk_classic::mesh::GatherField<stk_classic::mesh::Field<Scalar,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7>, Relation>::PtrField PtrField; 00180 typedef typename ToArrayVector<typename shards::ArrayAppend< typename shards::ArrayAppend< shards::Array<Scalar,shards::FortranOrder,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7>, Relation>::type, stk_classic::mesh::EntityDimension >::type>::ArrayVectorType ScratchArray; 00181 00182 AlgFieldGather(Algorithm *algorithm, const char *name) 00183 : m_field(*algorithm->m_metaData.get_field<PtrField>(name)), 00184 m_array() 00185 { 00186 algorithm->add_field(this); 00187 } 00188 00189 AlgFieldGather(Algorithm *algorithm, const char *name, stk_classic::mesh::FieldState field_state) 00190 : m_field(algorithm->m_metaData.get_field<PtrField>(name)->field_of_state(field_state)), 00191 m_array() 00192 { 00193 algorithm->add_field(this); 00194 } 00195 00196 // AlgFieldGather(Algorithm *algorithm, T &field) 00197 // : m_field(field), 00198 // m_array() 00199 // { 00200 // algorithm->add_field(this); 00201 // } 00202 00203 // AlgFieldGather(Algorithm *algorithm, T &field, stk_classic::mesh::FieldState field_state) 00204 // : m_field(field.field_of_state(field_state)), 00205 // m_array() 00206 // { 00207 // algorithm->add_field(this); 00208 // } 00209 00210 virtual ~AlgFieldGather() 00211 {} 00212 00213 virtual void set(const stk_classic::mesh::Bucket &bucket) { 00214 m_begin = stk_classic::mesh::field_data<PtrField>(m_field, bucket.begin()); 00215 m_end = stk_classic::mesh::field_data<PtrField>(m_field, bucket.end()); 00216 00217 unsigned dims[8]; 00218 dims[0] = DimTagInfo<Tag1>::value(bucket); 00219 dims[1] = DimTagInfo<Tag2>::value(bucket); 00220 dims[2] = DimTagInfo<Tag3>::value(bucket); 00221 dims[3] = DimTagInfo<Tag4>::value(bucket); 00222 dims[4] = DimTagInfo<Tag5>::value(bucket); 00223 dims[5] = DimTagInfo<Tag6>::value(bucket); 00224 dims[6] = DimTagInfo<Tag7>::value(bucket); 00225 dims[7] = 0; 00226 00227 stk_classic::mesh::BucketArray<PtrField> gather_array(m_field, bucket); 00228 00229 dims[stk_classic::mesh::FieldTraits<T>::Rank] = gather_array.dimension(0); 00230 dims[stk_classic::mesh::FieldTraits<T>::Rank + 1] = gather_array.dimension(1); 00231 00232 m_array.resize(&dims[0]); 00233 m_size = 1; 00234 for (int i = 0; i < ScratchArray::Rank - 2; ++i) 00235 m_size *= m_array.dimension(i); 00236 00237 m_ptr = m_array.contiguous_data(); 00238 } 00239 00240 void fill(const Scalar &value) { 00241 Scalar *d = m_ptr; 00242 for (Scalar **p = m_begin; p != m_end; ++p) 00243 for (Scalar *q = *p; q != *p + m_size; ++q) 00244 *d++ = value; 00245 } 00246 00247 void gather() { 00248 Scalar *d = m_ptr; 00249 for (Scalar **p = m_begin; p != m_end; ++p) 00250 for (Scalar *q = *p; q != *p + m_size; ++q) 00251 *d++ = *q; 00252 } 00253 00254 void scatter() 00255 { 00256 Scalar *d = m_ptr; 00257 for (Scalar **p = m_begin; p != m_end; ++p) 00258 for (Scalar *q = *p; q != *p + m_size; ++q) 00259 *q = *d++; 00260 } 00261 00262 void assemble() 00263 { 00264 Scalar *d = m_ptr; 00265 for (Scalar **p = m_begin; p != m_end; ++p) 00266 for (Scalar *q = *p; q != *p + m_size; ++q) 00267 *q += *d++; 00268 } 00269 00270 PtrField & m_field; 00271 Scalar ** m_begin; 00272 Scalar ** m_end; 00273 Scalar * m_ptr; 00274 unsigned m_size; 00275 ScratchArray m_array; 00276 }; 00277 00278 00279 template <class RelationField> 00280 class AlgFieldX; 00281 00282 00283 template< typename Scalar , 00284 class Tag1 , class Tag2 , class Tag3 , class Tag4 , 00285 class Tag5 , class Tag6 , class Tag7, class Relation> 00286 struct AlgFieldX< stk_classic::mesh::GatherField <stk_classic::mesh::Field<Scalar,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7>, Relation> > : public AlgField 00287 { 00288 typedef stk_classic::mesh::Field<Scalar,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7> T; 00289 typedef typename stk_classic::mesh::GatherField<stk_classic::mesh::Field<Scalar,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7>, Relation>::PtrField PtrField; 00290 typedef typename shards::ArrayAppend< typename shards::ArrayAppend< shards::Array<Scalar,shards::FortranOrder,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7>, Relation>::type, stk_classic::mesh::EntityDimension >::type Array; 00291 00292 AlgFieldX(Algorithm *algorithm, const char *name) 00293 : m_field(*algorithm->m_metaData.get_field<PtrField>(name)), 00294 m_begin(0), 00295 m_end(0), 00296 m_ptr(0) 00297 { 00298 algorithm->add_field(this); 00299 } 00300 00301 AlgFieldX(Algorithm *algorithm, const char *name, stk_classic::mesh::FieldState field_state) 00302 : m_field(algorithm->m_metaData.get_field<PtrField>(name)->field_of_state(field_state)), 00303 m_begin(0), 00304 m_end(0), 00305 m_ptr(0) 00306 { 00307 algorithm->add_field(this); 00308 } 00309 00310 // AlgFieldX(Algorithm *algorithm, T &field) 00311 // : m_field(field), 00312 // m_array() 00313 // { 00314 // algorithm->add_field(this); 00315 // } 00316 00317 // AlgFieldX(Algorithm *algorithm, T &field, stk_classic::mesh::FieldState field_state) 00318 // : m_field(field.field_of_state(field_state)), 00319 // m_array() 00320 // { 00321 // algorithm->add_field(this); 00322 // } 00323 00324 virtual ~AlgFieldX() 00325 {} 00326 00327 virtual void set(const stk_classic::mesh::Bucket &bucket) { 00328 m_begin = stk_classic::mesh::field_data<PtrField>(m_field, bucket.begin()); 00329 m_end = stk_classic::mesh::field_data<PtrField>(m_field, bucket.end()); 00330 m_ptr = m_begin; 00331 } 00332 00333 // PtrField::Array get(unsigned i) 00334 // { 00335 // return PtrField::Array(m_begi 00336 // void fill(const T::Array &value) { 00337 // std::fill(m_ptr, m_ptr + m_array.size(), value); 00338 // } 00339 00340 PtrField & m_field; 00341 Scalar ** m_begin; 00342 Scalar ** m_end; 00343 Scalar ** m_ptr; 00344 }; 00345 00346 00347 template <class T> 00348 struct AlgFieldArray : public AlgField, public stk_classic::mesh::BucketArray<T> 00349 { 00350 typedef stk_classic::mesh::BucketArray<T> Array; 00351 00352 AlgFieldArray(Algorithm *algorithm, const char *name) 00353 : m_field(*algorithm->m_metaData.get_field<T>(name)) 00354 { 00355 algorithm->add_field(this); 00356 } 00357 00358 AlgFieldArray(Algorithm *algorithm, const char *name, stk_classic::mesh::FieldState field_state) 00359 : m_field(algorithm->m_metaData.get_field<T>(name)->field_of_state(field_state)) 00360 { 00361 algorithm->add_field(this); 00362 } 00363 00364 AlgFieldArray(Algorithm *algorithm, T &field) 00365 : m_field(field) 00366 { 00367 algorithm->add_field(this); 00368 } 00369 00370 AlgFieldArray(Algorithm *algorithm, T &field, stk_classic::mesh::FieldState field_state) 00371 : m_field(field.field_of_state(field_state)) 00372 { 00373 algorithm->add_field(this); 00374 } 00375 00376 virtual void set(const stk_classic::mesh::Bucket &bucket) { 00377 Array::setup(m_field, bucket); 00378 } 00379 00380 T & m_field; 00381 }; 00382 00383 00384 template <class Field> 00385 class FillFieldAlgorithm; 00386 00387 template< typename Scalar , 00388 class Tag1 , class Tag2 , class Tag3 , class Tag4 , 00389 class Tag5 , class Tag6 , class Tag7> 00390 class FillFieldAlgorithm< stk_classic::mesh::Field<Scalar,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7> > 00391 { 00392 public: 00393 typedef stk_classic::mesh::Field<Scalar,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7> Field; 00394 typedef shards::ArrayVector<Scalar,shards::FortranOrder, Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7> FillArray; 00395 00396 FillFieldAlgorithm(Field &field, const FillArray &fill_value) 00397 : m_field(field), 00398 m_fillValue(), 00399 m_value(0) 00400 { 00401 std::vector<unsigned> dims; 00402 fill_value.dimensions(dims); 00403 00404 m_fillValue.resize(&dims[0]); 00405 std::copy(fill_value.contiguous_data(), fill_value.contiguous_data() + fill_value.size(), m_fillValue.contiguous_data()); 00406 } 00407 00408 FillFieldAlgorithm(Field &field, const Scalar &value) 00409 : m_field(field), 00410 m_fillValue(), 00411 m_value(value) 00412 {} 00413 00414 enum { chunk_size = 0 }; 00415 00416 void apply( const stk_classic::AlgorithmWork & work ) 00417 { 00418 //const stk_classic::mesh::Bucket& bucket = work.bucket ; 00419 if (m_fillValue.size()) { 00420 Scalar *begin_p = stk_classic::mesh::field_data<Field>(m_field, work.bucket_slice_begin); 00421 Scalar *end_p = stk_classic::mesh::field_data<Field>(m_field, work.bucket_slice_end); 00422 for (Scalar *p = begin_p; p != end_p; p += m_fillValue.size()) 00423 std::copy(m_fillValue.contiguous_data(), m_fillValue.contiguous_data() + m_fillValue.size(), p); 00424 } 00425 else { 00426 Scalar *begin_p = stk_classic::mesh::field_data<Field>(m_field, work.bucket_slice_begin); 00427 Scalar *end_p = stk_classic::mesh::field_data<Field>(m_field, work.bucket_slice_end); 00428 std::fill(begin_p, end_p, m_value); 00429 } 00430 } 00431 00432 private: 00433 Field & m_field; 00434 FillArray m_fillValue; 00435 Scalar m_value; 00436 }; 00437 00438 } // namespace stk_classic 00439 00440 #endif