OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
Field.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
27#include "Field/Field.h"
28#include "Field/IndexedField.h"
30#include "Index/SIndex.h"
31#include "SubField/SubField.h"
32#include "Utility/IpplStats.h"
33
34
35//=============================================================================
36// Global functions
37//=============================================================================
38
39//-----------------------------------------------------------------------------
40// Wrappers for internal mesh object constructor calls:
41//-----------------------------------------------------------------------------
42// Generic case, report unimplemented mesh type:
43// (Compiler limitations doesn't allow this yet; user will get an obscure
44// compile error instead of this runtime error if he specifies an unsupported
45// mesh type for the Field Mesh parameter --tjw):
46// template<class T, unsigned Dim, class M, class C>
47// M* makeMesh(Field<T,Dim,M,C>& f)
48// {
49// ERRORMSG("makeMesh() invoked from Field(): unimplemented mesh type" << endl);
50// }
51
52// Generic makeMesh function
53template<class T, unsigned Dim, class M, class C>
55{
56
57
58
59 NDIndex<Dim> ndi;
60 ndi = f.getLayout().getDomain();
61 return (new M(ndi));
62}
63
64/*
65// Specialization for UniformCartesian
66template<class T, unsigned Dim, class MFLOAT, class C>
67UniformCartesian<Dim,MFLOAT>*
68makeMesh(Field<T,Dim,UniformCartesian<Dim,MFLOAT>,C>& f)
69{
70
71
72
73 NDIndex<Dim> ndi;
74 ndi = f.getLayout().getDomain();
75 return (new UniformCartesian<Dim,MFLOAT>(ndi));
76}
77
78// Specialization for Cartesian
79template<class T, unsigned Dim, class MFLOAT, class C>
80Cartesian<Dim,MFLOAT>*
81makeMesh(Field<T,Dim,Cartesian<Dim,MFLOAT>,C>& f)
82{
83
84
85
86 NDIndex<Dim> ndi;
87 ndi = f.getLayout().getDomain();
88 return (new Cartesian<Dim,MFLOAT>(ndi));
89}
90*/
91
92//=============================================================================
93// Field member functions
94//=============================================================================
95
96
98// A default constructor, which should be used only if the user calls the
99// 'initialize' function before doing anything else. There are no special
100// checks in the rest of the Field methods to check that the Field has
101// been properly initialized
102template<class T, unsigned Dim, class M, class C>
104
105
106 store_mesh(0, true);
107}
108
109
111// Field destructor
112template<class T, unsigned Dim, class M, class C>
114
115
116 delete_mesh();
117}
118
119
121// Create a new Field with a given layout and optional guard cells.
122// The default type of BCond lets you add new ones dynamically.
123// The makeMesh() global function is a way to allow for different types of
124// constructor arguments for different mesh types.
125template<class T, unsigned Dim, class M, class C>
127
128
129 store_mesh(makeMesh(*this), true);
130}
131
132template<class T, unsigned Dim, class M, class C>
134 : BareField<T,Dim>(l,gc) {
135
136
137 store_mesh(makeMesh(*this), true);
138}
139
140template<class T, unsigned Dim, class M, class C>
142 : BareField<T,Dim>(l), Bc(bc) {
143
144
145 store_mesh(makeMesh(*this), true);
146}
147
148template<class T, unsigned Dim, class M, class C>
150 const BConds<T,Dim,M,C>& bc)
151 : BareField<T,Dim>(l,gc), Bc(bc) {
152
153
154 store_mesh(makeMesh(*this), true);
155}
156
157template<class T, unsigned Dim, class M, class C>
159 const GuardCellSizes<Dim>& gc)
160 : BareField<T,Dim>(l,gc), Bc(bc) {
161
162
163 store_mesh(makeMesh(*this), true);
164}
165
166template<class T, unsigned Dim, class M, class C>
168 : BareField<T,Dim>( (Layout_t &) spec.get_Layout(), spec.get_GC()),
169 Bc(spec.get_BC()) {
170
171
172 store_mesh(makeMesh(*this), true);
173}
174
175
177// Constructors which include a Mesh object as argument
178template<class T, unsigned Dim, class M, class C>
180 : BareField<T,Dim>(l) {
181
182
183 store_mesh(&m, false);
184}
185
186template<class T, unsigned Dim, class M, class C>
188 const GuardCellSizes<Dim>& gc)
189 : BareField<T,Dim>(l,gc) {
190
191 store_mesh(&m, false);
192}
193
194template<class T, unsigned Dim, class M, class C>
196 const BConds<T,Dim,M,C>& bc)
197 : BareField<T,Dim>(l), Bc(bc) {
198
199
200 store_mesh(&m, false);
201}
202
203template<class T, unsigned Dim, class M, class C>
205 const GuardCellSizes<Dim>& gc,
206 const BConds<T,Dim,M,C>& bc)
207 : BareField<T,Dim>(l,gc), Bc(bc) {
208
209 store_mesh(&m, false);
210}
211
212template<class T, unsigned Dim, class M, class C>
214 const BConds<T,Dim,M,C>& bc,
215 const GuardCellSizes<Dim>& gc)
216 : BareField<T,Dim>(l,gc), Bc(bc) {
217
218 store_mesh(&m, false);
219}
220
221template<class T, unsigned Dim, class M, class C>
223 : BareField<T,Dim>( (Layout_t &) spec.get_Layout(), spec.get_GC()),
224 Bc(spec.get_BC()) {
225
226
227 store_mesh(&m, false);
228}
229
230
232// Initialize the Field, if it was constructed from the default constructor.
233// This should NOT be called if the Field was constructed by providing
234// a FieldLayout or FieldSpec
235template<class T, unsigned Dim, class M, class C>
237
238
240 store_mesh(makeMesh(*this), true);
241}
242
243template<class T, unsigned Dim, class M, class C>
245 const GuardCellSizes<Dim>& gc) {
246
247
249 store_mesh(makeMesh(*this), true);
250}
251
252template<class T, unsigned Dim, class M, class C>
254 const BConds<T,Dim,M,C>& bc) {
255
256
258 Bc = bc;
259 store_mesh(makeMesh(*this), true);
260}
261
262template<class T, unsigned Dim, class M, class C>
264 const GuardCellSizes<Dim>& gc,
265 const BConds<T,Dim,M,C>& bc) {
266
267
269 Bc = bc;
270 store_mesh(makeMesh(*this), true);
271}
272
273template<class T, unsigned Dim, class M, class C>
275 const BConds<T,Dim,M,C>& bc,
276 const GuardCellSizes<Dim>& gc) {
277
278
280 Bc = bc;
281 store_mesh(makeMesh(*this), true);
282}
283
284template<class T, unsigned Dim, class M, class C>
286
287
289 spec.get_GC());
290 Bc = spec.get_BC();
291 store_mesh(makeMesh(*this), true);
292}
293
294
296// Initialize the Field, also specifying a mesh
297template<class T, unsigned Dim, class M, class C>
299
300
302 store_mesh(&m, false);
303}
304
305//UL: for pinned memory allocation
306template<class T, unsigned Dim, class M, class C>
307void Field<T,Dim,M,C>::initialize(Mesh_t& m, Layout_t & l, const bool p) {
308
309
311 store_mesh(&m, false);
312}
313
314template<class T, unsigned Dim, class M, class C>
316 const GuardCellSizes<Dim>& gc) {
317
319 store_mesh(&m, false);
320}
321
322template<class T, unsigned Dim, class M, class C>
324 const BConds<T,Dim,M,C>& bc) {
325
326
328 Bc = bc;
329 store_mesh(&m, false);
330}
331
332template<class T, unsigned Dim, class M, class C>
334 const GuardCellSizes<Dim>& gc,
335 const BConds<T,Dim,M,C>& bc) {
336
338 Bc = bc;
339 store_mesh(&m, false);
340}
341
342template<class T, unsigned Dim, class M, class C>
344 const BConds<T,Dim,M,C>& bc,
345 const GuardCellSizes<Dim>& gc) {
346
348 Bc = bc;
349 store_mesh(&m, false);
350}
351
352template<class T, unsigned Dim, class M, class C>
354
355
357 spec.get_GC());
358 Bc = spec.get_BC();
359 store_mesh(&m, false);
360}
361
362
364// If you make any modifications using an iterator, you must call this.
365template<class T, unsigned Dim, class M, class C>
366void Field<T,Dim,M,C>::fillGuardCells(bool reallyFill) const {
367
368
369
370 // Fill the internal guard cells.
372
373 // Handle the user-supplied boundary conditions. If we're not supposed
374 // to really fill the guard cells and the BC does not change physical
375 // cells, don't bother.
376 if (reallyFill || Bc.changesPhysicalCells()) {
377 // cast away const, so we can apply BC's
378 Field<T,Dim,M,C>& ncf = const_cast<Field<T,Dim,M,C>&>(*this);
379 ncf.getBConds().apply(ncf);
380 INCIPPLSTAT(incBoundaryConditions);
381 }
382}
383
384
386// When we apply a bracket it converts the type
387// to IndexedField so that we can check at compile time
388// that we have the right number of indexes and brackets.
389template<class T, unsigned Dim, class M, class C>
391
392
393 return IndexedField<T,Dim,1,M,C>(*this,idx);
394}
395
396
398// Also allow using an integer instead of a whole Index
399template<class T, unsigned Dim, class M, class C>
401
402
403 return IndexedField<T,Dim,1,M,C>(*this,i);
404}
405
406
408// Also allow using a single NDIndex instead of N Index objects:
409template<class T, unsigned D, class M, class C>
411
412
413 return IndexedField<T,D,D,M,C>(*this,n);
414}
415
416
418// Also allow using a sparse index
419template<class T, unsigned D, class M, class C>
421
422
423 return SubField<T,D,M,C,SIndex<D> >(*this, s);
424}
425
426
428// I/O (special stuff not inherited from BareField):
429// Print out contents of Centering class
430template<class T, unsigned Dim, class M, class C>
431void Field<T,Dim,M,C>::print_Centerings(std::ostream& out) {
432
433
434 Centering_t::print_Centerings(out);
435}
436
437
439// Repartition onto a new layout, or when the mesh changes
440template<class T, unsigned Dim, class M, class C>
442
443
444
445 // see if the userlist corresponds to our current mesh
446 if (mesh != 0 && mesh->get_Id() == userlist->getUserListID()) {
447 // for now, we don't care if the mesh changes ... but we might later
448 } else {
449 // the layout has changed, so redistribute our data
450
451 // Cast to the proper type of FieldLayout.
452 Layout_t *newLayout = (Layout_t *)( userlist );
453
454 // Build a new temporary field on the new layout.
455 Field<T,Dim,M,C> tempField(get_mesh(), *newLayout, this->getGC(), getBConds());
456
457 // Copy our data over to the new layout.
458 tempField = *this;
459
460 // Copy back the pointers to the new local fields.
462
463 INCIPPLSTAT(incRepartitions);
464 }
465}
466
467
469// Tell this object that an object is being deleted
470template<class T, unsigned Dim, class M, class C>
472
473
474 // see if the userlist corresponds to our current mesh
475 if (mesh != 0 && mesh->get_Id() == userlist->getUserListID()) {
476 mesh = 0;
477 } else {
478 // since this is not for our mesh, defer to the base class function
480 }
481}
482
483
485// a virtual function which is called by this base class to get a
486// specific instance of DataSourceObject based on the type of data
487// and the connection method (the argument to the call).
488template<class T, unsigned Dim, class M, class C>
490 DataConnect *dc,
491 int tm) {
492
493 return make_DataSourceObject(nm, dc, tm, *this);
494}
495
496
498// store the given mesh object pointer, and the flag whether we use it or not
499template<class T, unsigned Dim, class M, class C>
500void Field<T,Dim,M,C>::store_mesh(Mesh_t* m, bool WeOwn) {
501
502
503 mesh = m;
504 WeOwnMesh = WeOwn;
505 if (mesh != 0)
506 mesh->checkin(*this);
507}
508
509
511// delete the mesh object, if necessary; otherwise, just zero the pointer
512template<class T, unsigned Dim, class M, class C>
514
515
516 if (mesh != 0) {
517 mesh->checkout(*this);
518 if (WeOwnMesh)
519 delete mesh;
520 mesh = 0;
521 }
522}
523
524
525/***************************************************************************
526 * $RCSfile: Field.cpp,v $ $Author: adelmann $
527 * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:26 $
528 * IPPL_VERSION_ID: $Id: Field.cpp,v 1.1.1.1 2003/01/23 07:40:26 adelmann Exp $
529 ***************************************************************************/
const unsigned Dim
DataSourceObject * make_DataSourceObject(const char *, DataConnect *, int, Field< T, Dim, M, C > &)
M * makeMesh(Field< T, Dim, M, C > &f)
Definition: Field.hpp:54
#define INCIPPLSTAT(stat)
Definition: IpplStats.h:236
virtual ~Field()
void initialize(Layout_t &)
virtual void notifyUserOfDelete(UserList *)
bool WeOwnMesh
Definition: Field.h:175
void fillGuardCells(bool reallyFill=true) const
void delete_mesh()
Mesh_t & get_mesh() const
Definition: Field.h:110
void store_mesh(Mesh_t *, bool)
bcond_container Bc
Definition: Field.h:171
virtual void Repartition(UserList *)
Mesh_t * mesh
Definition: Field.h:174
const bcond_container & getBConds() const
Definition: Field.h:104
IndexedField< T, Dim, 1, M, C > operator[](const Index &)
virtual DataSourceObject * createDataSourceObject(const char *, DataConnect *, int)
void print_Centerings(std::ostream &)
const GuardCellSizes< Dim > & getGC() const
Definition: BareField.h:146
virtual void notifyUserOfDelete(UserList *)
Definition: BareField.hpp:1079
ac_id_larray Locals_ac
Definition: BareField.h:331
Layout_t & getLayout() const
Definition: BareField.h:131
virtual void fillGuardCells(bool reallyFill=true) const
Definition: BareField.hpp:297
void initialize(Layout_t &)
Definition: BareField.hpp:100
const NDIndex< Dim > & getDomain() const
Definition: FieldLayout.h:325
bool changesPhysicalCells() const
Definition: BCond.hpp:268
void apply(Field< T, D, M, C > &a)
Definition: BCond.hpp:258
const FieldLayout< Dim > & get_Layout(void) const
Definition: FieldSpec.h:51
BConds< T, Dim, M, C > get_BC(void) const
Definition: FieldSpec.h:52
GuardCellSizes< Dim > get_GC(void) const
Definition: FieldSpec.h:53
Definition: Index.h:237
Definition: SIndex.h:64
ID_t getUserListID() const
Definition: UserList.cpp:54