Sierra Toolkit Version of the Day
AlgorithmRunSimple.hpp
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 {
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::mesh::Bucket &bucket) = 0;
00055 };
00056 
00057 
00058 typedef std::vector<AlgField *> AlgFieldVector;
00059 
00060 
00061 class Algorithm
00062 {
00063 public:
00064   Algorithm(stk::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::mesh::Bucket& bucket, int begin, int end ) {
00081 //     run(bucket, begin, end);
00082 //   }
00083   
00084 public:
00085   const stk::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::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::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::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::mesh::Bucket &bucket) {
00125     m_ptr = stk::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::mesh::Cartesian>
00153 {
00154   static unsigned value(const stk::mesh::Bucket &bucket) {
00155     return 3;
00156   }
00157 };
00158 
00159 
00160 template <>
00161 struct DimTagInfo<void>
00162 {
00163   static unsigned value(const stk::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::mesh::GatherField <stk::mesh::Field<Scalar,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7>, Relation> > : public AlgField
00177 {
00178   typedef stk::mesh::Field<Scalar,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7> T;
00179   typedef typename stk::mesh::GatherField<stk::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::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::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::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::mesh::Bucket &bucket) {
00214     m_begin = stk::mesh::field_data<PtrField>(m_field, bucket.begin());
00215     m_end = stk::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::mesh::BucketArray<PtrField> gather_array(m_field, bucket);
00228 
00229     dims[stk::mesh::FieldTraits<T>::Rank] = gather_array.dimension(0);
00230     dims[stk::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::mesh::GatherField <stk::mesh::Field<Scalar,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7>, Relation> > : public AlgField
00287 {
00288   typedef stk::mesh::Field<Scalar,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7> T;
00289   typedef typename stk::mesh::GatherField<stk::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::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::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::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::mesh::Bucket &bucket) {
00328     m_begin = stk::mesh::field_data<PtrField>(m_field, bucket.begin());
00329     m_end = stk::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::mesh::BucketArray<T>
00349 {
00350   typedef stk::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::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::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::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::mesh::Field<Scalar,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7> >
00391 {
00392 public:
00393   typedef stk::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::AlgorithmWork & work )
00417   {
00418     //const stk::mesh::Bucket& bucket = work.bucket ;
00419     if (m_fillValue.size()) { 
00420       Scalar *begin_p = stk::mesh::field_data<Field>(m_field, work.bucket_slice_begin);
00421       Scalar *end_p = stk::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::mesh::field_data<Field>(m_field, work.bucket_slice_begin);
00427       Scalar *end_p = stk::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
00439 
00440 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines