OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
Cartesian.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// Cartesian.cpp
27// Implementations for Cartesian mesh class (nonuniform spacings)
28
29// include files
30#include "Utility/PAssert.h"
32#include "Utility/IpplInfo.h"
33#include "Field/BareField.h"
35#include "Field/LField.h"
36#include "Field/Field.h"
37#include "Field/Assign.h"
38#include "Field/AssignDefs.h"
39
40//-----------------------------------------------------------------------------
41// Setup chores common to all constructors:
42//-----------------------------------------------------------------------------
43template <unsigned Dim, class MFLOAT>
44void
46setup()
47{
48 hasSpacingFields = false;
49}
50
51//-----------------------------------------------------------------------------
52// Constructors from NDIndex object:
53//-----------------------------------------------------------------------------
54template <unsigned Dim, class MFLOAT>
56Cartesian(const NDIndex<Dim>& ndi)
57{
58 unsigned int d,i;
59 for (d=0; d<Dim; d++)
60 gridSizes[d] = ndi[d].length(); // Number of vertices along this dimension.
61 setup(); // Setup chores, such as array allocations
62 for (d=0; d<Dim; d++) {
63 MeshBC[2*d] = Reflective; // Default mesh: reflective boundary conds
64 MeshBC[2*d+1] = Reflective; // Default mesh: reflective boundary conds
65 origin(d) = ndi[d].first(); // Default origin at ndi[d].first()
66 // default mesh spacing from stride()
67 for (i=0; i < gridSizes[d]-1; i++) {
68 (meshSpacing[d])[i] = ndi[d].stride();
69 (meshPosition[d])[i] = MFLOAT(i);
70 }
71 (meshPosition[d])[gridSizes[d]-1] = MFLOAT(gridSizes[d]-1);
72 }
73 set_Dvc(); // Set derivative coefficients from spacings.
74}
75// Also specify mesh spacings:
76template <unsigned Dim, class MFLOAT>
78Cartesian(const NDIndex<Dim>& ndi, MFLOAT** const delX)
79{
80 unsigned int d;
81 for (d=0; d<Dim; d++)
82 gridSizes[d] = ndi[d].length(); // Number of vertices along this dimension.
83 setup(); // Setup chores, such as array allocations
84 for (d=0; d<Dim; d++) {
85 MeshBC[2*d] = Reflective; // Default mesh: reflective boundary conds
86 MeshBC[2*d+1] = Reflective; // Default mesh: reflective boundary conds
87 origin(d) = ndi[d].first(); // Default origin at ndi[d].first()
88 }
89 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
90 set_Dvc(); // Set derivative coefficients from spacings.
91}
92// Also specify mesh spacings and origin:
93template <unsigned Dim, class MFLOAT>
95Cartesian(const NDIndex<Dim>& ndi, MFLOAT** const delX,
96 const Vektor<MFLOAT,Dim>& orig)
97{
98 int d;
99 for (d=0; d<Dim; d++)
100 gridSizes[d] = ndi[d].length(); // Number of vertices along this dimension.
101 setup(); // Setup chores, such as array allocations
102 for (d=0; d<Dim; d++) {
103 MeshBC[2*d] = Reflective; // Default mesh: reflective boundary conds
104 MeshBC[2*d+1] = Reflective; // Default mesh: reflective boundary conds
105 }
106 set_origin(orig); // Set origin.
107 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
108 set_Dvc(); // Set derivative coefficients from spacings.
109}
110// Also specify a MeshBC_E array for mesh boundary conditions:
111template <unsigned Dim, class MFLOAT>
113Cartesian(const NDIndex<Dim>& ndi, MFLOAT** const delX,
114 const Vektor<MFLOAT,Dim>& orig, MeshBC_E* const mbc)
115{
116 int d;
117 for (d=0; d<Dim; d++)
118 gridSizes[d] = ndi[d].length(); // Number of vertices along this dimension.
119 setup(); // Setup chores, such as array allocations
120 set_origin(orig); // Set origin.
121 set_MeshBC(mbc); // Set up mesh boundary conditions
122 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
123 set_Dvc(); // Set derivative coefficients from spacings.
124}
125//-----------------------------------------------------------------------------
126// Constructors from Index objects:
127//-----------------------------------------------------------------------------
128
129//===========1D============
130template <unsigned Dim, class MFLOAT>
132Cartesian(const Index& I)
133{
134 PInsist(Dim==1,"Number of Index arguments does not match mesh dimension!!");
135 gridSizes[0] = I.length(); // Number of vertices along this dimension.
136 setup(); // Setup chores, such as array allocations
137 origin(0) = I.first(); // Default origin at I.first()
138 unsigned int i;
139 // Default mesh spacing from stride()
140 for (i=0; i < gridSizes[0]-1; i++) {
141 (meshSpacing[0])[i] = I.stride();
142 (meshPosition[0])[i] = MFLOAT(i);
143 }
144 (meshPosition[0])[gridSizes[0]-1] = MFLOAT(gridSizes[0]-1);
145 for (unsigned int d=0; d<Dim; d++) {
146 MeshBC[2*d] = Reflective; // Default mesh: reflective boundary conds
147 MeshBC[2*d+1] = Reflective; // Default mesh: reflective boundary conds
148 }
149 set_Dvc(); // Set derivative coefficients from spacings.
150}
151// Also specify mesh spacings:
152template <unsigned Dim, class MFLOAT>
154Cartesian(const Index& I, MFLOAT** const delX)
155{
156 PInsist(Dim==1,"Number of Index arguments does not match mesh dimension!!");
157 gridSizes[0] = I.length(); // Number of vertices along this dimension.
158 setup(); // Setup chores, such as array allocations
159 origin(0) = I.first(); // Default origin at I.first()
160 for (unsigned int d=0; d<Dim; d++) {
161 MeshBC[2*d] = Reflective; // Default mesh: reflective boundary conds
162 MeshBC[2*d+1] = Reflective; // Default mesh: reflective boundary conds
163 }
164 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
165 set_Dvc(); // Set derivative coefficients from spacings.
166}
167// Also specify mesh spacings and origin:
168template <unsigned Dim, class MFLOAT>
170Cartesian(const Index& I, MFLOAT** const delX,
171 const Vektor<MFLOAT,Dim>& orig)
172{
173 PInsist(Dim==1,"Number of Index arguments does not match mesh dimension!!");
174 setup();
175 gridSizes[0] = I.length(); // Number of vertices along this dimension.
176 for (unsigned int d=0; d<Dim; d++) {
177 MeshBC[2*d] = Reflective; // Default mesh: reflective boundary conds
178 MeshBC[2*d+1] = Reflective; // Default mesh: reflective boundary conds
179 }
180 set_origin(orig); // Set origin.
181 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
182 set_Dvc(); // Set derivative coefficients from spacings.
183}
184// Also specify a MeshBC_E array for mesh boundary conditions:
185template <unsigned Dim, class MFLOAT>
187Cartesian(const Index& I, MFLOAT** const delX,
188 const Vektor<MFLOAT,Dim>& orig, MeshBC_E* const mbc)
189{
190 PInsist(Dim==1,"Number of Index arguments does not match mesh dimension!!");
191 setup();
192 gridSizes[0] = I.length(); // Number of vertices along this dimension.
193 set_origin(orig); // Set origin.
194 set_MeshBC(mbc); // Set up mesh boundary conditions
195 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
196 set_Dvc(); // Set derivative coefficients from spacings.
197}
198
199//===========2D============
200template <unsigned Dim, class MFLOAT>
202Cartesian(const Index& I, const Index& J)
203{
204 PInsist(Dim==2,"Number of Index arguments does not match mesh dimension!!");
205 gridSizes[0] = I.length(); // Number of vertices along this dimension.
206 gridSizes[1] = J.length(); // Number of vertices along this dimension.
207 setup(); // Setup chores, such as array allocations
208 origin(0) = I.first(); // Default origin at I.first(),J.first()
209 origin(1) = J.first();
210 unsigned int i;
211 // Default mesh spacing from stride()
212 for (i=0; i < gridSizes[0]-1; i++) {
213 (meshSpacing[0])[i] = I.stride();
214 (meshPosition[0])[i] = MFLOAT(i);
215 }
216 (meshPosition[0])[gridSizes[0]-1] = MFLOAT(gridSizes[0]-1);
217 for (i=0; i < gridSizes[1]-1; i++) {
218 (meshSpacing[1])[i] = J.stride();
219 (meshPosition[1])[i] = MFLOAT(i);
220 }
221 (meshPosition[1])[gridSizes[1]-1] = MFLOAT(gridSizes[1]-1);
222 for (unsigned int d=0; d<Dim; d++) {
223 MeshBC[2*d] = Reflective; // Default mesh: reflective boundary conds
224 MeshBC[2*d+1] = Reflective; // Default mesh: reflective boundary conds
225 }
226 set_Dvc(); // Set derivative coefficients from spacings.
227}
228// Also specify mesh spacings:
229template <unsigned Dim, class MFLOAT>
231Cartesian(const Index& I, const Index& J, MFLOAT** const delX)
232{
233 PInsist(Dim==2,"Number of Index arguments does not match mesh dimension!!");
234 gridSizes[0] = I.length(); // Number of vertices along this dimension.
235 gridSizes[1] = J.length(); // Number of vertices along this dimension.
236 setup(); // Setup chores, such as array allocations
237 origin(0) = I.first(); // Default origin at I.first(),J.first()
238 origin(1) = J.first();
239 for (unsigned int d=0; d<Dim; d++) {
240 MeshBC[2*d] = Reflective; // Default mesh: reflective boundary conds
241 MeshBC[2*d+1] = Reflective; // Default mesh: reflective boundary conds
242 }
243 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
244 set_Dvc(); // Set derivative coefficients from spacings.
245}
246// Also specify mesh spacings and origin:
247template <unsigned Dim, class MFLOAT>
249Cartesian(const Index& I, const Index& J, MFLOAT** const delX,
250 const Vektor<MFLOAT,Dim>& orig)
251{
252 PInsist(Dim==2,"Number of Index arguments does not match mesh dimension!!");
253 gridSizes[0] = I.length(); // Number of vertices along this dimension.
254 gridSizes[1] = J.length(); // Number of vertices along this dimension.
255 setup(); // Setup chores, such as array allocations
256 for (unsigned int d=0; d<Dim; d++) {
257 MeshBC[2*d] = Reflective; // Default mesh: reflective boundary conds
258 MeshBC[2*d+1] = Reflective; // Default mesh: reflective boundary conds
259 }
260 set_origin(orig); // Set origin.
261 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
262 set_Dvc(); // Set derivative coefficients from spacings.
263}
264// Also specify a MeshBC_E array for mesh boundary conditions:
265template <unsigned Dim, class MFLOAT>
267Cartesian(const Index& I, const Index& J, MFLOAT** const delX,
268 const Vektor<MFLOAT,Dim>& orig, MeshBC_E* const mbc)
269{
270 PInsist(Dim==2,"Number of Index arguments does not match mesh dimension!!");
271 gridSizes[0] = I.length(); // Number of vertices along this dimension.
272 gridSizes[1] = J.length(); // Number of vertices along this dimension.
273 setup(); // Setup chores, such as array allocations
274 set_origin(orig); // Set origin.
275 set_MeshBC(mbc); // Set up mesh boundary conditions
276 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
277 set_Dvc(); // Set derivative coefficients from spacings.
278}
279
280//===========3D============
281template <unsigned Dim, class MFLOAT>
283Cartesian(const Index& I, const Index& J, const Index& K)
284{
285 PInsist(Dim==3,"Number of Index arguments does not match mesh dimension!!");
286 gridSizes[0] = I.length(); // Number of vertices along this dimension.
287 gridSizes[1] = J.length(); // Number of vertices along this dimension.
288 gridSizes[2] = K.length(); // Number of vertices along this dimension.
289 // Setup chores, such as array allocations
290 setup();
291 origin(0) = I.first(); // Default origin at I.first(),J.first(),K.first()
292 origin(1) = J.first();
293 origin(2) = K.first();
294 unsigned int i;
295 // Default mesh spacing from stride()
296 for (i=0; i < gridSizes[0]-1; i++) {
297 (meshSpacing[0])[i] = I.stride();
298 (meshPosition[0])[i] = MFLOAT(i);
299 }
300 (meshPosition[0])[gridSizes[0]-1] = MFLOAT(gridSizes[0]-1);
301 for (i=0; i < gridSizes[1]-1; i++) {
302 (meshSpacing[1])[i] = J.stride();
303 (meshPosition[1])[i] = MFLOAT(i);
304 }
305 (meshPosition[1])[gridSizes[1]-1] = MFLOAT(gridSizes[1]-1);
306 for (i=0; i < gridSizes[2]-1; i++) {
307 (meshSpacing[2])[i] = K.stride();
308 (meshPosition[2])[i] = MFLOAT(i);
309 }
310 (meshPosition[2])[gridSizes[2]-1] = MFLOAT(gridSizes[2]-1);
311
312 for (unsigned int d=0; d<Dim; d++) {
313 MeshBC[2*d] = Reflective; // Default mesh: reflective boundary conds
314 MeshBC[2*d+1] = Reflective; // Default mesh: reflective boundary conds
315 }
316 set_Dvc(); // Set derivative coefficients from spacings.
317}
318// Also specify mesh spacings:
319template <unsigned Dim, class MFLOAT>
321Cartesian(const Index& I, const Index& J, const Index& K,
322 MFLOAT** const delX)
323{
324 PInsist(Dim==3,"Number of Index arguments does not match mesh dimension!!");
325 gridSizes[0] = I.length(); // Number of vertices along this dimension.
326 gridSizes[1] = J.length(); // Number of vertices along this dimension.
327 gridSizes[2] = K.length(); // Number of vertices along this dimension.
328 setup(); // Setup chores, such as array allocations
329 origin(0) = I.first(); // Default origin at I.first(),J.first(),K.first()
330 origin(1) = J.first();
331 origin(2) = K.first();
332 for (unsigned int d=0; d<Dim; d++) {
333 MeshBC[2*d] = Reflective; // Default mesh: reflective boundary conds
334 MeshBC[2*d+1] = Reflective; // Default mesh: reflective boundary conds
335 }
336 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
337 set_Dvc(); // Set derivative coefficients from spacings.
338}
339// Also specify mesh spacings and origin:
340template <unsigned Dim, class MFLOAT>
342Cartesian(const Index& I, const Index& J, const Index& K,
343 MFLOAT** const delX, const Vektor<MFLOAT,Dim>& orig)
344{
345 PInsist(Dim==3,"Number of Index arguments does not match mesh dimension!!");
346 gridSizes[0] = I.length(); // Number of vertices along this dimension.
347 gridSizes[1] = J.length(); // Number of vertices along this dimension.
348 gridSizes[2] = K.length(); // Number of vertices along this dimension.
349 setup(); // Setup chores, such as array allocations
350 for (unsigned int d=0; d<Dim; d++) {
351 MeshBC[2*d] = Reflective; // Default mesh: reflective boundary conds
352 MeshBC[2*d+1] = Reflective; // Default mesh: reflective boundary conds
353 }
354 set_origin(orig); // Set origin.
355 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
356 set_Dvc(); // Set derivative coefficients from spacings.
357}
358// Also specify a MeshBC_E array for mesh boundary conditions:
359template <unsigned Dim, class MFLOAT>
361Cartesian(const Index& I, const Index& J, const Index& K,
362 MFLOAT** const delX, const Vektor<MFLOAT,Dim>& orig,
363 MeshBC_E* const mbc)
364{
365 PInsist(Dim==3,"Number of Index arguments does not match mesh dimension!!");
366 gridSizes[0] = I.length(); // Number of vertices along this dimension.
367 gridSizes[1] = J.length(); // Number of vertices along this dimension.
368 gridSizes[2] = K.length(); // Number of vertices along this dimension.
369 setup(); // Setup chores, such as array allocations
370 set_origin(orig); // Set origin.
371 set_MeshBC(mbc); // Set up mesh boundary conditions
372 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
373 set_Dvc(); // Set derivative coefficients from spacings.
374}
375
376//-----------------------------------------------------------------------------
377// initialize using NDIndex object:
378//-----------------------------------------------------------------------------
379template <unsigned Dim, class MFLOAT>
380void
382initialize(const NDIndex<Dim>& ndi)
383{
384 unsigned int d,i;
385 for (d=0; d<Dim; d++)
386 gridSizes[d] = ndi[d].length(); // Number of vertices along this dimension.
387 setup(); // Setup chores, such as array allocations
388 for (d=0; d<Dim; d++) {
389 MeshBC[2*d] = Reflective; // Default mesh: reflective boundary conds
390 MeshBC[2*d+1] = Reflective; // Default mesh: reflective boundary conds
391 origin(d) = ndi[d].first(); // Default origin at ndi[d].first()
392 // default mesh spacing from stride()
393 for (i=0; i < gridSizes[d]-1; i++) {
394 (meshSpacing[d])[i] = ndi[d].stride();
395 (meshPosition[d])[i] = MFLOAT(i);
396 }
397 (meshPosition[d])[gridSizes[d]-1] = MFLOAT(gridSizes[d]-1);
398 }
399 set_Dvc(); // Set derivative coefficients from spacings.
400}
401// Also specify mesh spacings:
402template <unsigned Dim, class MFLOAT>
403void
405initialize(const NDIndex<Dim>& ndi, MFLOAT** const delX)
406{
407 unsigned int d;
408 for (d=0; d<Dim; d++)
409 gridSizes[d] = ndi[d].length(); // Number of vertices along this dimension.
410 setup(); // Setup chores, such as array allocations
411 for (d=0; d<Dim; d++) {
412 MeshBC[2*d] = Reflective; // Default mesh: reflective boundary conds
413 MeshBC[2*d+1] = Reflective; // Default mesh: reflective boundary conds
414 origin(d) = ndi[d].first(); // Default origin at ndi[d].first()
415 }
416 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
417 set_Dvc(); // Set derivative coefficients from spacings.
418}
419// Also specify mesh spacings and origin:
420template <unsigned Dim, class MFLOAT>
421void
423initialize(const NDIndex<Dim>& ndi, MFLOAT** const delX,
424 const Vektor<MFLOAT,Dim>& orig)
425{
426 int d;
427 for (d=0; d<Dim; d++)
428 gridSizes[d] = ndi[d].length(); // Number of vertices along this dimension.
429 setup(); // Setup chores, such as array allocations
430 for (d=0; d<Dim; d++) {
431 MeshBC[2*d] = Reflective; // Default mesh: reflective boundary conds
432 MeshBC[2*d+1] = Reflective; // Default mesh: reflective boundary conds
433 }
434 set_origin(orig); // Set origin.
435 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
436 set_Dvc(); // Set derivative coefficients from spacings.
437}
438// Also specify a MeshBC_E array for mesh boundary conditions:
439template <unsigned Dim, class MFLOAT>
440void
442initialize(const NDIndex<Dim>& ndi, MFLOAT** const delX,
443 const Vektor<MFLOAT,Dim>& orig, MeshBC_E* const mbc)
444{
445 int d;
446 for (d=0; d<Dim; d++)
447 gridSizes[d] = ndi[d].length(); // Number of vertices along this dimension.
448 setup(); // Setup chores, such as array allocations
449 set_origin(orig); // Set origin.
450 set_MeshBC(mbc); // Set up mesh boundary conditions
451 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
452 set_Dvc(); // Set derivative coefficients from spacings.
453}
454//-----------------------------------------------------------------------------
455// initialize using Index objects:
456//-----------------------------------------------------------------------------
457
458//===========1D============
459template <unsigned Dim, class MFLOAT>
460void
462initialize(const Index& I)
463{
464 PInsist(Dim==1,"Number of Index arguments does not match mesh dimension!!");
465 gridSizes[0] = I.length(); // Number of vertices along this dimension.
466 setup(); // Setup chores, such as array allocations
467 origin(0) = I.first(); // Default origin at I.first()
468 unsigned int i;
469 // Default mesh spacing from stride()
470 for (i=0; i < gridSizes[0]-1; i++) {
471 (meshSpacing[0])[i] = I.stride();
472 (meshPosition[0])[i] = MFLOAT(i);
473 }
474 (meshPosition[0])[gridSizes[0]-1] = MFLOAT(gridSizes[0]-1);
475 for (unsigned int d=0; d<Dim; d++) {
476 MeshBC[2*d] = Reflective; // Default mesh: reflective boundary conds
477 MeshBC[2*d+1] = Reflective; // Default mesh: reflective boundary conds
478 }
479 set_Dvc(); // Set derivative coefficients from spacings.
480}
481// Also specify mesh spacings:
482template <unsigned Dim, class MFLOAT>
483void
485initialize(const Index& I, MFLOAT** const delX)
486{
487 PInsist(Dim==1,"Number of Index arguments does not match mesh dimension!!");
488 gridSizes[0] = I.length(); // Number of vertices along this dimension.
489 setup(); // Setup chores, such as array allocations
490 origin(0) = I.first(); // Default origin at I.first()
491 for (unsigned int d=0; d<Dim; d++) {
492 MeshBC[2*d] = Reflective; // Default mesh: reflective boundary conds
493 MeshBC[2*d+1] = Reflective; // Default mesh: reflective boundary conds
494 }
495 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
496 set_Dvc(); // Set derivative coefficients from spacings.
497}
498// Also specify mesh spacings and origin:
499template <unsigned Dim, class MFLOAT>
500void
502initialize(const Index& I, MFLOAT** const delX,
503 const Vektor<MFLOAT,Dim>& orig)
504{
505 PInsist(Dim==1,"Number of Index arguments does not match mesh dimension!!");
506 setup();
507 gridSizes[0] = I.length(); // Number of vertices along this dimension.
508 for (unsigned int d=0; d<Dim; d++) {
509 MeshBC[2*d] = Reflective; // Default mesh: reflective boundary conds
510 MeshBC[2*d+1] = Reflective; // Default mesh: reflective boundary conds
511 }
512 set_origin(orig); // Set origin.
513 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
514 set_Dvc(); // Set derivative coefficients from spacings.
515}
516// Also specify a MeshBC_E array for mesh boundary conditions:
517template <unsigned Dim, class MFLOAT>
518void
520initialize(const Index& I, MFLOAT** const delX,
521 const Vektor<MFLOAT,Dim>& orig, MeshBC_E* const mbc)
522{
523 PInsist(Dim==1,"Number of Index arguments does not match mesh dimension!!");
524 setup();
525 gridSizes[0] = I.length(); // Number of vertices along this dimension.
526 set_origin(orig); // Set origin.
527 set_MeshBC(mbc); // Set up mesh boundary conditions
528 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
529 set_Dvc(); // Set derivative coefficients from spacings.
530}
531
532//===========2D============
533template <unsigned Dim, class MFLOAT>
534void
536initialize(const Index& I, const Index& J)
537{
538 PInsist(Dim==2,"Number of Index arguments does not match mesh dimension!!");
539 gridSizes[0] = I.length(); // Number of vertices along this dimension.
540 gridSizes[1] = J.length(); // Number of vertices along this dimension.
541 setup(); // Setup chores, such as array allocations
542 origin(0) = I.first(); // Default origin at I.first(),J.first()
543 origin(1) = J.first();
544 unsigned int i;
545 // Default mesh spacing from stride()
546 for (i=0; i < gridSizes[0]-1; i++) {
547 (meshSpacing[0])[i] = I.stride();
548 (meshPosition[0])[i] = MFLOAT(i);
549 }
550 (meshPosition[0])[gridSizes[0]-1] = MFLOAT(gridSizes[0]-1);
551 for (i=0; i < gridSizes[1]-1; i++) {
552 (meshSpacing[1])[i] = J.stride();
553 (meshPosition[1])[i] = MFLOAT(i);
554 }
555 (meshPosition[1])[gridSizes[1]-1] = MFLOAT(gridSizes[1]-1);
556 for (unsigned int d=0; d<Dim; d++) {
557 MeshBC[2*d] = Reflective; // Default mesh: reflective boundary conds
558 MeshBC[2*d+1] = Reflective; // Default mesh: reflective boundary conds
559 }
560 set_Dvc(); // Set derivative coefficients from spacings.
561}
562// Also specify mesh spacings:
563template <unsigned Dim, class MFLOAT>
564void
566initialize(const Index& I, const Index& J, MFLOAT** const delX)
567{
568 PInsist(Dim==2,"Number of Index arguments does not match mesh dimension!!");
569 gridSizes[0] = I.length(); // Number of vertices along this dimension.
570 gridSizes[1] = J.length(); // Number of vertices along this dimension.
571 setup(); // Setup chores, such as array allocations
572 origin(0) = I.first(); // Default origin at I.first(),J.first()
573 origin(1) = J.first();
574 for (unsigned int d=0; d<Dim; d++) {
575 MeshBC[2*d] = Reflective; // Default mesh: reflective boundary conds
576 MeshBC[2*d+1] = Reflective; // Default mesh: reflective boundary conds
577 }
578 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
579 set_Dvc(); // Set derivative coefficients from spacings.
580}
581// Also specify mesh spacings and origin:
582template <unsigned Dim, class MFLOAT>
583void
585initialize(const Index& I, const Index& J, MFLOAT** const delX,
586 const Vektor<MFLOAT,Dim>& orig)
587{
588 PInsist(Dim==2,"Number of Index arguments does not match mesh dimension!!");
589 gridSizes[0] = I.length(); // Number of vertices along this dimension.
590 gridSizes[1] = J.length(); // Number of vertices along this dimension.
591 setup(); // Setup chores, such as array allocations
592 for (unsigned int d=0; d<Dim; d++) {
593 MeshBC[2*d] = Reflective; // Default mesh: reflective boundary conds
594 MeshBC[2*d+1] = Reflective; // Default mesh: reflective boundary conds
595 }
596 set_origin(orig); // Set origin.
597 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
598 set_Dvc(); // Set derivative coefficients from spacings.
599}
600// Also specify a MeshBC_E array for mesh boundary conditions:
601template <unsigned Dim, class MFLOAT>
602void
604initialize(const Index& I, const Index& J, MFLOAT** const delX,
605 const Vektor<MFLOAT,Dim>& orig, MeshBC_E* const mbc)
606{
607 PInsist(Dim==2,"Number of Index arguments does not match mesh dimension!!");
608 gridSizes[0] = I.length(); // Number of vertices along this dimension.
609 gridSizes[1] = J.length(); // Number of vertices along this dimension.
610 setup(); // Setup chores, such as array allocations
611 set_origin(orig); // Set origin.
612 set_MeshBC(mbc); // Set up mesh boundary conditions
613 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
614 set_Dvc(); // Set derivative coefficients from spacings.
615}
616
617//===========3D============
618template <unsigned Dim, class MFLOAT>
619void
621initialize(const Index& I, const Index& J, const Index& K)
622{
623 PInsist(Dim==3,"Number of Index arguments does not match mesh dimension!!");
624 gridSizes[0] = I.length(); // Number of vertices along this dimension.
625 gridSizes[1] = J.length(); // Number of vertices along this dimension.
626 gridSizes[2] = K.length(); // Number of vertices along this dimension.
627 // Setup chores, such as array allocations
628 setup();
629 origin(0) = I.first(); // Default origin at I.first(),J.first(),K.first()
630 origin(1) = J.first();
631 origin(2) = K.first();
632 int i;
633 // Default mesh spacing from stride()
634 for (i=0; i < gridSizes[0]-1; i++) {
635 (meshSpacing[0])[i] = I.stride();
636 (meshPosition[0])[i] = MFLOAT(i);
637 }
638 (meshPosition[0])[gridSizes[0]-1] = MFLOAT(gridSizes[0]-1);
639 for (i=0; i < gridSizes[1]-1; i++) {
640 (meshSpacing[1])[i] = J.stride();
641 (meshPosition[1])[i] = MFLOAT(i);
642 }
643 (meshPosition[1])[gridSizes[1]-1] = MFLOAT(gridSizes[1]-1);
644 for (i=0; i < gridSizes[2]-1; i++) {
645 (meshSpacing[2])[i] = K.stride();
646 (meshPosition[2])[i] = MFLOAT(i);
647 }
648 (meshPosition[2])[gridSizes[2]-1] = MFLOAT(gridSizes[2]-1);
649
650 for (unsigned int d=0; d<Dim; d++) {
651 MeshBC[2*d] = Reflective; // Default mesh: reflective boundary conds
652 MeshBC[2*d+1] = Reflective; // Default mesh: reflective boundary conds
653 }
654 set_Dvc(); // Set derivative coefficients from spacings.
655}
656// Also specify mesh spacings:
657template <unsigned Dim, class MFLOAT>
658void
660initialize(const Index& I, const Index& J, const Index& K,
661 MFLOAT** const delX)
662{
663 PInsist(Dim==3,"Number of Index arguments does not match mesh dimension!!");
664 gridSizes[0] = I.length(); // Number of vertices along this dimension.
665 gridSizes[1] = J.length(); // Number of vertices along this dimension.
666 gridSizes[2] = K.length(); // Number of vertices along this dimension.
667 setup(); // Setup chores, such as array allocations
668 origin(0) = I.first(); // Default origin at I.first(),J.first(),K.first()
669 origin(1) = J.first();
670 origin(2) = K.first();
671 for (unsigned int d=0; d<Dim; d++) {
672 MeshBC[2*d] = Reflective; // Default mesh: reflective boundary conds
673 MeshBC[2*d+1] = Reflective; // Default mesh: reflective boundary conds
674 }
675 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
676 set_Dvc(); // Set derivative coefficients from spacings.
677}
678// Also specify mesh spacings and origin:
679template <unsigned Dim, class MFLOAT>
680void
682initialize(const Index& I, const Index& J, const Index& K,
683 MFLOAT** const delX, const Vektor<MFLOAT,Dim>& orig)
684{
685 PInsist(Dim==3,"Number of Index arguments does not match mesh dimension!!");
686 gridSizes[0] = I.length(); // Number of vertices along this dimension.
687 gridSizes[1] = J.length(); // Number of vertices along this dimension.
688 gridSizes[2] = K.length(); // Number of vertices along this dimension.
689 setup(); // Setup chores, such as array allocations
690 for (unsigned int d=0; d<Dim; d++) {
691 MeshBC[2*d] = Reflective; // Default mesh: reflective boundary conds
692 MeshBC[2*d+1] = Reflective; // Default mesh: reflective boundary conds
693 }
694 set_origin(orig); // Set origin.
695 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
696 set_Dvc(); // Set derivative coefficients from spacings.
697}
698// Also specify a MeshBC_E array for mesh boundary conditions:
699template <unsigned Dim, class MFLOAT>
700void
702initialize(const Index& I, const Index& J, const Index& K,
703 MFLOAT** const delX, const Vektor<MFLOAT,Dim>& orig,
704 MeshBC_E* const mbc)
705{
706 PInsist(Dim==3,"Number of Index arguments does not match mesh dimension!!");
707 gridSizes[0] = I.length(); // Number of vertices along this dimension.
708 gridSizes[1] = J.length(); // Number of vertices along this dimension.
709 gridSizes[2] = K.length(); // Number of vertices along this dimension.
710 setup(); // Setup chores, such as array allocations
711 set_origin(orig); // Set origin.
712 set_MeshBC(mbc); // Set up mesh boundary conditions
713 set_meshSpacing(delX); // Set mesh spacings and compute cell volume
714 set_Dvc(); // Set derivative coefficients from spacings.
715}
716
717//-----------------------------------------------------------------------------
718// Set/accessor functions for member data:
719//-----------------------------------------------------------------------------
720// Set the origin of mesh vertex positions:
721template<unsigned Dim, class MFLOAT>
724{
725 origin = o;
726 for (unsigned d=0; d<Dim; ++d) {
727 (meshPosition[d])[0] = o(d);
728 for (unsigned vert=1; vert<gridSizes[d]; ++vert) {
729 (meshPosition[d])[vert] = (meshPosition[d])[vert-1] +
730 (meshSpacing[d])[vert-1];
731 }
732 }
733 // Apply the current state of the mesh BC to add guards to meshPosition map:
734 for (unsigned face=0; face < 2*Dim; ++face) updateMeshSpacingGuards(face);
735 this->notifyOfChange();
736}
737// Get the origin of mesh vertex positions:
738template<unsigned Dim, class MFLOAT>
740get_origin() const
741{
742 return origin;
743}
744
745// Set the spacings of mesh vertex positions:
746template<unsigned Dim, class MFLOAT>
748set_meshSpacing(MFLOAT** const del)
749{
750 unsigned d, cell, face;
751
752 for (d=0;d<Dim;++d) {
753 (meshPosition[d])[0] = origin(d);
754 for (cell=0; cell < gridSizes[d]-1; cell++) {
755 (meshSpacing[d])[cell] = del[d][cell];
756 (meshPosition[d])[cell+1] = (meshPosition[d])[cell] + del[d][cell];
757 }
758 }
759 // Apply the current state of the mesh BC to add guards to meshSpacings map:
760 for (face=0; face < 2*Dim; ++face) updateMeshSpacingGuards(face);
761 // if spacing fields allocated, we must update values
762 if (hasSpacingFields) storeSpacingFields();
763 this->notifyOfChange();
764}
765
766// Set only the derivative constants, using pre-set spacings:
767template<unsigned Dim, class MFLOAT>
769set_Dvc()
770{
771 unsigned d;
772 MFLOAT coef = 1.0;
773 for (d=1;d<Dim;++d) coef *= 0.5;
774
775 for (d=0;d<Dim;++d) {
776 MFLOAT dvc = coef;
777 for (unsigned b=0; b<(1<<Dim); ++b) {
778 int s = ( b&(1<<d) ) ? 1 : -1;
779 Dvc[b](d) = s*dvc;
780 }
781 }
782}
783
784// Get the spacings of mesh vertex positions along specified direction:
785template<unsigned Dim, class MFLOAT>
787get_meshSpacing(unsigned d, MFLOAT* spacings) const
788{
789 PAssert_LT(d, Dim);
790 for (unsigned int cell=0; cell < gridSizes[d]-1; cell++)
791 spacings[cell] = (*(meshSpacing[d].find(cell))).second;
792 return;
793}
794//leak template<unsigned Dim, class MFLOAT>
795//leak MFLOAT* Cartesian<Dim,MFLOAT>::
796//leak get_meshSpacing(unsigned d) const
797//leak {
798//leak PAssert_LT(d, Dim);
799//leak MFLOAT* theMeshSpacing = new MFLOAT[gridSizes[d]-1];
800//leak for (int cell=0; cell < gridSizes[d]-1; cell++)
801//leak theMeshSpacing[cell] = (*(meshSpacing[d].find(cell))).second;
802//leak return theMeshSpacing;
803//leak }
804
806
807// Applicative templates for Mesh BC PETE_apply() functions, used
808// by BrickExpression in storeSpacingFields()
809
810// Periodic:
811template<class T>
813{
814};
815template<class T>
816inline void PETE_apply(OpMeshPeriodic<T> /*e*/, T& a, T b) { a = b; }
817
818// Reflective/None:
819template<class T>
821{
822 OpMeshExtrapolate(T& o, T& s) : Offset(o), Slope(s) {}
824};
825// template<class T>
826// inline void apply(OpMeshExtrapolate<T> e, T& a, T b)
827template<class T>
829{
830 a = b*e.Slope+e.Offset;
831}
832
834
835// Create BareField's of vertex and cell spacings
836// Special prototypes taking no args or FieldLayout ctor args:
837// No-arg case:
838template<unsigned Dim, class MFLOAT>
841{
842 // Set up default FieldLayout parameters:
843 e_dim_tag et[Dim];
844 for (unsigned int d=0; d<Dim; d++) et[d] = PARALLEL;
845 storeSpacingFields(et, -1);
846}
847// 1D
848template<unsigned Dim, class MFLOAT>
850storeSpacingFields(e_dim_tag p1, int vnodes)
851{
852 e_dim_tag et[1];
853 et[0] = p1;
854 storeSpacingFields(et, vnodes);
855}
856// 2D
857template<unsigned Dim, class MFLOAT>
859storeSpacingFields(e_dim_tag p1, e_dim_tag p2, int vnodes)
860{
861 e_dim_tag et[2];
862 et[0] = p1;
863 et[1] = p2;
864 storeSpacingFields(et, vnodes);
865}
866// 3D
867template<unsigned Dim, class MFLOAT>
869storeSpacingFields(e_dim_tag p1, e_dim_tag p2, e_dim_tag p3, int vnodes)
870{
871 e_dim_tag et[3];
872 et[0] = p1;
873 et[1] = p2;
874 et[2] = p3;
875 storeSpacingFields(et, vnodes);
876}
877
878
879// The general storeSpacingfields() function; others invoke this internally:
880template<unsigned Dim, class MFLOAT>
882storeSpacingFields(e_dim_tag* et, int vnodes)
883{
884 unsigned int d;
885 int currentLocation[Dim];
886 NDIndex<Dim> cells, verts;
887 for (d=0; d<Dim; d++) {
888 cells[d] = Index(gridSizes[d]-1);
889 verts[d] = Index(gridSizes[d]);
890 }
891 if (!hasSpacingFields) {
892 // allocate layouts and spacing fields
893 FlCell = new FieldLayout<Dim>(cells, et, vnodes);
894 // Note: enough guard cells only for existing Div(), etc. implementations:
895 VertSpacings =
897 FlVert = new FieldLayout<Dim>(verts, et, vnodes);
898 // Note: enough guard cells only for existing Div(), etc. implementations:
899 CellSpacings =
901 }
902 // VERTEX-VERTEX SPACINGS:
903 BareField<Vektor<MFLOAT,Dim>,Dim>& vertSpacings = *VertSpacings;
904 Vektor<MFLOAT,Dim> vertexSpacing;
905 vertSpacings.Uncompress(); // Must do this prior to assign via iterator
907 cfi_end = vertSpacings.end();
908 for (cfi = vertSpacings.begin(); cfi != cfi_end; ++cfi) {
909 cfi.GetCurrentLocation(currentLocation);
910 for (d=0; d<Dim; d++)
911 vertexSpacing(d) = (*(meshSpacing[d].find(currentLocation[d]))).second;
912 *cfi = vertexSpacing;
913 }
914 // CELL-CELL SPACINGS:
915 BareField<Vektor<MFLOAT,Dim>,Dim>& cellSpacings = *CellSpacings;
916 Vektor<MFLOAT,Dim> cellSpacing;
917 cellSpacings.Uncompress(); // Must do this prior to assign via iterator
919 vfi_end = cellSpacings.end();
920 for (vfi = cellSpacings.begin(); vfi != vfi_end; ++vfi) {
921 vfi.GetCurrentLocation(currentLocation);
922 for (d=0; d<Dim; d++)
923 cellSpacing(d) = 0.5 * ((meshSpacing[d])[currentLocation[d]] +
924 (meshSpacing[d])[currentLocation[d]-1]);
925 *vfi = cellSpacing;
926 }
927 //-------------------------------------------------
928 // Now the hard part, filling in the guard cells:
929 //-------------------------------------------------
930 // The easy part of the hard part is filling so that all the internal
931 // guard layers are right:
932 cellSpacings.fillGuardCells();
933 vertSpacings.fillGuardCells();
934 // The hard part of the hard part is filling the external guard layers,
935 // using the mesh BC to figure out how:
936 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
937 // Temporaries used in loop over faces
938 Vektor<MFLOAT,Dim> v0,v1; v0 = 0.0; v1 = 1.0; // Used for Reflective mesh BC
939 typedef Vektor<MFLOAT,Dim> T; // Used multipple places in loop below
940 typename BareField<T,Dim>::iterator_if cfill_i; // Iterator used below
941 typename BareField<T,Dim>::iterator_if vfill_i; // Iterator used below
942 int coffset, voffset; // Pointer offsets used with LField::iterator below
943 MeshBC_E bct; // Scalar value of mesh BC used for each face in loop
944 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
945 for (unsigned int face=0; face < 2*Dim; face++) {
946 // NDIndex's spanning elements and guard elements:
947 NDIndex<Dim> cSlab = AddGuardCells(verts,cellSpacings.getGuardCellSizes());
948 NDIndex<Dim> vSlab = AddGuardCells(cells,vertSpacings.getGuardCellSizes());
949 // Shrink it down to be the guards along the active face:
950 d = face/2;
951 // The following bitwise AND logical test returns true if face is odd
952 // (meaning the "high" or "right" face in the numbering convention) and
953 // returns false if face is even (meaning the "low" or "left" face in
954 // the numbering convention):
955 if ( face & 1 ) {
956 cSlab[d] = Index(verts[d].max() + 1,
957 verts[d].max() + cellSpacings.rightGuard(d));
958 vSlab[d] = Index(cells[d].max() + 1,
959 cells[d].max() + vertSpacings.rightGuard(d));
960 } else {
961 cSlab[d] = Index(verts[d].min() - cellSpacings.leftGuard(d),
962 verts[d].min() - 1);
963 vSlab[d] = Index(cells[d].min() - vertSpacings.leftGuard(d),
964 cells[d].min() - 1);
965 }
966 // Compute pointer offsets used with LField::iterator below:
967 switch (MeshBC[face]) {
968 case Periodic:
969 bct = Periodic;
970 if ( face & 1 ) {
971 coffset = -verts[d].length();
972 voffset = -cells[d].length();
973 } else {
974 coffset = verts[d].length();
975 voffset = cells[d].length();
976 }
977 break;
978 case Reflective:
979 bct = Reflective;
980 if ( face & 1 ) {
981 coffset = 2*verts[d].max() + 1;
982 voffset = 2*cells[d].max() + 1 - 1;
983 } else {
984 coffset = 2*verts[d].min() - 1;
985 voffset = 2*cells[d].min() - 1 + 1;
986 }
987 break;
988 case NoBC:
989 bct = NoBC;
990 if ( face & 1 ) {
991 coffset = 2*verts[d].max() + 1;
992 voffset = 2*cells[d].max() + 1 - 1;
993 } else {
994 coffset = 2*verts[d].min() - 1;
995 voffset = 2*cells[d].min() - 1 + 1;
996 }
997 break;
998 default:
999 throw IpplException("Cartesian::storeSpacingFields", "unknown MeshBC type");
1000 }
1001
1002 // Loop over all the LField's in the BareField's:
1003 // +++++++++++++++cellSpacings++++++++++++++
1004 for (cfill_i=cellSpacings.begin_if();
1005 cfill_i!=cellSpacings.end_if(); ++cfill_i)
1006 {
1007 // Cache some things we will use often below.
1008 // Pointer to the data for the current LField (right????):
1009 LField<T,Dim> &fill = *(*cfill_i).second;
1010 // NDIndex spanning all elements in the LField, including the guards:
1011 const NDIndex<Dim> &fill_alloc = fill.getAllocated();
1012 // If the previously-created boundary guard-layer NDIndex "cSlab"
1013 // contains any of the elements in this LField (they will be guard
1014 // elements if it does), assign the values into them here by applying
1015 // the boundary condition:
1016 if ( cSlab.touches( fill_alloc ) )
1017 {
1018 // Find what it touches in this LField.
1019 NDIndex<Dim> dest = cSlab.intersect( fill_alloc );
1020
1021 // For exrapolation boundary conditions, the boundary guard-layer
1022 // elements are typically copied from interior values; the "src"
1023 // NDIndex specifies the interior elements to be copied into the
1024 // "dest" boundary guard-layer elements (possibly after some
1025 // mathematical operations like multipplying by minus 1 later):
1026 NDIndex<Dim> src = dest; // Create dest equal to src
1027 // Now calculate the interior elements; the coffset variable
1028 // computed above makes this right for "low" or "high" face cases:
1029 src[d] = coffset - src[d];
1030
1031 // TJW: Why is there another loop over LField's here??????????
1032 // Loop over the ones that src touches.
1033 typename BareField<T,Dim>::iterator_if from_i;
1034 for (from_i=cellSpacings.begin_if();
1035 from_i!=cellSpacings.end_if(); ++from_i)
1036 {
1037 // Cache a few things.
1038 LField<T,Dim> &from = *(*from_i).second;
1039 const NDIndex<Dim> &from_owned = from.getOwned();
1040 const NDIndex<Dim> &from_alloc = from.getAllocated();
1041 // If src touches this LField...
1042 if ( src.touches( from_owned ) )
1043 {
1044 NDIndex<Dim> from_it = src.intersect( from_alloc );
1045 NDIndex<Dim> cfill_it = dest.plugBase( from_it );
1046 // Build iterators for the copy...
1047 typedef typename LField<T,Dim>::iterator LFI;
1048 LFI lhs = fill.begin(cfill_it);
1049 LFI rhs = from.begin(from_it);
1050 // And do the assignment.
1051 if (bct == Periodic) {
1053 (lhs,rhs,OpMeshPeriodic<T>()).apply();
1054 } else {
1055 if (bct == Reflective) {
1057 (lhs,rhs,OpMeshExtrapolate<T>(v0,v1)).apply();
1058 } else {
1059 if (bct == NoBC) {
1061 (lhs,rhs,OpMeshExtrapolate<T>(v0,v0)).apply();
1062 }
1063 }
1064 }
1065 }
1066 }
1067 }
1068 }
1069 // +++++++++++++++vertSpacings++++++++++++++
1070 for (vfill_i=vertSpacings.begin_if();
1071 vfill_i!=vertSpacings.end_if(); ++vfill_i)
1072 {
1073 // Cache some things we will use often below.
1074 // Pointer to the data for the current LField (right????):
1075 LField<T,Dim> &fill = *(*vfill_i).second;
1076 // NDIndex spanning all elements in the LField, including the guards:
1077 const NDIndex<Dim> &fill_alloc = fill.getAllocated();
1078 // If the previously-created boundary guard-layer NDIndex "cSlab"
1079 // contains any of the elements in this LField (they will be guard
1080 // elements if it does), assign the values into them here by applying
1081 // the boundary condition:
1082 if ( vSlab.touches( fill_alloc ) )
1083 {
1084 // Find what it touches in this LField.
1085 NDIndex<Dim> dest = vSlab.intersect( fill_alloc );
1086
1087 // For exrapolation boundary conditions, the boundary guard-layer
1088 // elements are typically copied from interior values; the "src"
1089 // NDIndex specifies the interior elements to be copied into the
1090 // "dest" boundary guard-layer elements (possibly after some
1091 // mathematical operations like multipplying by minus 1 later):
1092 NDIndex<Dim> src = dest; // Create dest equal to src
1093 // Now calculate the interior elements; the voffset variable
1094 // computed above makes this right for "low" or "high" face cases:
1095 src[d] = voffset - src[d];
1096
1097 // TJW: Why is there another loop over LField's here??????????
1098 // Loop over the ones that src touches.
1099 typename BareField<T,Dim>::iterator_if from_i;
1100 for (from_i=vertSpacings.begin_if();
1101 from_i!=vertSpacings.end_if(); ++from_i)
1102 {
1103 // Cache a few things.
1104 LField<T,Dim> &from = *(*from_i).second;
1105 const NDIndex<Dim> &from_owned = from.getOwned();
1106 const NDIndex<Dim> &from_alloc = from.getAllocated();
1107 // If src touches this LField...
1108 if ( src.touches( from_owned ) )
1109 {
1110 NDIndex<Dim> from_it = src.intersect( from_alloc );
1111 NDIndex<Dim> vfill_it = dest.plugBase( from_it );
1112 // Build iterators for the copy...
1113 typedef typename LField<T,Dim>::iterator LFI;
1114 LFI lhs = fill.begin(vfill_it);
1115 LFI rhs = from.begin(from_it);
1116 // And do the assignment.
1117 if (bct == Periodic) {
1119 (lhs,rhs,OpMeshPeriodic<T>()).apply();
1120 } else {
1121 if (bct == Reflective) {
1123 (lhs,rhs,OpMeshExtrapolate<T>(v0,v1)).apply();
1124 } else {
1125 if (bct == NoBC) {
1127 (lhs,rhs,OpMeshExtrapolate<T>(v0,v0)).apply();
1128 }
1129 }
1130 }
1131 }
1132 }
1133 }
1134 }
1135
1136 }
1137
1138 hasSpacingFields = true; // Flag this as having been done to this object.
1139}
1140
1141
1142// These specify both the total number of vnodes and the numbers of vnodes
1143// along each dimension for the partitioning of the index space. Obviously
1144// this restricts the number of vnodes to be a product of the numbers along
1145// each dimension (the constructor implementation checks this): Special
1146// cases for 1-3 dimensions, ala FieldLayout ctors (see FieldLayout.h for
1147// more relevant comments, including definition of recurse):
1148
1149// 1D
1150template<unsigned Dim, class MFLOAT>
1153 unsigned vnodes1,
1154 bool recurse,
1155 int vnodes) {
1156 e_dim_tag et[1];
1157 et[0] = p1;
1158 unsigned vnodesPerDirection[Dim];
1159 vnodesPerDirection[0] = vnodes1;
1160 storeSpacingFields(et, vnodesPerDirection, recurse, vnodes);
1161}
1162// 2D
1163template<unsigned Dim, class MFLOAT>
1166 unsigned vnodes1, unsigned vnodes2,
1167 bool recurse,int vnodes) {
1168 e_dim_tag et[2];
1169 et[0] = p1;
1170 et[1] = p2;
1171 unsigned vnodesPerDirection[Dim];
1172 vnodesPerDirection[0] = vnodes1;
1173 vnodesPerDirection[1] = vnodes2;
1174 storeSpacingFields(et, vnodesPerDirection, recurse, vnodes);
1175}
1176// 3D
1177template<unsigned Dim, class MFLOAT>
1180 unsigned vnodes1, unsigned vnodes2, unsigned vnodes3,
1181 bool recurse, int vnodes) {
1182 e_dim_tag et[3];
1183 et[0] = p1;
1184 et[1] = p2;
1185 et[2] = p3;
1186 unsigned vnodesPerDirection[Dim];
1187 vnodesPerDirection[0] = vnodes1;
1188 vnodesPerDirection[1] = vnodes2;
1189 vnodesPerDirection[2] = vnodes3;
1190 storeSpacingFields(et, vnodesPerDirection, recurse, vnodes);
1191}
1192
1193// TJW: Note: should clean up here eventually, and put redundant code from
1194// this and the other general storeSpacingFields() implementation into one
1195// function. Need to check this in quickly for Blanca right now --12/8/98
1196// The general storeSpacingfields() function; others invoke this internally:
1197template<unsigned Dim, class MFLOAT>
1200 unsigned* vnodesPerDirection,
1201 bool recurse, int vnodes) {
1202 unsigned int d;
1203 int currentLocation[Dim];
1204 NDIndex<Dim> cells, verts;
1205 for (d=0; d<Dim; d++) {
1206 cells[d] = Index(gridSizes[d]-1);
1207 verts[d] = Index(gridSizes[d]);
1208 }
1209 if (!hasSpacingFields) {
1210 // allocate layouts and spacing fields
1211 FlCell =
1212 new FieldLayout<Dim>(cells, p, vnodesPerDirection, recurse, vnodes);
1213 // Note: enough guard cells only for existing Div(), etc. implementations:
1214 VertSpacings =
1216 FlVert =
1217 new FieldLayout<Dim>(verts, p, vnodesPerDirection, recurse, vnodes);
1218 // Note: enough guard cells only for existing Div(), etc. implementations:
1219 CellSpacings =
1221 }
1222 // VERTEX-VERTEX SPACINGS:
1223 BareField<Vektor<MFLOAT,Dim>,Dim>& vertSpacings = *VertSpacings;
1224 Vektor<MFLOAT,Dim> vertexSpacing;
1225 vertSpacings.Uncompress(); // Must do this prior to assign via iterator
1227 cfi_end = vertSpacings.end();
1228 for (cfi = vertSpacings.begin(); cfi != cfi_end; ++cfi) {
1229 cfi.GetCurrentLocation(currentLocation);
1230 for (d=0; d<Dim; d++)
1231 vertexSpacing(d) = (*(meshSpacing[d].find(currentLocation[d]))).second;
1232 *cfi = vertexSpacing;
1233 }
1234 // CELL-CELL SPACINGS:
1235 BareField<Vektor<MFLOAT,Dim>,Dim>& cellSpacings = *CellSpacings;
1236 Vektor<MFLOAT,Dim> cellSpacing;
1237 cellSpacings.Uncompress(); // Must do this prior to assign via iterator
1239 vfi_end = cellSpacings.end();
1240 for (vfi = cellSpacings.begin(); vfi != vfi_end; ++vfi) {
1241 vfi.GetCurrentLocation(currentLocation);
1242 for (d=0; d<Dim; d++)
1243 cellSpacing(d) = 0.5 * ((meshSpacing[d])[currentLocation[d]] +
1244 (meshSpacing[d])[currentLocation[d]-1]);
1245 *vfi = cellSpacing;
1246 }
1247 //-------------------------------------------------
1248 // Now the hard part, filling in the guard cells:
1249 //-------------------------------------------------
1250 // The easy part of the hard part is filling so that all the internal
1251 // guard layers are right:
1252 cellSpacings.fillGuardCells();
1253 vertSpacings.fillGuardCells();
1254 // The hard part of the hard part is filling the external guard layers,
1255 // using the mesh BC to figure out how:
1256 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1257 // Temporaries used in loop over faces
1258 Vektor<MFLOAT,Dim> v0,v1; v0 = 0.0; v1 = 1.0; // Used for Reflective mesh BC
1259 unsigned int face;
1260 typedef Vektor<MFLOAT,Dim> T; // Used multipple places in loop below
1261 typename BareField<T,Dim>::iterator_if cfill_i; // Iterator used below
1262 typename BareField<T,Dim>::iterator_if vfill_i; // Iterator used below
1263 int coffset, voffset; // Pointer offsets used with LField::iterator below
1264 MeshBC_E bct; // Scalar value of mesh BC used for each face in loop
1265 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1266 for (face=0; face < 2*Dim; face++) {
1267 // NDIndex's spanning elements and guard elements:
1268 NDIndex<Dim> cSlab = AddGuardCells(verts,cellSpacings.getGuardCellSizes());
1269 NDIndex<Dim> vSlab = AddGuardCells(cells,vertSpacings.getGuardCellSizes());
1270 // Shrink it down to be the guards along the active face:
1271 d = face/2;
1272 // The following bitwise AND logical test returns true if face is odd
1273 // (meaning the "high" or "right" face in the numbering convention) and
1274 // returns false if face is even (meaning the "low" or "left" face in
1275 // the numbering convention):
1276 if ( face & 1 ) {
1277 cSlab[d] = Index(verts[d].max() + 1,
1278 verts[d].max() + cellSpacings.rightGuard(d));
1279 vSlab[d] = Index(cells[d].max() + 1,
1280 cells[d].max() + vertSpacings.rightGuard(d));
1281 } else {
1282 cSlab[d] = Index(verts[d].min() - cellSpacings.leftGuard(d),
1283 verts[d].min() - 1);
1284 vSlab[d] = Index(cells[d].min() - vertSpacings.leftGuard(d),
1285 cells[d].min() - 1);
1286 }
1287 // Compute pointer offsets used with LField::iterator below:
1288 switch (MeshBC[face]) {
1289 case Periodic:
1290 bct = Periodic;
1291 if ( face & 1 ) {
1292 coffset = -verts[d].length();
1293 voffset = -cells[d].length();
1294 } else {
1295 coffset = verts[d].length();
1296 voffset = cells[d].length();
1297 }
1298 break;
1299 case Reflective:
1300 bct = Reflective;
1301 if ( face & 1 ) {
1302 coffset = 2*verts[d].max() + 1;
1303 voffset = 2*cells[d].max() + 1 - 1;
1304 } else {
1305 coffset = 2*verts[d].min() - 1;
1306 voffset = 2*cells[d].min() - 1 + 1;
1307 }
1308 break;
1309 case NoBC:
1310 bct = NoBC;
1311 if ( face & 1 ) {
1312 coffset = 2*verts[d].max() + 1;
1313 voffset = 2*cells[d].max() + 1 - 1;
1314 } else {
1315 coffset = 2*verts[d].min() - 1;
1316 voffset = 2*cells[d].min() - 1 + 1;
1317 }
1318 break;
1319 default:
1320 ERRORMSG("Cartesian::storeSpacingFields(): unknown MeshBC type" << endl);
1321 break;
1322 }
1323
1324 // Loop over all the LField's in the BareField's:
1325 // +++++++++++++++cellSpacings++++++++++++++
1326 for (cfill_i=cellSpacings.begin_if();
1327 cfill_i!=cellSpacings.end_if(); ++cfill_i)
1328 {
1329 // Cache some things we will use often below.
1330 // Pointer to the data for the current LField (right????):
1331 LField<T,Dim> &fill = *(*cfill_i).second;
1332 // NDIndex spanning all elements in the LField, including the guards:
1333 const NDIndex<Dim> &fill_alloc = fill.getAllocated();
1334 // If the previously-created boundary guard-layer NDIndex "cSlab"
1335 // contains any of the elements in this LField (they will be guard
1336 // elements if it does), assign the values into them here by applying
1337 // the boundary condition:
1338 if ( cSlab.touches( fill_alloc ) )
1339 {
1340 // Find what it touches in this LField.
1341 NDIndex<Dim> dest = cSlab.intersect( fill_alloc );
1342
1343 // For exrapolation boundary conditions, the boundary guard-layer
1344 // elements are typically copied from interior values; the "src"
1345 // NDIndex specifies the interior elements to be copied into the
1346 // "dest" boundary guard-layer elements (possibly after some
1347 // mathematical operations like multipplying by minus 1 later):
1348 NDIndex<Dim> src = dest; // Create dest equal to src
1349 // Now calculate the interior elements; the coffset variable
1350 // computed above makes this right for "low" or "high" face cases:
1351 src[d] = coffset - src[d];
1352
1353 // TJW: Why is there another loop over LField's here??????????
1354 // Loop over the ones that src touches.
1355 typename BareField<T,Dim>::iterator_if from_i;
1356 for (from_i=cellSpacings.begin_if();
1357 from_i!=cellSpacings.end_if(); ++from_i)
1358 {
1359 // Cache a few things.
1360 LField<T,Dim> &from = *(*from_i).second;
1361 const NDIndex<Dim> &from_owned = from.getOwned();
1362 const NDIndex<Dim> &from_alloc = from.getAllocated();
1363 // If src touches this LField...
1364 if ( src.touches( from_owned ) )
1365 {
1366 NDIndex<Dim> from_it = src.intersect( from_alloc );
1367 NDIndex<Dim> cfill_it = dest.plugBase( from_it );
1368 // Build iterators for the copy...
1369 typedef typename LField<T,Dim>::iterator LFI;
1370 LFI lhs = fill.begin(cfill_it);
1371 LFI rhs = from.begin(from_it);
1372 // And do the assignment.
1373 if (bct == Periodic) {
1375 (lhs,rhs,OpMeshPeriodic<T>()).apply();
1376 } else {
1377 if (bct == Reflective) {
1379 (lhs,rhs,OpMeshExtrapolate<T>(v0,v1)).apply();
1380 } else {
1381 if (bct == NoBC) {
1383 (lhs,rhs,OpMeshExtrapolate<T>(v0,v0)).apply();
1384 }
1385 }
1386 }
1387 }
1388 }
1389 }
1390 }
1391 // +++++++++++++++vertSpacings++++++++++++++
1392 for (vfill_i=vertSpacings.begin_if();
1393 vfill_i!=vertSpacings.end_if(); ++vfill_i)
1394 {
1395 // Cache some things we will use often below.
1396 // Pointer to the data for the current LField (right????):
1397 LField<T,Dim> &fill = *(*vfill_i).second;
1398 // NDIndex spanning all elements in the LField, including the guards:
1399 const NDIndex<Dim> &fill_alloc = fill.getAllocated();
1400 // If the previously-created boundary guard-layer NDIndex "cSlab"
1401 // contains any of the elements in this LField (they will be guard
1402 // elements if it does), assign the values into them here by applying
1403 // the boundary condition:
1404 if ( vSlab.touches( fill_alloc ) )
1405 {
1406 // Find what it touches in this LField.
1407 NDIndex<Dim> dest = vSlab.intersect( fill_alloc );
1408
1409 // For exrapolation boundary conditions, the boundary guard-layer
1410 // elements are typically copied from interior values; the "src"
1411 // NDIndex specifies the interior elements to be copied into the
1412 // "dest" boundary guard-layer elements (possibly after some
1413 // mathematical operations like multipplying by minus 1 later):
1414 NDIndex<Dim> src = dest; // Create dest equal to src
1415 // Now calculate the interior elements; the voffset variable
1416 // computed above makes this right for "low" or "high" face cases:
1417 src[d] = voffset - src[d];
1418
1419 // TJW: Why is there another loop over LField's here??????????
1420 // Loop over the ones that src touches.
1421 typename BareField<T,Dim>::iterator_if from_i;
1422 for (from_i=vertSpacings.begin_if();
1423 from_i!=vertSpacings.end_if(); ++from_i)
1424 {
1425 // Cache a few things.
1426 LField<T,Dim> &from = *(*from_i).second;
1427 const NDIndex<Dim> &from_owned = from.getOwned();
1428 const NDIndex<Dim> &from_alloc = from.getAllocated();
1429 // If src touches this LField...
1430 if ( src.touches( from_owned ) )
1431 {
1432 NDIndex<Dim> from_it = src.intersect( from_alloc );
1433 NDIndex<Dim> vfill_it = dest.plugBase( from_it );
1434 // Build iterators for the copy...
1435 typedef typename LField<T,Dim>::iterator LFI;
1436 LFI lhs = fill.begin(vfill_it);
1437 LFI rhs = from.begin(from_it);
1438 // And do the assignment.
1439 if (bct == Periodic) {
1441 (lhs,rhs,OpMeshPeriodic<T>()).apply();
1442 } else {
1443 if (bct == Reflective) {
1445 (lhs,rhs,OpMeshExtrapolate<T>(v0,v1)).apply();
1446 } else {
1447 if (bct == NoBC) {
1449 (lhs,rhs,OpMeshExtrapolate<T>(v0,v0)).apply();
1450 }
1451 }
1452 }
1453 }
1454 }
1455 }
1456 }
1457
1458 }
1459
1460 hasSpacingFields = true; // Flag this as having been done to this object.
1461}
1462
1463
1464//-----------------------------------------------------------------------------
1465// I/O:
1466//-----------------------------------------------------------------------------
1467// Formatted output of Cartesian object:
1468template< unsigned Dim, class MFLOAT >
1469void
1471print(std::ostream& out)
1472{
1473 unsigned int d;
1474 out << "======Cartesian<" << Dim << ",MFLOAT>==begin======" << std::endl;
1475 for (d=0; d < Dim; d++)
1476 out << "gridSizes[" << d << "] = " << gridSizes[d] << std::endl;
1477 out << "origin = " << origin << std::endl;
1478 for (d=0; d < Dim; d++) {
1479 out << "--------meshSpacing[" << d << "]---------" << std::endl;
1481 for (mi=meshSpacing[d].begin(); mi != meshSpacing[d].end(); ++mi) {
1482 out << "meshSpacing[" << d << "][" << (*mi).first << "] = "
1483 << (*mi).second << std::endl;
1484 }
1485 }
1486 for (unsigned b=0; b < (1<<Dim); b++)
1487 out << "Dvc[" << b << "] = " << Dvc[b] << std::endl;
1488 for (d=0; d < Dim; d++)
1489 out << "MeshBC[" << 2*d << "] = " << Mesh<Dim>::MeshBC_E_Names[MeshBC[2*d]]
1490 << " ; MeshBC[" << 2*d+1 << "] = " << Mesh<Dim>::MeshBC_E_Names[MeshBC[2*d+1]]
1491 << std::endl;
1492 out << "======Cartesian<" << Dim << ",MFLOAT>==end========" << std::endl;
1493}
1494
1495//--------------------------------------------------------------------------
1496// Various (Cartesian) mesh mechanisms:
1497//--------------------------------------------------------------------------
1498
1499// Volume of cell indexed by NDIndex:
1500template <unsigned Dim, class MFLOAT>
1501MFLOAT
1503getCellVolume(const NDIndex<Dim>& ndi) const
1504{
1505 MFLOAT volume = 1.0;
1506 for (unsigned int d=0; d<Dim; d++)
1507 if (ndi[d].length() != 1) {
1508 ERRORMSG("Cartesian::getCellVolume() error: arg is not a NDIndex"
1509 << "specifying a single element" << endl);
1510 }
1511 else {
1512 volume *= (*(meshSpacing[d].find(ndi[d].first()))).second;
1513 }
1514 return volume;
1515}
1516// Field of volumes of all cells:
1517template <unsigned Dim, class MFLOAT>
1521{
1522 // N.B.: here, other places taking Field& (in UniformCartesian, too), should
1523 // have check on domain of input Field& to make sure it's big enough to hold
1524 // all the values for this mesh object.
1525 volumes = 1.0;
1526 int currentLocation[Dim];
1527 volumes.Uncompress();
1528 // Iterate through all cells:
1530 fi_end=volumes.end();
1531 for (fi = volumes.begin(); fi != fi_end; ++fi) {
1532 fi.GetCurrentLocation(currentLocation);
1533 for (unsigned int d=0; d<Dim; d++)
1534 *fi *= (*(meshSpacing[d].find(currentLocation[d]))).second;
1535 }
1536 return volumes;
1537}
1538// Volume of range of cells bounded by verticies specified by input NDIndex;
1539template <unsigned Dim, class MFLOAT>
1540MFLOAT
1542getVertRangeVolume(const NDIndex<Dim>& ndi) const
1543{
1544 // Get vertex positions of extremal cells:
1545 Vektor<MFLOAT,Dim> v0, v1;
1546 unsigned int d;
1547 int i0, i1;
1548 for (d=0; d<Dim; d++) {
1549 i0 = ndi[d].first();
1550 if ( (i0 < -(int(gridSizes[d])-1)/2) ||
1551 (i0 > 3*(int(gridSizes[d])-1)/2) )
1552 ERRORMSG("Cartesian::getVertRangeVolume() error: " << ndi
1553 << " is an NDIndex ranging outside the mesh and guard layers;"
1554 << " not allowed." << endl);
1555 v0(d) = (*(meshPosition[d].find(i0))).second;
1556 i1 = ndi[d].last();
1557 if ( (i1 < -(int(gridSizes[d])-1)/2) ||
1558 (i1 > 3*(int(gridSizes[d])-1)/2) )
1559 ERRORMSG("Cartesian::getVertRangeVolume() error: " << ndi
1560 << " is an NDIndex ranging outside the mesh and guard layers;"
1561 << " not allowed." << endl);
1562 v1(d) = (*(meshPosition[d].find(i1))).second;
1563 }
1564 // Compute volume of rectangular solid beweeen these extremal vertices:
1565 MFLOAT volume = 1.0;
1566 for (d=0; d<Dim; d++) volume *= std::abs(v1(d) - v0(d));
1567 return volume;
1568}
1569// Volume of range of cells spanned by input NDIndex (index of cells):
1570template <unsigned Dim, class MFLOAT>
1571MFLOAT
1573getCellRangeVolume(const NDIndex<Dim>& ndi) const
1574{
1575 // Get vertex positions bounding extremal cells:
1576 Vektor<MFLOAT,Dim> v0, v1;
1577 int i0, i1;
1578 for (unsigned int d=0; d<Dim; d++) {
1579 i0 = ndi[d].first();
1580 if ( (i0 < -(int(gridSizes[d])-1)/2) ||
1581 (i0 > 3*(int(gridSizes[d])-1)/2) )
1582 ERRORMSG("Cartesian::getCellRangeVolume() error: " << ndi
1583 << " is an NDIndex ranging outside the mesh and guard layers;"
1584 << " not allowed." << endl);
1585 v0(d) = (*(meshPosition[d].find(i0))).second;
1586 i1 = ndi[d].last()+1;
1587 if ( (i1 < -(int(gridSizes[d])-1)/2) ||
1588 (i1 > 3*(int(gridSizes[d])-1)/2) )
1589 ERRORMSG("Cartesian::getCellRangeVolume() error: " << ndi
1590 << " is an NDIndex ranging outside the mesh and guard layers;"
1591 << " not allowed." << endl);
1592 v1(d) = (*(meshPosition[d].find(i1))).second;
1593 }
1594 // Compute volume of rectangular solid beweeen these extremal vertices:
1595 MFLOAT volume = 1.0;
1596 for (unsigned int d=0; d<Dim; d++) volume *= std::abs(v1(d) - v0(d));
1597 return volume;
1598}
1599
1600// Nearest vertex index to (x,y,z):
1601template <unsigned Dim, class MFLOAT>
1605{
1606 unsigned int d;
1607 Vektor<MFLOAT,Dim> boxMin, boxMax;
1608 for (d=0; d<Dim; d++) {
1609 int gs = (int(gridSizes[d])-1)/2;
1610 boxMin(d) = (*(meshPosition[d].find(-gs))).second;
1611 boxMax(d) = (*(meshPosition[d].find(3*gs))).second;
1612 }
1613 for (d=0; d<Dim; d++)
1614 if ( (x(d) < boxMin(d)) || (x(d) > boxMax(d)) )
1615 ERRORMSG("Cartesian::getNearestVertex() - input point is outside"
1616 << " mesh boundary and guard layers; not allowed." << endl);
1617
1618 // Find coordinate vectors of the vertices just above and just below the
1619 // input point (extremal vertices on cell containing point);
1620 MFLOAT xVertexBelow, xVertexAbove, xVertex;
1621 int vertBelow, vertAbove, vertNearest[Dim];
1622 for (d=0; d<Dim; d++) {
1623 vertBelow = -(int(gridSizes[d])-1)/2;
1624 vertAbove = 3*(int(gridSizes[d])-1)/2;
1625 xVertexBelow = (*(meshPosition[d].find(vertBelow))).second;
1626 xVertexAbove = (*(meshPosition[d].find(vertAbove))).second;
1627 // check for out of bounds
1628 if (x(d) < xVertexBelow) {
1629 vertNearest[d] = vertBelow;
1630 continue;
1631 }
1632 if (x(d) > xVertexAbove) {
1633 vertNearest[d] = vertAbove;
1634 continue;
1635 }
1636 while (vertAbove > vertBelow+1) {
1637 vertNearest[d] = (vertAbove+vertBelow)/2;
1638 xVertex = (*(meshPosition[d].find(vertNearest[d]))).second;
1639 if (x(d) > xVertex) {
1640 vertBelow = vertNearest[d];
1641 xVertexBelow = xVertex;
1642 }
1643 else if (x(d) < xVertex) {
1644 vertAbove = vertNearest[d];
1645 xVertexAbove = xVertex;
1646 }
1647 else { // found exact match!
1648 vertAbove = vertBelow;
1649 }
1650 }
1651 if (vertAbove != vertBelow) {
1652 if ((x(d)-xVertexBelow)<(xVertexAbove-x(d))) {
1653 vertNearest[d] = vertBelow;
1654 }
1655 else {
1656 vertNearest[d] = vertAbove;
1657 }
1658 }
1659 }
1660
1661 // Construct the NDIndex for nearest vert get its position vector:
1662 NDIndex<Dim> ndi;
1663 for (d=0; d<Dim; d++) ndi[d] = Index(vertNearest[d],vertNearest[d],1);
1664
1665 return ndi;
1666}
1667// Nearest vertex index with all vertex coordinates below (x,y,z):
1668template <unsigned Dim, class MFLOAT>
1671getVertexBelow(const Vektor<MFLOAT,Dim>& x) const
1672{
1673 unsigned int d;
1674 Vektor<MFLOAT,Dim> boxMin, boxMax;
1675 for (d=0; d<Dim; d++) {
1676 int gs = (int(gridSizes[d]) - 1)/2;
1677 boxMin(d) = (*(meshPosition[d].find(-gs))).second;
1678 boxMax(d) = (*(meshPosition[d].find(3*gs))).second;
1679 }
1680 for (d=0; d<Dim; d++)
1681 if ( (x(d) < boxMin(d)) || (x(d) > boxMax(d)) )
1682 ERRORMSG("Cartesian::getVertexBelow() - input point is outside"
1683 << " mesh boundary and guard layers; not allowed." << endl);
1684
1685 // Find coordinate vectors of the vertices just below the input point;
1686 MFLOAT xVertexBelow, xVertexAbove, xVertex;
1687 int vertBelow, vertAbove, vertNearest[Dim];
1688 for (d=0; d<Dim; d++) {
1689 vertBelow = -(int(gridSizes[d])-1)/2;
1690 vertAbove = 3*(int(gridSizes[d])-1)/2;
1691 xVertexBelow = (*(meshPosition[d].find(vertBelow))).second;
1692 xVertexAbove = (*(meshPosition[d].find(vertAbove))).second;
1693 // check for out of bounds
1694 if (x(d) < xVertexBelow) {
1695 vertNearest[d] = vertBelow;
1696 continue;
1697 }
1698 if (x(d) > xVertexAbove) {
1699 vertNearest[d] = vertAbove;
1700 continue;
1701 }
1702 while (vertAbove > vertBelow+1) {
1703 vertNearest[d] = (vertAbove+vertBelow)/2;
1704 xVertex = (*(meshPosition[d].find(vertNearest[d]))).second;
1705 if (x(d) > xVertex) {
1706 vertBelow = vertNearest[d];
1707 xVertexBelow = xVertex;
1708 }
1709 else if (x(d) < xVertex) {
1710 vertAbove = vertNearest[d];
1711 xVertexAbove = xVertex;
1712 }
1713 else { // found exact match!
1714 vertAbove = vertBelow;
1715 }
1716 }
1717 if (vertAbove != vertBelow) {
1718 vertNearest[d] = vertBelow;
1719 }
1720 }
1721
1722 // Construct the NDIndex for nearest vert get its position vector:
1723 NDIndex<Dim> ndi;
1724 for (d=0; d<Dim; d++) ndi[d] = Index(vertNearest[d],vertNearest[d],1);
1725
1726 return ndi;
1727}
1728// (x,y,z) coordinates of indexed vertex:
1729template <unsigned Dim, class MFLOAT>
1732getVertexPosition(const NDIndex<Dim>& ndi) const
1733{
1734 unsigned int d;
1735 int i;
1736 Vektor<MFLOAT,Dim> vertexPosition;
1737 for (d=0; d<Dim; d++) {
1738 if (ndi[d].length() != 1)
1739 ERRORMSG("Cartesian::getVertexPosition() error: " << ndi
1740 << " is not an NDIndex specifying a single element" << endl);
1741 i = ndi[d].first();
1742 if ( (i < -(int(gridSizes[d])-1)/2) ||
1743 (i > 3*(int(gridSizes[d])-1)/2) )
1744 ERRORMSG("Cartesian::getVertexPosition() error: " << ndi
1745 << " is an NDIndex outside the mesh and guard layers;"
1746 << " not allowed." << endl);
1747 vertexPosition(d) = (*(meshPosition[d].find(i))).second;
1748 }
1749 return vertexPosition;
1750}
1751// Field of (x,y,z) coordinates of all vertices:
1752template <unsigned Dim, class MFLOAT>
1756 Cartesian<Dim,MFLOAT>,Vert>& vertexPositions) const
1757{
1758 int currentLocation[Dim];
1759 Vektor<MFLOAT,Dim> vertexPosition;
1760 vertexPositions.Uncompress();
1762 fi_end = vertexPositions.end();
1763 for (fi = vertexPositions.begin(); fi != fi_end; ++fi) {
1764 // Construct a NDIndex for each field element:
1765 fi.GetCurrentLocation(currentLocation);
1766 for (unsigned int d=0; d<Dim; d++) {
1767 vertexPosition(d) = (*(meshPosition[d].find(currentLocation[d]))).second;
1768 }
1769 *fi = vertexPosition;
1770 }
1771 return vertexPositions;
1772}
1773
1774// (x,y,z) coordinates of indexed cell:
1775template <unsigned Dim, class MFLOAT>
1778getCellPosition(const NDIndex<Dim>& ndi) const
1779{
1780 unsigned int d;
1781 int i;
1782 Vektor<MFLOAT,Dim> cellPosition;
1783 for (d=0; d<Dim; d++) {
1784 if (ndi[d].length() != 1)
1785 ERRORMSG("Cartesian::getCellPosition() error: " << ndi
1786 << " is not an NDIndex specifying a single element" << endl);
1787 i = ndi[d].first();
1788 if ( (i < -(int(gridSizes[d])-1)/2) ||
1789 (i >= 3*(int(gridSizes[d])-1)/2) )
1790 ERRORMSG("Cartesian::getCellPosition() error: " << ndi
1791 << " is an NDIndex outside the mesh and guard layers;"
1792 << " not allowed." << endl);
1793 cellPosition(d) = 0.5 * ( (*(meshPosition[d].find(i))).second +
1794 (*(meshPosition[d].find(i+1))).second );
1795 }
1796 return cellPosition;
1797}
1798// Field of (x,y,z) coordinates of all cells:
1799template <unsigned Dim, class MFLOAT>
1803 Cartesian<Dim,MFLOAT>,Cell>& cellPositions) const
1804{
1805 int currentLocation[Dim];
1806 Vektor<MFLOAT,Dim> cellPosition;
1807 cellPositions.Uncompress();
1809 fi_end = cellPositions.end();
1810 for (fi = cellPositions.begin(); fi != fi_end; ++fi) {
1811 // Construct a NDIndex for each field element:
1812 fi.GetCurrentLocation(currentLocation);
1813 for (unsigned int d=0; d<Dim; d++) {
1814 cellPosition(d) =
1815 0.5 * ( (*(meshPosition[d].find(currentLocation[d]))).second +
1816 (*(meshPosition[d].find(currentLocation[d]+1))).second );
1817 }
1818 *fi = cellPosition;
1819 }
1820 return cellPositions;
1821}
1822
1823// Vertex-vertex grid spacing of indexed cell:
1824template <unsigned Dim, class MFLOAT>
1827getDeltaVertex(const NDIndex<Dim>& ndi) const
1828{
1829 // return value
1830 Vektor<MFLOAT,Dim> vertexVertexSpacing(0);
1831
1832 for (unsigned int d=0; d<Dim; d++) {
1833 // endpoints of the index range ... make sure they are in ascending order
1834 int a = ndi[d].first();
1835 int b = ndi[d].last();
1836 if (b < a) {
1837 int tmpa = a; a = b; b = tmpa;
1838 }
1839
1840 // make sure we have valid endpoints
1841 if (a < -((int(gridSizes[d])-1)/2) || b >= 3*(int(gridSizes[d])-1)/2) {
1842 ERRORMSG("Cartesian::getDeltaVertex() error: " << ndi
1843 << " is an NDIndex ranging outside"
1844 << " the mesh and guard layers region; not allowed."
1845 << endl);
1846 }
1847
1848 // add up all the values between the endpoints
1849 // N.B.: following may need modification to be right for periodic Mesh BC:
1850 while (a <= b)
1851 vertexVertexSpacing[d] += (*(meshSpacing[d].find(a++))).second;
1852 }
1853
1854 return vertexVertexSpacing;
1855}
1856
1857// Field of vertex-vertex grid spacings of all cells:
1858template <unsigned Dim, class MFLOAT>
1862 Cartesian<Dim,MFLOAT>,Cell>& vertexSpacings) const
1863{
1864 int currentLocation[Dim];
1865 Vektor<MFLOAT,Dim> vertexVertexSpacing;
1866 vertexSpacings.Uncompress();
1868 fi_end = vertexSpacings.end();
1869 for (fi = vertexSpacings.begin(); fi != fi_end; ++fi) {
1870 fi.GetCurrentLocation(currentLocation);
1871 for (unsigned int d=0; d<Dim; d++)
1872 vertexVertexSpacing[d]=(*(meshSpacing[d].find(currentLocation[d]))).second;
1873 *fi = vertexVertexSpacing;
1874 }
1875 return vertexSpacings;
1876}
1877
1878// Cell-cell grid spacing of indexed cell:
1879template <unsigned Dim, class MFLOAT>
1882getDeltaCell(const NDIndex<Dim>& ndi) const
1883{
1884 // return value
1885 Vektor<MFLOAT,Dim> cellCellSpacing(0);
1886
1887 for (unsigned int d=0; d<Dim; d++) {
1888 // endpoints of the index range ... make sure they are in ascending order
1889 int a = ndi[d].first();
1890 int b = ndi[d].last();
1891 if (b < a) {
1892 int tmpa = a; a = b; b = tmpa;
1893 }
1894
1895 // make sure the endpoints are valid
1896 if (a <= -(int(gridSizes[d])-1)/2 || b >= 3*(int(gridSizes[d])-1)/2) {
1897 ERRORMSG("Cartesian::getDeltaCell() error: " << ndi
1898 << " is an NDIndex ranging outside"
1899 << " the mesh and guard layers region; not allowed."
1900 << endl);
1901 }
1902
1903 // add up the contributions along the interval ...
1904 while (a <= b) {
1905 cellCellSpacing[d] += ((*(meshSpacing[d].find(a))).second +
1906 (*(meshSpacing[d].find(a-1))).second) * 0.5;
1907 a++;
1908 }
1909 }
1910 return cellCellSpacing;
1911}
1912
1913// Field of cell-cell grid spacings of all cells:
1914template <unsigned Dim, class MFLOAT>
1918 Cartesian<Dim,MFLOAT>,Vert>& cellSpacings) const
1919{
1920 int currentLocation[Dim];
1921 Vektor<MFLOAT,Dim> cellCellSpacing;
1922 cellSpacings.Uncompress();
1924 fi_end = cellSpacings.end();
1925 for (fi = cellSpacings.begin(); fi != fi_end; ++fi) {
1926 fi.GetCurrentLocation(currentLocation);
1927 for (unsigned int d=0; d<Dim; d++)
1928 cellCellSpacing[d]+=((*(meshSpacing[d].find(currentLocation[d]))).second +
1929 (*(meshSpacing[d].find(currentLocation[d]-1))).second) * 0.5;
1930 *fi = cellCellSpacing;
1931 }
1932 return cellSpacings;
1933}
1934// Array of surface normals to cells adjoining indexed cell:
1935template <unsigned Dim, class MFLOAT>
1938getSurfaceNormals(const NDIndex<Dim>& /*ndi*/) const
1939{
1940 Vektor<MFLOAT,Dim>* surfaceNormals = new Vektor<MFLOAT,Dim>[2*Dim];
1941 unsigned int d, i;
1942 for (d=0; d<Dim; d++) {
1943 for (i=0; i<Dim; i++) {
1944 surfaceNormals[2*d](i) = 0.0;
1945 surfaceNormals[2*d+1](i) = 0.0;
1946 }
1947 surfaceNormals[2*d](d) = -1.0;
1948 surfaceNormals[2*d+1](d) = 1.0;
1949 }
1950 return surfaceNormals;
1951}
1952// Array of (pointers to) Fields of surface normals to all cells:
1953template <unsigned Dim, class MFLOAT>
1954void
1958 surfaceNormalsFields ) const
1959{
1960 Vektor<MFLOAT,Dim>* surfaceNormals = new Vektor<MFLOAT,Dim>[2*Dim];
1961 unsigned int d, i;
1962 for (d=0; d<Dim; d++) {
1963 for (i=0; i<Dim; i++) {
1964 surfaceNormals[2*d](i) = 0.0;
1965 surfaceNormals[2*d+1](i) = 0.0;
1966 }
1967 surfaceNormals[2*d](d) = -1.0;
1968 surfaceNormals[2*d+1](d) = 1.0;
1969 }
1970 for (d=0; d<2*Dim; d++) assign((*(surfaceNormalsFields[d])),
1971 surfaceNormals[d]);
1972 // return surfaceNormalsFields;
1973}
1974// Similar functions, but specify the surface normal to a single face, using
1975// the following numbering convention: 0 means low face of 1st dim, 1 means
1976// high face of 1st dim, 2 means low face of 2nd dim, 3 means high face of
1977// 2nd dim, and so on:
1978// Surface normal to face on indexed cell:
1979template <unsigned Dim, class MFLOAT>
1982getSurfaceNormal(const NDIndex<Dim>& /*ndi*/, unsigned face) const
1983{
1984 Vektor<MFLOAT,Dim> surfaceNormal;
1985 unsigned int d;
1986 // The following bitwise AND logical test returns true if face is odd
1987 // (meaning the "high" or "right" face in the numbering convention) and
1988 // returns false if face is even (meaning the "low" or "left" face in the
1989 // numbering convention):
1990 if ( face & 1 ) {
1991 for (d=0; d<Dim; d++) {
1992 if ((face/2) == d) {
1993 surfaceNormal(face) = -1.0;
1994 } else {
1995 surfaceNormal(face) = 0.0;
1996 }
1997 }
1998 } else {
1999 for (d=0; d<Dim; d++) {
2000 if ((face/2) == d) {
2001 surfaceNormal(face) = 1.0;
2002 } else {
2003 surfaceNormal(face) = 0.0;
2004 }
2005 }
2006 }
2007 return surfaceNormal;
2008}
2009// Field of surface normals to face on all cells:
2010template <unsigned Dim, class MFLOAT>
2014 Cartesian<Dim,MFLOAT>,Cell>& surfaceNormalField,
2015 unsigned face) const
2016{
2017 Vektor<MFLOAT,Dim> surfaceNormal;
2018 unsigned int d;
2019 // The following bitwise AND logical test returns true if face is odd
2020 // (meaning the "high" or "right" face in the numbering convention) and
2021 // returns false if face is even (meaning the "low" or "left" face in the
2022 // numbering convention):
2023 if ( face & 1 ) {
2024 for (d=0; d<Dim; d++) {
2025 if ((face/2) == d) {
2026 surfaceNormal(face) = -1.0;
2027 } else {
2028 surfaceNormal(face) = 0.0;
2029 }
2030 }
2031 } else {
2032 for (d=0; d<Dim; d++) {
2033 if ((face/2) == d) {
2034 surfaceNormal(face) = 1.0;
2035 } else {
2036 surfaceNormal(face) = 0.0;
2037 }
2038 }
2039 }
2040 surfaceNormalField = surfaceNormal;
2041 return surfaceNormalField;
2042}
2043
2044// Set up mesh boundary conditions:
2045// Face specifies the mesh face, following usual numbering convention.
2046// MeshBC_E "type" specifies the kind of BC reflective/periodic/none.
2047// One face at a time:
2048template <unsigned Dim, class MFLOAT>
2049void
2051set_MeshBC(unsigned face, MeshBC_E meshBCType)
2052{
2053 MeshBC[face] = meshBCType;
2054 updateMeshSpacingGuards(face);
2055 // if spacing fields allocated, we must update values
2056 if (hasSpacingFields) storeSpacingFields();
2057}
2058// All faces at once:
2059template <unsigned Dim, class MFLOAT>
2060void
2062set_MeshBC(MeshBC_E* meshBCTypes)
2063{
2064 for (unsigned int face=0; face < 2*Dim; face++) {
2065 MeshBC[face] = meshBCTypes[face];
2066 updateMeshSpacingGuards(face);
2067 }
2068 // if spacing fields allocated, we must update values
2069 if (hasSpacingFields) storeSpacingFields();
2070}
2071// Helper function to update guard layer values of mesh spacings:
2072template <unsigned Dim, class MFLOAT>
2073void
2076{
2077 // Apply the current state of the mesh BC to add guards to meshSpacings map
2078 // Assume worst case of needing ngridpts/2 guard layers (for periodic, most
2079 // likely):
2080 int d = face/2;
2081 unsigned int cell, guardLayer;
2082 // The following bitwise AND logical test returns true if face is odd
2083 // (meaning the "high" or "right" face in the numbering convention) and
2084 // returns false if face is even (meaning the "low" or "left" face in
2085 // the numbering convention):
2086 if ( face & 1 ) {
2087 // "High" guard cells:
2088 switch (MeshBC[d*2]) {
2089 case Periodic:
2090 for (guardLayer = 0; guardLayer <= (gridSizes[d]-1)/2; guardLayer++) {
2091 cell = gridSizes[d] - 1 + guardLayer;
2092 (meshSpacing[d])[cell] = (meshSpacing[d])[guardLayer];
2093 (meshPosition[d])[cell+1] = (meshPosition[d])[cell] +
2094 (meshSpacing[d])[cell];
2095 }
2096 break;
2097 case Reflective:
2098 for (guardLayer = 0; guardLayer <= (gridSizes[d]-1)/2; guardLayer++) {
2099 cell = gridSizes[d] - 1 + guardLayer;
2100 (meshSpacing[d])[cell] = (meshSpacing[d])[cell - guardLayer - 1];
2101 (meshPosition[d])[cell+1] = (meshPosition[d])[cell] +
2102 (meshSpacing[d])[cell];
2103 }
2104 break;
2105 case NoBC:
2106 for (guardLayer = 0; guardLayer <= (gridSizes[d]-1)/2; guardLayer++) {
2107 cell = gridSizes[d] - 1 + guardLayer;
2108 (meshSpacing[d])[cell] = 0;
2109 (meshPosition[d])[cell+1] = (meshPosition[d])[cell] +
2110 (meshSpacing[d])[cell];
2111 }
2112 break;
2113 default:
2114 ERRORMSG("Cartesian::updateMeshSpacingGuards(): unknown MeshBC type"
2115 << endl);
2116 break;
2117 }
2118 }
2119 else {
2120 // "Low" guard cells:
2121 switch (MeshBC[d]) {
2122 case Periodic:
2123 for (guardLayer = 0; guardLayer <= (gridSizes[d]-1)/2; guardLayer++) {
2124 cell = -1 - guardLayer;
2125 (meshSpacing[d])[cell] = (meshSpacing[d])[gridSizes[d] + cell];
2126 (meshPosition[d])[cell] = (meshPosition[d])[cell+1] -
2127 (meshSpacing[d])[cell];
2128 }
2129 break;
2130 case Reflective:
2131 for (guardLayer = 0; guardLayer <= (gridSizes[d]-1)/2; guardLayer++) {
2132 cell = -1 - guardLayer;
2133 (meshSpacing[d])[cell] = (meshSpacing[d])[-cell - 1];
2134 (meshPosition[d])[cell] = (meshPosition[d])[cell+1] -
2135 (meshSpacing[d])[cell];
2136 }
2137 break;
2138 case NoBC:
2139 for (guardLayer = 0; guardLayer <= (gridSizes[d]-1)/2; guardLayer++) {
2140 cell = -1 - guardLayer;
2141 (meshSpacing[d])[cell] = 0;
2142 (meshPosition[d])[cell] = (meshPosition[d])[cell+1] -
2143 (meshSpacing[d])[cell];
2144 }
2145 break;
2146 default:
2147 ERRORMSG("Cartesian::updateMeshSpacingGuards(): unknown MeshBC type"
2148 << endl);
2149 break;
2150 }
2151 }
2152}
2153
2154// Get mesh boundary conditions:
2155// One face at a time
2156template <unsigned Dim, class MFLOAT>
2159get_MeshBC(unsigned face) const
2160{
2161 MeshBC_E mb;
2162 mb = MeshBC[face];
2163 return mb;
2164}
2165// All faces at once
2166template <unsigned Dim, class MFLOAT>
2167MeshBC_E*
2169get_MeshBC() const
2170{
2171 MeshBC_E* mb = new MeshBC_E[2*Dim];
2172 for (unsigned int b=0; b < 2*Dim; b++) mb[b] = MeshBC[b];
2173 return mb;
2174}
2175
2176
2177
2178//--------------------------------------------------------------------------
2179// Global functions
2180//--------------------------------------------------------------------------
2181
2182
2183//*****************************************************************************
2184// Stuff taken from old Cartesian.h, modified for new nonuniform Cartesian:
2185//*****************************************************************************
2186
2187//----------------------------------------------------------------------
2188// Divergence Vektor/Vert -> Scalar/Cell
2189//----------------------------------------------------------------------
2190template < class T, class MFLOAT >
2194{
2195 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2196 BareField<Vektor<MFLOAT,1U>,1U>& vertSpacings = *(x.get_mesh().VertSpacings);
2197 const NDIndex<1U>& domain = r.getDomain();
2198 Index I = domain[0];
2199 r[I] =
2200 dot(x[I ], x.get_mesh().Dvc[0]/vertSpacings[I]) +
2201 dot(x[I+1], x.get_mesh().Dvc[1]/vertSpacings[I]);
2202 return r;
2203}
2204//----------------------------------------------------------------------
2205template < class T, class MFLOAT >
2209{
2210 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2211 BareField<Vektor<MFLOAT,2U>,2U>& vertSpacings = *(x.get_mesh().VertSpacings);
2212 const NDIndex<2U>& domain = r.getDomain();
2213 Index I = domain[0];
2214 Index J = domain[1];
2215 r[I][J] =
2216 dot(x[I ][J ], x.get_mesh().Dvc[0]/vertSpacings[I][J]) +
2217 dot(x[I+1][J ], x.get_mesh().Dvc[1]/vertSpacings[I][J]) +
2218 dot(x[I ][J+1], x.get_mesh().Dvc[2]/vertSpacings[I][J]) +
2219 dot(x[I+1][J+1], x.get_mesh().Dvc[3]/vertSpacings[I][J]);
2220 return r;
2221}
2222//----------------------------------------------------------------------
2223template < class T, class MFLOAT >
2227{
2228 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2229 BareField<Vektor<MFLOAT,3U>,3U>& vertSpacings = *(x.get_mesh().VertSpacings);
2230 const NDIndex<3U>& domain = r.getDomain();
2231 Index I = domain[0];
2232 Index J = domain[1];
2233 Index K = domain[2];
2234 r[I][J][K] =
2235 dot(x[I ][J ][K ], x.get_mesh().Dvc[0]/vertSpacings[I][J][K]) +
2236 dot(x[I+1][J ][K ], x.get_mesh().Dvc[1]/vertSpacings[I][J][K]) +
2237 dot(x[I ][J+1][K ], x.get_mesh().Dvc[2]/vertSpacings[I][J][K]) +
2238 dot(x[I+1][J+1][K ], x.get_mesh().Dvc[3]/vertSpacings[I][J][K]) +
2239 dot(x[I ][J ][K+1], x.get_mesh().Dvc[4]/vertSpacings[I][J][K]) +
2240 dot(x[I+1][J ][K+1], x.get_mesh().Dvc[5]/vertSpacings[I][J][K]) +
2241 dot(x[I ][J+1][K+1], x.get_mesh().Dvc[6]/vertSpacings[I][J][K]) +
2242 dot(x[I+1][J+1][K+1], x.get_mesh().Dvc[7]/vertSpacings[I][J][K]);
2243 return r;
2244}
2245//----------------------------------------------------------------------
2246// Divergence Vektor/Cell -> Scalar/Vert
2247//----------------------------------------------------------------------
2248template < class T, class MFLOAT >
2252{
2253 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2254 BareField<Vektor<MFLOAT,1U>,1U>& cellSpacings = *(x.get_mesh().CellSpacings);
2255 const NDIndex<1U>& domain = r.getDomain();
2256 Index I = domain[0];
2257 r[I] =
2258 dot(x[I-1], x.get_mesh().Dvc[0]/cellSpacings[I]) +
2259 dot(x[I ], x.get_mesh().Dvc[1]/cellSpacings[I]);
2260 return r;
2261}
2262//----------------------------------------------------------------------
2263template < class T, class MFLOAT >
2267{
2268 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2269 BareField<Vektor<MFLOAT,2U>,2U>& cellSpacings = *(x.get_mesh().CellSpacings);
2270 const NDIndex<2U>& domain = r.getDomain();
2271 Index I = domain[0];
2272 Index J = domain[1];
2273 r[I][J] =
2274 dot(x[I-1][J-1], x.get_mesh().Dvc[0]/cellSpacings[I][J]) +
2275 dot(x[I ][J-1], x.get_mesh().Dvc[1]/cellSpacings[I][J]) +
2276 dot(x[I-1][J ], x.get_mesh().Dvc[2]/cellSpacings[I][J]) +
2277 dot(x[I ][J ], x.get_mesh().Dvc[3]/cellSpacings[I][J]);
2278 return r;
2279}
2280//----------------------------------------------------------------------
2281template < class T, class MFLOAT >
2285{
2286 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2287 BareField<Vektor<MFLOAT,3U>,3U>& cellSpacings = *(x.get_mesh().CellSpacings);
2288 const NDIndex<3U>& domain = r.getDomain();
2289 Index I = domain[0];
2290 Index J = domain[1];
2291 Index K = domain[2];
2292 r[I][J][K] =
2293 dot(x[I-1][J-1][K-1], x.get_mesh().Dvc[0]/cellSpacings[I][J][K]) +
2294 dot(x[I ][J-1][K-1], x.get_mesh().Dvc[1]/cellSpacings[I][J][K]) +
2295 dot(x[I-1][J ][K-1], x.get_mesh().Dvc[2]/cellSpacings[I][J][K]) +
2296 dot(x[I ][J ][K-1], x.get_mesh().Dvc[3]/cellSpacings[I][J][K]) +
2297 dot(x[I-1][J-1][K ], x.get_mesh().Dvc[4]/cellSpacings[I][J][K]) +
2298 dot(x[I ][J-1][K ], x.get_mesh().Dvc[5]/cellSpacings[I][J][K]) +
2299 dot(x[I-1][J ][K ], x.get_mesh().Dvc[6]/cellSpacings[I][J][K]) +
2300 dot(x[I ][J ][K ], x.get_mesh().Dvc[7]/cellSpacings[I][J][K]);
2301 return r;
2302}
2303
2304
2305// TJW: I've attempted to update these differential operators from uniform
2306// cartesian implementations to workfor (nonuniform) Cartesian class, but they
2307// may really need to get changed in other ways, such as something besides
2308// simple centered differncing for cell-cell and vert-vert cases. Flag these
2309// operator implementations since they may be a source of trouble until tested
2310// and debugged further. The Grad() operators, especially, may be wrong. All
2311// that being said, I have tested quite a few of these, including the following
2312// two needed by Tecolote: 1) Div SymTenzor/Cell->Vektor/Vert 2) Grad
2313// Vektor/Vert->Tenzor/Cell
2314
2315// BEGIN FLAGGED DIFFOPS REGION I
2316
2317//----------------------------------------------------------------------
2318// Divergence Vektor/Vert -> Scalar/Vert
2319// (Re-coded 1/20/1998 tjw. Hope it's right....???)
2320//----------------------------------------------------------------------
2321template < class T, class MFLOAT >
2325{
2326 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2327 BareField<Vektor<MFLOAT,1U>,1U>& vS = *(x.get_mesh().VertSpacings);
2328 const NDIndex<1U>& domain = r.getDomain();
2329 Index I = domain[0];
2331 idx[0] = 1.0;
2332 r[I] = dot(idx, (x[I+1] - x[I-1])/(vS[I ] + vS[I-1]));
2333 return r;
2334}
2335//----------------------------------------------------------------------
2336template < class T, class MFLOAT >
2340{
2341 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2342 BareField<Vektor<MFLOAT,2U>,2U>& vS = *(x.get_mesh().VertSpacings);
2343 const NDIndex<2U>& domain = r.getDomain();
2344 Index I = domain[0];
2345 Index J = domain[1];
2346 Vektor<MFLOAT,2U> idx,idy;
2347 idx[0] = 1.0;
2348 idx[1] = 0.0;
2349 idy[0] = 0.0;
2350 idy[1] = 1.0;
2351 r[I][J] =
2352 dot(idx, (x[I+1][J ] - x[I-1][J ])/(vS[I ][J ] + vS[I-1][J ])) +
2353 dot(idy, (x[I ][J+1] - x[I ][J-1])/(vS[I ][J ] + vS[I ][J-1]));
2354 return r;
2355}
2356//----------------------------------------------------------------------
2357template < class T, class MFLOAT >
2361{
2362 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2363 BareField<Vektor<MFLOAT,3U>,3U>& vS = *(x.get_mesh().VertSpacings);
2364 const NDIndex<3U>& domain = r.getDomain();
2365 Index I = domain[0];
2366 Index J = domain[1];
2367 Index K = domain[2];
2368 Vektor<MFLOAT,3U> idx,idy,idz;
2369 idx[0] = 1.0;
2370 idx[1] = 0.0;
2371 idx[2] = 0.0;
2372 idy[0] = 0.0;
2373 idy[1] = 1.0;
2374 idy[2] = 0.0;
2375 idz[0] = 0.0;
2376 idz[1] = 0.0;
2377 idz[2] = 1.0;
2378 r[I][J][K] =
2379 dot(idx, ((x[I+1][J ][K ] - x[I-1][J ][K ])/
2380 (vS[I ][J ][K ] + vS[I-1][J ][K ]))) +
2381 dot(idy, ((x[I ][J+1][K ] - x[I ][J-1][K ])/
2382 (vS[I ][J ][K ] + vS[I ][J-1][K ]))) +
2383 dot(idz, ((x[I ][J ][K+1] - x[I ][J ][K-1])/
2384 (vS[I ][J ][K ] + vS[I ][J ][K-1])));
2385 return r;
2386}
2387//----------------------------------------------------------------------
2388// Divergence Vektor/Cell -> Scalar/Cell (???right? tjw 3/10/97)
2389// (Re-coded 1/20/1998 tjw. Hope it's right....???)
2390// TJW 5/14/1999: I think there's a bug here, in the denominators. For example,
2391// the 1D denom should be (cs[I+1] + cs[I]) as I see it.
2392// This one wasn't in test/simple/TestCartesian.cpp.
2393//----------------------------------------------------------------------
2394template < class T, class MFLOAT >
2398{
2399 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2400 BareField<Vektor<MFLOAT,1U>,1U>& cS = *(x.get_mesh().CellSpacings);
2401 const NDIndex<1U>& domain = r.getDomain();
2402 Index I = domain[0];
2404 idx[0] = 1.0;
2405 r[I] = dot(idx, (x[I+1] - x[I-1])/(cS[I ] + cS[I-1]));
2406 return r;
2407}
2408//----------------------------------------------------------------------
2409template < class T, class MFLOAT >
2413{
2414 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2415 BareField<Vektor<MFLOAT,2U>,2U>& cS = *(x.get_mesh().CellSpacings);
2416 const NDIndex<2U>& domain = r.getDomain();
2417 Index I = domain[0];
2418 Index J = domain[1];
2419 Vektor<MFLOAT,2U> idx,idy;
2420 idx[0] = 1.0;
2421 idx[1] = 0.0;
2422 idy[0] = 0.0;
2423 idy[1] = 1.0;
2424 r[I][J] =
2425 dot(idx, (x[I+1][J ] - x[I-1][J ])/(cS[I ][J ] + cS[I-1][J ])) +
2426 dot(idy, (x[I ][J+1] - x[I ][J-1])/(cS[I ][J ] + cS[I ][J-1]));
2427 return r;
2428}
2429//----------------------------------------------------------------------
2430template < class T, class MFLOAT >
2434{
2435 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2436 BareField<Vektor<MFLOAT,3U>,3U>& cS = *(x.get_mesh().CellSpacings);
2437 const NDIndex<3U>& domain = r.getDomain();
2438 Index I = domain[0];
2439 Index J = domain[1];
2440 Index K = domain[2];
2441 Vektor<MFLOAT,3U> idx,idy,idz;
2442 idx[0] = 1.0;
2443 idx[1] = 0.0;
2444 idx[2] = 0.0;
2445 idy[0] = 0.0;
2446 idy[1] = 1.0;
2447 idy[2] = 0.0;
2448 idz[0] = 0.0;
2449 idz[1] = 0.0;
2450 idz[2] = 1.0;
2451 r[I][J][K] =
2452 dot(idx, ((x[I+1][J ][K ] - x[I-1][J ][K ])/
2453 (cS[I ][J ][K ] + cS[I-1][J ][K ]))) +
2454 dot(idy, ((x[I ][J+1][K ] - x[I ][J-1][K ])/
2455 (cS[I ][J ][K ] + cS[I ][J-1][K ]))) +
2456 dot(idz, ((x[I ][J ][K+1] - x[I ][J ][K-1])/
2457 (cS[I ][J ][K ] + cS[I ][J ][K-1])));
2458 return r;
2459}
2460//----------------------------------------------------------------------
2461// Divergence Tenzor/Vert -> Vektor/Cell (???dot right thing? tjw 1/20/1998)
2462//----------------------------------------------------------------------
2463template < class T, class MFLOAT >
2467{
2468 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2469 BareField<Vektor<MFLOAT,1U>,1U>& vertSpacings = *(x.get_mesh().VertSpacings);
2470 const NDIndex<1U>& domain = r.getDomain();
2471 Index I = domain[0];
2472 r[I] =
2473 dot(x[I ], x.get_mesh().Dvc[0]/vertSpacings[I]) +
2474 dot(x[I+1], x.get_mesh().Dvc[1]/vertSpacings[I]);
2475 return r;
2476}
2477//----------------------------------------------------------------------
2478template < class T, class MFLOAT >
2482{
2483 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2484 BareField<Vektor<MFLOAT,2U>,2U>& vertSpacings = *(x.get_mesh().VertSpacings);
2485 const NDIndex<2U>& domain = r.getDomain();
2486 Index I = domain[0];
2487 Index J = domain[1];
2488 r[I][J] =
2489 dot(x[I ][J ], x.get_mesh().Dvc[0]/vertSpacings[I][J]) +
2490 dot(x[I+1][J ], x.get_mesh().Dvc[1]/vertSpacings[I][J]) +
2491 dot(x[I ][J+1], x.get_mesh().Dvc[2]/vertSpacings[I][J]) +
2492 dot(x[I+1][J+1], x.get_mesh().Dvc[3]/vertSpacings[I][J]);
2493 return r;
2494}
2495//----------------------------------------------------------------------
2496template < class T, class MFLOAT >
2500{
2501 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2502 BareField<Vektor<MFLOAT,3U>,3U>& vertSpacings = *(x.get_mesh().VertSpacings);
2503 const NDIndex<3U>& domain = r.getDomain();
2504 Index I = domain[0];
2505 Index J = domain[1];
2506 Index K = domain[2];
2507 r[I][J][K] =
2508 dot(x[I ][J ][K ], x.get_mesh().Dvc[0]/vertSpacings[I][J][K]) +
2509 dot(x[I+1][J ][K ], x.get_mesh().Dvc[1]/vertSpacings[I][J][K]) +
2510 dot(x[I ][J+1][K ], x.get_mesh().Dvc[2]/vertSpacings[I][J][K]) +
2511 dot(x[I+1][J+1][K ], x.get_mesh().Dvc[3]/vertSpacings[I][J][K]) +
2512 dot(x[I ][J ][K+1], x.get_mesh().Dvc[4]/vertSpacings[I][J][K]) +
2513 dot(x[I+1][J ][K+1], x.get_mesh().Dvc[5]/vertSpacings[I][J][K]) +
2514 dot(x[I ][J+1][K+1], x.get_mesh().Dvc[6]/vertSpacings[I][J][K]) +
2515 dot(x[I+1][J+1][K+1], x.get_mesh().Dvc[7]/vertSpacings[I][J][K]);
2516 return r;
2517}
2518//----------------------------------------------------------------------
2519// Divergence SymTenzor/Vert -> Vektor/Cell (???dot right thing? tjw 1/20/1998)
2520//----------------------------------------------------------------------
2521template < class T, class MFLOAT >
2525{
2526 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2527 BareField<Vektor<MFLOAT,1U>,1U>& vertSpacings = *(x.get_mesh().VertSpacings);
2528 const NDIndex<1U>& domain = r.getDomain();
2529 Index I = domain[0];
2530 r[I] =
2531 dot(x[I ], x.get_mesh().Dvc[0]/vertSpacings[I]) +
2532 dot(x[I+1], x.get_mesh().Dvc[1]/vertSpacings[I]);
2533 return r;
2534}
2535//----------------------------------------------------------------------
2536template < class T, class MFLOAT >
2540{
2541 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2542 BareField<Vektor<MFLOAT,2U>,2U>& vertSpacings = *(x.get_mesh().VertSpacings);
2543 const NDIndex<2U>& domain = r.getDomain();
2544 Index I = domain[0];
2545 Index J = domain[1];
2546 r[I][J] =
2547 dot(x[I ][J ], x.get_mesh().Dvc[0]/vertSpacings[I][J]) +
2548 dot(x[I+1][J ], x.get_mesh().Dvc[1]/vertSpacings[I][J]) +
2549 dot(x[I ][J+1], x.get_mesh().Dvc[2]/vertSpacings[I][J]) +
2550 dot(x[I+1][J+1], x.get_mesh().Dvc[3]/vertSpacings[I][J]);
2551 return r;
2552}
2553//----------------------------------------------------------------------
2554template < class T, class MFLOAT >
2558{
2559 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2560 BareField<Vektor<MFLOAT,3U>,3U>& vertSpacings = *(x.get_mesh().VertSpacings);
2561 const NDIndex<3U>& domain = r.getDomain();
2562 Index I = domain[0];
2563 Index J = domain[1];
2564 Index K = domain[2];
2565 r[I][J][K] =
2566 dot(x[I ][J ][K ], x.get_mesh().Dvc[0]/vertSpacings[I][J][K]) +
2567 dot(x[I+1][J ][K ], x.get_mesh().Dvc[1]/vertSpacings[I][J][K]) +
2568 dot(x[I ][J+1][K ], x.get_mesh().Dvc[2]/vertSpacings[I][J][K]) +
2569 dot(x[I+1][J+1][K ], x.get_mesh().Dvc[3]/vertSpacings[I][J][K]) +
2570 dot(x[I ][J ][K+1], x.get_mesh().Dvc[4]/vertSpacings[I][J][K]) +
2571 dot(x[I+1][J ][K+1], x.get_mesh().Dvc[5]/vertSpacings[I][J][K]) +
2572 dot(x[I ][J+1][K+1], x.get_mesh().Dvc[6]/vertSpacings[I][J][K]) +
2573 dot(x[I+1][J+1][K+1], x.get_mesh().Dvc[7]/vertSpacings[I][J][K]);
2574 return r;
2575}
2576
2577//----------------------------------------------------------------------
2578// Divergence Tenzor/Cell -> Vektor/Vert (???dot right thing? tjw 1/20/1998)
2579//----------------------------------------------------------------------
2580template < class T, class MFLOAT >
2584{
2585 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2586 BareField<Vektor<MFLOAT,1U>,1U>& cellSpacings = *(x.get_mesh().CellSpacings);
2587 const NDIndex<1U>& domain = r.getDomain();
2588 Index I = domain[0];
2589 r[I] =
2590 dot(x[I-1], x.get_mesh().Dvc[0]/cellSpacings[I]) +
2591 dot(x[I ], x.get_mesh().Dvc[1]/cellSpacings[I]);
2592 return r;
2593}
2594//----------------------------------------------------------------------
2595template < class T, class MFLOAT >
2599{
2600 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2601 BareField<Vektor<MFLOAT,2U>,2U>& cellSpacings = *(x.get_mesh().CellSpacings);
2602 const NDIndex<2U>& domain = r.getDomain();
2603 Index I = domain[0];
2604 Index J = domain[1];
2605 r[I][J] =
2606 dot(x[I-1][J-1], x.get_mesh().Dvc[0]/cellSpacings[I][J]) +
2607 dot(x[I ][J-1], x.get_mesh().Dvc[1]/cellSpacings[I][J]) +
2608 dot(x[I-1][J ], x.get_mesh().Dvc[2]/cellSpacings[I][J]) +
2609 dot(x[I ][J ], x.get_mesh().Dvc[3]/cellSpacings[I][J]);
2610 return r;
2611}
2612//----------------------------------------------------------------------
2613template < class T, class MFLOAT >
2617{
2618 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2619 BareField<Vektor<MFLOAT,3U>,3U>& cellSpacings = *(x.get_mesh().CellSpacings);
2620 const NDIndex<3U>& domain = r.getDomain();
2621 Index I = domain[0];
2622 Index J = domain[1];
2623 Index K = domain[2];
2624 r[I][J][K] =
2625 dot(x[I-1][J-1][K-1], x.get_mesh().Dvc[0]/cellSpacings[I][J][K]) +
2626 dot(x[I ][J-1][K-1], x.get_mesh().Dvc[1]/cellSpacings[I][J][K]) +
2627 dot(x[I-1][J ][K-1], x.get_mesh().Dvc[2]/cellSpacings[I][J][K]) +
2628 dot(x[I ][J ][K-1], x.get_mesh().Dvc[3]/cellSpacings[I][J][K]) +
2629 dot(x[I-1][J-1][K ], x.get_mesh().Dvc[4]/cellSpacings[I][J][K]) +
2630 dot(x[I ][J-1][K ], x.get_mesh().Dvc[5]/cellSpacings[I][J][K]) +
2631 dot(x[I-1][J ][K ], x.get_mesh().Dvc[6]/cellSpacings[I][J][K]) +
2632 dot(x[I ][J ][K ], x.get_mesh().Dvc[7]/cellSpacings[I][J][K]);
2633 return r;
2634}
2635
2636//----------------------------------------------------------------------
2637// Divergence SymTenzor/Cell -> Vektor/Vert (???dot right thing? tjw 1/20/1998)
2638//----------------------------------------------------------------------
2639template < class T, class MFLOAT >
2643{
2644 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2645 BareField<Vektor<MFLOAT,1U>,1U>& cellSpacings = *(x.get_mesh().CellSpacings);
2646 const NDIndex<1U>& domain = r.getDomain();
2647 Index I = domain[0];
2648 r[I] =
2649 dot(x[I-1], x.get_mesh().Dvc[0]/cellSpacings[I]) +
2650 dot(x[I ], x.get_mesh().Dvc[1]/cellSpacings[I]);
2651 return r;
2652}
2653//----------------------------------------------------------------------
2654template < class T, class MFLOAT >
2658{
2659 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2660 BareField<Vektor<MFLOAT,2U>,2U>& cellSpacings = *(x.get_mesh().CellSpacings);
2661 const NDIndex<2U>& domain = r.getDomain();
2662 Index I = domain[0];
2663 Index J = domain[1];
2664 r[I][J] =
2665 dot(x[I-1][J-1], x.get_mesh().Dvc[0]/cellSpacings[I][J]) +
2666 dot(x[I ][J-1], x.get_mesh().Dvc[1]/cellSpacings[I][J]) +
2667 dot(x[I-1][J ], x.get_mesh().Dvc[2]/cellSpacings[I][J]) +
2668 dot(x[I ][J ], x.get_mesh().Dvc[3]/cellSpacings[I][J]);
2669 return r;
2670}
2671//----------------------------------------------------------------------
2672template < class T, class MFLOAT >
2676{
2677 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2678 BareField<Vektor<MFLOAT,3U>,3U>& cellSpacings = *(x.get_mesh().CellSpacings);
2679 const NDIndex<3U>& domain = r.getDomain();
2680 Index I = domain[0];
2681 Index J = domain[1];
2682 Index K = domain[2];
2683 r[I][J][K] =
2684 dot(x[I-1][J-1][K-1], x.get_mesh().Dvc[0]/cellSpacings[I][J][K]) +
2685 dot(x[I ][J-1][K-1], x.get_mesh().Dvc[1]/cellSpacings[I][J][K]) +
2686 dot(x[I-1][J ][K-1], x.get_mesh().Dvc[2]/cellSpacings[I][J][K]) +
2687 dot(x[I ][J ][K-1], x.get_mesh().Dvc[3]/cellSpacings[I][J][K]) +
2688 dot(x[I-1][J-1][K ], x.get_mesh().Dvc[4]/cellSpacings[I][J][K]) +
2689 dot(x[I ][J-1][K ], x.get_mesh().Dvc[5]/cellSpacings[I][J][K]) +
2690 dot(x[I-1][J ][K ], x.get_mesh().Dvc[6]/cellSpacings[I][J][K]) +
2691 dot(x[I ][J ][K ], x.get_mesh().Dvc[7]/cellSpacings[I][J][K]);
2692 return r;
2693}
2694
2695// END FLAGGED DIFFOPS REGION I
2696
2697//----------------------------------------------------------------------
2698// Grad Scalar/Vert -> Vektor/Cell
2699//----------------------------------------------------------------------
2700template < class T, class MFLOAT >
2704{
2705 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2706 BareField<Vektor<MFLOAT,1U>,1U>& vertSpacings = *(x.get_mesh().VertSpacings);
2707 const NDIndex<1U>& domain = r.getDomain();
2708 Index I = domain[0];
2709 r[I] = (x[I ]*x.get_mesh().Dvc[0] +
2710 x[I+1]*x.get_mesh().Dvc[1])/vertSpacings[I];
2711 return r;
2712}
2713//----------------------------------------------------------------------
2714template < class T, class MFLOAT >
2718{
2719 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2720 BareField<Vektor<MFLOAT,2U>,2U>& vertSpacings = *(x.get_mesh().VertSpacings);
2721 const NDIndex<2U>& domain = r.getDomain();
2722 Index I = domain[0];
2723 Index J = domain[1];
2724 r[I][J] = (x[I ][J ]*x.get_mesh().Dvc[0] +
2725 x[I+1][J ]*x.get_mesh().Dvc[1] +
2726 x[I ][J+1]*x.get_mesh().Dvc[2] +
2727 x[I+1][J+1]*x.get_mesh().Dvc[3])/vertSpacings[I][J];
2728 return r;
2729}
2730//----------------------------------------------------------------------
2731template < class T, class MFLOAT >
2735{
2736 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2737 BareField<Vektor<MFLOAT,3U>,3U>& vertSpacings = *(x.get_mesh().VertSpacings);
2738 const NDIndex<3U>& domain = r.getDomain();
2739 Index I = domain[0];
2740 Index J = domain[1];
2741 Index K = domain[2];
2742 r[I][J][K] = (x[I ][J ][K ]*x.get_mesh().Dvc[0] +
2743 x[I+1][J ][K ]*x.get_mesh().Dvc[1] +
2744 x[I ][J+1][K ]*x.get_mesh().Dvc[2] +
2745 x[I+1][J+1][K ]*x.get_mesh().Dvc[3] +
2746 x[I ][J ][K+1]*x.get_mesh().Dvc[4] +
2747 x[I+1][J ][K+1]*x.get_mesh().Dvc[5] +
2748 x[I ][J+1][K+1]*x.get_mesh().Dvc[6] +
2749 x[I+1][J+1][K+1]*x.get_mesh().Dvc[7])/vertSpacings[I][J][K];
2750 return r;
2751}
2752//----------------------------------------------------------------------
2753// Grad Scalar/Cell -> Vektor/Vert
2754// (cellSpacings[I,J,K]->[I-1,....] 1/20/1998 tjw)
2755// (reverted to cellSpacings[I-1,J-1,K-1]->[I,....] 2/2/1998 tjw)
2756//----------------------------------------------------------------------
2757template < class T, class MFLOAT >
2761{
2762 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2763 BareField<Vektor<MFLOAT,1U>,1U>& cellSpacings = *(x.get_mesh().CellSpacings);
2764 const NDIndex<1U>& domain = r.getDomain();
2765 Index I = domain[0];
2766 r[I] = (x[I-1]*x.get_mesh().Dvc[0] +
2767 x[I ]*x.get_mesh().Dvc[1])/cellSpacings[I];
2768 return r;
2769}
2770//----------------------------------------------------------------------
2771template < class T, class MFLOAT >
2775{
2776 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2777 BareField<Vektor<MFLOAT,2U>,2U>& cellSpacings = *(x.get_mesh().CellSpacings);
2778 const NDIndex<2U>& domain = r.getDomain();
2779 Index I = domain[0];
2780 Index J = domain[1];
2781 r[I][J] = (x[I-1][J-1]*x.get_mesh().Dvc[0] +
2782 x[I ][J-1]*x.get_mesh().Dvc[1] +
2783 x[I-1][J ]*x.get_mesh().Dvc[2] +
2784 x[I ][J ]*x.get_mesh().Dvc[3])/cellSpacings[I][J];
2785 return r;
2786}
2787//----------------------------------------------------------------------
2788template < class T, class MFLOAT >
2792{
2793 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2794 BareField<Vektor<MFLOAT,3U>,3U>& cellSpacings = *(x.get_mesh().CellSpacings);
2795 const NDIndex<3U>& domain = r.getDomain();
2796 Index I = domain[0];
2797 Index J = domain[1];
2798 Index K = domain[2];
2799 Vektor<MFLOAT,3U> dvc[1<<3U];
2800 for (unsigned int d=0; d < 1<<3U; d++) dvc[d] = x.get_mesh().Dvc[d];
2801 r[I][J][K] = (x[I-1][J-1][K-1]*dvc[0] +
2802 x[I ][J-1][K-1]*dvc[1] +
2803 x[I-1][J ][K-1]*dvc[2] +
2804 x[I ][J ][K-1]*dvc[3] +
2805 x[I-1][J-1][K ]*dvc[4] +
2806 x[I ][J-1][K ]*dvc[5] +
2807 x[I-1][J ][K ]*dvc[6] +
2808 x[I ][J ][K ]*dvc[7])/
2809 cellSpacings[I][J][K];
2810 return r;
2811}
2812
2813// TJW: I've attempted to update these differential operators from uniform
2814// cartesian implementations to workfor (nonuniform) Cartesian class, but they
2815// may really need to get changed in other ways, such as something besides
2816// simple centered differncing for cell-cell and vert-vert cases. Flag these
2817// operator implementations since they may be a source of trouble until tested
2818// and debugged further. The Grad() operators, especially, may be wrong. All
2819// that being said, I have tested quite a few of these, including the following
2820// two needed by Tecolote: 1) Div SymTenzor/Cell->Vektor/Vert 2) Grad
2821// Vektor/Vert->Tenzor/Cell
2822
2823// BEGIN FLAGGED DIFFOPS REGION II
2824
2825//----------------------------------------------------------------------
2826// Grad Scalar/Vert -> Vektor/Vert (???right? tjw 1/16/98)
2827//----------------------------------------------------------------------
2828template < class T, class MFLOAT >
2832{
2833 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2834 BareField<Vektor<MFLOAT,1U>,1U>& vertSpacings =
2835 *(x.get_mesh().VertSpacings);
2836 const NDIndex<1U>& domain = r.getDomain();
2837 Index I = domain[0];
2838
2840 idx[0] = 1.0;
2841
2842 r[I] = idx*((x[I+1] - x[I-1])/(vertSpacings[I] + vertSpacings[I-1]));
2843 return r;
2844}
2845//----------------------------------------------------------------------
2846template < class T, class MFLOAT >
2850{
2851 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2852 BareField<Vektor<MFLOAT,2U>,2U>& vertSpacings =
2853 *(x.get_mesh().VertSpacings);
2854 const NDIndex<2U>& domain = r.getDomain();
2855 Index I = domain[0];
2856 Index J = domain[1];
2857
2858 Vektor<MFLOAT,2U> idx,idy;
2859 idx[0] = 1.0;
2860 idx[1] = 0.0;
2861 idy[0] = 0.0;
2862 idy[1] = 1.0;
2863
2864 r[I][J] =
2865 idx*((x[I+1][J ] - x[I-1][J ])/
2866 (vertSpacings[I][J] + vertSpacings[I-1][J])) +
2867 idy*((x[I ][J+1] - x[I ][J-1])/
2868 (vertSpacings[I][J] + vertSpacings[I][J-1]));
2869 return r;
2870}
2871//----------------------------------------------------------------------
2872template < class T, class MFLOAT >
2876{
2877 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2878 BareField<Vektor<MFLOAT,3U>,3U>& vertSpacings =
2879 *(x.get_mesh().VertSpacings);
2880 const NDIndex<3U>& domain = r.getDomain();
2881 Index I = domain[0];
2882 Index J = domain[1];
2883 Index K = domain[2];
2884
2885 Vektor<MFLOAT,3U> idx,idy,idz;
2886 idx[0] = 1.0;
2887 idx[1] = 0.0;
2888 idx[2] = 0.0;
2889 idy[0] = 0.0;
2890 idy[1] = 1.0;
2891 idy[2] = 0.0;
2892 idz[0] = 0.0;
2893 idz[1] = 0.0;
2894 idz[2] = 1.0;
2895
2896 r[I][J][K] =
2897 idx*((x[I+1][J ][K ] - x[I-1][J ][K ])/
2898 (vertSpacings[I][J][K] + vertSpacings[I-1][J][K])) +
2899 idy*((x[I ][J+1][K ] - x[I ][J-1][K ])/
2900 (vertSpacings[I][J][K] + vertSpacings[I][J-1][K])) +
2901 idz*((x[I ][J ][K+1] - x[I ][J ][K-1])/
2902 (vertSpacings[I][J][K] + vertSpacings[I][J][K-1]));
2903 return r;
2904}
2905//----------------------------------------------------------------------
2906// Grad Scalar/Cell -> Vektor/Cell
2907//----------------------------------------------------------------------
2908template < class T, class MFLOAT >
2912{
2913 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2914 BareField<Vektor<MFLOAT,1U>,1U>& cellSpacings =
2915 *(x.get_mesh().CellSpacings);
2916 const NDIndex<1U>& domain = r.getDomain();
2917 Index I = domain[0];
2918
2920 idx[0] = 1.0;
2921
2922 r[I] = idx*((x[I+1] - x[I-1])/(cellSpacings[I] + cellSpacings[I+1]));
2923 return r;
2924}
2925//----------------------------------------------------------------------
2926template < class T, class MFLOAT >
2930{
2931 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2932 BareField<Vektor<MFLOAT,2U>,2U>& cellSpacings =
2933 *(x.get_mesh().CellSpacings);
2934 const NDIndex<2U>& domain = r.getDomain();
2935 Index I = domain[0];
2936 Index J = domain[1];
2937
2938 Vektor<MFLOAT,2U> idx,idy;
2939 idx[0] = 1.0;
2940 idx[1] = 0.0;
2941 idy[0] = 0.0;
2942 idy[1] = 1.0;
2943
2944 r[I][J] =
2945 idx*((x[I+1][J ] - x[I-1][J ])/
2946 (cellSpacings[I][J] + cellSpacings[I+1][J])) +
2947 idy*((x[I ][J+1] - x[I ][J-1])/
2948 (cellSpacings[I][J] + cellSpacings[I][J+1]));
2949 return r;
2950}
2951//----------------------------------------------------------------------
2952template < class T, class MFLOAT >
2956{
2957 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2958 BareField<Vektor<MFLOAT,3U>,3U>& cellSpacings =
2959 *(x.get_mesh().CellSpacings);
2960 const NDIndex<3U>& domain = r.getDomain();
2961 Index I = domain[0];
2962 Index J = domain[1];
2963 Index K = domain[2];
2964
2965 Vektor<MFLOAT,3U> idx,idy,idz;
2966 idx[0] = 1.0;
2967 idx[1] = 0.0;
2968 idx[2] = 0.0;
2969 idy[0] = 0.0;
2970 idy[1] = 1.0;
2971 idy[2] = 0.0;
2972 idz[0] = 0.0;
2973 idz[1] = 0.0;
2974 idz[2] = 1.0;
2975
2976 r[I][J][K] =
2977 idx*((x[I+1][J ][K ] - x[I-1][J ][K ])/
2978 (cellSpacings[I][J][K] + cellSpacings[I+1][J][K])) +
2979 idy*((x[I ][J+1][K ] - x[I ][J-1][K ])/
2980 (cellSpacings[I][J][K] + cellSpacings[I][J+1][K])) +
2981 idz*((x[I ][J ][K+1] - x[I ][J ][K-1])/
2982 (cellSpacings[I][J][K] + cellSpacings[I][J][K+1]));
2983 return r;
2984}
2985//----------------------------------------------------------------------
2986// Grad Vektor/Vert -> Tenzor/Cell (???o.p. right thing? tjw 1/20/1998)
2987//----------------------------------------------------------------------
2988template < class T, class MFLOAT >
2992{
2993 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
2994 BareField<Vektor<MFLOAT,1U>,1U>& vS = *(x.get_mesh().VertSpacings);
2995 const NDIndex<1U>& domain = r.getDomain();
2996 Index I = domain[0];
2997 r[I] =
2998 outerProduct(x[I ], x.get_mesh().Dvc[0]/vS[I]) +
2999 outerProduct(x[I+1], x.get_mesh().Dvc[1]/vS[I]);
3000 return r;
3001}
3002//----------------------------------------------------------------------
3003template < class T, class MFLOAT >
3007{
3008 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
3009 BareField<Vektor<MFLOAT,2U>,2U>& vS = *(x.get_mesh().VertSpacings);
3010 const NDIndex<2U>& domain = r.getDomain();
3011 Index I = domain[0];
3012 Index J = domain[1];
3013 r[I][J] =
3014 outerProduct(x[I ][J ], x.get_mesh().Dvc[0]/vS[I][J]) +
3015 outerProduct(x[I+1][J ], x.get_mesh().Dvc[1]/vS[I][J]) +
3016 outerProduct(x[I ][J+1], x.get_mesh().Dvc[2]/vS[I][J]) +
3017 outerProduct(x[I+1][J+1], x.get_mesh().Dvc[3]/vS[I][J]);
3018 return r;
3019}
3020//----------------------------------------------------------------------
3021template < class T, class MFLOAT >
3025{
3026 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
3027 BareField<Vektor<MFLOAT,3U>,3U>& vS = *(x.get_mesh().VertSpacings);
3028 const NDIndex<3U>& domain = r.getDomain();
3029 Index I = domain[0];
3030 Index J = domain[1];
3031 Index K = domain[2];
3032 r[I][J][K] =
3033 outerProduct(x[I ][J ][K ], x.get_mesh().Dvc[0]/vS[I][J][K]) +
3034 outerProduct(x[I+1][J ][K ], x.get_mesh().Dvc[1]/vS[I][J][K]) +
3035 outerProduct(x[I ][J+1][K ], x.get_mesh().Dvc[2]/vS[I][J][K]) +
3036 outerProduct(x[I+1][J+1][K ], x.get_mesh().Dvc[3]/vS[I][J][K]) +
3037 outerProduct(x[I ][J ][K+1], x.get_mesh().Dvc[4]/vS[I][J][K]) +
3038 outerProduct(x[I+1][J ][K+1], x.get_mesh().Dvc[5]/vS[I][J][K]) +
3039 outerProduct(x[I ][J+1][K+1], x.get_mesh().Dvc[6]/vS[I][J][K]) +
3040 outerProduct(x[I+1][J+1][K+1], x.get_mesh().Dvc[7]/vS[I][J][K]);
3041
3042 return r;
3043}
3044//----------------------------------------------------------------------
3045// Grad Vektor/Cell -> Tenzor/Vert (???o.p. right thing? tjw 1/20/1998)
3046// (cellSpacings[I,J,K]->[I-1,....] 1/20/1998 tjw)
3047//----------------------------------------------------------------------
3048template < class T, class MFLOAT >
3052{
3053 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
3054 BareField<Vektor<MFLOAT,1U>,1U>& cellSpacings = *(x.get_mesh().CellSpacings);
3055 const NDIndex<1U>& domain = r.getDomain();
3056 Index I = domain[0];
3057 r[I] =
3058 outerProduct(x[I-1], x.get_mesh().Dvc[0]/cellSpacings[I-1]) +
3059 outerProduct(x[I ], x.get_mesh().Dvc[1]/cellSpacings[I-1]);
3060 return r;
3061}
3062//----------------------------------------------------------------------
3063template < class T, class MFLOAT >
3067{
3068 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
3069 BareField<Vektor<MFLOAT,2U>,2U>& cS = *(x.get_mesh().CellSpacings);
3070 const NDIndex<2U>& domain = r.getDomain();
3071 Index I = domain[0];
3072 Index J = domain[1];
3073 r[I][J] =
3074 outerProduct(x[I-1][J-1], x.get_mesh().Dvc[0]/cS[I-1][J-1]) +
3075 outerProduct(x[I ][J-1], x.get_mesh().Dvc[1]/cS[I-1][J-1]) +
3076 outerProduct(x[I-1][J ], x.get_mesh().Dvc[2]/cS[I-1][J-1]) +
3077 outerProduct(x[I ][J ], x.get_mesh().Dvc[3]/cS[I-1][J-1]);
3078 return r;
3079}
3080//----------------------------------------------------------------------
3081template < class T, class MFLOAT >
3085{
3086 PAssert_EQ(x.get_mesh().hasSpacingFields, true);
3087 BareField<Vektor<MFLOAT,3U>,3U>& cS = *(x.get_mesh().CellSpacings);
3088 const NDIndex<3U>& domain = r.getDomain();
3089 Index I = domain[0];
3090 Index J = domain[1];
3091 Index K = domain[2];
3092 r[I][J][K] =
3093 outerProduct(x[I-1][J-1][K-1], x.get_mesh().Dvc[0]/cS[I-1][J-1][K-1]) +
3094 outerProduct(x[I ][J-1][K-1], x.get_mesh().Dvc[1]/cS[I-1][J-1][K-1]) +
3095 outerProduct(x[I-1][J ][K-1], x.get_mesh().Dvc[2]/cS[I-1][J-1][K-1]) +
3096 outerProduct(x[I ][J ][K-1], x.get_mesh().Dvc[3]/cS[I-1][J-1][K-1]) +
3097 outerProduct(x[I-1][J-1][K ], x.get_mesh().Dvc[4]/cS[I-1][J-1][K-1]) +
3098 outerProduct(x[I ][J-1][K ], x.get_mesh().Dvc[5]/cS[I-1][J-1][K-1]) +
3099 outerProduct(x[I-1][J ][K ], x.get_mesh().Dvc[6]/cS[I-1][J-1][K-1]) +
3100 outerProduct(x[I ][J ][K ], x.get_mesh().Dvc[7]/cS[I-1][J-1][K-1]);
3101 return r;
3102}
3103
3104// END FLAGGED DIFFOPS REGION II
3105
3106namespace IPPL {
3107
3108//----------------------------------------------------------------------
3109// Weighted average Cell to Vert
3110//----------------------------------------------------------------------
3111template < class T1, class T2, class MFLOAT >
3116{
3117 const NDIndex<1U>& domain = r.getDomain();
3118 Index I = domain[0];
3119 r[I] = (x[I-1]*w[I-1] + x[I ]*w[I ])/(w[I-1] + w[I ]);
3120 return r;
3121}
3122//----------------------------------------------------------------------
3123template < class T1, class T2, class MFLOAT >
3128{
3129 const NDIndex<2U>& domain = r.getDomain();
3130 Index I = domain[0];
3131 Index J = domain[1];
3132
3133 r[I][J] = (x[I-1][J-1] * w[I-1][J-1] +
3134 x[I ][J-1] * w[I ][J-1] +
3135 x[I-1][J ] * w[I-1][J ] +
3136 x[I ][J ] * w[I ][J ])/
3137 (w[I-1][J-1] +
3138 w[I ][J-1] +
3139 w[I-1][J ] +
3140 w[I ][J ]);
3141 return r;
3142}
3143//----------------------------------------------------------------------
3144template < class T1, class T2, class MFLOAT >
3149{
3150 const NDIndex<3U>& domain = r.getDomain();
3151 Index I = domain[0];
3152 Index J = domain[1];
3153 Index K = domain[2];
3154
3155 r[I][J][K] = (x[I-1][J-1][K-1] * w[I-1][J-1][K-1] +
3156 x[I ][J-1][K-1] * w[I ][J-1][K-1] +
3157 x[I-1][J ][K-1] * w[I-1][J ][K-1] +
3158 x[I ][J ][K-1] * w[I ][J ][K-1] +
3159 x[I-1][J-1][K ] * w[I-1][J-1][K ] +
3160 x[I ][J-1][K ] * w[I ][J-1][K ] +
3161 x[I-1][J ][K ] * w[I-1][J ][K ] +
3162 x[I ][J ][K ] * w[I ][J ][K ] )/
3163 (w[I-1][J-1][K-1] +
3164 w[I ][J-1][K-1] +
3165 w[I-1][J ][K-1] +
3166 w[I ][J ][K-1] +
3167 w[I-1][J-1][K ] +
3168 w[I ][J-1][K ] +
3169 w[I-1][J ][K ] +
3170 w[I ][J ][K ]);
3171 return r;
3172}
3173//----------------------------------------------------------------------
3174// Weighted average Vert to Cell
3175// N.B.: won't work except for unit-stride (& zero-base?) Field's.
3176//----------------------------------------------------------------------
3177template < class T1, class T2, class MFLOAT >
3182{
3183 const NDIndex<1U>& domain = r.getDomain();
3184 Index I = domain[0];
3185 r[I] = (x[I+1]*w[I+1] + x[I ]*w[I ])/(w[I+1] + w[I ]);
3186 return r;
3187}
3188//----------------------------------------------------------------------
3189template < class T1, class T2, class MFLOAT >
3194{
3195 const NDIndex<2U>& domain = r.getDomain();
3196 Index I = domain[0];
3197 Index J = domain[1];
3198
3199 r[I][J] = (x[I+1][J+1] * w[I+1][J+1] +
3200 x[I ][J+1] * w[I ][J+1] +
3201 x[I+1][J ] * w[I+1][J ] +
3202 x[I ][J ] * w[I ][J ])/
3203 (w[I+1][J+1] +
3204 w[I ][J+1] +
3205 w[I+1][J ] +
3206 w[I ][J ]);
3207 return r;
3208}
3209//----------------------------------------------------------------------
3210template < class T1, class T2, class MFLOAT >
3215{
3216 const NDIndex<3U>& domain = r.getDomain();
3217 Index I = domain[0];
3218 Index J = domain[1];
3219 Index K = domain[2];
3220
3221 r[I][J][K] = (x[I+1][J+1][K+1] * w[I+1][J+1][K+1] +
3222 x[I ][J+1][K+1] * w[I ][J+1][K+1] +
3223 x[I+1][J ][K+1] * w[I+1][J ][K+1] +
3224 x[I ][J ][K+1] * w[I ][J ][K+1] +
3225 x[I+1][J+1][K ] * w[I+1][J+1][K ] +
3226 x[I ][J+1][K ] * w[I ][J+1][K ] +
3227 x[I+1][J ][K ] * w[I+1][J ][K ] +
3228 x[I ][J ][K ] * w[I ][J ][K ])/
3229 (w[I+1][J+1][K+1] +
3230 w[I ][J+1][K+1] +
3231 w[I+1][J ][K+1] +
3232 w[I ][J ][K+1] +
3233 w[I+1][J+1][K ] +
3234 w[I ][J+1][K ] +
3235 w[I+1][J ][K ] +
3236 w[I ][J ][K ]);
3237 return r;
3238}
3239
3240//----------------------------------------------------------------------
3241// Unweighted average Cell to Vert
3242//----------------------------------------------------------------------
3243template < class T1, class MFLOAT >
3247{
3248 const NDIndex<1U>& domain = r.getDomain();
3249 Index I = domain[0];
3250 r[I] = 0.5*(x[I-1] + x[I ]);
3251 return r;
3252}
3253//----------------------------------------------------------------------
3254template < class T1, class MFLOAT >
3258{
3259 const NDIndex<2U>& domain = r.getDomain();
3260 Index I = domain[0];
3261 Index J = domain[1];
3262 r[I][J] = 0.25*(x[I-1][J-1] + x[I ][J-1] + x[I-1][J ] + x[I ][J ]);
3263 return r;
3264}
3265//----------------------------------------------------------------------
3266template < class T1, class MFLOAT >
3270{
3271 const NDIndex<3U>& domain = r.getDomain();
3272 Index I = domain[0];
3273 Index J = domain[1];
3274 Index K = domain[2];
3275 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] +
3276 x[I ][J ][K-1] + x[I-1][J-1][K ] + x[I ][J-1][K ] +
3277 x[I-1][J ][K ] + x[I ][J ][K ]);
3278 return r;
3279}
3280//----------------------------------------------------------------------
3281// Unweighted average Vert to Cell
3282// N.B.: won't work except for unit-stride (& zero-base?) Field's.
3283//----------------------------------------------------------------------
3284template < class T1, class MFLOAT >
3288{
3289 const NDIndex<1U>& domain = r.getDomain();
3290 Index I = domain[0];
3291 r[I] = 0.5*(x[I+1] + x[I ]);
3292 return r;
3293}
3294//----------------------------------------------------------------------
3295template < class T1, class MFLOAT >
3299{
3300 const NDIndex<2U>& domain = r.getDomain();
3301 Index I = domain[0];
3302 Index J = domain[1];
3303 r[I][J] = 0.25*(x[I+1][J+1] + x[I ][J+1] + x[I+1][J ] + x[I ][J ]);
3304 return r;
3305}
3306//----------------------------------------------------------------------
3307template < class T1, class MFLOAT >
3311{
3312 const NDIndex<3U>& domain = r.getDomain();
3313 Index I = domain[0];
3314 Index J = domain[1];
3315 Index K = domain[2];
3316 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] +
3317 x[I ][J ][K+1] + x[I+1][J+1][K ] + x[I ][J+1][K ] +
3318 x[I+1][J ][K ] + x[I ][J ][K ]);
3319 return r;
3320}
3321
3322}
3323
3324/***************************************************************************
3325 * $RCSfile: Cartesian.cpp,v $ $Author: adelmann $
3326 * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:27 $
3327 * IPPL_VERSION_ID: $Id: Cartesian.cpp,v 1.1.1.1 2003/01/23 07:40:27 adelmann Exp $
3328 ***************************************************************************/
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
Definition: Vector3D.cpp:118
PartBunchBase< T, Dim >::ConstIterator begin(PartBunchBase< T, Dim > const &bunch)
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< T, 1U, Cartesian< 1U, MFLOAT >, Cell > & Div(Field< Vektor< T, 1U >, 1U, Cartesian< 1U, MFLOAT >, Vert > &x, Field< T, 1U, Cartesian< 1U, MFLOAT >, Cell > &r)
Definition: Cartesian.hpp:2192
void PETE_apply(OpMeshPeriodic< T >, T &a, T b)
Definition: Cartesian.hpp:816
Field< Vektor< T, 1U >, 1U, Cartesian< 1U, MFLOAT >, Cell > & Grad(Field< T, 1U, Cartesian< 1U, MFLOAT >, Vert > &x, Field< Vektor< T, 1U >, 1U, Cartesian< 1U, MFLOAT >, Cell > &r)
Definition: Cartesian.hpp:2702
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 PAssert_EQ(a, b)
Definition: PAssert.h:104
#define ERRORMSG(msg)
Definition: IpplInfo.h:350
const T * find(const T table[], const std::string &name)
Look up name.
Definition: TFind.h:34
constexpr double e
The value of.
Definition: Physics.h:39
std::string::iterator iterator
Definition: MSLang.h:16
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 end() const
Definition: BareField.h:241
iterator_if begin_if()
Definition: BareField.h:100
ac_id_larray::iterator iterator_if
Definition: BareField.h:92
void Uncompress() const
Definition: BareField.hpp:1005
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
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
Field< Vektor< MFLOAT, Dim >, Dim, Cartesian< Dim, MFLOAT >, Cell > & getDeltaVertexField(Field< Vektor< MFLOAT, Dim >, Dim, Cartesian< Dim, MFLOAT >, Cell > &) const
Definition: Cartesian.hpp:1861
void get_meshSpacing(unsigned d, MFLOAT *spacings) const
Definition: Cartesian.hpp:787
MFLOAT getCellRangeVolume(const NDIndex< Dim > &) const
Definition: Cartesian.hpp:1573
Field< Vektor< MFLOAT, Dim >, Dim, Cartesian< Dim, MFLOAT >, Vert > & getVertexPositionField(Field< Vektor< MFLOAT, Dim >, Dim, Cartesian< Dim, MFLOAT >, Vert > &) const
Definition: Cartesian.hpp:1755
NDIndex< Dim > getVertexBelow(const Vektor< MFLOAT, Dim > &) const
Definition: Cartesian.hpp:1671
Vektor< MFLOAT, Dim > getSurfaceNormal(const NDIndex< Dim > &, unsigned) const
Definition: Cartesian.hpp:1982
void set_meshSpacing(MFLOAT **const del)
Definition: Cartesian.hpp:748
void getSurfaceNormalFields(Field< Vektor< MFLOAT, Dim >, Dim, Cartesian< Dim, MFLOAT >, Cell > **) const
Definition: Cartesian.hpp:1956
Field< MFLOAT, Dim, Cartesian< Dim, MFLOAT >, Cell > & getCellVolumeField(Field< MFLOAT, Dim, Cartesian< Dim, MFLOAT >, Cell > &) const
Definition: Cartesian.hpp:1520
Vektor< MFLOAT, Dim > getDeltaCell(const NDIndex< Dim > &) const
Definition: Cartesian.hpp:1882
Field< Vektor< MFLOAT, Dim >, Dim, Cartesian< Dim, MFLOAT >, Cell > & getCellPositionField(Field< Vektor< MFLOAT, Dim >, Dim, Cartesian< Dim, MFLOAT >, Cell > &) const
Definition: Cartesian.hpp:1802
MFLOAT getCellVolume(const NDIndex< Dim > &) const
Definition: Cartesian.hpp:1503
Vektor< MFLOAT, Dim > getVertexPosition(const NDIndex< Dim > &) const
Definition: Cartesian.hpp:1732
void set_Dvc()
Definition: Cartesian.hpp:769
Vektor< MFLOAT, Dim > getCellPosition(const NDIndex< Dim > &) const
Definition: Cartesian.hpp:1778
void storeSpacingFields()
Definition: Cartesian.hpp:840
void set_MeshBC(unsigned face, MeshBC_E meshBCType)
Definition: Cartesian.hpp:2051
void set_origin(const Vektor< MFLOAT, Dim > &o)
Definition: Cartesian.hpp:723
MeshBC_E * get_MeshBC() const
Definition: Cartesian.hpp:2169
Cartesian()
Definition: Cartesian.h:42
void setup()
Definition: Cartesian.hpp:46
NDIndex< Dim > getNearestVertex(const Vektor< MFLOAT, Dim > &) const
Definition: Cartesian.hpp:1604
Vektor< MFLOAT, Dim > * getSurfaceNormals(const NDIndex< Dim > &) const
Definition: Cartesian.hpp:1938
Field< Vektor< MFLOAT, Dim >, Dim, Cartesian< Dim, MFLOAT >, Vert > & getDeltaCellField(Field< Vektor< MFLOAT, Dim >, Dim, Cartesian< Dim, MFLOAT >, Vert > &) const
Definition: Cartesian.hpp:1917
Vektor< MFLOAT, Dim > getDeltaVertex(const NDIndex< Dim > &) const
Definition: Cartesian.hpp:1827
Field< Vektor< MFLOAT, Dim >, Dim, Cartesian< Dim, MFLOAT >, Cell > & getSurfaceNormalField(Field< Vektor< MFLOAT, Dim >, Dim, Cartesian< Dim, MFLOAT >, Cell > &, unsigned) const
Definition: Cartesian.hpp:2013
void updateMeshSpacingGuards(int face)
Definition: Cartesian.hpp:2075
void print(std::ostream &)
Definition: Cartesian.hpp:1471
Vektor< MFLOAT, Dim > get_origin() const
Definition: Cartesian.hpp:740
void initialize(const NDIndex< Dim > &ndi)
Definition: Cartesian.hpp:382
MFLOAT getVertRangeVolume(const NDIndex< Dim > &) const
Definition: Cartesian.hpp:1542
OpMeshExtrapolate(T &o, T &s)
Definition: Cartesian.hpp:822
Definition: Centering.h:32
Definition: Centering.h:43
Definition: Mesh.h:35
MeshBC_E
Definition: Mesh.h:32
@ Periodic
Definition: Mesh.h:32
@ NoBC
Definition: Mesh.h:32
@ Reflective
Definition: Mesh.h:32