OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
UniformCartesian.hpp
Go to the documentation of this file.
1// -*- C++ -*-
2/***************************************************************************
3 *
4 * The IPPL Framework
5 *
6 ***************************************************************************/
7
8// UniformCartesian.cpp
9// Implementations for UniformCartesian mesh class (uniform spacings)
10
11// include files
12#include "Utility/PAssert.h"
13#include "Utility/IpplInfo.h"
14#include "Field/BareField.h"
16#include "Field/LField.h"
17#include "Field/Assign.h"
18#include "Field/AssignDefs.h"
19
20//-----------------------------------------------------------------------------
21// Setup chores common to all constructors:
22//-----------------------------------------------------------------------------
23template <unsigned Dim, class MFLOAT>
24void
26setup()
27{
28 hasSpacingFields = false;
29 FlCell = 0;
30 FlVert = 0;
31 VertSpacings = 0;
32 CellSpacings = 0;
33 volume = 0.0;
34}
35
36//-----------------------------------------------------------------------------
37// Constructors from NDIndex object:
38//-----------------------------------------------------------------------------
39template <unsigned Dim, class MFLOAT>
42{
43 setup();
44 for (unsigned int d=0; d<Dim; d++) {
45 gridSizes[d] = ndi[d].length(); // Number of vertices along this dimension.
46 meshSpacing[d] = ndi[d].stride(); // Default mesh spacing from stride()
47 origin(d) = ndi[d].first(); // Default origin at ndi[d].first
48 }
49 volume = 1.0; // Default mesh has unit cell volume.
50 set_Dvc(); // Set derivative coefficients from spacings.
51}
52// Also specify mesh spacings:
53template <unsigned Dim, class MFLOAT>
55UniformCartesian(const NDIndex<Dim>& ndi, MFLOAT* const delX)
56{
57 setup();
58 for (unsigned int d=0; d<Dim; d++) {
59 gridSizes[d] = ndi[d].length(); // Number of vertices along this dimension.
60 origin(d) = ndi[d].first(); // Default origin at ndi[d].first
61 }
62 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
64// Also specify mesh spacings and origin:
65template <unsigned Dim, class MFLOAT>
67UniformCartesian(const NDIndex<Dim>& ndi, MFLOAT* const delX,
68 const Vektor<MFLOAT,Dim>& orig)
70 setup();
71 for (unsigned int d=0; d<Dim; d++) {
72 gridSizes[d] = ndi[d].length(); // Number of vertices along this dimension.
73 }
74 set_origin(orig); // Set origin.
75 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
76}
77//-----------------------------------------------------------------------------
78// Constructors from Index objects:
79//-----------------------------------------------------------------------------
81//===========1D============
82template <unsigned Dim, class MFLOAT>
86 PInsist(Dim==1,"Number of Index arguments does not match mesh dimension!!");
87 setup();
88 gridSizes[0] = I.length(); // Number of vertices along this dimension.
89 meshSpacing[0] = I.stride(); // Default mesh spacing from stride()
90 origin(0) = I.first(); // Default origin at I.first()
91
92 volume = 1.0; // Default mesh has unit cell volume.
93 set_Dvc(); // Set derivative coefficients from spacings.
95// Also specify mesh spacings:
96template <unsigned Dim, class MFLOAT>
98UniformCartesian(const Index& I, MFLOAT* const delX)
99{
100 PInsist(Dim==1,"Number of Index arguments does not match mesh dimension!!");
101 setup();
102 gridSizes[0] = I.length(); // Number of vertices along this dimension.
103 origin(0) = I.first(); // Default origin at I.first()
104
105 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
106}
107// Also specify mesh spacings and origin:
108template <unsigned Dim, class MFLOAT>
110UniformCartesian(const Index& I, MFLOAT* const delX,
111 const Vektor<MFLOAT,Dim>& orig)
113 PInsist(Dim==1,"Number of Index arguments does not match mesh dimension!!");
114 setup();
115 gridSizes[0] = I.length(); // Number of vertices along this dimension.
116 set_origin(orig); // Set origin.
117 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
118}
119
120//===========2D============
121template <unsigned Dim, class MFLOAT>
123UniformCartesian(const Index& I, const Index& J)
124{
125 PInsist(Dim==2,"Number of Index arguments does not match mesh dimension!!");
126 setup();
127 gridSizes[0] = I.length(); // Number of vertices along this dimension.
128 gridSizes[1] = J.length(); // Number of vertices along this dimension.
129 meshSpacing[0] = I.stride(); // Default mesh spacing from stride()
130 meshSpacing[1] = J.stride();
131 origin(0) = I.first(); // Default origin at (I.first(),J.first())
132 origin(1) = J.first();
134 volume = 1.0; // Default mesh has unit cell volume.
135 set_Dvc(); // Set derivative coefficients from spacings.
136}
137// Also specify mesh spacings:
138template <unsigned Dim, class MFLOAT>
140UniformCartesian(const Index& I, const Index& J, MFLOAT* const delX)
141{
142 PInsist(Dim==2,"Number of Index arguments does not match mesh dimension!!");
143 setup();
144 gridSizes[0] = I.length(); // Number of vertices along this dimension.
145 gridSizes[1] = J.length(); // Number of vertices along this dimension.
146 origin(0) = I.first(); // Default origin at (I.first(),J.first())
147 origin(1) = J.first();
148 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
149}
150// Also specify mesh spacings and origin:
151template <unsigned Dim, class MFLOAT>
153UniformCartesian(const Index& I, const Index& J, MFLOAT* const delX,
154 const Vektor<MFLOAT,Dim>& orig)
155{
156 PInsist(Dim==2,"Number of Index arguments does not match mesh dimension!!");
157 setup();
158 gridSizes[0] = I.length(); // Number of vertices along this dimension.
159 gridSizes[1] = J.length(); // Number of vertices along this dimension.
160 set_origin(orig); // Set origin.
161 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
162}
163
164//===========3D============
165template <unsigned Dim, class MFLOAT>
167UniformCartesian(const Index& I, const Index& J, const Index& K)
169 PInsist(Dim==3,"Number of Index arguments does not match mesh dimension!!");
170 setup();
171 gridSizes[0] = I.length(); // Number of vertices along this dimension.
172 gridSizes[1] = J.length(); // Number of vertices along this dimension.
173 gridSizes[2] = K.length(); // Number of vertices along this dimension.
174 meshSpacing[0] = I.stride(); // Default mesh spacing from stride()
175 meshSpacing[1] = J.stride();
176 meshSpacing[2] = K.stride();
177 origin(0) = I.first(); // Default origin at (I.first(),J.first(),K.first())
178 origin(1) = J.first();
179 origin(2) = K.first();
180
181 volume = 1.0; // Default mesh has unit cell volume.
182 set_Dvc(); // Set derivative coefficients from spacings.
184// Also specify mesh spacings:
185template <unsigned Dim, class MFLOAT>
187UniformCartesian(const Index& I, const Index& J, const Index& K,
188 MFLOAT* const delX)
189{
190 PInsist(Dim==3,"Number of Index arguments does not match mesh dimension!!");
191 setup();
192 gridSizes[0] = I.length(); // Number of vertices along this dimension.
193 gridSizes[1] = J.length(); // Number of vertices along this dimension.
194 gridSizes[2] = K.length(); // Number of vertices along this dimension.
195 origin(0) = I.first(); // Default origin at (I.first(),J.first(),K.first())
196 origin(1) = J.first();
197 origin(2) = K.first();
198 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
199}
200// Also specify mesh spacings and origin:
201template <unsigned Dim, class MFLOAT>
203UniformCartesian(const Index& I, const Index& J, const Index& K,
204 MFLOAT* const delX, const Vektor<MFLOAT,Dim>& orig)
206 PInsist(Dim==3,"Number of Index arguments does not match mesh dimension!!");
207 setup();
208 gridSizes[0] = I.length(); // Number of vertices along this dimension.
209 gridSizes[1] = J.length(); // Number of vertices along this dimension.
210 gridSizes[2] = K.length(); // Number of vertices along this dimension.
211 set_origin(orig); // Set origin.
212 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
213}
215//-----------------------------------------------------------------------------
216// initialize with NDIndex object:
217//-----------------------------------------------------------------------------
218template <unsigned Dim, class MFLOAT>
219void
221initialize(const NDIndex<Dim>& ndi)
222{
223 setup();
224 for (unsigned int d=0; d<Dim; d++) {
225 gridSizes[d] = ndi[d].length(); // Number of vertices along this dimension.
226 meshSpacing[d] = ndi[d].stride(); // Default mesh spacing from stride()
227 origin(d) = ndi[d].first(); // Default origin at ndi[d].first
229 volume = 1.0; // Default mesh has unit cell volume.
230 set_Dvc(); // Set derivative coefficients from spacings.
231}
232// Also specify mesh spacings:
233template <unsigned Dim, class MFLOAT>
234void
236initialize(const NDIndex<Dim>& ndi, MFLOAT* const delX)
237{
238 setup();
239 for (unsigned int d=0; d<Dim; d++) {
240 gridSizes[d] = ndi[d].length(); // Number of vertices along this dimension.
241 origin(d) = ndi[d].first(); // Default origin at ndi[d].first
242 }
243 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
244}
245// Also specify mesh spacings and origin:
246template <unsigned Dim, class MFLOAT>
247void
249initialize(const NDIndex<Dim>& ndi, MFLOAT* const delX,
250 const Vektor<MFLOAT,Dim>& orig)
251{
252 setup();
253 for (unsigned int d=0; d<Dim; d++) {
254 gridSizes[d] = ndi[d].length(); // Number of vertices along this dimension.
255 }
256 set_origin(orig); // Set origin.
257 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
258}
259//-----------------------------------------------------------------------------
260// initialize from Index objects:
261//-----------------------------------------------------------------------------
262
263//===========1D============
264template <unsigned Dim, class MFLOAT>
265void
267initialize(const Index& I)
268{
269 PInsist(Dim==1,"Number of Index arguments does not match mesh dimension!!");
270 setup();
271 gridSizes[0] = I.length(); // Number of vertices along this dimension.
272 meshSpacing[0] = I.stride(); // Default mesh spacing from stride()
273 origin(0) = I.first(); // Default origin at I.first()
274
275 volume = 1.0; // Default mesh has unit cell volume.
276 set_Dvc(); // Set derivative coefficients from spacings.
277}
278// Also specify mesh spacings:
279template <unsigned Dim, class MFLOAT>
280void
282initialize(const Index& I, MFLOAT* const delX)
283{
284 PInsist(Dim==1,"Number of Index arguments does not match mesh dimension!!");
285 setup();
286 gridSizes[0] = I.length(); // Number of vertices along this dimension.
287 origin(0) = I.first(); // Default origin at I.first()
288
289 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
290}
291// Also specify mesh spacings and origin:
292template <unsigned Dim, class MFLOAT>
293void
295initialize(const Index& I, MFLOAT* const delX,
296 const Vektor<MFLOAT,Dim>& orig)
297{
298 PInsist(Dim==1,"Number of Index arguments does not match mesh dimension!!");
299 setup();
300 gridSizes[0] = I.length(); // Number of vertices along this dimension.
301 set_origin(orig); // Set origin.
302 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
303}
304
305//===========2D============
306template <unsigned Dim, class MFLOAT>
307void
309initialize(const Index& I, const Index& J)
310{
311 PInsist(Dim==2,"Number of Index arguments does not match mesh dimension!!");
312 setup();
313 gridSizes[0] = I.length(); // Number of vertices along this dimension.
314 gridSizes[1] = J.length(); // Number of vertices along this dimension.
315 meshSpacing[0] = I.stride(); // Default mesh spacing from stride()
316 meshSpacing[1] = J.stride();
317 origin(0) = I.first(); // Default origin at (I.first(),J.first())
318 origin(1) = J.first();
319
320 volume = 1.0; // Default mesh has unit cell volume.
321 set_Dvc(); // Set derivative coefficients from spacings.
322}
323// Also specify mesh spacings:
324template <unsigned Dim, class MFLOAT>
325void
327initialize(const Index& I, const Index& J, MFLOAT* const delX)
328{
329 PInsist(Dim==2,"Number of Index arguments does not match mesh dimension!!");
330 setup();
331 gridSizes[0] = I.length(); // Number of vertices along this dimension.
332 gridSizes[1] = J.length(); // Number of vertices along this dimension.
333 origin(0) = I.first(); // Default origin at (I.first(),J.first())
334 origin(1) = J.first();
335 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
336}
337// Also specify mesh spacings and origin:
338template <unsigned Dim, class MFLOAT>
339void
341initialize(const Index& I, const Index& J, MFLOAT* const delX,
342 const Vektor<MFLOAT,Dim>& orig)
343{
344 PInsist(Dim==2,"Number of Index arguments does not match mesh dimension!!");
345 setup();
346 gridSizes[0] = I.length(); // Number of vertices along this dimension.
347 gridSizes[1] = J.length(); // Number of vertices along this dimension.
348 set_origin(orig); // Set origin.
349 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
350}
351
352//===========3D============
353template <unsigned Dim, class MFLOAT>
354void
356initialize(const Index& I, const Index& J, const Index& K)
357{
358 PInsist(Dim==3,"Number of Index arguments does not match mesh dimension!!");
359 setup();
360 gridSizes[0] = I.length(); // Number of vertices along this dimension.
361 gridSizes[1] = J.length(); // Number of vertices along this dimension.
362 gridSizes[2] = K.length(); // Number of vertices along this dimension.
363 meshSpacing[0] = I.stride(); // Default mesh spacing from stride()
364 meshSpacing[1] = J.stride();
365 meshSpacing[2] = K.stride();
366 origin(0) = I.first(); // Default origin at (I.first(),J.first(),K.first())
367 origin(1) = J.first();
368 origin(2) = K.first();
369
370 volume = 1.0; // Default mesh has unit cell volume.
371 set_Dvc(); // Set derivative coefficients from spacings.
372}
373// Also specify mesh spacings:
374template <unsigned Dim, class MFLOAT>
375void
377initialize(const Index& I, const Index& J, const Index& K,
378 MFLOAT* const delX)
379{
380 PInsist(Dim==3,"Number of Index arguments does not match mesh dimension!!");
381 setup();
382 gridSizes[0] = I.length(); // Number of vertices along this dimension.
383 gridSizes[1] = J.length(); // Number of vertices along this dimension.
384 gridSizes[2] = K.length(); // Number of vertices along this dimension.
385 origin(0) = I.first(); // Default origin at (I.first(),J.first(),K.first())
386 origin(1) = J.first();
387 origin(2) = K.first();
388 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
389}
390// Also specify mesh spacings and origin:
391template <unsigned Dim, class MFLOAT>
392void
394initialize(const Index& I, const Index& J, const Index& K,
395 MFLOAT* const delX, const Vektor<MFLOAT,Dim>& orig)
396{
397 PInsist(Dim==3,"Number of Index arguments does not match mesh dimension!!");
398 setup();
399 gridSizes[0] = I.length(); // Number of vertices along this dimension.
400 gridSizes[1] = J.length(); // Number of vertices along this dimension.
401 gridSizes[2] = K.length(); // Number of vertices along this dimension.
402 set_origin(orig); // Set origin.
403 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
404}
405
406//-----------------------------------------------------------------------------
407// Set/accessor functions for member data:
408//-----------------------------------------------------------------------------
409// Set the origin of mesh vertex positions:
410template<unsigned Dim, class MFLOAT>
413{
414 origin = o;
415 this->notifyOfChange();
416}
417// Get the origin of mesh vertex positions:
418template<unsigned Dim, class MFLOAT>
420get_origin() const
421{
422 return origin;
423}
424
425// Set the spacings of mesh vertex positions (recompute Dvc, cell volume):
426template<unsigned Dim, class MFLOAT>
428set_meshSpacing(MFLOAT* const del)
429{
430 unsigned d;
431 volume = 1.0;
432 for (d=0; d<Dim; ++d) {
433 meshSpacing[d] = del[d];
434 volume *= del[d];
435 }
436 set_Dvc();
437 // if spacing fields exist, we must recompute values
438 if (hasSpacingFields) storeSpacingFields();
439 this->notifyOfChange();
440}
441// Set only the derivative constants, using pre-set spacings:
442template<unsigned Dim, class MFLOAT>
444set_Dvc()
445{
446 unsigned d;
447 MFLOAT coef = 1.0;
448 for (d=1;d<Dim;++d) coef *= 0.5;
449
450 for (d=0;d<Dim;++d) {
451 MFLOAT dvc = coef/meshSpacing[d];
452 for (unsigned b=0; b<(1u<<Dim); ++b) {
453 int s = ( b&(1<<d) ) ? 1 : -1;
454 Dvc[b][d] = s*dvc;
455 }
456 }
457}
458// Get the spacings of mesh vertex positions along specified direction:
459template<unsigned Dim, class MFLOAT>
461get_meshSpacing(unsigned d) const
462{
463 PAssert_LT(d, Dim);
464 MFLOAT ms = meshSpacing[d];
465 return ms;
466}
467
468// Get the cell volume:
469template<unsigned Dim, class MFLOAT>
471get_volume() const
472{
473 return volume;
474}
475
477
478// Applicative templates for Mesh BC PETE_apply() functions, used
479// by BrickExpression in storeSpacingFields()
480
481// Reflective/None (all are the same for uniform, incl. Periodic).
482template<class T>
484{
485 OpUMeshExtrapolate(T& o, T& s) : Offset(o), Slope(s) {}
487};
488
489template<class T>
491{
492 a = b*e.Slope+e.Offset;
493}
494
496
497// Create BareField's of vertex and cell spacings
498// Special prototypes taking no args or FieldLayout ctor args:
499// No-arg case:
500template<unsigned Dim, class MFLOAT>
503{
504 // Set up default FieldLayout parameters:
505 e_dim_tag et[Dim];
506 for (unsigned int d=0; d<Dim; d++) et[d] = PARALLEL;
507 storeSpacingFields(et, -1);
508}
509// 1D
510template<unsigned Dim, class MFLOAT>
512storeSpacingFields(e_dim_tag p1, int vnodes)
513{
514 e_dim_tag et[1];
515 et[0] = p1;
516 storeSpacingFields(et, vnodes);
517}
518// 2D
519template<unsigned Dim, class MFLOAT>
521storeSpacingFields(e_dim_tag p1, e_dim_tag p2, int vnodes)
522{
523 e_dim_tag et[2];
524 et[0] = p1;
525 et[1] = p2;
526 storeSpacingFields(et, vnodes);
527}
528// 3D
529template<unsigned Dim, class MFLOAT>
531storeSpacingFields(e_dim_tag p1, e_dim_tag p2, e_dim_tag p3, int vnodes)
532{
533 e_dim_tag et[3];
534 et[0] = p1;
535 et[1] = p2;
536 et[2] = p3;
537 storeSpacingFields(et, vnodes);
538}
539// The general storeSpacingfields() function; others invoke this internally:
540template<unsigned Dim, class MFLOAT>
542storeSpacingFields(e_dim_tag* et, int vnodes)
543{
544 // VERTEX-VERTEX SPACINGS (same as CELL-CELL SPACINGS for uniform):
545 NDIndex<Dim> cells, verts;
546 unsigned int d;
547 for (d=0; d<Dim; d++) {
548 cells[d] = Index(gridSizes[d]-1);
549 verts[d] = Index(gridSizes[d]);
550 }
551 if (!hasSpacingFields) {
552 // allocate layout and spacing field
553 FlCell = new FieldLayout<Dim>(cells, et, vnodes);
554 // Note: enough guard cells only for existing Div(), etc. implementations:
555 // (not really used by Div() etc for UniformCartesian); someday should make
556 // this user-settable.
557 VertSpacings =
559 // Added 12/8/98 --TJW:
560 FlVert =
561 new FieldLayout<Dim>(verts, et, vnodes);
562 // Note: enough guard cells only for existing Div(), etc. implementations:
563 CellSpacings =
565 }
566 BareField<Vektor<MFLOAT,Dim>,Dim>& vertSpacings = *VertSpacings;
567 Vektor<MFLOAT,Dim> vertexSpacing;
568 for (d=0; d<Dim; d++)
569 vertexSpacing[d] = meshSpacing[d];
570 vertSpacings = vertexSpacing;
571 //-------------------------------------------------
572 // Now the hard part, filling in the guard cells:
573 //-------------------------------------------------
574 // The easy part of the hard part is filling so that all the internal
575 // guard layers are right:
576 vertSpacings.fillGuardCells();
577 // The hard part of the hard part is filling the external guard layers,
578 // using the mesh BC to figure out how:
579 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
580 // Temporaries used in loop over faces
581 Vektor<MFLOAT,Dim> v0,v1; v0 = 0.0; v1 = 1.0; // Used for Reflective mesh BC
582 unsigned int face;
583 typedef Vektor<MFLOAT,Dim> T; // Used multipple places in loop below
584 typename BareField<T,Dim>::iterator_if vfill_i; // Iterator used below
585 int voffset; // Pointer offsets used with LField::iterator below
586 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
587 for (face=0; face < 2*Dim; face++) {
588 // NDIndex's spanning elements and guard elements:
589 NDIndex<Dim> vSlab = AddGuardCells(cells,vertSpacings.getGuardCellSizes());
590 // Shrink it down to be the guards along the active face:
591 d = face/2;
592 // The following bitwise AND logical test returns true if face is odd
593 // (meaning the "high" or "right" face in the numbering convention) and
594 // returns false if face is even (meaning the "low" or "left" face in
595 // the numbering convention):
596 if ( face & 1u ) {
597 vSlab[d] = Index(cells[d].max() + 1,
598 cells[d].max() + vertSpacings.rightGuard(d));
599 } else {
600 vSlab[d] = Index(cells[d].min() - vertSpacings.leftGuard(d),
601 cells[d].min() - 1);
602 }
603 // Compute pointer offsets used with LField::iterator below:
604 // Treat all as Reflective BC (see Cartesian for comparison); for
605 // uniform cartesian mesh, all mesh BC's equivalent for this purpose:
606 if ( face & 1u ) {
607 voffset = 2*cells[d].max() + 1 - 1;
608 } else {
609 voffset = 2*cells[d].min() - 1 + 1;
610 }
611
612 // +++++++++++++++vertSpacings++++++++++++++
613 for (vfill_i=vertSpacings.begin_if();
614 vfill_i!=vertSpacings.end_if(); ++vfill_i)
615 {
616 // Cache some things we will use often below.
617 // Pointer to the data for the current LField (right????):
618 LField<T,Dim> &fill = *(*vfill_i).second;
619 // NDIndex spanning all elements in the LField, including the guards:
620 const NDIndex<Dim> &fill_alloc = fill.getAllocated();
621 // If the previously-created boundary guard-layer NDIndex "cSlab"
622 // contains any of the elements in this LField (they will be guard
623 // elements if it does), assign the values into them here by applying
624 // the boundary condition:
625 if ( vSlab.touches( fill_alloc ) )
626 {
627 // Find what it touches in this LField.
628 NDIndex<Dim> dest = vSlab.intersect( fill_alloc );
629
630 // For exrapolation boundary conditions, the boundary guard-layer
631 // elements are typically copied from interior values; the "src"
632 // NDIndex specifies the interior elements to be copied into the
633 // "dest" boundary guard-layer elements (possibly after some
634 // mathematical operations like multipplying by minus 1 later):
635 NDIndex<Dim> src = dest; // Create dest equal to src
636 // Now calculate the interior elements; the voffset variable
637 // computed above makes this right for "low" or "high" face cases:
638 src[d] = voffset - src[d];
639
640 // TJW: Why is there another loop over LField's here??????????
641 // Loop over the ones that src touches.
642 typename BareField<T,Dim>::iterator_if from_i;
643 for (from_i=vertSpacings.begin_if();
644 from_i!=vertSpacings.end_if(); ++from_i)
645 {
646 // Cache a few things.
647 LField<T,Dim> &from = *(*from_i).second;
648 const NDIndex<Dim> &from_owned = from.getOwned();
649 const NDIndex<Dim> &from_alloc = from.getAllocated();
650 // If src touches this LField...
651 if ( src.touches( from_owned ) )
652 {
653 NDIndex<Dim> from_it = src.intersect( from_alloc );
654 NDIndex<Dim> vfill_it = dest.plugBase( from_it );
655 // Build iterators for the copy...
656 typedef typename LField<T,Dim>::iterator LFI;
657 LFI lhs = fill.begin(vfill_it);
658 LFI rhs = from.begin(from_it);
659 // And do the assignment (reflective BC hardwired):
661 (lhs,rhs,OpUMeshExtrapolate<T>(v0,v1)).apply();
662 }
663 }
664 }
665 }
666
667 }
668
669 // For uniform cartesian mesh, cell-cell spacings are identical to
670 // vert-vert spacings:
671 //12/8/98 CellSpacings = VertSpacings;
672 // Added 12/8/98 --TJW:
673 BareField<Vektor<MFLOAT,Dim>,Dim>& cellSpacings = *CellSpacings;
674 cellSpacings = vertexSpacing;
675
676 hasSpacingFields = true; // Flag this as having been done to this object.
677}
678
679// These specify both the total number of vnodes and the numbers of vnodes
680// along each dimension for the partitioning of the index space. Obviously
681// this restricts the number of vnodes to be a product of the numbers along
682// each dimension (the constructor implementation checks this): Special
683// cases for 1-3 dimensions, ala FieldLayout ctors (see FieldLayout.h for
684// more relevant comments, including definition of recurse):
685
686// 1D
687template<unsigned Dim, class MFLOAT>
690 unsigned vnodes1,
691 bool recurse,
692 int vnodes) {
693 e_dim_tag et[1];
694 et[0] = p1;
695 unsigned vnodesPerDirection[Dim];
696 vnodesPerDirection[0] = vnodes1;
697 storeSpacingFields(et, vnodesPerDirection, recurse, vnodes);
698}
699// 2D
700template<unsigned Dim, class MFLOAT>
703 unsigned vnodes1, unsigned vnodes2,
704 bool recurse,int vnodes) {
705 e_dim_tag et[2];
706 et[0] = p1;
707 et[1] = p2;
708 unsigned vnodesPerDirection[Dim];
709 vnodesPerDirection[0] = vnodes1;
710 vnodesPerDirection[1] = vnodes2;
711 storeSpacingFields(et, vnodesPerDirection, recurse, vnodes);
712}
713// 3D
714template<unsigned Dim, class MFLOAT>
717 unsigned vnodes1, unsigned vnodes2, unsigned vnodes3,
718 bool recurse, int vnodes) {
719 e_dim_tag et[3];
720 et[0] = p1;
721 et[1] = p2;
722 et[2] = p3;
723 unsigned vnodesPerDirection[Dim];
724 vnodesPerDirection[0] = vnodes1;
725 vnodesPerDirection[1] = vnodes2;
726 vnodesPerDirection[2] = vnodes3;
727 storeSpacingFields(et, vnodesPerDirection, recurse, vnodes);
728}
729
730// TJW: Note: should clean up here eventually, and put redundant code from
731// this and the other general storeSpacingFields() implementation into one
732// function. Need to check this in quickly for Blanca right now --12/8/98
733// The general storeSpacingfields() function; others invoke this internally:
734template<unsigned Dim, class MFLOAT>
737 unsigned* vnodesPerDirection,
738 bool recurse, int vnodes)
739{
740 // VERTEX-VERTEX SPACINGS (same as CELL-CELL SPACINGS for uniform):
741 NDIndex<Dim> cells, verts;
742 unsigned int d;
743 for (d=0; d<Dim; d++) {
744 cells[d] = Index(gridSizes[d]-1);
745 verts[d] = Index(gridSizes[d]);
746 }
747 if (!hasSpacingFields) {
748 // allocate layout and spacing field
749 FlCell =
750 new FieldLayout<Dim>(cells, p, vnodesPerDirection, recurse, vnodes);
751 // Note: enough guard cells only for existing Div(), etc. implementations:
752 // (not really used by Div() etc for UniformCartesian); someday should make
753 // this user-settable.
754 VertSpacings =
756 // Added 12/8/98 --TJW:
757 FlVert =
758 new FieldLayout<Dim>(verts, p, vnodesPerDirection, recurse, vnodes);
759 // Note: enough guard cells only for existing Div(), etc. implementations:
760 CellSpacings =
762 }
763 BareField<Vektor<MFLOAT,Dim>,Dim>& vertSpacings = *VertSpacings;
764 Vektor<MFLOAT,Dim> vertexSpacing;
765 for (d=0; d<Dim; d++)
766 vertexSpacing[d] = meshSpacing[d];
767 vertSpacings = vertexSpacing;
768 //-------------------------------------------------
769 // Now the hard part, filling in the guard cells:
770 //-------------------------------------------------
771 // The easy part of the hard part is filling so that all the internal
772 // guard layers are right:
773 vertSpacings.fillGuardCells();
774 // The hard part of the hard part is filling the external guard layers,
775 // using the mesh BC to figure out how:
776 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
777 // Temporaries used in loop over faces
778 Vektor<MFLOAT,Dim> v0,v1; v0 = 0.0; v1 = 1.0; // Used for Reflective mesh BC
779 unsigned int face;
780 typedef Vektor<MFLOAT,Dim> T; // Used multipple places in loop below
781 typename BareField<T,Dim>::iterator_if vfill_i; // Iterator used below
782 int voffset; // Pointer offsets used with LField::iterator below
783 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
784 for (face=0; face < 2*Dim; face++) {
785 // NDIndex's spanning elements and guard elements:
786 NDIndex<Dim> vSlab = AddGuardCells(cells,vertSpacings.getGuardCellSizes());
787 // Shrink it down to be the guards along the active face:
788 d = face/2;
789 // The following bitwise AND logical test returns true if face is odd
790 // (meaning the "high" or "right" face in the numbering convention) and
791 // returns false if face is even (meaning the "low" or "left" face in
792 // the numbering convention):
793 if ( face & 1u ) {
794 vSlab[d] = Index(cells[d].max() + 1,
795 cells[d].max() + vertSpacings.rightGuard(d));
796 } else {
797 vSlab[d] = Index(cells[d].min() - vertSpacings.leftGuard(d),
798 cells[d].min() - 1);
799 }
800 // Compute pointer offsets used with LField::iterator below:
801 // Treat all as Reflective BC (see Cartesian for comparison); for
802 // uniform cartesian mesh, all mesh BC's equivalent for this purpose:
803 if ( face & 1u ) {
804 voffset = 2*cells[d].max() + 1 - 1;
805 } else {
806 voffset = 2*cells[d].min() - 1 + 1;
807 }
808
809 // +++++++++++++++vertSpacings++++++++++++++
810 for (vfill_i=vertSpacings.begin_if();
811 vfill_i!=vertSpacings.end_if(); ++vfill_i)
812 {
813 // Cache some things we will use often below.
814 // Pointer to the data for the current LField (right????):
815 LField<T,Dim> &fill = *(*vfill_i).second;
816 // NDIndex spanning all elements in the LField, including the guards:
817 const NDIndex<Dim> &fill_alloc = fill.getAllocated();
818 // If the previously-created boundary guard-layer NDIndex "cSlab"
819 // contains any of the elements in this LField (they will be guard
820 // elements if it does), assign the values into them here by applying
821 // the boundary condition:
822 if ( vSlab.touches( fill_alloc ) )
823 {
824 // Find what it touches in this LField.
825 NDIndex<Dim> dest = vSlab.intersect( fill_alloc );
826
827 // For exrapolation boundary conditions, the boundary guard-layer
828 // elements are typically copied from interior values; the "src"
829 // NDIndex specifies the interior elements to be copied into the
830 // "dest" boundary guard-layer elements (possibly after some
831 // mathematical operations like multipplying by minus 1 later):
832 NDIndex<Dim> src = dest; // Create dest equal to src
833 // Now calculate the interior elements; the voffset variable
834 // computed above makes this right for "low" or "high" face cases:
835 src[d] = voffset - src[d];
836
837 // TJW: Why is there another loop over LField's here??????????
838 // Loop over the ones that src touches.
839 typename BareField<T,Dim>::iterator_if from_i;
840 for (from_i=vertSpacings.begin_if();
841 from_i!=vertSpacings.end_if(); ++from_i)
842 {
843 // Cache a few things.
844 LField<T,Dim> &from = *(*from_i).second;
845 const NDIndex<Dim> &from_owned = from.getOwned();
846 const NDIndex<Dim> &from_alloc = from.getAllocated();
847 // If src touches this LField...
848 if ( src.touches( from_owned ) )
849 {
850 NDIndex<Dim> from_it = src.intersect( from_alloc );
851 NDIndex<Dim> vfill_it = dest.plugBase( from_it );
852 // Build iterators for the copy...
853 typedef typename LField<T,Dim>::iterator LFI;
854 LFI lhs = fill.begin(vfill_it);
855 LFI rhs = from.begin(from_it);
856 // And do the assignment (reflective BC hardwired):
858 (lhs,rhs,OpUMeshExtrapolate<T>(v0,v1)).apply();
859 }
860 }
861 }
862 }
863
864 }
865
866 // For uniform cartesian mesh, cell-cell spacings are identical to
867 // vert-vert spacings:
868 //12/8/98 CellSpacings = VertSpacings;
869 // Added 12/8/98 --TJW:
870 BareField<Vektor<MFLOAT,Dim>,Dim>& cellSpacings = *CellSpacings;
871 cellSpacings = vertexSpacing;
872
873 hasSpacingFields = true; // Flag this as having been done to this object.
874}
875
876//-----------------------------------------------------------------------------
877// I/O:
878//-----------------------------------------------------------------------------
879// Formatted output of UniformCartesian object:
880template< unsigned Dim, class MFLOAT >
881void
883print(std::ostream& out)
884{
885 Inform info("", out);
886 print(info);
887}
888
889template< unsigned Dim, class MFLOAT >
890void
892print(Inform& out)
893{
894 out << "======UniformCartesian<" << Dim << ",MFLOAT>==begin======\n";
895 unsigned int d;
896 for (d=0; d < Dim; d++)
897 out << "gridSizes[" << d << "] = " << gridSizes[d] << "\n";
898 out << "origin = " << origin << "\n";
899 for (d=0; d < Dim; d++)
900 out << "meshSpacing[" << d << "] = " << meshSpacing[d] << "\n";
901 for (d=0; d < (1u<<Dim); d++)
902 out << "Dvc[" << d << "] = " << Dvc[d] << "\n";
903 out << "cell volume = " << volume << "\n";
904 out << "======UniformCartesian<" << Dim << ",MFLOAT>==end========\n";
905}
906
907//--------------------------------------------------------------------------
908// Various (UniformCartesian) mesh mechanisms:
909//--------------------------------------------------------------------------
910
911// Volume of single cell indexed by NDIndex:
912template <unsigned Dim, class MFLOAT>
913MFLOAT
915getCellVolume(const NDIndex<Dim>& ndi) const
916{
917 unsigned int d;
918 for (d=0; d<Dim; d++)
919 if (ndi[d].length() != 1)
920 ERRORMSG("UniformCartesian::getCellVolume() error: arg is not a NDIndex"
921 << "specifying a single element" << endl);
922 return volume;
923}
924// Field of volumes of all cells:
925template <unsigned Dim, class MFLOAT>
929 volumes) const
930{
931 volumes = volume;
932 return volumes;
933}
934// Volume of range of cells bounded by verticies specified by input NDIndex;
935template <unsigned Dim, class MFLOAT>
936MFLOAT
938getVertRangeVolume(const NDIndex<Dim>& ndi) const
939{
940 // Get vertex positions of extremal cells:
941 Vektor<MFLOAT,Dim> v0, v1;
942 NDIndex<Dim> ndi0, ndi1;
943 unsigned int d;
944 int i0, i1;
945 for (d=0; d<Dim; d++) {
946 i0 = ndi[d].first();
947 i1 = ndi[d].last();
948 ndi0[d] = Index(i0,i0,1); // Bounding vertex (from below)
949 ndi1[d] = Index(i1,i1,1); // Bounding vertex (from above)
950 }
951 v0 = getVertexPosition(ndi0);
952 v1 = getVertexPosition(ndi1);
953 // Compute volume of rectangular solid beweeen these extremal vertices:
954 MFLOAT volume = 1.0;
955 for (d=0; d<Dim; d++) volume *= abs(v1(d) - v0(d));
956 return volume;
957}
958// Volume of range of cells spanned by input NDIndex (index of cells):
959template <unsigned Dim, class MFLOAT>
960MFLOAT
962getCellRangeVolume(const NDIndex<Dim>& ndi) const
963{
964 // Get vertex positions bounding extremal cells:
965 Vektor<MFLOAT,Dim> v0, v1;
966 NDIndex<Dim> ndi0, ndi1;
967 unsigned int d;
968 int i0, i1;
969 for (d=0; d<Dim; d++) {
970 i0 = ndi[d].first();
971 i1 = ndi[d].last() + 1;
972 ndi0[d] = Index(i0,i0,1); // Bounding vertex (from below)
973 ndi1[d] = Index(i1,i1,1); // Bounding vertex (from above)
974 }
975 v0 = getVertexPosition(ndi0);
976 v1 = getVertexPosition(ndi1);
977 // Compute volume of rectangular solid beweeen these extremal vertices:
978 MFLOAT volume = 1.0;
979 for (d=0; d<Dim; d++) volume *= abs(v1(d) - v0(d));
980 return volume;
981}
982
983// Nearest vertex index to (x,y,z):
984template <unsigned Dim, class MFLOAT>
988{
989 // Find coordinate vectors of the vertices just above and just below the
990 // input point (extremal vertices on cell containing point):
991 NDIndex<Dim> ndi;
992 int i;
993 for (unsigned int d=0; d<Dim; d++) {
994 i = (int)((x(d) - origin(d))/meshSpacing[d] + 0.5);
995 if (x(d) >= origin(d))
996 ndi[d] = Index(i,i);
997 else
998 ndi[d] = Index(i-1,i-1);
999 }
1000 return ndi;
1001}
1002// Nearest vertex index with all vertex coordinates below (x,y,z):
1003template <unsigned Dim, class MFLOAT>
1006getVertexBelow(const Vektor<MFLOAT,Dim>& x) const
1007{
1008 // Find coordinate vectors of the vertices just above and just below the
1009 // input point (extremal vertices on cell containing point):
1010 NDIndex<Dim> ndi;
1011 int i;
1012 for (unsigned int d=0; d<Dim; d++) {
1013 i = (int)((x(d) - origin(d))/meshSpacing[d]);
1014 if (x(d) >= origin(d))
1015 ndi[d] = Index(i,i);
1016 else
1017 ndi[d] = Index(i-1,i-1);
1018 }
1019 return ndi;
1020}
1021// (x,y,z) coordinates of indexed vertex:
1022template <unsigned Dim, class MFLOAT>
1025getVertexPosition(const NDIndex<Dim>& ndi) const
1026{
1027 unsigned int d;
1028 for (d=0; d<Dim; d++) {
1029 if (ndi[d].length() != 1)
1030 ERRORMSG("UniformCartesian::getVertexPosition() error: arg is not a"
1031 << " NDIndex specifying a single element" << endl);
1032 }
1033 // N.B.: following may need modification to be right for periodic Mesh BC:
1034 Vektor<MFLOAT,Dim> vertexPosition;
1035 for (d=0; d<Dim; d++)
1036 vertexPosition(d) = ndi[d].first()*meshSpacing[d] + origin(d);
1037 return vertexPosition;
1038}
1039// Field of (x,y,z) coordinates of all vertices:
1040template <unsigned Dim, class MFLOAT>
1044 UniformCartesian<Dim,MFLOAT>,Vert>& vertexPositions) const
1045{
1046 unsigned int d;
1047 int currentLocation[Dim];
1048 Vektor<MFLOAT,Dim> vertexPosition;
1049 vertexPositions.Uncompress(); // uncompress field before entering values!
1051 fi_end = vertexPositions.end();
1052 for (fi = vertexPositions.begin(); fi != fi_end; ++fi) {
1053 fi.GetCurrentLocation(currentLocation);
1054 for (d=0; d<Dim; d++)
1055 vertexPosition(d) = origin(d) + currentLocation[d]*meshSpacing[d];
1056 *fi = vertexPosition;
1057 }
1058 return vertexPositions;
1059}
1060
1061// (x,y,z) coordinates of indexed cell:
1062template <unsigned Dim, class MFLOAT>
1065getCellPosition(const NDIndex<Dim>& ndi) const
1066{
1067 unsigned int d;
1068 for (d=0; d<Dim; d++) {
1069 if (ndi[d].length() != 1)
1070 ERRORMSG("UniformCartesian::getCellPosition() error: arg is not a"
1071 << " NDIndex specifying a single element" << endl);
1072 }
1073 // N.B.: following may need modification to be right for periodic Mesh BC:
1074 Vektor<MFLOAT,Dim> cellPosition;
1075 for (d=0; d<Dim; d++)
1076 cellPosition(d) = (ndi[d].first()+0.5)*meshSpacing[d] + origin(d);
1077 return cellPosition;
1078}
1079// Field of (x,y,z) coordinates of all cells:
1080template <unsigned Dim, class MFLOAT>
1084 UniformCartesian<Dim,MFLOAT>,Cell>& cellPositions) const
1085{
1086 unsigned int d;
1087 int currentLocation[Dim];
1088 Vektor<MFLOAT,Dim> cellPosition;
1089 cellPositions.Uncompress(); // uncompress field before entering values!
1091 fi_end = cellPositions.end();
1092 for (fi = cellPositions.begin(); fi != fi_end; ++fi) {
1093 fi.GetCurrentLocation(currentLocation);
1094 for (d=0; d<Dim; d++)
1095 cellPosition(d) = origin(d) + (currentLocation[d]+0.5)*meshSpacing[d];
1096 *fi = cellPosition;
1097 }
1098 return cellPositions;
1099}
1100
1101// Vertex-vertex grid spacing of indexed cell:
1102template <unsigned Dim, class MFLOAT>
1105getDeltaVertex(const NDIndex<Dim>& ndi) const
1106{
1107 // bfh: updated to compute interval for a whole index range
1108 Vektor<MFLOAT,Dim> vertexVertexSpacing;
1109 for (unsigned int d=0; d<Dim; d++)
1110 vertexVertexSpacing[d] = meshSpacing[d] * ndi[d].length();
1111 return vertexVertexSpacing;
1112}
1113
1114// Field of vertex-vertex grid spacings of all cells:
1115template <unsigned Dim, class MFLOAT>
1119 UniformCartesian<Dim,MFLOAT>,Cell>& vertexSpacings) const
1120{
1121 Vektor<MFLOAT,Dim> vertexVertexSpacing;
1122 unsigned int d;
1123 for (d=0; d<Dim; d++) vertexVertexSpacing(d) = meshSpacing[d];
1124 vertexSpacings = vertexVertexSpacing;
1125 return vertexSpacings;
1126}
1127
1128// Cell-cell grid spacing of indexed vertex:
1129template <unsigned Dim, class MFLOAT>
1132getDeltaCell(const NDIndex<Dim>& ndi) const
1133{
1134 // bfh: updated to compute interval for a whole index range
1135 Vektor<MFLOAT,Dim> cellCellSpacing;
1136 for (unsigned int d=0; d<Dim; d++)
1137 cellCellSpacing[d] = meshSpacing[d] * ndi[d].length();
1138 return cellCellSpacing;
1139}
1140
1141// Field of cell-cell grid spacings of all vertices:
1142template <unsigned Dim, class MFLOAT>
1146 UniformCartesian<Dim,MFLOAT>,Vert>& cellSpacings) const
1147{
1148 Vektor<MFLOAT,Dim> cellCellSpacing;
1149 unsigned int d;
1150 for (d=0; d<Dim; d++) cellCellSpacing(d) = meshSpacing[d];
1151 cellSpacings = cellCellSpacing;
1152 return cellSpacings;
1153}
1154// Array of surface normals to cells adjoining indexed cell:
1155template <unsigned Dim, class MFLOAT>
1158getSurfaceNormals(const NDIndex<Dim>& /*ndi*/) const
1159{
1160 Vektor<MFLOAT,Dim>* surfaceNormals = new Vektor<MFLOAT,Dim>[2*Dim];
1161 unsigned int d, i;
1162 for (d=0; d<Dim; d++) {
1163 for (i=0; i<Dim; i++) {
1164 surfaceNormals[2*d](i) = 0.0;
1165 surfaceNormals[2*d+1](i) = 0.0;
1166 }
1167 surfaceNormals[2*d](d) = -1.0;
1168 surfaceNormals[2*d+1](d) = 1.0;
1169 }
1170 return surfaceNormals;
1171}
1172// Array of (pointers to) Fields of surface normals to all cells:
1173template <unsigned Dim, class MFLOAT>
1174void
1178 surfaceNormalsFields ) const
1179{
1180 Vektor<MFLOAT,Dim>* surfaceNormals = new Vektor<MFLOAT,Dim>[2*Dim];
1181 unsigned int d, i;
1182 for (d=0; d<Dim; d++) {
1183 for (i=0; i<Dim; i++) {
1184 surfaceNormals[2*d](i) = 0.0;
1185 surfaceNormals[2*d+1](i) = 0.0;
1186 }
1187 surfaceNormals[2*d](d) = -1.0;
1188 surfaceNormals[2*d+1](d) = 1.0;
1189 }
1190 for (d=0; d<2*Dim; d++) assign((*(surfaceNormalsFields[d])),
1191 surfaceNormals[d]);
1192 // return surfaceNormalsFields;
1193}
1194// Similar functions, but specify the surface normal to a single face, using
1195// the following numbering convention: 0 means low face of 1st dim, 1 means
1196// high face of 1st dim, 2 means low face of 2nd dim, 3 means high face of
1197// 2nd dim, and so on:
1198// Surface normal to face on indexed cell:
1199template <unsigned Dim, class MFLOAT>
1202getSurfaceNormal(const NDIndex<Dim>& /*ndi*/, unsigned face) const
1203{
1204 Vektor<MFLOAT,Dim> surfaceNormal;
1205 unsigned int d;
1206 // The following bitwise AND logical test returns true if face is odd
1207 // (meaning the "high" or "right" face in the numbering convention) and
1208 // returns false if face is even (meaning the "low" or "left" face in the
1209 // numbering convention):
1210 if ( face & 1 ) {
1211 for (d=0; d<Dim; d++) {
1212 if ((face/2) == d) {
1213 surfaceNormal(face) = -1.0;
1214 } else {
1215 surfaceNormal(face) = 0.0;
1216 }
1217 }
1218 } else {
1219 for (d=0; d<Dim; d++) {
1220 if ((face/2) == d) {
1221 surfaceNormal(face) = 1.0;
1222 } else {
1223 surfaceNormal(face) = 0.0;
1224 }
1225 }
1226 }
1227 return surfaceNormal;
1228}
1229// Field of surface normals to face on all cells:
1230template <unsigned Dim, class MFLOAT>
1234 UniformCartesian<Dim,MFLOAT>,Cell>& surfaceNormalField,
1235 unsigned face) const
1236{
1237 Vektor<MFLOAT,Dim> surfaceNormal;
1238 unsigned int d;
1239 // The following bitwise AND logical test returns true if face is odd
1240 // (meaning the "high" or "right" face in the numbering convention) and
1241 // returns false if face is even (meaning the "low" or "left" face in the
1242 // numbering convention):
1243 if ( face & 1 ) {
1244 for (d=0; d<Dim; d++) {
1245 if ((face/2) == d) {
1246 surfaceNormal(face) = -1.0;
1247 } else {
1248 surfaceNormal(face) = 0.0;
1249 }
1250 }
1251 } else {
1252 for (d=0; d<Dim; d++) {
1253 if ((face/2) == d) {
1254 surfaceNormal(face) = 1.0;
1255 } else {
1256 surfaceNormal(face) = 0.0;
1257 }
1258 }
1259 }
1260 surfaceNormalField = surfaceNormal;
1261 return surfaceNormalField;
1262}
1263
1264
1265//--------------------------------------------------------------------------
1266// Global functions
1267//--------------------------------------------------------------------------
1268
1269
1270//*****************************************************************************
1271// Stuff taken from old Cartesian.h, which now applies to UniformCartesian:
1272//*****************************************************************************
1273
1274//----------------------------------------------------------------------
1275// Divergence Vektor/Vert -> Scalar/Cell
1276//----------------------------------------------------------------------
1277template < class T, class MFLOAT >
1281{
1282 const NDIndex<1U>& domain = r.getDomain();
1283 Index I = domain[0];
1284
1285 assign( r[I] ,
1286 dot(x[I ], x.get_mesh().Dvc[0]) +
1287 dot(x[I+1], x.get_mesh().Dvc[1]));
1288 return r;
1289}
1290//----------------------------------------------------------------------
1291template < class T, class MFLOAT >
1295{
1296 const NDIndex<2U>& domain = r.getDomain();
1297 Index I = domain[0];
1298 Index J = domain[1];
1299
1300 assign( r[I][J] ,
1301 dot(x[I ][J ], x.get_mesh().Dvc[0]) +
1302 dot(x[I+1][J ], x.get_mesh().Dvc[1]) +
1303 dot(x[I ][J+1], x.get_mesh().Dvc[2]) +
1304 dot(x[I+1][J+1], x.get_mesh().Dvc[3]));
1305 return r;
1306}
1307//----------------------------------------------------------------------
1308template < class T, class MFLOAT >
1312{
1313 const NDIndex<3U>& domain = r.getDomain();
1314 Index I = domain[0];
1315 Index J = domain[1];
1316 Index K = domain[2];
1317
1318 assign( r[I][J][K] ,
1319 dot(x[I ][J ][K ], x.get_mesh().Dvc[0]) +
1320 dot(x[I+1][J ][K ], x.get_mesh().Dvc[1]) +
1321 dot(x[I ][J+1][K ], x.get_mesh().Dvc[2]) +
1322 dot(x[I+1][J+1][K ], x.get_mesh().Dvc[3]) +
1323 dot(x[I ][J ][K+1], x.get_mesh().Dvc[4]) +
1324 dot(x[I+1][J ][K+1], x.get_mesh().Dvc[5]) +
1325 dot(x[I ][J+1][K+1], x.get_mesh().Dvc[6]) +
1326 dot(x[I+1][J+1][K+1], x.get_mesh().Dvc[7]));
1327 return r;
1328}
1329//----------------------------------------------------------------------
1330// Divergence Vektor/Cell -> Scalar/Vert
1331//----------------------------------------------------------------------
1332template < class T, class MFLOAT >
1336{
1337 const NDIndex<1U>& domain = r.getDomain();
1338 Index I = domain[0];
1339
1340 assign( r[I] ,
1341 dot(x[I-1], x.get_mesh().Dvc[0]) +
1342 dot(x[I ], x.get_mesh().Dvc[1]));
1343 return r;
1344}
1345//----------------------------------------------------------------------
1346// (tjw: the one in cv.cpp)
1347template < class T, class MFLOAT >
1351{
1352 const NDIndex<2U>& domain = r.getDomain();
1353 Index I = domain[0];
1354 Index J = domain[1];
1355
1356 assign( r[I][J] ,
1357 dot(x[I-1][J-1], x.get_mesh().Dvc[0]) +
1358 dot(x[I ][J-1], x.get_mesh().Dvc[1]) +
1359 dot(x[I-1][J ], x.get_mesh().Dvc[2]) +
1360 dot(x[I ][J ], x.get_mesh().Dvc[3]));
1361 return r;
1362}
1363//----------------------------------------------------------------------
1364template < class T, class MFLOAT >
1368{
1369 const NDIndex<3U>& domain = r.getDomain();
1370 Index I = domain[0];
1371 Index J = domain[1];
1372 Index K = domain[2];
1373
1374 assign( r[I][J][K] ,
1375 dot(x[I-1][J-1][K-1], x.get_mesh().Dvc[0]) +
1376 dot(x[I ][J-1][K-1], x.get_mesh().Dvc[1]) +
1377 dot(x[I-1][J ][K-1], x.get_mesh().Dvc[2]) +
1378 dot(x[I ][J ][K-1], x.get_mesh().Dvc[3]) +
1379 dot(x[I-1][J-1][K ], x.get_mesh().Dvc[4]) +
1380 dot(x[I ][J-1][K ], x.get_mesh().Dvc[5]) +
1381 dot(x[I-1][J ][K ], x.get_mesh().Dvc[6]) +
1382 dot(x[I ][J ][K ], x.get_mesh().Dvc[7]));
1383 return r;
1384}
1385//----------------------------------------------------------------------
1386// Divergence Vektor/Vert -> Scalar/Vert
1387//----------------------------------------------------------------------
1388template < class T, class MFLOAT >
1392{
1393 const NDIndex<1U>& domain = r.getDomain();
1394 Index I = domain[0];
1395 Vektor<T,1U> idx;
1396 idx[0] = 0.5/x.get_mesh().get_meshSpacing(0);
1397
1398 assign( r[I] , dot( idx , (x[I+1] - x[I-1]) ) );
1399 return r;
1400}
1401//----------------------------------------------------------------------
1402template < class T, class MFLOAT >
1406{
1407 const NDIndex<2U>& domain = r.getDomain();
1408 Index I = domain[0];
1409 Index J = domain[1];
1410 Vektor<T,2U> idx,idy;
1411 idx[0] = 0.5/x.get_mesh().get_meshSpacing(0);
1412 idx[1] = 0.0;
1413 idy[0] = 0.0;
1414 idy[1] = 0.5/x.get_mesh().get_meshSpacing(1);
1415
1416 assign( r[I][J] ,
1417 dot( idx , (x[I+1][J ] - x[I-1][J ])) +
1418 dot( idy , (x[I ][J+1] - x[I ][J-1])) );
1419 return r;
1420}
1421//----------------------------------------------------------------------
1422template < class T, class MFLOAT >
1426{
1427 const NDIndex<3U>& domain = r.getDomain();
1428 Index I = domain[0];
1429 Index J = domain[1];
1430 Index K = domain[2];
1431 Vektor<T,3U> idx,idy,idz;
1432 idx[0] = 0.5/x.get_mesh().get_meshSpacing(0);
1433 idx[1] = 0.0;
1434 idx[2] = 0.0;
1435 idy[0] = 0.0;
1436 idy[1] = 0.5/x.get_mesh().get_meshSpacing(1);
1437 idy[2] = 0.0;
1438 idz[0] = 0.0;
1439 idz[1] = 0.0;
1440 idz[2] = 0.5/x.get_mesh().get_meshSpacing(2);
1441
1442 assign( r[I][J][K] ,
1443 dot(idx , (x[I+1][J ][K ] - x[I-1][J ][K ] )) +
1444 dot(idy , (x[I ][J+1][K ] - x[I ][J-1][K ] )) +
1445 dot(idz , (x[I ][J ][K+1] - x[I ][J ][K-1] )) );
1446 return r;
1447}
1448//----------------------------------------------------------------------
1449// Divergence Vektor/Edge -> Scalar/Vert
1450//----------------------------------------------------------------------
1451template < class T, class MFLOAT >
1455{
1456 const NDIndex<1U>& domain = r.getDomain();
1457 Index I = domain[0];
1458 Vektor<T,1U> idx;
1459 idx[0] = 1.0/x.get_mesh().get_meshSpacing(0);
1460
1461 assign( r[I] , dot( idx , (x[I] - x[I-1]) ) );
1462 return r;
1463}
1464//----------------------------------------------------------------------
1465template < class T, class MFLOAT >
1469{
1470 const NDIndex<2U>& domain = r.getDomain();
1471 Index I = domain[0];
1472 Index J = domain[1];
1473 Vektor<T,2U> idx,idy;
1474 idx[0] = 1.0/x.get_mesh().get_meshSpacing(0);
1475 idx[1] = 0.0;
1476 idy[0] = 0.0;
1477 idy[1] = 1.0/x.get_mesh().get_meshSpacing(1);
1478
1479 assign( r[I][J] ,
1480 dot( idx , (x[I][J] - x[I-1][J ])) +
1481 dot( idy , (x[I][J] - x[I ][J-1])) );
1482 return r;
1483}
1484//----------------------------------------------------------------------
1485template < class T, class MFLOAT >
1489{
1490 const NDIndex<3U>& domain = r.getDomain();
1491 Index I = domain[0];
1492 Index J = domain[1];
1493 Index K = domain[2];
1494 Vektor<T,3U> idx,idy,idz;
1495 idx[0] = 1.0/x.get_mesh().get_meshSpacing(0);
1496 idx[1] = 0.0;
1497 idx[2] = 0.0;
1498 idy[0] = 0.0;
1499 idy[1] = 1.0/x.get_mesh().get_meshSpacing(1);
1500 idy[2] = 0.0;
1501 idz[0] = 0.0;
1502 idz[1] = 0.0;
1503 idz[2] = 1.0/x.get_mesh().get_meshSpacing(2);
1504
1505 assign( r[I][J][K] ,
1506 dot(idx , (x[I][J][K] - x[I-1][J ][K ] )) +
1507 dot(idy , (x[I][J][K] - x[I ][J-1][K ] )) +
1508 dot(idz , (x[I][J][K] - x[I ][J ][K-1] )) );
1509 return r;
1510}
1511//----------------------------------------------------------------------
1512// Divergence Vektor/Cell -> Scalar/Cell
1513//----------------------------------------------------------------------
1514template < class T, class MFLOAT >
1518{
1519 const NDIndex<1U>& domain = r.getDomain();
1520 Index I = domain[0];
1521 Vektor<T,1U> idx;
1522 idx[0] = 0.5/x.get_mesh().get_meshSpacing(0);
1523
1524 assign( r[I] , dot( idx , (x[I+1] - x[I-1]) ) );
1525 return r;
1526}
1527//----------------------------------------------------------------------
1528template < class T, class MFLOAT >
1532{
1533 const NDIndex<2U>& domain = r.getDomain();
1534 Index I = domain[0];
1535 Index J = domain[1];
1536 Vektor<T,2U> idx,idy;
1537 idx[0] = 0.5/x.get_mesh().get_meshSpacing(0);
1538 idx[1] = 0.0;
1539 idy[0] = 0.0;
1540 idy[1] = 0.5/x.get_mesh().get_meshSpacing(1);
1541
1542 assign( r[I][J] ,
1543 dot( idx , (x[I+1][J ] - x[I-1][J ])) +
1544 dot( idy , (x[I ][J+1] - x[I ][J-1])) );
1545 return r;
1546}
1547//----------------------------------------------------------------------
1548template < class T, class MFLOAT >
1552{
1553 const NDIndex<3U>& domain = r.getDomain();
1554 Index I = domain[0];
1555 Index J = domain[1];
1556 Index K = domain[2];
1557 Vektor<T,3U> idx,idy,idz;
1558 idx[0] = 0.5/x.get_mesh().get_meshSpacing(0);
1559 idx[1] = 0.0;
1560 idx[2] = 0.0;
1561 idy[0] = 0.0;
1562 idy[1] = 0.5/x.get_mesh().get_meshSpacing(1);
1563 idy[2] = 0.0;
1564 idz[0] = 0.0;
1565 idz[1] = 0.0;
1566 idz[2] = 0.5/x.get_mesh().get_meshSpacing(2);
1567
1568 assign( r[I][J][K] ,
1569 dot(idx , (x[I+1][J ][K ] - x[I-1][J ][K ] )) +
1570 dot(idy , (x[I ][J+1][K ] - x[I ][J-1][K ] )) +
1571 dot(idz , (x[I ][J ][K+1] - x[I ][J ][K-1] )) );
1572 return r;
1573}
1574//----------------------------------------------------------------------
1575// Divergence Tenzor/Vert -> Vektor/Cell
1576//----------------------------------------------------------------------
1577template < class T, class MFLOAT >
1581{
1582 const NDIndex<1U>& domain = r.getDomain();
1583 Index I = domain[0];
1584
1585 assign( r[I] ,
1586 dot(x[I ], x.get_mesh().Dvc[0]) +
1587 dot(x[I+1], x.get_mesh().Dvc[1]));
1588 return r;
1589}
1590//----------------------------------------------------------------------
1591template < class T, class MFLOAT >
1595{
1596 const NDIndex<2U>& domain = r.getDomain();
1597 Index I = domain[0];
1598 Index J = domain[1];
1599
1600 assign( r[I][J] ,
1601 dot(x[I ][J ], x.get_mesh().Dvc[0]) +
1602 dot(x[I+1][J ], x.get_mesh().Dvc[1]) +
1603 dot(x[I ][J+1], x.get_mesh().Dvc[2]) +
1604 dot(x[I+1][J+1], x.get_mesh().Dvc[3]));
1605
1606 return r;
1607}
1608//----------------------------------------------------------------------
1609template < class T, class MFLOAT >
1613{
1614 const NDIndex<3U>& domain = r.getDomain();
1615 Index I = domain[0];
1616 Index J = domain[1];
1617 Index K = domain[2];
1618
1619 assign( r[I][J][K] ,
1620 dot(x[I ][J ][K ], x.get_mesh().Dvc[0]) +
1621 dot(x[I+1][J ][K ], x.get_mesh().Dvc[1]) +
1622 dot(x[I ][J+1][K ], x.get_mesh().Dvc[2]) +
1623 dot(x[I+1][J+1][K ], x.get_mesh().Dvc[3]) +
1624 dot(x[I ][J ][K+1], x.get_mesh().Dvc[4]) +
1625 dot(x[I+1][J ][K+1], x.get_mesh().Dvc[5]) +
1626 dot(x[I ][J+1][K+1], x.get_mesh().Dvc[6]) +
1627 dot(x[I+1][J+1][K+1], x.get_mesh().Dvc[7]));
1628
1629 return r;
1630}
1631//----------------------------------------------------------------------
1632// Divergence SymTenzor/Vert -> Vektor/Cell
1633//----------------------------------------------------------------------
1634template < class T, class MFLOAT >
1638{
1639 const NDIndex<1U>& domain = r.getDomain();
1640 Index I = domain[0];
1641
1642 assign( r[I] ,
1643 dot(x[I ], x.get_mesh().Dvc[0]) +
1644 dot(x[I+1], x.get_mesh().Dvc[1]));
1645 return r;
1646}
1647//----------------------------------------------------------------------
1648template < class T, class MFLOAT >
1652{
1653 const NDIndex<2U>& domain = r.getDomain();
1654 Index I = domain[0];
1655 Index J = domain[1];
1656
1657 assign( r[I][J] ,
1658 dot(x[I ][J ], x.get_mesh().Dvc[0]) +
1659 dot(x[I+1][J ], x.get_mesh().Dvc[1]) +
1660 dot(x[I ][J+1], x.get_mesh().Dvc[2]) +
1661 dot(x[I+1][J+1], x.get_mesh().Dvc[3]));
1662 return r;
1663}
1664//----------------------------------------------------------------------
1665template < class T, class MFLOAT >
1669{
1670 const NDIndex<3U>& domain = r.getDomain();
1671 Index I = domain[0];
1672 Index J = domain[1];
1673 Index K = domain[2];
1674
1675 assign( r[I][J][K] ,
1676 dot(x[I ][J ][K ], x.get_mesh().Dvc[0]) +
1677 dot(x[I+1][J ][K ], x.get_mesh().Dvc[1]) +
1678 dot(x[I ][J+1][K ], x.get_mesh().Dvc[2]) +
1679 dot(x[I+1][J+1][K ], x.get_mesh().Dvc[3]) +
1680 dot(x[I ][J ][K+1], x.get_mesh().Dvc[4]) +
1681 dot(x[I+1][J ][K+1], x.get_mesh().Dvc[5]) +
1682 dot(x[I ][J+1][K+1], x.get_mesh().Dvc[6]) +
1683 dot(x[I+1][J+1][K+1], x.get_mesh().Dvc[7]));
1684 return r;
1685}
1686
1687//----------------------------------------------------------------------
1688// Divergence Tenzor/Cell -> Vektor/Vert
1689//----------------------------------------------------------------------
1690template < class T, class MFLOAT >
1694{
1695 const NDIndex<1U>& domain = r.getDomain();
1696 Index I = domain[0];
1697
1698 assign( r[I] ,
1699 dot(x[I-1], x.get_mesh().Dvc[0]) +
1700 dot(x[I ], x.get_mesh().Dvc[1]));
1701 return r;
1702}
1703//----------------------------------------------------------------------
1704template < class T, class MFLOAT >
1708{
1709 const NDIndex<2U>& domain = r.getDomain();
1710 Index I = domain[0];
1711 Index J = domain[1];
1712
1713 assign( r[I][J] ,
1714 dot(x[I-1][J-1], x.get_mesh().Dvc[0]) +
1715 dot(x[I ][J-1], x.get_mesh().Dvc[1]) +
1716 dot(x[I-1][J ], x.get_mesh().Dvc[2]) +
1717 dot(x[I ][J ], x.get_mesh().Dvc[3]));
1718 return r;
1719}
1720//----------------------------------------------------------------------
1721template < class T, class MFLOAT >
1725{
1726 const NDIndex<3U>& domain = r.getDomain();
1727 Index I = domain[0];
1728 Index J = domain[1];
1729 Index K = domain[2];
1730
1731 assign( r[I][J][K] ,
1732 dot(x[I-1][J-1][K-1], x.get_mesh().Dvc[0]) +
1733 dot(x[I ][J-1][K-1], x.get_mesh().Dvc[1]) +
1734 dot(x[I-1][J ][K-1], x.get_mesh().Dvc[2]) +
1735 dot(x[I ][J ][K-1], x.get_mesh().Dvc[3]) +
1736 dot(x[I-1][J-1][K ], x.get_mesh().Dvc[4]) +
1737 dot(x[I ][J-1][K ], x.get_mesh().Dvc[5]) +
1738 dot(x[I-1][J ][K ], x.get_mesh().Dvc[6]) +
1739 dot(x[I ][J ][K ], x.get_mesh().Dvc[7]));
1740 return r;
1741}
1742
1743//----------------------------------------------------------------------
1744// Divergence SymTenzor/Cell -> Vektor/Vert
1745//----------------------------------------------------------------------
1746template < class T, class MFLOAT >
1750{
1751 const NDIndex<1U>& domain = r.getDomain();
1752 Index I = domain[0];
1753
1754 assign( r[I] ,
1755 dot(x[I-1], x.get_mesh().Dvc[0]) +
1756 dot(x[I ], x.get_mesh().Dvc[1]));
1757 return r;
1758}
1759//----------------------------------------------------------------------
1760template < class T, class MFLOAT >
1764{
1765 const NDIndex<2U>& domain = r.getDomain();
1766 Index I = domain[0];
1767 Index J = domain[1];
1768
1769 assign( r[I][J] ,
1770 dot(x[I-1][J-1], x.get_mesh().Dvc[0]) +
1771 dot(x[I ][J-1], x.get_mesh().Dvc[1]) +
1772 dot(x[I-1][J ], x.get_mesh().Dvc[2]) +
1773 dot(x[I ][J ], x.get_mesh().Dvc[3]));
1774 return r;
1775}
1776//----------------------------------------------------------------------
1777template < class T, class MFLOAT >
1781{
1782 const NDIndex<3U>& domain = r.getDomain();
1783 Index I = domain[0];
1784 Index J = domain[1];
1785 Index K = domain[2];
1786
1787 assign( r[I][J][K] ,
1788 dot(x[I-1][J-1][K-1], x.get_mesh().Dvc[0]) +
1789 dot(x[I ][J-1][K-1], x.get_mesh().Dvc[1]) +
1790 dot(x[I-1][J ][K-1], x.get_mesh().Dvc[2]) +
1791 dot(x[I ][J ][K-1], x.get_mesh().Dvc[3]) +
1792 dot(x[I-1][J-1][K ], x.get_mesh().Dvc[4]) +
1793 dot(x[I ][J-1][K ], x.get_mesh().Dvc[5]) +
1794 dot(x[I-1][J ][K ], x.get_mesh().Dvc[6]) +
1795 dot(x[I ][J ][K ], x.get_mesh().Dvc[7]));
1796 return r;
1797}
1798
1799//----------------------------------------------------------------------
1800// Grad Scalar/Vert -> Vektor/Cell
1801//----------------------------------------------------------------------
1802template < class T, class MFLOAT >
1806{
1807 const NDIndex<1U>& domain = r.getDomain();
1808 Index I = domain[0];
1809
1810 assign( r[I] ,
1811 x[I ] * x.get_mesh().Dvc[0] +
1812 x[I+1] * x.get_mesh().Dvc[1]);
1813 return r;
1814}
1815//----------------------------------------------------------------------
1816template < class T, class MFLOAT >
1820{
1821 const NDIndex<2U>& domain = r.getDomain();
1822 Index I = domain[0];
1823 Index J = domain[1];
1824
1825 assign( r[I][J] ,
1826 x[I ][J ] * x.get_mesh().Dvc[0] +
1827 x[I+1][J ] * x.get_mesh().Dvc[1] +
1828 x[I ][J+1] * x.get_mesh().Dvc[2] +
1829 x[I+1][J+1] * x.get_mesh().Dvc[3]);
1830 return r;
1831}
1832//----------------------------------------------------------------------
1833template < class T, class MFLOAT >
1837{
1838 const NDIndex<3U>& domain = r.getDomain();
1839 Index I = domain[0];
1840 Index J = domain[1];
1841 Index K = domain[2];
1842
1843 assign( r[I][J][K] ,
1844 x[I ][J ][K ] * x.get_mesh().Dvc[0] +
1845 x[I+1][J ][K ] * x.get_mesh().Dvc[1] +
1846 x[I ][J+1][K ] * x.get_mesh().Dvc[2] +
1847 x[I+1][J+1][K ] * x.get_mesh().Dvc[3] +
1848 x[I ][J ][K+1] * x.get_mesh().Dvc[4] +
1849 x[I+1][J ][K+1] * x.get_mesh().Dvc[5] +
1850 x[I ][J+1][K+1] * x.get_mesh().Dvc[6] +
1851 x[I+1][J+1][K+1] * x.get_mesh().Dvc[7]);
1852
1853 return r;
1854}
1855//----------------------------------------------------------------------
1856// Grad Scalar/Vert -> Vektor/Edge
1857//----------------------------------------------------------------------
1858template < class T, class MFLOAT >
1862{
1863 const NDIndex<1U>& domain = r.getDomain();
1864 Index I = Index(domain[0].first(), domain[0].last()-1);
1865
1866 assign( r[I] ,
1867 x[I ] * x.get_mesh().Dvc[0] +
1868 x[I+1] * x.get_mesh().Dvc[1]);
1869 return r;
1870}
1871//----------------------------------------------------------------------
1872template < class T, class MFLOAT >
1876{
1877 const NDIndex<2U>& domain = r.getDomain();
1878 Index I = Index(domain[0].first(), domain[0].last()-1);
1879 Index J = Index(domain[1].first(), domain[1].last()-1);
1880
1881 Vektor<T,2U> idx,idy;
1882 idx[0] = 1.0/x.get_mesh().get_meshSpacing(0);
1883 idx[1] = 0.0;
1884 idy[0] = 0.0;
1885 idy[1] = 1.0/x.get_mesh().get_meshSpacing(1);
1886
1887 assign( r[I][J] ,
1888 (x[I+1][J ] - x[I ][J ]) * idx +
1889 (x[I ][J+1] - x[I ][J ]) * idy);
1890 I = Index(domain[0].last(), domain[0].last());
1891 assign( r[I][J](1),
1892 (x[I][J+1] - x[I][J]));
1893 I = Index(domain[0].first(), domain[0].last()-1);
1894 J = Index(domain[1].last(), domain[1].last());
1895 assign( r[I][J](0),
1896 (x[I+1][J] - x[I][J]));
1897 J = Index(domain[1].first(), domain[1].last()-1);
1898 return r;
1899}
1900//----------------------------------------------------------------------
1901template < class T, class MFLOAT >
1905{
1906 const NDIndex<3U>& domain = r.getDomain();
1907 Index I = Index(domain[0].first(), domain[0].last()-1);
1908 Index J = Index(domain[1].first(), domain[1].last()-1);
1909 Index K = Index(domain[2].first(), domain[2].last()-1);
1910
1911 Vektor<T,3U> idx,idy,idz;
1912 idx[0] = 1.0/x.get_mesh().get_meshSpacing(0);
1913 idx[1] = 0.0;
1914 idx[2] = 0.0;
1915 idy[0] = 0.0;
1916 idy[1] = 1.0/x.get_mesh().get_meshSpacing(1);
1917 idy[2] = 0.0;
1918 idz[0] = 0.0;
1919 idz[1] = 0.0;
1920 idz[2] = 1.0/x.get_mesh().get_meshSpacing(2);
1921
1922 assign( r[I][J][K] ,
1923 (x[I+1][J ][K ] - x[I ][J ][K ]) * idx +
1924 (x[I ][J+1][K ] - x[I ][J ][K ]) * idy +
1925 (x[I ][J ][K+1] - x[I ][J ][K ]) * idz);
1926 I = Index(domain[0].last(), domain[0].last());
1927 assign( r[I][J][K](1),
1928 (x[I ][J+1][K ] - x[I ][J ][K ]));
1929 assign( r[I][J][K](2),
1930 (x[I ][J ][K+1] - x[I ][J ][K ]));
1931 I = Index(domain[0].first(), domain[0].last()-1);
1932 J = Index(domain[1].last(), domain[1].last());
1933 assign( r[I][J][K](0),
1934 (x[I+1][J ][K ] - x[I ][J ][K ]));
1935 assign( r[I][J][K](2),
1936 (x[I ][J ][K+1] - x[I ][J ][K ]));
1937 J = Index(domain[1].first(), domain[1].last()-1);
1938 K = Index(domain[2].last(), domain[2].last());
1939 assign( r[I][J][K](0),
1940 (x[I+1][J ][K ] - x[I ][J ][K ]));
1941 assign( r[I][J][K](1),
1942 (x[I ][J+1][K ] - x[I ][J ][K ]));
1943 K = Index(domain[2].first(), domain[2].last()-1);
1944
1945 return r;
1946}
1947//----------------------------------------------------------------------
1948// Grad Scalar/Cell -> Vektor/Vert
1949//----------------------------------------------------------------------
1950template < class T, class MFLOAT >
1954{
1955 const NDIndex<1U>& domain = r.getDomain();
1956 Index I = domain[0];
1957
1958 assign( r[I] ,
1959 x[I-1] * x.get_mesh().Dvc[0] +
1960 x[I ] * x.get_mesh().Dvc[1]);
1961 return r;
1962}
1963//----------------------------------------------------------------------
1964template < class T, class MFLOAT >
1968{
1969 const NDIndex<2U>& domain = r.getDomain();
1970 Index I = domain[0];
1971 Index J = domain[1];
1972
1973 assign( r[I][J] ,
1974 x[I-1][J-1] * x.get_mesh().Dvc[0] +
1975 x[I ][J-1] * x.get_mesh().Dvc[1] +
1976 x[I-1][J ] * x.get_mesh().Dvc[2] +
1977 x[I ][J ] * x.get_mesh().Dvc[3]);
1978 return r;
1979}
1980//----------------------------------------------------------------------
1981template < class T, class MFLOAT >
1985{
1986 const NDIndex<3U>& domain = r.getDomain();
1987 Index I = domain[0];
1988 Index J = domain[1];
1989 Index K = domain[2];
1990
1991 assign( r[I][J][K] ,
1992 x[I-1][J-1][K-1] * x.get_mesh().Dvc[0] +
1993 x[I ][J-1][K-1] * x.get_mesh().Dvc[1] +
1994 x[I-1][J ][K-1] * x.get_mesh().Dvc[2] +
1995 x[I ][J ][K-1] * x.get_mesh().Dvc[3] +
1996 x[I-1][J-1][K ] * x.get_mesh().Dvc[4] +
1997 x[I ][J-1][K ] * x.get_mesh().Dvc[5] +
1998 x[I-1][J ][K ] * x.get_mesh().Dvc[6] +
1999 x[I ][J ][K ] * x.get_mesh().Dvc[7]);
2000 return r;
2001}
2002//----------------------------------------------------------------------
2003// Grad Scalar/Vert -> Vektor/Vert
2004//----------------------------------------------------------------------
2005template < class T, class MFLOAT >
2009{
2010 const NDIndex<1U>& domain = r.getDomain();
2011 Index I = domain[0];
2012
2013 Vektor<T,1U> idx;
2014 idx[0] = 0.5/x.get_mesh().get_meshSpacing(0);
2015
2016 assign( r[I] , idx * (x[I+1] - x[I-1] ) );
2017 return r;
2018}
2019//----------------------------------------------------------------------
2020template < class T, class MFLOAT >
2024{
2025 const NDIndex<2U>& domain = r.getDomain();
2026 Index I = domain[0];
2027 Index J = domain[1];
2028
2029 Vektor<T,2U> idx,idy;
2030 idx[0] = 0.5/x.get_mesh().get_meshSpacing(0);
2031 idx[1] = 0.0;
2032 idy[0] = 0.0;
2033 idy[1] = 0.5/x.get_mesh().get_meshSpacing(1);
2034
2035 assign( r[I][J] ,
2036 idx * (x[I+1][J ] - x[I-1][J ]) +
2037 idy * (x[I ][J+1] - x[I ][J-1]) );
2038 return r;
2039}
2040//----------------------------------------------------------------------
2041template < class T, class MFLOAT >
2045{
2046 const NDIndex<3U>& domain = r.getDomain();
2047 Index I = domain[0];
2048 Index J = domain[1];
2049 Index K = domain[2];
2050
2051 Vektor<T,3U> idx,idy,idz;
2052 idx[0] = 0.5/x.get_mesh().get_meshSpacing(0);
2053 idx[1] = 0.0;
2054 idx[2] = 0.0;
2055 idy[0] = 0.0;
2056 idy[1] = 0.5/x.get_mesh().get_meshSpacing(1);
2057 idy[2] = 0.0;
2058 idz[0] = 0.0;
2059 idz[1] = 0.0;
2060 idz[2] = 0.5/x.get_mesh().get_meshSpacing(2);
2061
2062 assign(r[I][J][K] ,
2063 idx * (x[I+1][J ][K ] - x[I-1][J ][K ]) +
2064 idy * (x[I ][J+1][K ] - x[I ][J-1][K ]) +
2065 idz * (x[I ][J ][K+1] - x[I ][J ][K-1]));
2066 return r;
2067}
2068//----------------------------------------------------------------------
2069// Grad Scalar/Cell -> Vektor/Cell
2070//----------------------------------------------------------------------
2071template < class T, class MFLOAT >
2075{
2076 const NDIndex<1U>& domain = r.getDomain();
2077 Index I = domain[0];
2078
2079 Vektor<T,1U> idx;
2080 idx[0] = 0.5/x.get_mesh().get_meshSpacing(0);
2081
2082 assign( r[I] , idx * (x[I+1] - x[I-1] ) );
2083 return r;
2084}
2085//----------------------------------------------------------------------
2086template < class T, class MFLOAT >
2090{
2091 const NDIndex<2U>& domain = r.getDomain();
2092 Index I = domain[0];
2093 Index J = domain[1];
2094
2095 Vektor<T,2U> idx,idy;
2096 idx[0] = 0.5/x.get_mesh().get_meshSpacing(0);
2097 idx[1] = 0.0;
2098 idy[0] = 0.0;
2099 idy[1] = 0.5/x.get_mesh().get_meshSpacing(1);
2100
2101 assign( r[I][J] ,
2102 idx * (x[I+1][J ] - x[I-1][J ]) +
2103 idy * (x[I ][J+1] - x[I ][J-1]) );
2104
2105 return r;
2106}
2107//----------------------------------------------------------------------
2108template < class T, class MFLOAT >
2112{
2113 const NDIndex<3U>& domain = r.getDomain();
2114 Index I = domain[0];
2115 Index J = domain[1];
2116 Index K = domain[2];
2117
2118 Vektor<T,3U> idx,idy,idz;
2119 idx[0] = 0.5/x.get_mesh().get_meshSpacing(0);
2120 idx[1] = 0.0;
2121 idx[2] = 0.0;
2122 idy[0] = 0.0;
2123 idy[1] = 0.5/x.get_mesh().get_meshSpacing(1);
2124 idy[2] = 0.0;
2125 idz[0] = 0.0;
2126 idz[1] = 0.0;
2127 idz[2] = 0.5/x.get_mesh().get_meshSpacing(2);
2128
2129 assign(r[I][J][K] ,
2130 idx * (x[I+1][J ][K ] - x[I-1][J ][K ]) +
2131 idy * (x[I ][J+1][K ] - x[I ][J-1][K ]) +
2132 idz * (x[I ][J ][K+1] - x[I ][J ][K-1]));
2133
2134 //approximate at the border up to a term of order O(h^2)
2135 Vektor<T,3U> xx = Vektor<T,3U>(1.0,0.0,0.0);
2136 Vektor<T,3U> yy = Vektor<T,3U>(0.0,1.0,0.0);
2137 Vektor<T,3U> zz = Vektor<T,3U>(0.0,0.0,1.0);
2138
2139 Index lo(0, 0);
2140
2141 int maxI = I.length() - 1;
2142 int maxJ = J.length() - 1;
2143 int maxK = K.length() - 1;
2144
2145 Index Iup(maxI, maxI);
2146 Index Jup(maxJ, maxJ);
2147 Index Kup(maxK, maxK);
2148
2149 r[lo][J][K] = (idx * (- 1.0*x[lo+2][J][K]
2150 + 4.0*x[lo+1][J][K]
2151 - 3.0*x[lo ][J][K])
2152 + yy*r[lo][J][K]
2153 + zz*r[lo][J][K]);
2154 r[Iup][J][K] = (idx * ( 1.0*x[Iup-2][J][K]
2155 - 4.0*x[Iup-1][J][K]
2156 + 3.0*x[Iup ][J][K])
2157 + yy*r[Iup][J][K]
2158 + zz*r[Iup][J][K]);
2159
2160 r[I][lo][K] = (idy * (- 1.0*x[I][lo+2][K]
2161 + 4.0*x[I][lo+1][K]
2162 - 3.0*x[I][lo ][K])
2163 + xx*r[I][lo][K]
2164 + zz*r[I][lo][K]);
2165 r[I][Jup][K] = (idy * ( 1.0*x[I][Jup-2][K]
2166 - 4.0*x[I][Jup-1][K]
2167 + 3.0*x[I][Jup ][K])
2168 + xx*r[I][Jup][K]
2169 + zz*r[I][Jup][K]);
2170
2171 r[I][J][lo] = (idz * (- 1.0*x[I][J][lo+2]
2172 + 4.0*x[I][J][lo+1]
2173 - 3.0*x[I][J][lo ])
2174 + xx*r[I][J][lo]
2175 + yy*r[I][J][lo]);
2176 r[I][J][Kup] = (idz * ( 1.0*x[I][J][Kup-2]
2177 - 4.0*x[I][J][Kup-1]
2178 + 3.0*x[I][J][Kup ])
2179 + xx*r[I][J][Kup]
2180 + yy*r[I][J][Kup]);
2181
2182 return r;
2183}
2184
2185
2186template < class T, class MFLOAT >
2190{
2191 const NDIndex<3U>& domain = r.getDomain();
2192 Index I = domain[0];
2193 Index J = domain[1];
2194 Index K = domain[2];
2195
2196 Vektor<T,3U> idx,idy,idz;
2197 idx[0] = 0.5/x.get_mesh().get_meshSpacing(0);
2198 idx[1] = 0.0;
2199 idx[2] = 0.0;
2200 idy[0] = 0.0;
2201 idy[1] = 0.5/x.get_mesh().get_meshSpacing(1);
2202 idy[2] = 0.0;
2203 idz[0] = 0.0;
2204 idz[1] = 0.0;
2205 idz[2] = 0.5/x.get_mesh().get_meshSpacing(2);
2206
2207 assign(r[I][J][K] ,
2208 idx * (x[I+1][J ][K ] - x[I-1][J ][K ]) +
2209 idy * (x[I ][J+1][K ] - x[I ][J-1][K ]) +
2210 idz * (x[I ][J ][K+1] - x[I ][J ][K-1]));
2211 return r;
2212}
2213//----------------------------------------------------------------------
2214// Grad Vektor/Vert -> Tenzor/Cell
2215//----------------------------------------------------------------------
2216template < class T, class MFLOAT >
2220{
2221 const NDIndex<1U>& domain = r.getDomain();
2222 Index I = domain[0];
2223
2224 assign( r[I] ,
2225 outerProduct( x[I ] , x.get_mesh().Dvc[0] ) +
2226 outerProduct( x[I+1] , x.get_mesh().Dvc[1])) ;
2227 return r;
2228}
2229//----------------------------------------------------------------------
2230template < class T, class MFLOAT >
2234{
2235 const NDIndex<2U>& domain = r.getDomain();
2236 Index I = domain[0];
2237 Index J = domain[1];
2238
2239 assign( r[I][J] ,
2240 outerProduct( x[I ][J ] , x.get_mesh().Dvc[0] ) +
2241 outerProduct( x[I+1][J ] , x.get_mesh().Dvc[1] ) +
2242 outerProduct( x[I ][J+1] , x.get_mesh().Dvc[2] ) +
2243 outerProduct( x[I+1][J+1] , x.get_mesh().Dvc[3] )) ;
2244 return r;
2245}
2246//----------------------------------------------------------------------
2247template < class T, class MFLOAT >
2251{
2252 const NDIndex<3U>& domain = r.getDomain();
2253 Index I = domain[0];
2254 Index J = domain[1];
2255 Index K = domain[2];
2256
2257 assign( r[I][J][K] ,
2258 outerProduct( x[I ][J ][K ] , x.get_mesh().Dvc[0] ) +
2259 outerProduct( x[I+1][J ][K ] , x.get_mesh().Dvc[1] ) +
2260 outerProduct( x[I ][J+1][K ] , x.get_mesh().Dvc[2] ) +
2261 outerProduct( x[I+1][J+1][K ] , x.get_mesh().Dvc[3] ) +
2262 outerProduct( x[I ][J ][K+1] , x.get_mesh().Dvc[4] ) +
2263 outerProduct( x[I+1][J ][K+1] , x.get_mesh().Dvc[5] ) +
2264 outerProduct( x[I ][J+1][K+1] , x.get_mesh().Dvc[6] ) +
2265 outerProduct( x[I+1][J+1][K+1] , x.get_mesh().Dvc[7] ));
2266
2267 return r;
2268}
2269//----------------------------------------------------------------------
2270// Grad Vektor/Cell -> Tenzor/Vert
2271//----------------------------------------------------------------------
2272template < class T, class MFLOAT >
2276{
2277 const NDIndex<1U>& domain = r.getDomain();
2278 Index I = domain[0];
2279
2280 assign( r[I] ,
2281 outerProduct( x[I-1] , x.get_mesh().Dvc[0] ) +
2282 outerProduct( x[I ] , x.get_mesh().Dvc[1] ));
2283 return r;
2284}
2285//----------------------------------------------------------------------
2286template < class T, class MFLOAT >
2290{
2291 const NDIndex<2U>& domain = r.getDomain();
2292 Index I = domain[0];
2293 Index J = domain[1];
2294
2295 assign( r[I][J] ,
2296 outerProduct( x[I-1][J-1] , x.get_mesh().Dvc[0] ) +
2297 outerProduct( x[I ][J-1] , x.get_mesh().Dvc[1] ) +
2298 outerProduct( x[I-1][J ] , x.get_mesh().Dvc[2] ) +
2299 outerProduct( x[I ][J ] , x.get_mesh().Dvc[3] ));
2300 return r;
2301}
2302//----------------------------------------------------------------------
2303template < class T, class MFLOAT >
2307{
2308 const NDIndex<3U>& domain = r.getDomain();
2309 Index I = domain[0];
2310 Index J = domain[1];
2311 Index K = domain[2];
2312
2313 assign( r[I][J][K] ,
2314 outerProduct( x[I-1][J-1][K-1] , x.get_mesh().Dvc[0] ) +
2315 outerProduct( x[I ][J-1][K-1] , x.get_mesh().Dvc[1] ) +
2316 outerProduct( x[I-1][J ][K-1] , x.get_mesh().Dvc[2] ) +
2317 outerProduct( x[I ][J ][K-1] , x.get_mesh().Dvc[3] ) +
2318 outerProduct( x[I-1][J-1][K ] , x.get_mesh().Dvc[4] ) +
2319 outerProduct( x[I ][J-1][K ] , x.get_mesh().Dvc[5] ) +
2320 outerProduct( x[I-1][J ][K ] , x.get_mesh().Dvc[6] ) +
2321 outerProduct( x[I ][J ][K ] , x.get_mesh().Dvc[7] ));
2322 return r;
2323}
2324
2325namespace IPPL {
2326
2327//----------------------------------------------------------------------
2328// Weighted average Cell to Vert
2329//----------------------------------------------------------------------
2330template < class T1, class T2, class MFLOAT >
2335{
2336 const NDIndex<1U>& domain = r.getDomain();
2337 Index I = domain[0];
2338 assign( r[I] ,
2339 ( x[I-1] * w[I-1] + x[I ] * w[I ] )/
2340 ( w[I-1] + w[I ] ) );
2341 return r;
2342}
2343//----------------------------------------------------------------------
2344template < class T1, class T2, class MFLOAT >
2349{
2350 const NDIndex<2U>& domain = r.getDomain();
2351 Index I = domain[0];
2352 Index J = domain[1];
2353
2354 assign( r[I][J] ,
2355 ( x[I-1][J-1] * w[I-1][J-1] +
2356 x[I ][J-1] * w[I ][J-1] +
2357 x[I-1][J ] * w[I-1][J ] +
2358 x[I ][J ] * w[I ][J ] )/
2359 ( w[I-1][J-1] +
2360 w[I ][J-1] +
2361 w[I-1][J ] +
2362 w[I ][J ] ) );
2363 return r;
2364}
2365//----------------------------------------------------------------------
2366template < class T1, class T2, class MFLOAT >
2371{
2372 const NDIndex<3U>& domain = r.getDomain();
2373 Index I = domain[0];
2374 Index J = domain[1];
2375 Index K = domain[2];
2376
2377 assign( r[I][J][K] ,
2378 ( x[I-1][J-1][K-1] * w[I-1][J-1][K-1] +
2379 x[I ][J-1][K-1] * w[I ][J-1][K-1] +
2380 x[I-1][J ][K-1] * w[I-1][J ][K-1] +
2381 x[I ][J ][K-1] * w[I ][J ][K-1] +
2382 x[I-1][J-1][K ] * w[I-1][J-1][K ] +
2383 x[I ][J-1][K ] * w[I ][J-1][K ] +
2384 x[I-1][J ][K ] * w[I-1][J ][K ] +
2385 x[I ][J ][K ] * w[I ][J ][K ] )/
2386 ( w[I-1][J-1][K-1] +
2387 w[I ][J-1][K-1] +
2388 w[I-1][J ][K-1] +
2389 w[I ][J ][K-1] +
2390 w[I-1][J-1][K ] +
2391 w[I ][J-1][K ] +
2392 w[I-1][J ][K ] +
2393 w[I ][J ][K ] ) );
2394 return r;
2395}
2396//----------------------------------------------------------------------
2397// Weighted average Vert to Cell
2398// N.B.: won't work except for unit-stride (& zero-base?) Field's.
2399//----------------------------------------------------------------------
2400template < class T1, class T2, class MFLOAT >
2405{
2406 const NDIndex<1U>& domain = r.getDomain();
2407 Index I = domain[0];
2408 assign( r[I] ,
2409 ( x[I+1] * w[I+1] + x[I ] * w[I ] )/
2410 ( w[I+1] + w[I ] ) );
2411 return r;
2412}
2413//----------------------------------------------------------------------
2414template < class T1, class T2, class MFLOAT >
2419{
2420 const NDIndex<2U>& domain = r.getDomain();
2421 Index I = domain[0];
2422 Index J = domain[1];
2423
2424 assign( r[I][J] ,
2425 ( x[I+1][J+1] * w[I+1][J+1] +
2426 x[I ][J+1] * w[I ][J+1] +
2427 x[I+1][J ] * w[I+1][J ] +
2428 x[I ][J ] * w[I ][J ] )/
2429 ( w[I+1][J+1] +
2430 w[I ][J+1] +
2431 w[I+1][J ] +
2432 w[I ][J ] ) );
2433 return r;
2434}
2435//----------------------------------------------------------------------
2436template < class T1, class T2, class MFLOAT >
2441{
2442 const NDIndex<3U>& domain = r.getDomain();
2443 Index I = domain[0];
2444 Index J = domain[1];
2445 Index K = domain[2];
2446
2447 assign( r[I][J][K] ,
2448 ( x[I+1][J+1][K+1] * w[I+1][J+1][K+1] +
2449 x[I ][J+1][K+1] * w[I ][J+1][K+1] +
2450 x[I+1][J ][K+1] * w[I+1][J ][K+1] +
2451 x[I ][J ][K+1] * w[I ][J ][K+1] +
2452 x[I+1][J+1][K ] * w[I+1][J+1][K ] +
2453 x[I ][J+1][K ] * w[I ][J+1][K ] +
2454 x[I+1][J ][K ] * w[I+1][J ][K ] +
2455 x[I ][J ][K ] * w[I ][J ][K ] )/
2456 ( w[I+1][J+1][K+1] +
2457 w[I ][J+1][K+1] +
2458 w[I+1][J ][K+1] +
2459 w[I ][J ][K+1] +
2460 w[I+1][J+1][K ] +
2461 w[I ][J+1][K ] +
2462 w[I+1][J ][K ] +
2463 w[I ][J ][K ] ) );
2464 return r;
2465}
2466
2467//----------------------------------------------------------------------
2468// Unweighted average Cell to Vert
2469//----------------------------------------------------------------------
2470template < class T1, class MFLOAT >
2474{
2475 const NDIndex<1U>& domain = r.getDomain();
2476 Index I = domain[0];
2477 r[I] = 0.5*(x[I-1] + x[I ]);
2478 return r;
2479}
2480//----------------------------------------------------------------------
2481template < class T1, class MFLOAT >
2485{
2486 const NDIndex<2U>& domain = r.getDomain();
2487 Index I = domain[0];
2488 Index J = domain[1];
2489 r[I][J] = 0.25*(x[I-1][J-1] + x[I ][J-1] + x[I-1][J ] + x[I ][J ]);
2490 return r;
2491}
2492//----------------------------------------------------------------------
2493template < class T1, class MFLOAT >
2497{
2498 const NDIndex<3U>& domain = r.getDomain();
2499 Index I = domain[0];
2500 Index J = domain[1];
2501 Index K = domain[2];
2502 r[I][J][K] = 0.125*(x[I-1][J-1][K-1] + x[I ][J-1][K-1] + x[I-1][J ][K-1] +
2503 x[I ][J ][K-1] + x[I-1][J-1][K ] + x[I ][J-1][K ] +
2504 x[I-1][J ][K ] + x[I ][J ][K ]);
2505 return r;
2506}
2507//----------------------------------------------------------------------
2508// Unweighted average Vert to Cell
2509// N.B.: won't work except for unit-stride (& zero-base?) Field's.
2510//----------------------------------------------------------------------
2511template < class T1, class MFLOAT >
2514
2516{
2517 const NDIndex<1U>& domain = r.getDomain();
2518 Index I = domain[0];
2519 r[I] = 0.5*(x[I+1] + x[I ]);
2520 return r;
2521}
2522//----------------------------------------------------------------------
2523template < class T1, class MFLOAT >
2527{
2528 const NDIndex<2U>& domain = r.getDomain();
2529 Index I = domain[0];
2530 Index J = domain[1];
2531 r[I][J] = 0.25*(x[I+1][J+1] + x[I ][J+1] + x[I+1][J ] + x[I ][J ]);
2532 return r;
2533}
2534//----------------------------------------------------------------------
2535template < class T1, class MFLOAT >
2539{
2540 const NDIndex<3U>& domain = r.getDomain();
2541 Index I = domain[0];
2542 Index J = domain[1];
2543 Index K = domain[2];
2544 r[I][J][K] = 0.125*(x[I+1][J+1][K+1] + x[I ][J+1][K+1] + x[I+1][J ][K+1] +
2545 x[I ][J ][K+1] + x[I+1][J+1][K ] + x[I ][J+1][K ] +
2546 x[I+1][J ][K ] + x[I ][J ][K ]);
2547 return r;
2548}
2549
2550}
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
Definition: Vector3D.cpp:118
const unsigned Dim
e_dim_tag
Definition: FieldLayout.h:55
@ PARALLEL
Definition: FieldLayout.h:55
void assign(const BareField< T, Dim > &a, RHS b, OP op, ExprTag< true >)
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:84
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:76
NDIndex< Dim > AddGuardCells(const NDIndex< Dim > &idx, const GuardCellSizes< Dim > &g)
Field< Vektor< T, 3U >, 3U, UniformCartesian< 3U, MFLOAT >, Cell > & Grad1Ord(Field< T, 3U, UniformCartesian< 3U, MFLOAT >, Cell > &x, Field< Vektor< T, 3U >, 3U, UniformCartesian< 3U, MFLOAT >, Cell > &r)
Field< Vektor< T, 1U >, 1U, UniformCartesian< 1U, MFLOAT >, Cell > & Grad(Field< T, 1U, UniformCartesian< 1U, MFLOAT >, Vert > &x, Field< Vektor< T, 1U >, 1U, UniformCartesian< 1U, MFLOAT >, Cell > &r)
Field< T, 1U, UniformCartesian< 1U, MFLOAT >, Cell > & Div(Field< Vektor< T, 1U >, 1U, UniformCartesian< 1U, MFLOAT >, Vert > &x, Field< T, 1U, UniformCartesian< 1U, MFLOAT >, Cell > &r)
void PETE_apply(OpUMeshExtrapolate< T > e, T &a, T b)
std::complex< double > a
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
Tenzor< typename PETEBinaryReturn< T1, T2, OpMultipply >::type, D > outerProduct(const Vektor< T1, D > &v1, const Vektor< T2, D > &v2)
Definition: Tenzor.h:443
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
#define PAssert_LT(a, b)
Definition: PAssert.h:106
#define PInsist(c, m)
Definition: PAssert.h:120
#define ERRORMSG(msg)
Definition: IpplInfo.h:350
constexpr double e
The value of.
Definition: Physics.h:39
std::string::iterator iterator
Definition: MSLang.h:16
bool info
Info flag.
Definition: Options.cpp:28
Field< T1, 1U, Cartesian< 1U, MFLOAT >, Vert > & Average(Field< T1, 1U, Cartesian< 1U, MFLOAT >, Cell > &x, Field< T2, 1U, Cartesian< 1U, MFLOAT >, Cell > &w, Field< T1, 1U, Cartesian< 1U, MFLOAT >, Vert > &r)
Definition: Cartesian.hpp:3113
Definition: Offset.h:66
Definition: Tenzor.h:35
Definition: Vektor.h:32
Definition: Field.h:33
bool touches(const NDIndex< Dim > &) const
NDIndex< Dim > plugBase(const NDIndex< D > &i) const
Definition: NDIndex.h:114
NDIndex< Dim > intersect(const NDIndex< Dim > &) const
unsigned rightGuard(unsigned d) const
Definition: BareField.h:149
iterator_if begin_if()
Definition: BareField.h:100
ac_id_larray::iterator iterator_if
Definition: BareField.h:92
iterator_if end_if()
Definition: BareField.h:101
virtual void fillGuardCells(bool reallyFill=true) const
Definition: BareField.hpp:297
iterator begin() const
Definition: BareField.h:234
const GuardCellSizes< Dim > & getGuardCellSizes() const
Definition: BareField.h:147
unsigned leftGuard(unsigned d) const
Definition: BareField.h:148
Definition: LField.h:58
const NDIndex< Dim > & getOwned() const
Definition: LField.h:99
const NDIndex< Dim > & getAllocated() const
Definition: LField.h:98
const iterator & begin() const
Definition: LField.h:110
NDIndex< Dim > getVertexBelow(const Vektor< MFLOAT, Dim > &) const
void getSurfaceNormalFields(Field< Vektor< MFLOAT, Dim >, Dim, UniformCartesian< Dim, MFLOAT >, Cell > **) const
Field< Vektor< MFLOAT, Dim >, Dim, UniformCartesian< Dim, MFLOAT >, Vert > & getDeltaCellField(Field< Vektor< MFLOAT, Dim >, Dim, UniformCartesian< Dim, MFLOAT >, Vert > &) const
void set_origin(const Vektor< MFLOAT, Dim > &o)
Vektor< MFLOAT, Dim > * getSurfaceNormals(const NDIndex< Dim > &) const
Field< MFLOAT, Dim, UniformCartesian< Dim, MFLOAT >, Cell > & getCellVolumeField(Field< MFLOAT, Dim, UniformCartesian< Dim, MFLOAT >, Cell > &) const
Vektor< MFLOAT, Dim > getVertexPosition(const NDIndex< Dim > &) const
Field< Vektor< MFLOAT, Dim >, Dim, UniformCartesian< Dim, MFLOAT >, Cell > & getDeltaVertexField(Field< Vektor< MFLOAT, Dim >, Dim, UniformCartesian< Dim, MFLOAT >, Cell > &) const
MFLOAT get_meshSpacing(unsigned d) const
Field< Vektor< MFLOAT, Dim >, Dim, UniformCartesian< Dim, MFLOAT >, Cell > & getSurfaceNormalField(Field< Vektor< MFLOAT, Dim >, Dim, UniformCartesian< Dim, MFLOAT >, Cell > &, unsigned) const
MFLOAT get_volume() const
Vektor< MFLOAT, Dim > getDeltaVertex(const NDIndex< Dim > &) const
MFLOAT getCellVolume(const NDIndex< Dim > &) const
MFLOAT getCellRangeVolume(const NDIndex< Dim > &) const
Field< Vektor< MFLOAT, Dim >, Dim, UniformCartesian< Dim, MFLOAT >, Cell > & getCellPositionField(Field< Vektor< MFLOAT, Dim >, Dim, UniformCartesian< Dim, MFLOAT >, Cell > &) const
Field< Vektor< MFLOAT, Dim >, Dim, UniformCartesian< Dim, MFLOAT >, Vert > & getVertexPositionField(Field< Vektor< MFLOAT, Dim >, Dim, UniformCartesian< Dim, MFLOAT >, Vert > &) const
void set_meshSpacing(MFLOAT *const del)
NDIndex< Dim > getNearestVertex(const Vektor< MFLOAT, Dim > &) const
MFLOAT getVertRangeVolume(const NDIndex< Dim > &) const
Vektor< MFLOAT, Dim > getCellPosition(const NDIndex< Dim > &) const
void print(std::ostream &)
Vektor< MFLOAT, Dim > get_origin() const
Vektor< MFLOAT, Dim > getSurfaceNormal(const NDIndex< Dim > &, unsigned) const
void initialize(const NDIndex< Dim > &ndi)
Vektor< MFLOAT, Dim > getDeltaCell(const NDIndex< Dim > &) const
Definition: Index.h:237
int stride() const
Definition: IndexInlines.h:121
unsigned int length() const
Definition: IndexInlines.h:131
int first() const
Definition: IndexInlines.h:116
Definition: Centering.h:32
Definition: Centering.h:43
Definition: Centering.h:50
OpUMeshExtrapolate(T &o, T &s)
Definition: Inform.h:42