Sierra Toolkit  Version of the Day
AlgorithmRunSimple.hpp
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 #ifndef stk_algsup_AlgorithmRunSimple_hpp
10 #define stk_algsup_AlgorithmRunSimple_hpp
11 
12 #include <string>
13 
14 #include <Shards_ArrayVector.hpp>
15 
16 #include <stk_mesh/base/Types.hpp>
17 #include <stk_mesh/base/FieldData.hpp>
18 #include <stk_algsup/AlgorithmRunner.hpp>
19 
20 namespace stk_classic {
21 namespace mesh {
26 template< class F, class R >
28  : public Field<typename FieldTraits<F>::data_type *, R>
29 {
30 #ifndef DOXYGEN_COMPILE
31 
32  public:
33  typedef Field<typename FieldTraits<F>::data_type *, R> PtrField;
34 
35  typedef F RelatedField;
36  typedef R Relation;
37 
38  private:
39 
40  ~GatherField();
41  GatherField();
42  GatherField( const GatherField & );
43  GatherField & operator = ( const GatherField & );
44 
45 #endif /* DOXYGEN_COMPILE */
46 };
47 } // namespace mesh
48 
49 struct AlgField
50 {
51  virtual ~AlgField()
52  {}
53 
54  virtual void set(const stk_classic::mesh::Bucket &bucket) = 0;
55 };
56 
57 
58 typedef std::vector<AlgField *> AlgFieldVector;
59 
60 
61 class Algorithm
62 {
63 public:
64  Algorithm(stk_classic::mesh::MetaData &meta_data)
65  : m_metaData(meta_data)
66  {}
67 
68  virtual ~Algorithm()
69  {}
70 
71  void add_field(AlgField *field) {
72  m_fieldVector.push_back(field);
73  }
74 
75  virtual void apply( const AlgorithmWork & ) = 0 ;
76 
77 // static void number_cruncher(.....);
78 
79 
80 // void run(const stk_classic::mesh::Bucket& bucket, int begin, int end ) {
81 // run(bucket, begin, end);
82 // }
83 
84 public:
85  const stk_classic::mesh::MetaData & m_metaData;
86 
87 private:
88  AlgFieldVector m_fieldVector;
89 };
90 
91 
92 template <class T>
93 struct AlgFieldPtr : public AlgField
94 {
95  typedef typename stk_classic::mesh::FieldTraits<T>::data_type Scalar;
96 
97  AlgFieldPtr(Algorithm *algorithm, const char *name)
98  : m_field(*algorithm->m_metaData.get_field<T>(name))
99  {
100  algorithm->add_field(this);
101  }
102 
103  AlgFieldPtr(Algorithm *algorithm, const char *name, stk_classic::mesh::FieldState field_state)
104  : m_field(algorithm->m_metaData.get_field<T>(name)->field_of_state(field_state))
105  {
106  algorithm->add_field(this);
107  }
108 
109  AlgFieldPtr(Algorithm *algorithm, T &field)
110  : m_field(field)
111  {
112  algorithm->add_field(this);
113  }
114 
115  AlgFieldPtr(Algorithm *algorithm, T &field, stk_classic::mesh::FieldState field_state)
116  : m_field(field.field_of_state(field_state))
117  {
118  algorithm->add_field(this);
119  }
120 
121  virtual ~AlgFieldPtr()
122  {}
123 
124  virtual void set(const stk_classic::mesh::Bucket &bucket) {
125  m_ptr = stk_classic::mesh::field_data<T>(m_field, bucket.begin());
126  }
127 
128  T & m_field;
129  Scalar * m_ptr;
130 };
131 
132 
133 template< class ArrayType >
134 struct ToArrayVector
135 {};
136 
137 
138 template< typename Scalar , shards::ArrayOrder Order ,
139  class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
140  class Tag5 , class Tag6 , class Tag7>
141 struct ToArrayVector< shards::Array<Scalar,Order,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,void> >
142 {
143  typedef shards::ArrayVector<Scalar,Order,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,void> ArrayVectorType;
144 };
145 
146 
147 template <class T>
148 struct DimTagInfo;
149 
150 
151 template <>
152 struct DimTagInfo<stk_classic::mesh::Cartesian>
153 {
154  static unsigned value(const stk_classic::mesh::Bucket &bucket) {
155  return 3;
156  }
157 };
158 
159 
160 template <>
161 struct DimTagInfo<void>
162 {
163  static unsigned value(const stk_classic::mesh::Bucket &bucket) {
164  return 0;
165  }
166 };
167 
168 
169 template <class RelationField>
170 class AlgFieldGather;
171 
172 
173 template< typename Scalar ,
174  class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
175  class Tag5 , class Tag6 , class Tag7, class Relation>
176 struct AlgFieldGather< stk_classic::mesh::GatherField <stk_classic::mesh::Field<Scalar,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7>, Relation> > : public AlgField
177 {
180  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;
181 
182  AlgFieldGather(Algorithm *algorithm, const char *name)
183  : m_field(*algorithm->m_metaData.get_field<PtrField>(name)),
184  m_array()
185  {
186  algorithm->add_field(this);
187  }
188 
189  AlgFieldGather(Algorithm *algorithm, const char *name, stk_classic::mesh::FieldState field_state)
190  : m_field(algorithm->m_metaData.get_field<PtrField>(name)->field_of_state(field_state)),
191  m_array()
192  {
193  algorithm->add_field(this);
194  }
195 
196 // AlgFieldGather(Algorithm *algorithm, T &field)
197 // : m_field(field),
198 // m_array()
199 // {
200 // algorithm->add_field(this);
201 // }
202 
203 // AlgFieldGather(Algorithm *algorithm, T &field, stk_classic::mesh::FieldState field_state)
204 // : m_field(field.field_of_state(field_state)),
205 // m_array()
206 // {
207 // algorithm->add_field(this);
208 // }
209 
210  virtual ~AlgFieldGather()
211  {}
212 
213  virtual void set(const stk_classic::mesh::Bucket &bucket) {
214  m_begin = stk_classic::mesh::field_data<PtrField>(m_field, bucket.begin());
215  m_end = stk_classic::mesh::field_data<PtrField>(m_field, bucket.end());
216 
217  unsigned dims[8];
218  dims[0] = DimTagInfo<Tag1>::value(bucket);
219  dims[1] = DimTagInfo<Tag2>::value(bucket);
220  dims[2] = DimTagInfo<Tag3>::value(bucket);
221  dims[3] = DimTagInfo<Tag4>::value(bucket);
222  dims[4] = DimTagInfo<Tag5>::value(bucket);
223  dims[5] = DimTagInfo<Tag6>::value(bucket);
224  dims[6] = DimTagInfo<Tag7>::value(bucket);
225  dims[7] = 0;
226 
227  stk_classic::mesh::BucketArray<PtrField> gather_array(m_field, bucket);
228 
229  dims[stk_classic::mesh::FieldTraits<T>::Rank] = gather_array.dimension(0);
230  dims[stk_classic::mesh::FieldTraits<T>::Rank + 1] = gather_array.dimension(1);
231 
232  m_array.resize(&dims[0]);
233  m_size = 1;
234  for (int i = 0; i < ScratchArray::Rank - 2; ++i)
235  m_size *= m_array.dimension(i);
236 
237  m_ptr = m_array.contiguous_data();
238  }
239 
240  void fill(const Scalar &value) {
241  Scalar *d = m_ptr;
242  for (Scalar **p = m_begin; p != m_end; ++p)
243  for (Scalar *q = *p; q != *p + m_size; ++q)
244  *d++ = value;
245  }
246 
247  void gather() {
248  Scalar *d = m_ptr;
249  for (Scalar **p = m_begin; p != m_end; ++p)
250  for (Scalar *q = *p; q != *p + m_size; ++q)
251  *d++ = *q;
252  }
253 
254  void scatter()
255  {
256  Scalar *d = m_ptr;
257  for (Scalar **p = m_begin; p != m_end; ++p)
258  for (Scalar *q = *p; q != *p + m_size; ++q)
259  *q = *d++;
260  }
261 
262  void assemble()
263  {
264  Scalar *d = m_ptr;
265  for (Scalar **p = m_begin; p != m_end; ++p)
266  for (Scalar *q = *p; q != *p + m_size; ++q)
267  *q += *d++;
268  }
269 
270  PtrField & m_field;
271  Scalar ** m_begin;
272  Scalar ** m_end;
273  Scalar * m_ptr;
274  unsigned m_size;
275  ScratchArray m_array;
276 };
277 
278 
279 template <class RelationField>
280 class AlgFieldX;
281 
282 
283 template< typename Scalar ,
284  class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
285  class Tag5 , class Tag6 , class Tag7, class Relation>
286 struct AlgFieldX< stk_classic::mesh::GatherField <stk_classic::mesh::Field<Scalar,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7>, Relation> > : public AlgField
287 {
290  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;
291 
292  AlgFieldX(Algorithm *algorithm, const char *name)
293  : m_field(*algorithm->m_metaData.get_field<PtrField>(name)),
294  m_begin(0),
295  m_end(0),
296  m_ptr(0)
297  {
298  algorithm->add_field(this);
299  }
300 
301  AlgFieldX(Algorithm *algorithm, const char *name, stk_classic::mesh::FieldState field_state)
302  : m_field(algorithm->m_metaData.get_field<PtrField>(name)->field_of_state(field_state)),
303  m_begin(0),
304  m_end(0),
305  m_ptr(0)
306  {
307  algorithm->add_field(this);
308  }
309 
310 // AlgFieldX(Algorithm *algorithm, T &field)
311 // : m_field(field),
312 // m_array()
313 // {
314 // algorithm->add_field(this);
315 // }
316 
317 // AlgFieldX(Algorithm *algorithm, T &field, stk_classic::mesh::FieldState field_state)
318 // : m_field(field.field_of_state(field_state)),
319 // m_array()
320 // {
321 // algorithm->add_field(this);
322 // }
323 
324  virtual ~AlgFieldX()
325  {}
326 
327  virtual void set(const stk_classic::mesh::Bucket &bucket) {
328  m_begin = stk_classic::mesh::field_data<PtrField>(m_field, bucket.begin());
329  m_end = stk_classic::mesh::field_data<PtrField>(m_field, bucket.end());
330  m_ptr = m_begin;
331  }
332 
333 // PtrField::Array get(unsigned i)
334 // {
335 // return PtrField::Array(m_begi
336 // void fill(const T::Array &value) {
337 // std::fill(m_ptr, m_ptr + m_array.size(), value);
338 // }
339 
340  PtrField & m_field;
341  Scalar ** m_begin;
342  Scalar ** m_end;
343  Scalar ** m_ptr;
344 };
345 
346 
347 template <class T>
348 struct AlgFieldArray : public AlgField, public stk_classic::mesh::BucketArray<T>
349 {
350  typedef stk_classic::mesh::BucketArray<T> Array;
351 
352  AlgFieldArray(Algorithm *algorithm, const char *name)
353  : m_field(*algorithm->m_metaData.get_field<T>(name))
354  {
355  algorithm->add_field(this);
356  }
357 
358  AlgFieldArray(Algorithm *algorithm, const char *name, stk_classic::mesh::FieldState field_state)
359  : m_field(algorithm->m_metaData.get_field<T>(name)->field_of_state(field_state))
360  {
361  algorithm->add_field(this);
362  }
363 
364  AlgFieldArray(Algorithm *algorithm, T &field)
365  : m_field(field)
366  {
367  algorithm->add_field(this);
368  }
369 
370  AlgFieldArray(Algorithm *algorithm, T &field, stk_classic::mesh::FieldState field_state)
371  : m_field(field.field_of_state(field_state))
372  {
373  algorithm->add_field(this);
374  }
375 
376  virtual void set(const stk_classic::mesh::Bucket &bucket) {
377  Array::setup(m_field, bucket);
378  }
379 
380  T & m_field;
381 };
382 
383 
384 template <class Field>
385 class FillFieldAlgorithm;
386 
387 template< typename Scalar ,
388  class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
389  class Tag5 , class Tag6 , class Tag7>
390 class FillFieldAlgorithm< stk_classic::mesh::Field<Scalar,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7> >
391 {
392 public:
394  typedef shards::ArrayVector<Scalar,shards::FortranOrder, Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7> FillArray;
395 
396  FillFieldAlgorithm(Field &field, const FillArray &fill_value)
397  : m_field(field),
398  m_fillValue(),
399  m_value(0)
400  {
401  std::vector<unsigned> dims;
402  fill_value.dimensions(dims);
403 
404  m_fillValue.resize(&dims[0]);
405  std::copy(fill_value.contiguous_data(), fill_value.contiguous_data() + fill_value.size(), m_fillValue.contiguous_data());
406  }
407 
408  FillFieldAlgorithm(Field &field, const Scalar &value)
409  : m_field(field),
410  m_fillValue(),
411  m_value(value)
412  {}
413 
414  enum { chunk_size = 0 };
415 
416  void apply( const stk_classic::AlgorithmWork & work )
417  {
418  //const stk_classic::mesh::Bucket& bucket = work.bucket ;
419  if (m_fillValue.size()) {
420  Scalar *begin_p = stk_classic::mesh::field_data<Field>(m_field, work.bucket_slice_begin);
421  Scalar *end_p = stk_classic::mesh::field_data<Field>(m_field, work.bucket_slice_end);
422  for (Scalar *p = begin_p; p != end_p; p += m_fillValue.size())
423  std::copy(m_fillValue.contiguous_data(), m_fillValue.contiguous_data() + m_fillValue.size(), p);
424  }
425  else {
426  Scalar *begin_p = stk_classic::mesh::field_data<Field>(m_field, work.bucket_slice_begin);
427  Scalar *end_p = stk_classic::mesh::field_data<Field>(m_field, work.bucket_slice_end);
428  std::fill(begin_p, end_p, m_value);
429  }
430  }
431 
432 private:
433  Field & m_field;
434  FillArray m_fillValue;
435  Scalar m_value;
436 };
437 
438 } // namespace stk_classic
439 
440 #endif
const stk_classic::mesh::FieldBase * get_field(const FieldIdMap &field_id_map, int field_id)
Definition: ImplDetails.cpp:51
The manager of an integrated collection of parts and fields.
Definition: MetaData.hpp:56
Field with defined data type and multi-dimensions (if any)
Field with defined data type and multi-dimensions (if any)
Definition: Field.hpp:118
A relation between two mesh entities with a relation identifier and kind .
Definition: Relation.hpp:58
Sierra Toolkit.
Implement ArrayDimTag for the entity count dimension of a BucketArray.
Definition: FieldData.hpp:196
void fill(ForwardIterator first, ForwardIterator last, const T &value)
A container for the field data of a homogeneous collection of entities.
Definition: Bucket.hpp:94
Field data Array for a given array field and bucket
Definition: FieldData.hpp:65
FieldState
Enumeration of states for multi-state fields.
Definition: FieldState.hpp:34