MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
HopFunc.h
Go to the documentation of this file.
1 /**********************************************************************
2 ** This program is part of 'MOOSE', the
3 ** Messaging Object Oriented Simulation Environment.
4 ** Copyright (C) 2003-2013 Upinder S. Bhalla. and NCBS
5 ** It is made available under the terms of the
6 ** GNU Lesser General Public License version 2.1
7 ** See the file COPYING.LIB for the full notice.
8 **********************************************************************/
9 
10 #ifndef _HOP_FUNC_H
11 #define _HOP_FUNC_H
12 
13 double* addToBuf(
14  const Eref& e, HopIndex hopIndex, unsigned int size );
15 void dispatchBuffers( const Eref& e, HopIndex hopIndex );
16 double* remoteGet( const Eref& e , unsigned int bindIndex );
17 void remoteGetVec( const Eref& e, unsigned int bindIndex,
18  vector< vector< double > >& getRecvBuf,
19  vector< unsigned int >& numOnNode );
20 void remoteFieldGetVec( const Eref& e, unsigned int bindIndex,
21  vector< double >& getRecvBuf );
22 unsigned int mooseNumNodes();
23 unsigned int mooseMyNode();
24 
29 class HopFunc0: public OpFunc0Base
30 {
31  public:
32  HopFunc0( HopIndex hopIndex )
33  : hopIndex_( hopIndex )
34  {;}
35  void op( const Eref& e ) const
36  {
37  addToBuf( e, hopIndex_, 0 );
39  }
40  private:
42 };
43 
44 // Function to hop across nodes, with one argument.
45 template < class A > class HopFunc1: public OpFunc1Base< A >
46 {
47  public:
48  HopFunc1( HopIndex hopIndex )
49  : hopIndex_( hopIndex )
50  {;}
51  void op( const Eref& e, A arg ) const
52  {
53  double* buf = addToBuf( e, hopIndex_, Conv< A >::size( arg ) );
54  Conv< A >::val2buf( arg, &buf );
56  }
57 
59  unsigned int localOpVec( Element* elm,
60  const vector< A >& arg,
61  const OpFunc1Base< A >* op,
62  unsigned int k ) const
63  {
64  unsigned int numLocalData = elm->numLocalData();
65  unsigned int start = elm->localDataStart();
66  for ( unsigned int p = 0; p < numLocalData; ++p ) {
67  unsigned int numField = elm->numField( p );
68  for ( unsigned int q = 0; q < numField; ++q ) {
69  Eref er( elm, p + start, q );
70  op->op( er, arg[ k % arg.size() ] );
71  k++;
72  }
73  }
74  return k;
75  }
76 
78  unsigned int localFieldOpVec( const Eref& er,
79  const vector< A >& arg,
80  const OpFunc1Base< A >* op )
81  const
82  {
83  assert( er.getNode() == mooseMyNode() );
84  unsigned int di = er.dataIndex();
85  Element* elm = er.element();
86  unsigned int numField =
87  elm->numField( di - er.element()->localDataStart() );
88  for ( unsigned int q = 0; q < numField; ++q ) {
89  Eref temp( elm, di, q );
90  op->op( temp, arg[ q % arg.size() ] );
91  }
92  return numField;
93  }
94 
96  unsigned int remoteOpVec( const Eref& er,
97  const vector< A >& arg,
98  const OpFunc1Base< A >* op,
99  unsigned int start, unsigned int end ) const
100  {
101  unsigned int k = start;
102  unsigned int nn = end - start;
103  if ( mooseNumNodes() > 1 && nn > 0 ) {
104  // nn includes dataIndices. FieldIndices are handled by
105  // other functions.
106  vector< A > temp( nn );
107  // Have to do the insertion entry by entry because the
108  // argument vector may wrap around.
109  for ( unsigned int j = 0; j < nn; ++j ) {
110  unsigned int x = k % arg.size();
111  temp[j] = arg[x];
112  k++;
113  }
114  double* buf = addToBuf( er, hopIndex_,
115  Conv< vector< A > >::size( temp ) );
116  Conv< vector< A > >::val2buf( temp, &buf );
117  dispatchBuffers( er, hopIndex_ );
118  // HopIndex says that it is a SetVec call.
119  }
120  return k;
121  }
122 
123  void dataOpVec( const Eref& e, const vector< A >& arg,
124  const OpFunc1Base< A >* op ) const
125  {
126  Element* elm = e.element();
127  vector< unsigned int > endOnNode( mooseNumNodes(), 0 );
128  unsigned int lastEnd = 0;
129  for ( unsigned int i = 0; i < mooseNumNodes(); ++i ) {
130  endOnNode[i] = elm->getNumOnNode(i) + lastEnd;
131  lastEnd = endOnNode[i];
132  }
133  unsigned int k = 0; // counter for index to arg vector.
134  // The global case just sends all entries to all nodes.
135  for ( unsigned int i = 0; i < mooseNumNodes(); ++i ) {
136  if ( i == mooseMyNode() ) {
137  k = localOpVec( elm, arg, op, k );
138  assert( k == endOnNode[i] );
139  } else {
140  if ( !elm->isGlobal() ) {
141  unsigned int start = elm->startDataIndex( i );
142  if ( start < elm->numData() ) {
143  Eref starter( elm, start );
144  assert( elm->getNode( starter.dataIndex() ) == i );
145  k = remoteOpVec( starter, arg, op, k, endOnNode[i]);
146  }
147  }
148  }
149  }
150  if ( elm->isGlobal() ) {
151  Eref starter( elm, 0 );
152  remoteOpVec( starter, arg, op, 0, arg.size() );
153  }
154  }
155 
156  void opVec( const Eref& er, const vector< A >& arg,
157  const OpFunc1Base< A >* op ) const
158  {
159  Element* elm = er.element();
160  if ( elm->hasFields() ) {
161  if ( er.getNode() == mooseMyNode() ) {
162  // True for globals as well as regular objects on current node
163  localFieldOpVec( er, arg, op );
164  }
165  if ( elm->isGlobal() || er.getNode() != mooseMyNode() ) {
166  // Go just to the node where the fields reside, and
167  // assign the vector there. May be all nodes if global.
168  remoteOpVec( er, arg, op, 0, arg.size() );
169  }
170  } else {
171  dataOpVec( er, arg, op );
172  }
173  }
174  private:
176 };
177 
182 template< class A >
184 {
185  return new HopFunc1< A >( hopIndex );
186 }
187 
188 // Function to hop across nodes, with two arguments.
189 template < class A1, class A2 > class HopFunc2: public OpFunc2Base< A1, A2 >
190 {
192 
193  public:
194  HopFunc2( HopIndex hopIndex )
195  : hopIndex_( hopIndex )
196  {;}
197  void op( const Eref& e, A1 arg1, A2 arg2 ) const
198  {
199  double* buf = addToBuf( e, hopIndex_,
200  Conv< A1 >::size( arg1 ) + Conv< A2 >::size( arg2 ) );
201  /*
202  Conv< A1 >::val2buf( arg1, buf );
203  Conv< A2 >::val2buf( arg2, buf + Conv< A1 >.size( arg1 ) );
204  or
205  buf = Conv< A1 >.val2buf( arg1, buf );
206  Conv< A2 >::val2buf( arg2, buf );
207  or
208  */
209  Conv< A1 >::val2buf( arg1, &buf );
210  Conv< A2 >::val2buf( arg2, &buf );
212  }
213 
214  void opVec( const Eref& e,
215  const vector< A1 >& arg1,
216  const vector< A1 >& arg2,
217  const OpFunc2Base< A1, A2 >* op ) const
218  {
219  Element* elm = e.element();
220  unsigned int k = 0; // counter for index to arg vector.
221  if ( elm->isGlobal() ) {
222  // Need to ensure that all nodes get the same args,
223  // as opposed to below, where they are serial.
224  }
225  for ( unsigned int i = 0; i < mooseNumNodes(); ++i ) {
226  if ( i == mooseMyNode() ) {
227  unsigned int numData = elm->numLocalData();
228  for ( unsigned int p = 0; p < numData; ++p ) {
229  unsigned int numField = elm->numField( p );
230  for ( unsigned int q = 0; q < numField; ++q ) {
231  Eref er( elm, p, q );
232  unsigned int x = k % arg1.size();
233  unsigned int y = k % arg2.size();
234  op->op( er, arg1[x], arg2[y] );
235  k++;
236  }
237  }
238  } else {
239  unsigned int dataIndex = k;
240  // nn includes dataIndices and if present fieldIndices
241  // too. It may involve a query to the remote node.
242  unsigned int nn = elm->getNumOnNode( i );
243  vector< A1 > temp1( nn );
244  vector< A2 > temp2( nn );
245  // Have to do the insertion entry by entry because the
246  // argument vectors may wrap around.
247  for ( unsigned int j = 0; j < nn; ++j ) {
248  unsigned int x = k % arg1.size();
249  unsigned int y = k % arg2.size();
250  temp1[j] = arg1[x];
251  temp2[j] = arg2[y];
252  k++;
253  }
254  double* buf = addToBuf( e, hopIndex_,
255  Conv< vector< A1 > >::size( temp1 ) +
256  Conv< vector< A2 > >::size( temp2 ) );
257  Conv< vector< A1 > >::val2buf( temp1, &buf );
258  Conv< vector< A2 > >::val2buf( temp2, &buf );
259  dispatchBuffers( Eref( elm, dataIndex ), hopIndex_ );
260  // HopIndex says that it is a SetVec call.
261  }
262  }
263  }
264  private:
266 };
267 
268 template< class A1, class A2 >
270  HopIndex hopIndex) const
271 {
272  return new HopFunc2< A1, A2 >( hopIndex );
273 }
274 
275 // Function to hop across nodes, with three arguments.
276 template < class A1, class A2, class A3 > class HopFunc3:
277  public OpFunc3Base< A1, A2, A3 >
278 {
279  public:
280  HopFunc3( HopIndex hopIndex )
281  : hopIndex_( hopIndex )
282  {;}
283 
284  void op( const Eref& e, A1 arg1, A2 arg2, A3 arg3 ) const
285  {
286  double* buf = addToBuf( e, hopIndex_,
287  Conv< A1 >::size( arg1 ) + Conv< A2 >::size( arg2 ) +
288  Conv< A3 >::size( arg3 ) );
289  Conv< A1 >::val2buf( arg1, &buf );
290  Conv< A2 >::val2buf( arg2, &buf );
291  Conv< A3 >::val2buf( arg3, &buf );
293  }
294  private:
296 };
297 
298 template< class A1, class A2, class A3 >
300  HopIndex hopIndex) const
301 {
302  return new HopFunc3< A1, A2, A3 >( hopIndex );
303 }
304 
305 // Function to hop across nodes, with three arguments.
306 template < class A1, class A2, class A3, class A4 > class HopFunc4:
307  public OpFunc4Base< A1, A2, A3, A4 >
308 {
309  public:
310  HopFunc4( HopIndex hopIndex )
311  : hopIndex_( hopIndex )
312  {;}
313 
314  void op( const Eref& e, A1 arg1, A2 arg2, A3 arg3, A4 arg4 ) const
315  {
316  double* buf = addToBuf( e, hopIndex_,
317  Conv< A1 >::size( arg1 ) + Conv< A2 >::size( arg2 ) +
318  Conv< A3 >::size( arg3 ) + Conv< A4 >::size( arg4 ) );
319  Conv< A1 >::val2buf( arg1, &buf );
320  Conv< A2 >::val2buf( arg2, &buf );
321  Conv< A3 >::val2buf( arg3, &buf );
322  Conv< A4 >::val2buf( arg4, &buf );
324  }
325  private:
327 };
328 
329 template< class A1, class A2, class A3, class A4 >
331  HopIndex hopIndex) const
332 {
333  return new HopFunc4< A1, A2, A3, A4 >( hopIndex );
334 }
335 
336 // Function to hop across nodes, with three arguments.
337 template < class A1, class A2, class A3, class A4, class A5 >
338  class HopFunc5: public OpFunc5Base< A1, A2, A3, A4, A5 >
339 {
340  public:
341  HopFunc5( HopIndex hopIndex )
342  : hopIndex_( hopIndex )
343  {;}
344 
345  void op( const Eref& e, A1 arg1, A2 arg2, A3 arg3,
346  A4 arg4, A5 arg5 ) const
347  {
348  double* buf = addToBuf( e, hopIndex_,
349  Conv< A1 >::size( arg1 ) + Conv< A2 >::size( arg2 ) +
350  Conv< A3 >::size( arg3 ) + Conv< A4 >::size( arg4 ) +
351  Conv< A5 >::size( arg5 ) );
352  Conv< A1 >::val2buf( arg1, &buf );
353  Conv< A2 >::val2buf( arg2, &buf );
354  Conv< A3 >::val2buf( arg3, &buf );
355  Conv< A4 >::val2buf( arg4, &buf );
356  Conv< A5 >::val2buf( arg5, &buf );
358  }
359  private:
361 };
362 
363 template< class A1, class A2, class A3, class A4, class A5 >
365  HopIndex hopIndex) const
366 {
367  return new HopFunc5< A1, A2, A3, A4, A5 >( hopIndex );
368 }
369 
370 // Function to hop across nodes, with three arguments.
371 template < class A1, class A2, class A3, class A4, class A5, class A6 >
372  class HopFunc6: public OpFunc6Base< A1, A2, A3, A4, A5, A6 >
373 {
374  public:
375  HopFunc6( HopIndex hopIndex )
376  : hopIndex_( hopIndex )
377  {;}
378 
379  void op( const Eref& e, A1 arg1, A2 arg2, A3 arg3,
380  A4 arg4, A5 arg5, A6 arg6 ) const
381  {
382  double* buf = addToBuf( e, hopIndex_,
383  Conv< A1 >::size( arg1 ) + Conv< A2 >::size( arg2 ) +
384  Conv< A3 >::size( arg3 ) + Conv< A4 >::size( arg4 ) +
385  Conv< A5 >::size( arg5 ) + Conv< A6 >::size( arg6 ) );
386  Conv< A1 >::val2buf( arg1, &buf );
387  Conv< A2 >::val2buf( arg2, &buf );
388  Conv< A3 >::val2buf( arg3, &buf );
389  Conv< A4 >::val2buf( arg4, &buf );
390  Conv< A5 >::val2buf( arg5, &buf );
391  Conv< A6 >::val2buf( arg6, &buf );
393  }
394  private:
396 };
397 
398 template< class A1, class A2, class A3, class A4, class A5, class A6 >
400  HopIndex hopIndex) const
401 {
402  return new HopFunc6< A1, A2, A3, A4, A5, A6 >( hopIndex );
403 }
404 
405 
406 // Function to Get value after hop across nodes, with one argument.
407 template < class A > class GetHopFunc: public OpFunc1Base< A* >
408 {
409  public:
410  GetHopFunc( HopIndex hopIndex )
411  : hopIndex_( hopIndex )
412  {;}
413 
414  void op( const Eref& e, A* ret ) const
415  {
416  double* buf = remoteGet( e, hopIndex_.bindIndex() );
417  *ret = Conv< A >::buf2val( &buf );
418  }
419 
420  void getLocalFieldVec( const Eref& er, vector< A >& ret,
421  const GetOpFuncBase< A >* op ) const
422  {
423  unsigned int p = er.dataIndex();
424  Element* elm = er.element();
425  unsigned int numField = elm->numField(
426  p - elm->localDataStart() );
427  for ( unsigned int q = 0; q < numField; ++q ) {
428  Eref temp( elm, p, q );
429  ret.push_back( op->returnOp( temp ) );
430  }
431  }
432 
433  void getRemoteFieldVec( const Eref& e, vector< A >& ret,
434  const GetOpFuncBase< A >* op ) const
435  {
436  vector< double > buf;
438  assert( buf.size() > 0 );
439  unsigned int numField = buf[0];
440  double* val = &buf[1]; // zeroth entry is numField.
441  for ( unsigned int j = 0; j < numField; ++j ) {
442  ret.push_back( Conv< A >::buf2val( &val ) );
443  }
444  }
445 
446  void getLocalVec( Element *elm, vector< A >& ret,
447  const GetOpFuncBase< A >* op ) const
448  {
449  unsigned int start = elm->localDataStart();
450  unsigned int end = start + elm->numLocalData();
451  for ( unsigned int p = start; p < end; ++p ) {
452  Eref er( elm, p, 0 );
453  ret.push_back( op->returnOp( er ) );
454  }
455  }
456 
457  void getMultiNodeVec( const Eref& e, vector< A >& ret,
458  const GetOpFuncBase< A >* op ) const
459  {
460  Element* elm = e.element();
461  vector< vector< double > > buf;
462  vector< unsigned int > numOnNode;
463  remoteGetVec( e, hopIndex_.bindIndex(), buf, numOnNode );
464  assert( numOnNode.size() == mooseNumNodes() );
465  assert( buf.size() == mooseNumNodes() );
466  assert( buf.size() == numOnNode.size() );
467  for ( unsigned int i = 0; i < mooseNumNodes(); ++i ) {
468  if ( i == mooseMyNode() ) {
469  getLocalVec( elm, ret, op );
470  } else {
471  vector< double >& temp = buf[i];
472  assert( static_cast< unsigned int >( temp[0] ) ==
473  numOnNode[i] );
474  double* val = &temp[1]; // zeroth entry is numOnNode.
475  for ( unsigned int j = 0; j < numOnNode[i]; ++j ) {
476  // val++; // Skip the index.
477  // ret.push_back( Conv< A >::buf2val( &temp[k + 1] ) );
478  ret.push_back( Conv< A >::buf2val( &val ) );
479  }
480  }
481  }
482  }
483 
484  void opGetVec( const Eref& e, vector< A >& ret,
485  const GetOpFuncBase< A >* op ) const
486  {
487  Element* elm = e.element();
488  ret.clear();
489  ret.reserve( elm->numData() );
490  if ( elm->hasFields() ) {
491  if ( e.getNode() == mooseMyNode() ) {
492  getLocalFieldVec( e, ret, op );
493  } else {
494  getRemoteFieldVec( e, ret, op );
495  }
496  } else {
497  if ( mooseNumNodes() == 1 || elm->isGlobal() ) {
498  getLocalVec( elm, ret, op );
499  } else {
500  getMultiNodeVec( e, ret, op );
501  }
502  }
503  }
504  private:
506 };
507 
512 template< class A >
514 {
515  return new GetHopFunc< A >( hopIndex );
516 }
517 
518 #endif // _HOP_FUNC_H
static void val2buf(const T &val, double **buf)
Definition: Conv.h:56
virtual A returnOp(const Eref &e) const =0
virtual void op(const Eref &e, A arg) const =0
unsigned int localFieldOpVec(const Eref &er, const vector< A > &arg, const OpFunc1Base< A > *op) const
Executes the local vector assignment. Returns number of entries.
Definition: HopFunc.h:78
unsigned short bindIndex() const
Definition: OpFuncBase.h:32
void opVec(const Eref &er, const vector< A > &arg, const OpFunc1Base< A > *op) const
Definition: HopFunc.h:156
unsigned int getNode() const
Definition: Eref.cpp:52
void op(const Eref &e, A1 arg1, A2 arg2, A3 arg3, A4 arg4) const
Definition: HopFunc.h:314
void op(const Eref &e) const
Definition: HopFunc.h:35
double * addToBuf(const Eref &e, HopIndex hopIndex, unsigned int size)
Definition: HopFunc.cpp:29
void op(const Eref &e, A1 arg1, A2 arg2) const
Definition: HopFunc.h:197
const OpFunc * makeHopFunc(HopIndex hopIndex) const
Definition: HopFunc.h:330
const OpFunc * makeHopFunc(HopIndex hopIndex) const
Definition: HopFunc.h:299
const OpFunc * makeHopFunc(HopIndex hopIndex) const
Definition: HopFunc.h:183
unsigned int dataIndex() const
Definition: Eref.h:50
HopIndex hopIndex_
Definition: HopFunc.h:505
void op(const Eref &e, A arg) const
Definition: HopFunc.h:51
void remoteFieldGetVec(const Eref &e, unsigned int bindIndex, vector< double > &getRecvBuf)
Definition: HopFunc.cpp:79
HopFunc4(HopIndex hopIndex)
Definition: HopFunc.h:310
void opVec(const Eref &e, const vector< A1 > &arg1, const vector< A1 > &arg2, const OpFunc2Base< A1, A2 > *op) const
Definition: HopFunc.h:214
unsigned int localOpVec(Element *elm, const vector< A > &arg, const OpFunc1Base< A > *op, unsigned int k) const
Executes the local vector assignment. Returns current arg index.
Definition: HopFunc.h:59
HopFunc0(HopIndex hopIndex)
Definition: HopFunc.h:32
Element * element() const
Definition: Eref.h:42
void getLocalVec(Element *elm, vector< A > &ret, const GetOpFuncBase< A > *op) const
Definition: HopFunc.h:446
void op(const Eref &e, A1 arg1, A2 arg2, A3 arg3) const
Definition: HopFunc.h:284
void opGetVec(const Eref &e, vector< A > &ret, const GetOpFuncBase< A > *op) const
Definition: HopFunc.h:484
Definition: Conv.h:30
unsigned int remoteOpVec(const Eref &er, const vector< A > &arg, const OpFunc1Base< A > *op, unsigned int start, unsigned int end) const
Dispatches remote vector assignment. start and end are arg index.
Definition: HopFunc.h:96
HopIndex hopIndex_
Definition: HopFunc.h:360
unsigned int mooseNumNodes()
Definition: HopFunc.cpp:87
const OpFunc * makeHopFunc(HopIndex hopIndex) const
Definition: HopFunc.h:399
HopFunc3(HopIndex hopIndex)
Definition: HopFunc.h:280
void remoteGetVec(const Eref &e, unsigned int bindIndex, vector< vector< double > > &getRecvBuf, vector< unsigned int > &numOnNode)
virtual unsigned int getNumOnNode(unsigned int node) const =0
static char dataIndex[]
Definition: mfield.cpp:406
double * remoteGet(const Eref &e, unsigned int bindIndex)
Definition: HopFunc.cpp:63
void dispatchBuffers(const Eref &e, HopIndex hopIndex)
Definition: HopFunc.cpp:47
HopIndex hopIndex_
Definition: HopFunc.h:265
virtual void op(const Eref &e, A1 arg1, A2 arg2) const =0
HopIndex hopIndex_
Definition: HopFunc.h:175
virtual unsigned int numField(unsigned int rawIndex) const =0
Returns number of field entries for specified data.
HopFunc6(HopIndex hopIndex)
Definition: HopFunc.h:375
HopFunc5(HopIndex hopIndex)
Definition: HopFunc.h:341
virtual bool hasFields() const =0
Definition: Eref.h:26
const OpFunc * makeHopFunc(HopIndex hopIndex) const
Definition: HopFunc.h:513
HopIndex hopIndex_
Definition: HopFunc.h:326
void op(const Eref &e, A *ret) const
Definition: HopFunc.h:414
unsigned int mooseMyNode()
Definition: HopFunc.cpp:92
virtual unsigned int numData() const =0
Returns number of data entries across all nodes.
virtual bool isGlobal() const =0
True if there is a copy of every dataEntry on all nodes.
const OpFunc * makeHopFunc(HopIndex hopIndex) const
Definition: HopFunc.h:364
virtual unsigned int localDataStart() const =0
Returns index of first data entry on this node.
virtual unsigned int numLocalData() const =0
Returns number of local data entries on this node.
void op(const Eref &e, A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5, A6 arg6) const
Definition: HopFunc.h:379
void getRemoteFieldVec(const Eref &e, vector< A > &ret, const GetOpFuncBase< A > *op) const
Definition: HopFunc.h:433
void dataOpVec(const Eref &e, const vector< A > &arg, const OpFunc1Base< A > *op) const
Definition: HopFunc.h:123
static const T & buf2val(double **buf)
Definition: Conv.h:44
void getLocalFieldVec(const Eref &er, vector< A > &ret, const GetOpFuncBase< A > *op) const
Definition: HopFunc.h:420
GetHopFunc(HopIndex hopIndex)
Definition: HopFunc.h:410
HopIndex hopIndex_
Definition: HopFunc.h:41
virtual unsigned int getNode(unsigned int dataIndex) const =0
Returns node number of specified dataIndex.
HopFunc1(HopIndex hopIndex)
Definition: HopFunc.h:48
HopFunc2(HopIndex hopIndex)
Definition: HopFunc.h:194
const OpFunc * makeHopFunc(HopIndex hopIndex) const
Definition: HopFunc.h:269
void getMultiNodeVec(const Eref &e, vector< A > &ret, const GetOpFuncBase< A > *op) const
Definition: HopFunc.h:457
HopIndex hopIndex_
Definition: HopFunc.h:395
virtual unsigned int startDataIndex(unsigned int nodeNum) const =0
Returns start dataIndex on specified node.
HopIndex hopIndex_
Definition: HopFunc.h:295
void op(const Eref &e, A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5) const
Definition: HopFunc.h:345