macro_element.cc
Go to the documentation of this file.
1// LIC// ====================================================================
2// LIC// This file forms part of oomph-lib, the object-oriented,
3// LIC// multi-physics finite-element library, available
4// LIC// at http://www.oomph-lib.org.
5// LIC//
6// LIC// Copyright (C) 2006-2022 Matthias Heil and Andrew Hazel
7// LIC//
8// LIC// This library is free software; you can redistribute it and/or
9// LIC// modify it under the terms of the GNU Lesser General Public
10// LIC// License as published by the Free Software Foundation; either
11// LIC// version 2.1 of the License, or (at your option) any later version.
12// LIC//
13// LIC// This library is distributed in the hope that it will be useful,
14// LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16// LIC// Lesser General Public License for more details.
17// LIC//
18// LIC// You should have received a copy of the GNU Lesser General Public
19// LIC// License along with this library; if not, write to the Free Software
20// LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21// LIC// 02110-1301 USA.
22// LIC//
23// LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
24// LIC//
25// LIC//====================================================================
26#include "macro_element.h"
27#include "domain.h"
28
29namespace oomph
30{
31 //=================================================================
32 /// Get global position r(S) at discrete time level t.
33 /// t=0: Present time; t>0: previous timestep.
34 //=================================================================
35 void QMacroElement<2>::macro_map(const double& t,
36 const Vector<double>& s,
38 {
39 using namespace QuadTreeNames;
40
41 Vector<double> bound_N(2);
42 Vector<double> bound_S(2);
43 Vector<double> bound_W(2);
44 Vector<double> bound_E(2);
45
46 Vector<double> diff_N(2);
47 Vector<double> diff_S(2);
48 Vector<double> diff_W(2);
49 Vector<double> diff_E(2);
50
51 Vector<double> f_rect(2);
52
53 Vector<double> corner_SE(2);
54 Vector<double> corner_SW(2);
55 Vector<double> corner_NE(2);
56 Vector<double> corner_NW(2);
57
58 Vector<double> edge_N(2);
59 Vector<double> edge_S(2);
60
61 Vector<double> zeta(1);
62
63 // Determine Vectors to corners
64 zeta[0] = 1.0;
66 t, Macro_element_number, QuadTreeNames::S, zeta, corner_SE);
67 zeta[0] = -1.0;
69 t, Macro_element_number, QuadTreeNames::S, zeta, corner_SW);
70 zeta[0] = 1.0;
72 t, Macro_element_number, QuadTreeNames::N, zeta, corner_NE);
73 zeta[0] = -1.0;
75 t, Macro_element_number, QuadTreeNames::N, zeta, corner_NW);
76
77
78 // Get the position on the N/S/W/E edges
79 zeta[0] = s[0];
81 t, Macro_element_number, QuadTreeNames::N, zeta, bound_N);
82 zeta[0] = s[0];
84 t, Macro_element_number, QuadTreeNames::S, zeta, bound_S);
85 zeta[0] = s[1];
87 t, Macro_element_number, QuadTreeNames::W, zeta, bound_W);
88 zeta[0] = s[1];
90 t, Macro_element_number, QuadTreeNames::E, zeta, bound_E);
91
92
93 for (int i = 0; i < 2; i++)
94 {
95 // Position on the straight S/W edges of the rectangle formed
96 // by the corner points
97 edge_S[i] =
98 corner_SW[i] + (corner_SE[i] - corner_SW[i]) * 0.5 * (s[0] + 1.0);
99 edge_N[i] =
100 corner_NW[i] + (corner_NE[i] - corner_NW[i]) * 0.5 * (s[0] + 1.0);
101
102 // Position inside rectangle
103 f_rect[i] = edge_S[i] + (edge_N[i] - edge_S[i]) * 0.5 * (s[1] + 1.0);
104
105 // Get difference between curved edge and point in rectangle
106 diff_N[i] = bound_N[i] - f_rect[i];
107 diff_S[i] = bound_S[i] - f_rect[i];
108 diff_E[i] = bound_E[i] - f_rect[i];
109 diff_W[i] = bound_W[i] - f_rect[i];
110
111 // Map it...
112 r[i] = f_rect[i] + diff_S[i] * (1.0 - 0.5 * (s[1] + 1.0)) +
113 diff_N[i] * 0.5 * (s[1] + 1.0) +
114 diff_W[i] * (1.0 - 0.5 * (s[0] + 1.0)) +
115 diff_E[i] * 0.5 * (s[0] + 1.0);
116 }
117 }
118
119 //=================================================================
120 /// Get global position r(S) at discrete time level t.
121 /// t=0: Present time; t>0: previous timestep.
122 //=================================================================
123 void QMacroElement<2>::macro_map(const unsigned& t,
124 const Vector<double>& S,
126 {
127 using namespace QuadTreeNames;
128
129 Vector<double> bound_N(2);
130 Vector<double> bound_S(2);
131 Vector<double> bound_W(2);
132 Vector<double> bound_E(2);
133
134 Vector<double> diff_N(2);
135 Vector<double> diff_S(2);
136 Vector<double> diff_W(2);
137 Vector<double> diff_E(2);
138
139 Vector<double> f_rect(2);
140
141 Vector<double> corner_SE(2);
142 Vector<double> corner_SW(2);
143 Vector<double> corner_NE(2);
144 Vector<double> corner_NW(2);
145
146 Vector<double> edge_N(2);
147 Vector<double> edge_S(2);
148
149 Vector<double> zeta(1);
150
151 // Determine Vectors to corners
152 zeta[0] = 1.0;
154 t, Macro_element_number, QuadTreeNames::S, zeta, corner_SE);
155 zeta[0] = -1.0;
157 t, Macro_element_number, QuadTreeNames::S, zeta, corner_SW);
158 zeta[0] = 1.0;
160 t, Macro_element_number, QuadTreeNames::N, zeta, corner_NE);
161 zeta[0] = -1.0;
163 t, Macro_element_number, QuadTreeNames::N, zeta, corner_NW);
164
165
166 // Get the position on the N/S/W/E edges
167 zeta[0] = S[0];
169 t, Macro_element_number, QuadTreeNames::N, zeta, bound_N);
170 zeta[0] = S[0];
172 t, Macro_element_number, QuadTreeNames::S, zeta, bound_S);
173 zeta[0] = S[1];
175 t, Macro_element_number, QuadTreeNames::W, zeta, bound_W);
176 zeta[0] = S[1];
178 t, Macro_element_number, QuadTreeNames::E, zeta, bound_E);
179
180
181 for (int i = 0; i < 2; i++)
182 {
183 // Position on the straight S/W edges of the rectangle formed
184 // by the corner points
185 edge_S[i] =
186 corner_SW[i] + (corner_SE[i] - corner_SW[i]) * 0.5 * (S[0] + 1.0);
187 edge_N[i] =
188 corner_NW[i] + (corner_NE[i] - corner_NW[i]) * 0.5 * (S[0] + 1.0);
189
190 // Position inside rectangle
191 f_rect[i] = edge_S[i] + (edge_N[i] - edge_S[i]) * 0.5 * (S[1] + 1.0);
192
193 // Get difference between curved edge and point in rectangle
194 diff_N[i] = bound_N[i] - f_rect[i];
195 diff_S[i] = bound_S[i] - f_rect[i];
196 diff_E[i] = bound_E[i] - f_rect[i];
197 diff_W[i] = bound_W[i] - f_rect[i];
198
199 // Map it...
200 r[i] = f_rect[i] + diff_S[i] * (1.0 - 0.5 * (S[1] + 1.0)) +
201 diff_N[i] * 0.5 * (S[1] + 1.0) +
202 diff_W[i] * (1.0 - 0.5 * (S[0] + 1.0)) +
203 diff_E[i] * 0.5 * (S[0] + 1.0);
204 }
205 }
206
207
208 //=================================================================
209 /// Output all macro element boundaries as tecplot zones
210 //=================================================================
212 const unsigned& nplot)
213 {
214 using namespace QuadTreeNames;
215
216 Vector<double> s(1);
217 Vector<double> f(2);
218 // Dump at present time
219 unsigned t = 0;
220 for (unsigned idirect = N; idirect <= W; idirect++)
221 {
222 outfile << "ZONE I=" << nplot << std::endl;
223 for (unsigned j = 0; j < nplot; j++)
224 {
225 s[0] = -1.0 + 2.0 * double(j) / double(nplot - 1);
227 t, Macro_element_number, idirect, s, f);
228 outfile << f[0] << " " << f[1] << std::endl;
229 }
230 }
231 }
232
233
234 //=============================================================================
235 /// Assembles the jacobian of the mapping from the macro coordinates to
236 /// the global coordinates
237 //=============================================================================
239 const unsigned& t, const Vector<double>& S, DenseMatrix<double>& jacobian)
240 {
241 using namespace QuadTreeNames;
242
243 Vector<double> bound_N(2);
244 Vector<double> bound_S(2);
245 Vector<double> bound_W(2);
246 Vector<double> bound_E(2);
247
248 Vector<double> dbound_N(2);
249 Vector<double> dbound_S(2);
250 Vector<double> dbound_E(2);
251 Vector<double> dbound_W(2);
252
253 Vector<double> corner_SE(2);
254 Vector<double> corner_SW(2);
255 Vector<double> corner_NE(2);
256 Vector<double> corner_NW(2);
257
258 Vector<double> zeta(1);
259
260
261 // Determine Vectors to corners
262 zeta[0] = 1.0;
264 t, Macro_element_number, QuadTreeNames::S, zeta, corner_SE);
265 zeta[0] = -1.0;
267 t, Macro_element_number, QuadTreeNames::S, zeta, corner_SW);
268 zeta[0] = 1.0;
270 t, Macro_element_number, QuadTreeNames::N, zeta, corner_NE);
271 zeta[0] = -1.0;
273 t, Macro_element_number, QuadTreeNames::N, zeta, corner_NW);
274
275
276 // Get the position and first derivativeson the N/S/W/E edges
277 zeta[0] = S[0];
279 t, Macro_element_number, QuadTreeNames::N, zeta, bound_N);
281 t, Macro_element_number, QuadTreeNames::N, zeta, dbound_N);
282 zeta[0] = S[0];
284 t, Macro_element_number, QuadTreeNames::S, zeta, bound_S);
286 t, Macro_element_number, QuadTreeNames::S, zeta, dbound_S);
287 zeta[0] = S[1];
289 t, Macro_element_number, QuadTreeNames::W, zeta, bound_W);
291 t, Macro_element_number, QuadTreeNames::W, zeta, dbound_W);
292 zeta[0] = S[1];
294 t, Macro_element_number, QuadTreeNames::E, zeta, bound_E);
296 t, Macro_element_number, QuadTreeNames::E, zeta, dbound_E);
297
298
299 // dr0/dm0
300 jacobian(0, 0) =
301 0.25 * (corner_SW[0] - corner_SE[0] + corner_NW[0] - corner_NE[0] -
302 corner_NE[0] * S[1] + corner_NW[0] * S[1] + corner_SE[0] * S[1] -
303 corner_SW[0] * S[1]) +
304 0.5 * (dbound_S[0] + dbound_N[0] - bound_W[0] + bound_E[0] -
305 dbound_S[0] * S[1] + dbound_N[0] * S[1]);
306 // dr1/dm0
307 jacobian(0, 1) =
308 0.25 * (corner_SW[1] - corner_SE[1] + corner_NW[1] - corner_NE[1] -
309 corner_NE[1] * S[1] + corner_NW[1] * S[1] + corner_SE[1] * S[1] -
310 corner_SW[1] * S[1]) +
311 0.5 * (dbound_S[1] + dbound_N[1] - bound_W[1] + bound_E[1] -
312 dbound_S[1] * S[1] + dbound_N[1] * S[1]);
313 // dr0/dm1
314 jacobian(1, 0) =
315 0.25 * (corner_SW[0] + corner_SE[0] - corner_NW[0] - corner_NE[0] +
316 corner_SE[0] * S[0] - corner_SW[0] * S[0] - corner_NE[0] * S[0] +
317 corner_NW[0] * S[0]) +
318 0.5 * (-bound_S[0] + bound_N[0] + dbound_W[0] + dbound_E[0] -
319 dbound_W[0] * S[0] + dbound_E[0] * S[0]);
320 // dr1/dm1
321 jacobian(1, 1) =
322 0.25 * (corner_SW[1] + corner_SE[1] - corner_NW[1] - corner_NE[1] +
323 corner_SE[1] * S[0] - corner_SW[1] * S[0] - corner_NE[1] * S[0] +
324 corner_NW[1] * S[0]) +
325 0.5 * (-bound_S[1] + bound_N[1] + dbound_W[1] + dbound_E[1] -
326 dbound_W[1] * S[0] + dbound_E[1] * S[0]);
327 }
328
329
330 //=============================================================================
331 /// Assembles the second derivative jacobian of the mapping from the
332 /// macro coordinates to global coordinates x
333 //=============================================================================
335 const unsigned& t, const Vector<double>& S, DenseMatrix<double>& jacobian2)
336 {
337 using namespace QuadTreeNames;
338
339 Vector<double> bound_N(2);
340 Vector<double> bound_S(2);
341 Vector<double> bound_W(2);
342 Vector<double> bound_E(2);
343
344 Vector<double> dbound_N(2);
345 Vector<double> dbound_S(2);
346 Vector<double> dbound_E(2);
347 Vector<double> dbound_W(2);
348
349 Vector<double> d2bound_N(2);
350 Vector<double> d2bound_S(2);
351 Vector<double> d2bound_E(2);
352 Vector<double> d2bound_W(2);
353
354 Vector<double> corner_SE(2);
355 Vector<double> corner_SW(2);
356 Vector<double> corner_NE(2);
357 Vector<double> corner_NW(2);
358
359 Vector<double> zeta(1);
360
361
362 // Determine Vectors to corners
363 zeta[0] = 1.0;
365 t, Macro_element_number, QuadTreeNames::S, zeta, corner_SE);
366 zeta[0] = -1.0;
368 t, Macro_element_number, QuadTreeNames::S, zeta, corner_SW);
369 zeta[0] = 1.0;
371 t, Macro_element_number, QuadTreeNames::N, zeta, corner_NE);
372 zeta[0] = -1.0;
374 t, Macro_element_number, QuadTreeNames::N, zeta, corner_NW);
375
376
377 // Get the position and first derivativeson the N/S/W/E edges
378 zeta[0] = S[0];
380 t, Macro_element_number, QuadTreeNames::N, zeta, bound_N);
382 t, Macro_element_number, QuadTreeNames::N, zeta, dbound_N);
384 t, Macro_element_number, QuadTreeNames::N, zeta, d2bound_N);
385 zeta[0] = S[0];
387 t, Macro_element_number, QuadTreeNames::S, zeta, bound_S);
389 t, Macro_element_number, QuadTreeNames::S, zeta, dbound_S);
391 t, Macro_element_number, QuadTreeNames::S, zeta, d2bound_S);
392 zeta[0] = S[1];
394 t, Macro_element_number, QuadTreeNames::W, zeta, bound_W);
396 t, Macro_element_number, QuadTreeNames::W, zeta, dbound_W);
398 t, Macro_element_number, QuadTreeNames::W, zeta, d2bound_W);
399 zeta[0] = S[1];
401 t, Macro_element_number, QuadTreeNames::E, zeta, bound_E);
403 t, Macro_element_number, QuadTreeNames::E, zeta, dbound_E);
405 t, Macro_element_number, QuadTreeNames::E, zeta, d2bound_E);
406
407
408 // d2x0/dm0^2
409 jacobian2(0, 0) = 0.5 * (d2bound_S[0] + d2bound_N[0] - d2bound_S[0] * S[1] +
410 d2bound_N[0] * S[1]);
411 // d2x0/dm1^2
412 jacobian2(1, 0) = 0.5 * (d2bound_W[0] + d2bound_E[0] - d2bound_W[0] * S[0] +
413 d2bound_E[0] * S[0]);
414 // d2x0/dm0dm1
415 jacobian2(2, 0) =
416 0.25 * (-corner_NE[0] + corner_NW[0] + corner_SE[0] - corner_SW[0]) +
417 0.5 * (-dbound_W[0] + dbound_E[0] - dbound_S[0] + dbound_N[0]);
418 // d2x1/dm0^2
419 jacobian2(0, 1) = 0.5 * (d2bound_S[1] + d2bound_N[1] - d2bound_S[1] * S[1] +
420 d2bound_N[1] * S[1]);
421 // d2x1/dm1^2
422 jacobian2(1, 1) = 0.5 * (d2bound_W[1] + d2bound_E[1] - d2bound_W[1] * S[0] +
423 d2bound_E[1] * S[0]);
424 // d2x1/dm0dm1
425 jacobian2(2, 1) =
426 0.25 * (-corner_NE[1] + corner_NW[1] + corner_SE[1] - corner_SW[1]) +
427 0.5 * (-dbound_W[1] + dbound_E[1] - dbound_S[1] + dbound_N[1]);
428 }
429
430
431 /// ///////////////////////////////////////////////////////////////////
432 /// ///////////////////////////////////////////////////////////////////
433 /// ///////////////////////////////////////////////////////////////////
434
435
436 //=================================================================
437 /// Get global position r(S) at discrete time level t.
438 /// t=0: Present time; t>0: previous timestep.
439 //=================================================================
440 void QMacroElement<3>::macro_map(const unsigned& t,
441 const Vector<double>& S,
443 {
444 // get the eight corners
445 Vector<double> corner_LDB(3);
446 Vector<double> corner_RDB(3);
447 Vector<double> corner_LUB(3);
448 Vector<double> corner_RUB(3);
449 Vector<double> corner_LDF(3);
450 Vector<double> corner_RDF(3);
451 Vector<double> corner_LUF(3);
452 Vector<double> corner_RUF(3);
453
454 Vector<double> zeta(2);
455 zeta[0] = -1.0;
456 zeta[1] = -1.0;
458 t, Macro_element_number, OcTreeNames::B, zeta, corner_LDB);
460 t, Macro_element_number, OcTreeNames::U, zeta, corner_LUB);
462 t, Macro_element_number, OcTreeNames::F, zeta, corner_LDF);
464 t, Macro_element_number, OcTreeNames::R, zeta, corner_RDB);
465 zeta[0] = 1.0;
466 zeta[1] = 1.0;
468 t, Macro_element_number, OcTreeNames::B, zeta, corner_RUB);
470 t, Macro_element_number, OcTreeNames::D, zeta, corner_RDF);
472 t, Macro_element_number, OcTreeNames::L, zeta, corner_LUF);
474 t, Macro_element_number, OcTreeNames::R, zeta, corner_RUF);
475
476
477 // get the position of the 4 corners of the center slice
478 Vector<double> corner_LD(3);
479 Vector<double> corner_RD(3);
480 Vector<double> corner_LU(3);
481 Vector<double> corner_RU(3);
482
483 zeta[0] = -1.0;
484 zeta[1] = S[2];
486 t, Macro_element_number, OcTreeNames::D, zeta, corner_LD);
488 t, Macro_element_number, OcTreeNames::U, zeta, corner_LU);
489 zeta[0] = 1.0;
491 t, Macro_element_number, OcTreeNames::D, zeta, corner_RD);
493 t, Macro_element_number, OcTreeNames::U, zeta, corner_RU);
494
495 // get position on the B,F faces;
496 Vector<double> face_B(3);
497 Vector<double> face_F(3);
498
499 zeta[0] = S[0];
500 zeta[1] = S[1];
502 t, Macro_element_number, OcTreeNames::B, zeta, face_B);
504 t, Macro_element_number, OcTreeNames::F, zeta, face_F);
505
506
507 // get position on the edges of the middle slice
508 Vector<double> edge_mid_L(3);
509 Vector<double> edge_mid_R(3);
510 Vector<double> edge_mid_D(3);
511 Vector<double> edge_mid_U(3);
512 zeta[0] = S[0];
513 zeta[1] = S[2];
515 t, Macro_element_number, OcTreeNames::U, zeta, edge_mid_U);
516
518 t, Macro_element_number, OcTreeNames::D, zeta, edge_mid_D);
519 zeta[0] = S[1];
520 zeta[1] = S[2];
522 t, Macro_element_number, OcTreeNames::L, zeta, edge_mid_L);
523
525 t, Macro_element_number, OcTreeNames::R, zeta, edge_mid_R);
526
527 // get position on the edges of the back slice
528 Vector<double> edge_back_L(3);
529 Vector<double> edge_back_R(3);
530 Vector<double> edge_back_D(3);
531 Vector<double> edge_back_U(3);
532 zeta[0] = S[0];
533 zeta[1] = -1.0;
535 t, Macro_element_number, OcTreeNames::U, zeta, edge_back_U);
536
538 t, Macro_element_number, OcTreeNames::D, zeta, edge_back_D);
539 zeta[0] = S[1];
540 zeta[1] = -1.0;
542 t, Macro_element_number, OcTreeNames::L, zeta, edge_back_L);
543
545 t, Macro_element_number, OcTreeNames::R, zeta, edge_back_R);
546
547 // get position on the edges of the front slice
548 Vector<double> edge_front_L(3);
549 Vector<double> edge_front_R(3);
550 Vector<double> edge_front_D(3);
551 Vector<double> edge_front_U(3);
552 zeta[0] = S[0];
553 zeta[1] = 1.0;
555 t, Macro_element_number, OcTreeNames::U, zeta, edge_front_U);
556
558 t, Macro_element_number, OcTreeNames::D, zeta, edge_front_D);
559 zeta[0] = S[1];
560 zeta[1] = 1.0;
562 t, Macro_element_number, OcTreeNames::L, zeta, edge_front_L);
563
565 t, Macro_element_number, OcTreeNames::R, zeta, edge_front_R);
566
567
568 for (unsigned i = 0; i < 3; i++)
569 {
570 // Position on the middle slice
571 // ============================
572 double slice_mid;
573
574 // the points on the up and down edges of the middle "rectangular slice"
575 double ptUp, ptDo;
576 ptUp = corner_LU[i] + (corner_RU[i] - corner_LU[i]) * 0.5 * (S[0] + 1.0);
577 ptDo = corner_LD[i] + (corner_RD[i] - corner_LD[i]) * 0.5 * (S[0] + 1.0);
578 // position in the rectangular middle slice
579 slice_mid = ptDo + 0.5 * (1.0 + S[1]) * (ptUp - ptDo);
580
581 // get the differences to the edges of the middle slice
582 double diff_L, diff_R, diff_D, diff_U;
583 diff_L = edge_mid_L[i] - slice_mid;
584 diff_R = edge_mid_R[i] - slice_mid;
585 diff_D = edge_mid_D[i] - slice_mid;
586 diff_U = edge_mid_U[i] - slice_mid;
587
588 // Map it to get the position in the middle slice
589 slice_mid +=
590 diff_L * (1.0 - 0.5 * (S[0] + 1.0)) + diff_R * 0.5 * (S[0] + 1.0) +
591 diff_D * (1.0 - 0.5 * (S[1] + 1.0)) + diff_U * 0.5 * (S[1] + 1.0);
592
593
594 // Position on the back slice
595 //===========================
596 double slice_back;
597
598 // the points on the up and down edges of the back "rectangular slice"
599 ptUp =
600 corner_LUB[i] + (corner_RUB[i] - corner_LUB[i]) * 0.5 * (S[0] + 1.0);
601 ptDo =
602 corner_LDB[i] + (corner_RDB[i] - corner_LDB[i]) * 0.5 * (S[0] + 1.0);
603 // position in the rectangular back slice
604 slice_back = ptDo + 0.5 * (1.0 + S[1]) * (ptUp - ptDo);
605
606 // get the differences to the edges of the middle slice
607 diff_L = edge_back_L[i] - slice_back;
608 diff_R = edge_back_R[i] - slice_back;
609 diff_D = edge_back_D[i] - slice_back;
610 diff_U = edge_back_U[i] - slice_back;
611
612 // Map it to get the position in the back slice
613 slice_back +=
614 diff_L * (1.0 - 0.5 * (S[0] + 1.0)) + diff_R * 0.5 * (S[0] + 1.0) +
615 diff_D * (1.0 - 0.5 * (S[1] + 1.0)) + diff_U * 0.5 * (S[1] + 1.0);
616
617 // Position on the front slice
618 //============================
619 double slice_front;
620
621 // the points on the up and down edges of the back "rectangular slice"
622 ptUp =
623 corner_LUF[i] + (corner_RUF[i] - corner_LUF[i]) * 0.5 * (S[0] + 1.0);
624 ptDo =
625 corner_LDF[i] + (corner_RDF[i] - corner_LDF[i]) * 0.5 * (S[0] + 1.0);
626 // position in the rectangular back slice
627 slice_front = ptDo + 0.5 * (1.0 + S[1]) * (ptUp - ptDo);
628
629 // get the differences to the edges of the middle slice
630 diff_L = edge_front_L[i] - slice_front;
631 diff_R = edge_front_R[i] - slice_front;
632 diff_D = edge_front_D[i] - slice_front;
633 diff_U = edge_front_U[i] - slice_front;
634
635 // Map it to get the position in the back slice
636 slice_front +=
637 diff_L * (1.0 - 0.5 * (S[0] + 1.0)) + diff_R * 0.5 * (S[0] + 1.0) +
638 diff_D * (1.0 - 0.5 * (S[1] + 1.0)) + diff_U * 0.5 * (S[1] + 1.0);
639
640 // Get difference between the back and front slices and the actual
641 // boundary
642 // ========================================================================
643
644 double diff_back = face_B[i] - slice_back;
645 double diff_front = face_F[i] - slice_front;
646
647 // final map
648 //==========
649
650 r[i] = slice_mid + 0.5 * (1 + S[2]) * diff_front +
651 0.5 * (1 - S[2]) * diff_back;
652 }
653 }
654
655
656 //=================================================================
657 /// Output all macro element boundaries as tecplot zones
658 //=================================================================
660 const unsigned& nplot)
661 {
662 using namespace OcTreeNames;
663
664 Vector<double> s(2);
665 Vector<double> f(3);
666 // Dump at present time
667 unsigned t = 0;
668 for (unsigned idirect = L; idirect <= F; idirect++)
669 {
670 outfile << "ZONE I=" << nplot << ", J=" << nplot << std::endl;
671 for (unsigned i = 0; i < nplot; i++)
672 {
673 s[1] = -1.0 + 2.0 * double(i) / double(nplot - 1);
674 for (unsigned j = 0; j < nplot; j++)
675 {
676 s[0] = -1.0 + 2.0 * double(j) / double(nplot - 1);
678 t, Macro_element_number, idirect, s, f);
679 outfile << f[0] << " " << f[1] << " " << f[2] << std::endl;
680 }
681 }
682 }
683 }
684
685} // namespace oomph
static char t char * s
Definition: cfortran.h:568
cstr elem_len * i
Definition: cfortran.h:603
char t
Definition: cfortran.h:568
virtual void macro_element_boundary(const unsigned &t, const unsigned &i_macro, const unsigned &i_direct, const Vector< double > &s, Vector< double > &f)=0
Vector representation of the i_macro-th macro element boundary i_direct (e.g. N/S/W/E in 2D) at time ...
virtual void dmacro_element_boundary(const unsigned &t, const unsigned &i_macro, const unsigned &i_direct, const Vector< double > &s, Vector< double > &f)
Vector representation of the i_macro-th macro element boundary derivatives i_direct (e....
Definition: domain.h:212
virtual void d2macro_element_boundary(const unsigned &t, const unsigned &i_macro, const unsigned &i_direct, const Vector< double > &s, Vector< double > &f)
Vector representation of the i_macro-th macro element boundary second derivatives i_direct (e....
Definition: domain.h:258
Domain * Domain_pt
Pointer to domain.
virtual void assemble_macro_to_eulerian_jacobian2(const unsigned &t, const Vector< double > &s, DenseMatrix< double > &jacobian2)
Assembles the second derivative jacobian of the mapping from the macro coordinates to the global coor...
virtual void output_macro_element_boundaries(std::ostream &outfile, const unsigned &nplot)=0
Output all macro element boundaries as tecplot zones.
void macro_map(const Vector< double > &s, Vector< double > &r)
The mapping from local to global coordinates at the current time : r(s)
unsigned Macro_element_number
What is the number of the current macro element within its domain.
virtual void assemble_macro_to_eulerian_jacobian(const unsigned &t, const Vector< double > &s, DenseMatrix< double > &jacobian)
the jacobian of the mapping from the macro coordinates to the global coordinates
//////////////////////////////////////////////////////////////////// ////////////////////////////////...