OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
SubParticleAssign.hpp
Go to the documentation of this file.
1 // -*- C++ -*-
2 /***************************************************************************
3  *
4  * The IPPL Framework
5  *
6  * This program was prepared by PSI.
7  * All rights in the program are reserved by PSI.
8  * Neither PSI nor the author(s)
9  * makes any warranty, express or implied, or assumes any liability or
10  * responsibility for the use of this software
11  *
12  * Visit www.amas.web.psi for more details
13  *
14  ***************************************************************************/
15 
16 // -*- C++ -*-
17 /***************************************************************************
18  *
19  * The IPPL Framework
20  *
21  *
22  * Visit http://people.web.psi.ch/adelmann/ for more details
23  *
24  ***************************************************************************/
25 
26 // include files
31 #include "Index/SIndex.h"
32 #include "Index/LSIndex.h"
33 #include "Field/BrickExpression.h"
34 #include "Utility/IpplStats.h"
35 
36 
37 
39 // simple struct used to indicate whether an operation is just an
40 // assign, or an accumulation
41 template<class OP>
42 struct PAIsAssign { enum { assign = 0 }; };
43 
44 template<>
45 struct PAIsAssign<OpAssign> { enum { assign = 1 }; };
46 
47 
49 // assign an arbitrary expression to a SubParticleAttrib, with an
50 // aligned expression. Note that the ParticleAttrib length may change,
51 // as it will be adjusted to have the same length as the number of local
52 // points in the SIndex indexing the SubParticleAttrib.
53 template<class PA, class T, unsigned Dim, class RHS, class OP>
55 
56  // Make sure the LHS ParticleAttrib has the proper length. It should
57  // have the same length as the number of LOCAL sparse index points.
58  // If it does not, we readjust the length. Note that for accumulations,
59  // like +=, -=, etc., the size must already be OK.
60  if (PAIsAssign<OP>::assign == 1)
61  a.adjustSize();
62  else
63  PInsist(a.getDomain().size() == a.getAttrib().size(),
64  "ParticleAttrib[SIndex] accumulation with wrong-sized attribute.");
65 
66  typedef typename RHS::Wrapped Wrapped;
67 
68  // Get the object wrapped in the PETE expression object
69  // RHS::Wrapped& bb = b.PETE_unwrap();
70  Wrapped& bb = b.PETE_unwrap();
71  // Check to see if the same type of indexing object is used by all
72  // the Field's involved in the expression. If any are different, we
73  // must flag an error. This also checks to make sure that all
74  // indexed fields have the proper number of brackets.
75  PInsist(for_each(bb,SameSubsetType(a.getSubsetType()),PETE_AndCombiner()),
76  "Sparse-Indexed expressions must use consistent indexing.");
77 
78  // Find the 'bounding box' of the LHS domain
79  NDIndex<Dim> boundBox;
80  a.makeNDIndex(boundBox);
81 
82  // Fill guard cells, if necessary ... this is done if the RHS domains
83  // represent a stencil, and the guard cells for the corresponding fields
84  // actually need to be swapped.
85  //tjw for_each(bb, FillGCIfNecessary(boundBox), PETE_NullCombiner());
86 
87  // This weird tag is needed, because using a no-argument FillGCIFNEcessary()
88  // function didn't work for some reason, at least with some compilers like
89  // the pre-7.3 SGI compiler and CodeWarrior Pro4. Once the global function
90  // invocation syntax FillGCIfNecessary<T,D>() is supported by all our
91  // compilers (it's not there yet in the non-beta SGI compiler), should be
92  // able to eliminate this FGCINTag business. --tjw 3/3/1999
94 
95  // Iterators for the LHS components and LField's
96  typename SubParticleAttrib<PA,T,Dim>::iterator sba = a.begin();
98  typename SIndex<Dim>::const_iterator_iv aend = a.end().getLFieldIter();
99 
100  // Do any initial work on the expression it needs before starting.
101  // E.g., for single-value subsets, this will distribute the values to nodes
102  sba.initialize();
104 
105  // Loop over all the local fields of the left hand side.
106  while (la != aend) {
107  // Some typedefs to make the lines shorter...
108  // types for the left hand side, right hand side and
109  // the whole expression.
110  typedef typename SubParticleAttrib<PA,T,Dim>::iterator LHS;
112 
113  // If there are any points in the local SIndex object (for the current
114  // local vnode, that is), there is some work to do here.
115  if ((*la)->size() > 0) {
116  // Now look and see if the RHS arrays are sufficiently aligned.
117  // We do this by trying to do a plugBase and seeing if it worked.
118  if (for_each(bb,PlugBase<Dim>((*la)->getDomain()),PETE_AndCombiner())) {
119  // Loop assign.
120  ExprT(sba,bb).apply();
121  } else {
122  ERRORMSG("All items in an expression must be aligned. ");
123  ERRORMSG("(Do you have enough guard cells?)" << endl);
124  ERRORMSG("This error occurred while evaluating a ");
125  ERRORMSG("SubParticleAttrib-expression ");
126  ERRORMSG("for a vnode with domain " << (*la)->getDomain() << endl);
127  Ippl::abort();
128  }
129  }
130 
131  // move iterators on to the next LField
132  la = sba.nextLField();
134  }
135 
136  INCIPPLSTAT(incParticleExpressions);
137 }
138 
139 
140 /***************************************************************************
141  * $RCSfile: SubParticleAssign.cpp,v $ $Author: adelmann $
142  * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:33 $
143  * IPPL_VERSION_ID: $Id: SubParticleAssign.cpp,v 1.1.1.1 2003/01/23 07:40:33 adelmann Exp $
144  ***************************************************************************/
145 
bool for_each(const BareFieldIterator< T, D > &p, SameFieldID s, C)
Definition: AssignDefs.h:30
FillGCIfNecessaryTag< D, T1 > FillGCIfNecessary(const BareField< T1, D > &bf)
Definition: AssignTags.h:126
std::complex< double > a
void assign(SubParticleAttrib< PA, T, Dim > a, RHS b, OP, ExprTag< true >)
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
#define ERRORMSG(msg)
Definition: IpplInfo.h:350
#define INCIPPLSTAT(stat)
Definition: IpplStats.h:236
#define PInsist(c, m)
Definition: PAssert.h:120
Definition: Assign.h:48
virtual void apply()
container_t::const_iterator const_iterator_iv
Definition: SIndex.h:71
const_iterator_iv nextLField()
const_iterator_iv getLFieldIter() const
static void abort(const char *=0)
Definition: IpplInfo.cpp:616