OPAL (Object Oriented Parallel Accelerator Library) 2022.1
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"
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
41template<class OP>
42struct PAIsAssign { enum { assign = 0 }; };
43
44template<>
45struct 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.
53template<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.
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
void assign(SubParticleAttrib< PA, T, Dim > a, RHS b, OP, ExprTag< true >)
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
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
#define PInsist(c, m)
Definition: PAssert.h:120
#define INCIPPLSTAT(stat)
Definition: IpplStats.h:236
#define ERRORMSG(msg)
Definition: IpplInfo.h:350
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