19 if (m_tetTree)
delete m_tetTree;
28 <<
" No materials are currently defined.\n";
33 <<
" Currently " <<
m_nMaterials <<
" materials are defined.\n"
34 <<
" Index Permittivity Resistivity Notes\n";
38 std::string name =
materials[i].medium->GetName();
39 std::cout <<
" " << name;
40 if (
materials[i].medium->IsDriftable()) std::cout <<
", drift medium";
41 if (
materials[i].medium->IsIonisable()) std::cout <<
", ionisable";
44 std::cout <<
" (drift medium)\n";
57 std::cerr <<
m_className <<
"::DriftMedium: Index out of range.\n";
71 std::cerr <<
m_className <<
"::NotDriftMedium: Index out of range.\n";
81 std::cerr <<
m_className <<
"::GetPermittivity: Index out of range.\n";
90 std::cerr <<
m_className <<
"::GetConductivity: Index out of range.\n";
100 std::cerr <<
" Material index " << imat <<
" is out of range.\n";
105 std::cerr <<
m_className <<
"::SetMedium: Null pointer.\n";
110 std::cout <<
m_className <<
"::SetMedium:\n Associated material " << imat
111 <<
" with medium " << m->
GetName() <<
".\n";
120 <<
" Material index " << imat <<
" is out of range.\n";
128 double& dmin,
double& dmax) {
131 std::cerr <<
" Element index (" << i <<
") out of range.\n";
141 double const z,
double& t1,
double& t2,
142 double& t3,
double& t4,
double jac[4][4],
145 if (!m_cacheElemBoundingBoxes) {
147 <<
" Caching the bounding boxes of all elements...";
148 CalculateElementBoundingBoxes();
149 std::cout <<
" done.\n";
150 m_cacheElemBoundingBoxes =
true;
154 std::vector<int> tetList;
155 if (m_useTetrahedralTree) {
156 if (!m_isTreeInitialized) {
157 if (!InitializeTetrahedralTree()) {
159 std::cerr <<
" Tetrahedral tree initialization failed.\n";
166 double jacbak[4][4], detbak = 1.;
167 double t1bak = 0., t2bak = 0., t3bak = 0., t4bak = 0.;
171 t1 = t2 = t3 = t4 = 0;
174 if (m_lastElement > -1 && !m_checkMultipleElement) {
177 if (Coordinates3(x, y, z, t1, t2, t3, t4, jac, det, element) == 0) {
178 if (t1 >= 0 && t1 <= +1 && t2 >= 0 && t2 <= +1 && t3 >= 0 && t3 <= +1) {
179 return m_lastElement;
183 if (Coordinates5(x, y, z, t1, t2, t3, t4, jac, det, element) == 0) {
184 if (t1 >= -1 && t1 <= +1 && t2 >= -1 && t2 <= +1)
return m_lastElement;
195 const int numElemToSearch = m_useTetrahedralTree ? tetList.size() :
nElements;
196 for (
int i = 0; i < numElemToSearch; ++i) {
197 const int idxToElemList = m_useTetrahedralTree ? tetList[i] : i;
199 if (x < element.xmin || x > element.
xmax || y < element.
ymin ||
200 y > element.
ymax || z < element.zmin || z > element.
zmax)
204 if (Coordinates3(x, y, z, t1, t2, t3, t4, jac, det, element) != 0) {
207 if (t1 < 0 || t1 > 1 || t2 < 0 || t2 > 1 || t3 < 0 || t3 > 1)
continue;
209 imap = idxToElemList;
210 m_lastElement = idxToElemList;
213 std::cout <<
" Found matching degenerate element " << idxToElemList
216 if (!m_checkMultipleElement)
return idxToElemList;
217 for (
int j = 0; j < 4; ++j) {
218 for (
int k = 0; k < 4; ++k) jacbak[j][k] = jac[j][k];
227 PrintElement(
"FindElement5", x, y, z, t1, t2, t3, t4, element, 6);
231 if (Coordinates5(x, y, z, t1, t2, t3, t4, jac, det, element) != 0) {
234 if (t1 < -1 || t1 > 1 || t2 < -1 || t2 > 1)
continue;
236 imap = idxToElemList;
237 m_lastElement = idxToElemList;
240 std::cout <<
" Found matching non-degenerate element "
241 << idxToElemList <<
".\n";
243 if (!m_checkMultipleElement)
return idxToElemList;
244 for (
int j = 0; j < 4; ++j) {
245 for (
int k = 0; k < 4; ++k) jacbak[j][k] = jac[j][k];
254 PrintElement(
"FindElement5", x, y, z, t1, t2, t3, t4, element, 8);
260 if (m_checkMultipleElement) {
264 std::cout <<
" No element matching point (" << x <<
", " << y
272 std::cout <<
" Found " << nfound <<
" elements matching point (" << x
273 <<
", " << y <<
").\n";
276 for (
int j = 0; j < 4; ++j) {
277 for (
int k = 0; k < 4; ++k) jac[j][k] = jacbak[j][k];
285 m_lastElement = imap;
292 std::cout <<
" No element matching point (" << x <<
", " << y
299 const double z,
double& t1,
double& t2,
300 double& t3,
double& t4,
double jac[4][4],
303 if (!m_cacheElemBoundingBoxes) {
305 <<
" Caching the bounding boxes of all elements...";
306 CalculateElementBoundingBoxes();
307 std::cout <<
" done.\n";
308 m_cacheElemBoundingBoxes =
true;
314 double t1bak = 0., t2bak = 0., t3bak = 0., t4bak = 0.;
318 t1 = t2 = t3 = t4 = 0.;
321 if (m_lastElement > -1 && !m_checkMultipleElement) {
323 if (Coordinates13(x, y, z, t1, t2, t3, t4, jac, det, element) == 0) {
324 if (t1 >= 0 && t1 <= +1 && t2 >= 0 && t2 <= +1 && t3 >= 0 && t3 <= +1 &&
325 t4 >= 0 && t4 <= +1) {
326 return m_lastElement;
332 std::vector<int> tetList;
333 if (m_useTetrahedralTree) {
334 if (!m_isTreeInitialized) {
335 if (!InitializeTetrahedralTree()) {
337 std::cerr <<
" Tetrahedral tree initialization failed.\n";
345 const int numElemToSearch = m_useTetrahedralTree ? tetList.size() :
nElements;
351 for (
int i = 0; i < numElemToSearch; i++) {
352 const int idxToElemList = m_useTetrahedralTree ? tetList[i] : i;
354 if (x < element.xmin || x > element.
xmax || y < element.
ymin ||
355 y > element.
ymax || z < element.zmin || z > element.
zmax)
357 if (Coordinates13(x, y, z, t1, t2, t3, t4, jac, det, element) != 0) {
360 if (t1 < 0 || t1 > 1 || t2 < 0 || t2 > 1 || t3 < 0 || t3 > 1 || t4 < 0 ||
365 imap = idxToElemList;
366 m_lastElement = idxToElemList;
369 std::cout <<
" Found matching element " << i <<
".\n";
371 if (!m_checkMultipleElement)
return idxToElemList;
372 for (
int j = 0; j < 4; ++j) {
373 for (
int k = 0; k < 4; ++k) jacbak[j][k] = jac[j][k];
382 PrintElement(
"FindElement13", x, y, z, t1, t2, t3, t4, element, 10);
387 if (m_checkMultipleElement) {
391 std::cout <<
" No element matching point (" << x <<
", " << y <<
", "
392 << z <<
") found.\n";
399 std::cerr <<
" Found << " << nfound <<
" elements matching point ("
400 << x <<
", " << y <<
", " << z <<
").\n";
403 for (
int j = 0; j < 4; ++j) {
404 for (
int k = 0; k < 4; ++k) jac[j][k] = jacbak[j][k];
412 m_lastElement = imap;
419 std::cout <<
" No element matching point (" << x <<
", " << y <<
", "
420 << z <<
") found.\n";
426 const double z,
double& t1,
double& t2,
427 double& t3, TMatrixD*& jac,
428 std::vector<TMatrixD*>& dN) {
430 if (m_lastElement >= 0) {
433 if (x >= n3.
x && y >= n3.
y && z >= n3.
z) {
437 if (x < n0.
x && y < n2.
y && z < n7.
z) {
438 imap = m_lastElement;
448 if (x < n3.
x || y < n3.
y || z < n3.
z)
continue;
452 if (x < n0.
x && y < n2.
y && z < n7.
z) {
461 std::cout <<
m_className <<
"::FindElementCube:\n";
462 std::cout <<
" Point (" << x <<
"," << y <<
"," << z
463 <<
") not in the mesh, it is background or PEC.\n";
468 std::cout <<
" First node (" << first3.
x <<
"," << first3.
y <<
","
469 << first3.
z <<
") in the mesh.\n";
470 std::cout <<
" dx= " << (first0.
x - first3.
x)
471 <<
", dy= " << (first2.
y - first3.
y)
472 <<
", dz= " << (first7.
z - first3.
z) <<
"\n";
478 std::cout <<
" Last node (" << last5.
x <<
"," << last5.
y <<
","
479 << last5.
z <<
") in the mesh.\n";
480 std::cout <<
" dx= " << (last0.
x - last3.
x)
481 <<
", dy= " << (last2.
y - last3.
y)
482 <<
", dz= " << (last7.
z - last3.
z) <<
"\n";
486 CoordinatesCube(x, y, z, t1, t2, t3, jac, dN,
elements[imap]);
493void ComponentFieldMap::Jacobian3(
const Element& element,
const double u,
494 const double v,
const double w,
double& det,
495 double jac[4][4])
const {
503 const Node& n0 =
nodes[element.emap[0]];
504 const Node& n1 =
nodes[element.emap[1]];
505 const Node& n2 =
nodes[element.emap[2]];
506 const Node& n3 =
nodes[element.emap[3]];
507 const Node& n4 =
nodes[element.emap[4]];
508 const Node& n5 =
nodes[element.emap[5]];
511 const double fouru = 4 * u;
512 const double fourv = 4 * v;
513 const double fourw = 4 * w;
515 const double ax = -n1.x + fourv * n1.x + fouru * n3.x + fourw * n5.x;
516 const double ay = -n1.y + fourv * n1.y + fouru * n3.y + fourw * n5.y;
517 const double bx = -n2.x + fourw * n2.x + fouru * n4.x + fourv * n5.x;
518 const double by = -n2.y + fourw * n2.y + fouru * n4.y + fourv * n5.y;
519 const double cx = -n0.x + fouru * n0.x + fourv * n3.x + fourw * n4.x;
520 const double cy = -n0.y + fouru * n0.y + fourv * n3.y + fourw * n4.y;
522 det = -((-1 + fourv) * n1.x + n2.x - fourw * n2.x + fouru * n3.x -
523 fouru * n4.x - fourv * n5.x + fourw * n5.x) *
525 ((-1 + fouru) * n0.x + n1.x - fourv * n1.x - fouru * n3.x +
526 fourv * n3.x + fourw * n4.x - fourw * n5.x) *
528 ((-1 + fouru) * n0.x + n2.x - fourw * n2.x + fourv * n3.x -
529 fouru * n4.x + fourw * n4.x - fourv * n5.x) *
533 jac[0][0] = ax * by - bx * ay;
534 jac[0][1] = (-1 + fourv) * n1.y + n2.y - fourw * n2.y + fouru * n3.y -
535 fouru * n4.y - fourv * n5.y + fourw * n5.y;
536 jac[0][2] = n1.x - fourv * n1.x + (-1 + fourw) * n2.x - fouru * n3.x +
537 fouru * n4.x + fourv * n5.x - fourw * n5.x;
538 jac[1][0] = bx * cy - cx * by;
539 jac[1][1] = n0.y - fouru * n0.y - n2.y + fourw * n2.y - fourv * n3.y +
540 fouru * n4.y - fourw * n4.y + fourv * n5.y;
541 jac[1][2] = (-1 + fouru) * n0.x + n2.x - fourw * n2.x + fourv * n3.x -
542 fouru * n4.x + fourw * n4.x - fourv * n5.x;
543 jac[2][0] = -ax * cy + cx * ay;
544 jac[2][1] = (-1 + fouru) * n0.y + n1.y - fourv * n1.y - fouru * n3.y +
545 fourv * n3.y + fourw * n4.y - fourw * n5.y;
546 jac[2][2] = n0.x - fouru * n0.x - n1.x + fourv * n1.x + fouru * n3.x -
547 fourv * n3.x - fourw * n4.x + fourw * n5.x;
550void ComponentFieldMap::Jacobian5(
const Element& element,
const double u,
551 const double v,
double& det,
552 double jac[4][4])
const {
560 const Node& n0 =
nodes[element.emap[0]];
561 const Node& n1 =
nodes[element.emap[1]];
562 const Node& n2 =
nodes[element.emap[2]];
563 const Node& n3 =
nodes[element.emap[3]];
564 const Node& n4 =
nodes[element.emap[4]];
565 const Node& n5 =
nodes[element.emap[5]];
566 const Node& n6 =
nodes[element.emap[6]];
567 const Node& n7 =
nodes[element.emap[7]];
568 const double u2 = u * u;
569 const double v2 = v * v;
570 const double twou = 2 * u;
571 const double twov = 2 * v;
572 const double two0x = 2 * n0.x;
573 const double two0y = 2 * n0.y;
574 const double two1x = 2 * n1.x;
575 const double two1y = 2 * n1.y;
576 const double two2x = 2 * n2.x;
577 const double two2y = 2 * n2.y;
578 const double two3x = 2 * n3.x;
579 const double two3y = 2 * n3.y;
580 const double two4x = 2 * n4.x;
581 const double two4y = 2 * n4.y;
582 const double two5x = 2 * n5.x;
583 const double two5y = 2 * n5.y;
584 const double two6x = 2 * n6.x;
585 const double two6y = 2 * n6.y;
586 const double two7x = 2 * n7.x;
587 const double two7y = 2 * n7.y;
590 (-twou * u2 * ((n2.x + n3.x - two6x) * (n0.y + n1.y - two4y) -
591 (n0.x + n1.x - two4x) * (n2.y + n3.y - two6y)) +
592 twov * v2 * (-((n0.x + n3.x - two7x) * (n1.y + n2.y - two5y)) +
593 (n1.x + n2.x - two5x) * (n0.y + n3.y - two7y)) +
594 2 * (-((n5.x - n7.x) * (n4.y - n6.y)) + (n4.x - n6.x) * (n5.y - n7.y)) +
595 v * (-(n6.x * n0.y) - two7x * n0.y + n6.x * n1.y - two7x * n1.y -
596 n6.x * n2.y - two7x * n2.y + n4.x * (n0.y - n1.y + n2.y - n3.y) +
597 n6.x * n3.y - two7x * n3.y - n0.x * n4.y + n1.x * n4.y -
598 n2.x * n4.y + n3.x * n4.y - two0x * n5.y - two1x * n5.y -
599 two2x * n5.y - two3x * n5.y + 8 * n7.x * n5.y + n0.x * n6.y -
600 n1.x * n6.y + n2.x * n6.y - n3.x * n6.y +
601 two5x * (n0.y + n1.y + n2.y + n3.y - 4 * n7.y) +
602 2 * (n0.x + n1.x + n2.x + n3.x) * n7.y) +
603 v2 * (-(n4.x * n0.y) + two5x * n0.y + n6.x * n0.y + two7x * n0.y +
604 n4.x * n1.y - two5x * n1.y - n6.x * n1.y - two7x * n1.y +
605 n4.x * n2.y + two5x * n2.y - n6.x * n2.y + two7x * n2.y -
606 n4.x * n3.y - two5x * n3.y + n6.x * n3.y - two7x * n3.y +
607 two2x * (n1.y + n3.y) - n2.x * n4.y + two5x * n4.y - two7x * n4.y -
608 two2x * n5.y - two4x * n5.y + two6x * n5.y + n2.x * n6.y -
609 two5x * n6.y + two7x * n6.y +
610 n0.x * (two1y + two3y + n4.y - two5y - n6.y - two7y) -
611 2 * (n2.x - n4.x + n6.x) * n7.y +
612 n3.x * (-two0y - two2y + n4.y + two5y - n6.y + two7y) +
613 n1.x * (-two0y - two2y - n4.y + two5y + n6.y + two7y)) +
614 u * (n5.x * n0.y - two6x * n0.y - n7.x * n0.y - n5.x * n1.y -
615 two6x * n1.y + n7.x * n1.y + n5.x * n2.y - two6x * n2.y -
616 n7.x * n2.y - n5.x * n3.y - two6x * n3.y + n7.x * n3.y -
617 two1x * n4.y - two2x * n4.y - two3x * n4.y + 8 * n6.x * n4.y +
618 n1.x * n5.y - n2.x * n5.y + n3.x * n5.y +
619 two4x * (n0.y + n1.y + n2.y + n3.y - 4 * n6.y) + two1x * n6.y +
620 two2x * n6.y + two3x * n6.y - (n1.x - n2.x + n3.x) * n7.y +
621 n0.x * (-two4y - n5.y + two6y + n7.y) +
622 v2 * (4 * n4.x * n0.y - 3 * n5.x * n0.y - 4 * n6.x * n0.y -
623 5 * n7.x * n0.y + 4 * n4.x * n1.y - 5 * n5.x * n1.y -
624 4 * n6.x * n1.y - 3 * n7.x * n1.y + 4 * n4.x * n2.y +
625 5 * n5.x * n2.y - 4 * n6.x * n2.y + 3 * n7.x * n2.y +
626 4 * n4.x * n3.y + 3 * n5.x * n3.y - 4 * n6.x * n3.y +
627 5 * n7.x * n3.y + 8 * n5.x * n4.y + 8 * n7.x * n4.y -
628 8 * n4.x * n5.y + 8 * n6.x * n5.y - 8 * n5.x * n6.y -
630 n3.x * (5 * n0.y + 3 * n1.y - 4 * n4.y - 3 * n5.y + 4 * n6.y -
632 n2.x * (3 * n0.y + 5 * n1.y - 4 * n4.y - 5 * n5.y + 4 * n6.y -
634 8 * n4.x * n7.y + 8 * n6.x * n7.y +
635 n1.x * (-5 * n2.y - 3 * n3.y - 4 * n4.y + 5 * n5.y +
636 4 * n6.y + 3 * n7.y) +
637 n0.x * (-3 * n2.y - 5 * n3.y - 4 * n4.y + 3 * n5.y +
638 4 * n6.y + 5 * n7.y)) -
639 twov * (n6.x * n0.y - 3 * n7.x * n0.y + n6.x * n1.y - n7.x * n1.y +
640 3 * n6.x * n2.y - n7.x * n2.y + 3 * n6.x * n3.y -
641 3 * n7.x * n3.y - 3 * n0.x * n4.y - 3 * n1.x * n4.y -
642 n2.x * n4.y - n3.x * n4.y + 4 * n7.x * n4.y + n0.x * n5.y +
643 3 * n1.x * n5.y + 3 * n2.x * n5.y + n3.x * n5.y -
644 4 * n6.x * n5.y - n0.x * n6.y - n1.x * n6.y -
645 3 * n2.x * n6.y - 3 * n3.x * n6.y + 4 * n7.x * n6.y -
646 n5.x * (n0.y + 3 * n1.y + 3 * n2.y + n3.y -
648 (3 * n0.x + n1.x + n2.x + 3 * n3.x - 4 * n6.x) * n7.y +
649 n4.x * (3 * n0.y + 3 * n1.y + n2.y + n3.y -
650 4 * (n5.y + n7.y)))) +
652 (two3x * n0.y - two4x * n0.y - n5.x * n0.y - two6x * n0.y +
653 n7.x * n0.y - two0x * n1.y + two4x * n1.y - n5.x * n1.y +
654 two6x * n1.y + n7.x * n1.y + two3x * n2.y - two4x * n2.y +
655 n5.x * n2.y - two6x * n2.y - n7.x * n2.y + two4x * n3.y +
656 n5.x * n3.y + two6x * n3.y - n7.x * n3.y - two3x * n4.y +
657 two5x * n4.y - two7x * n4.y - n3.x * n5.y - two4x * n5.y +
658 two6x * n5.y - two3x * n6.y - two5x * n6.y + two7x * n6.y +
659 n0.x * (-two3y + two4y + n5.y + two6y - n7.y) +
660 (n3.x + two4x - two6x) * n7.y +
661 n2.x * (-two1y - two3y + two4y - n5.y + two6y + n7.y) -
663 (n5.x * n0.y - n6.x * n0.y - n7.x * n0.y + n5.x * n1.y +
664 n6.x * n1.y - n7.x * n1.y - n5.x * n2.y + n6.x * n2.y +
665 n7.x * n2.y - n5.x * n3.y - n6.x * n3.y + n7.x * n3.y -
666 two5x * n4.y + two7x * n4.y - two6x * n5.y + two5x * n6.y -
668 n4.x * (n0.y - n1.y - n2.y + n3.y + two5y - two7y) +
669 n3.x * (n0.y - n2.y - n4.y + n5.y + n6.y - n7.y) +
671 (n0.x - n2.x) * (n1.y - n3.y - n4.y - n5.y + n6.y + n7.y)) +
672 v * (4 * n5.x * n0.y + 3 * n6.x * n0.y - 4 * n7.x * n0.y +
673 4 * n5.x * n1.y - 3 * n6.x * n1.y - 4 * n7.x * n1.y +
674 4 * n5.x * n2.y - 5 * n6.x * n2.y - 4 * n7.x * n2.y +
675 4 * n5.x * n3.y + 5 * n6.x * n3.y - 4 * n7.x * n3.y -
676 8 * n5.x * n4.y + 8 * n7.x * n4.y + 8 * n6.x * n5.y -
677 8 * n5.x * n6.y + 8 * n7.x * n6.y +
678 n4.x * (5 * n0.y - 5 * n1.y - 3 * n2.y + 3 * n3.y + 8 * n5.y -
681 n3.x * (3 * n1.y + 5 * n2.y - 3 * n4.y - 4 * n5.y - 5 * n6.y +
683 n0.x * (5 * n1.y + 3 * n2.y - 5 * n4.y - 4 * n5.y - 3 * n6.y +
685 n2.x * (-3 * n0.y - 5 * n3.y + 3 * n4.y - 4 * n5.y + 5 * n6.y +
687 n1.x * ((-1 + v) * (-2 + 3 * v) * n0.y + two2y - two4y + n5.y -
689 v * (-3 * n3.y + 5 * n4.y - 4 * n5.y + 3 * n6.y + 4 * n7.y -
690 3 * v * (n2.y + n4.y - n5.y - n6.y + n7.y))))) /
694 (u2 * (-n0.y - n1.y + n2.y + n3.y + two4y - two6y) +
695 2 * (-n4.y + n6.y + v * (n0.y + n1.y + n2.y + n3.y - two5y - two7y)) +
696 u * (n0.y - twov * n0.y - n1.y + twov * n1.y + n2.y + twov * n2.y -
697 n3.y - twov * n3.y - twov * two5y + twov * two7y)) /
700 (u2 * (n0.x + n1.x - n2.x - n3.x - two4x + two6x) -
701 2 * (-n4.x + n6.x + v * (n0.x + n1.x + n2.x + n3.x - two5x - two7x)) +
702 u * ((-1 + twov) * n0.x + n1.x - twov * n1.x - n2.x - twov * n2.x +
703 n3.x + twov * n3.x + twov * two5x - twov * two7x)) /
706 (v * (-n0.y + n1.y - n2.y + n3.y) - two5y +
707 twou * ((-1 + v) * n0.y + (-1 + v) * n1.y - n2.y - v * n2.y - n3.y -
708 v * n3.y + two4y - twov * n4.y + two6y + twov * n6.y) +
709 v2 * (n0.y - n1.y - n2.y + n3.y + two5y - two7y) + two7y) /
712 (v * (n0.x - n1.x + n2.x - n3.x) +
713 twou * (n0.x - v * n0.x + n1.x - v * n1.x + n2.x + v * n2.x + n3.x +
714 v * n3.x - two4x + twov * n4.x - two6x - twov * n6.x) +
715 two5x - two7x + v2 * (-n0.x + n1.x + n2.x - n3.x - two5x + two7x)) /
719void ComponentFieldMap::Jacobian13(
const Element& element,
const double t,
720 const double u,
const double v,
721 const double w,
double& det,
722 double jac[4][4])
const {
725 for (
int j = 0; j < 4; ++j) {
726 for (
int k = 0; k < 4; ++k) jac[j][k] = 0;
729 const Node& n0 =
nodes[element.emap[0]];
730 const Node& n1 =
nodes[element.emap[1]];
731 const Node& n2 =
nodes[element.emap[2]];
732 const Node& n3 =
nodes[element.emap[3]];
733 const Node& n4 =
nodes[element.emap[4]];
734 const Node& n5 =
nodes[element.emap[5]];
735 const Node& n6 =
nodes[element.emap[6]];
736 const Node& n7 =
nodes[element.emap[7]];
737 const Node& n8 =
nodes[element.emap[8]];
738 const Node& n9 =
nodes[element.emap[9]];
741 const double fourt = 4 * t;
742 const double fouru = 4 * u;
743 const double fourv = 4 * v;
744 const double fourw = 4 * w;
746 const double ttx = (-1 + fourt) * n0.x + 4 * (u * n4.x + v * n5.x + w * n6.x);
747 const double tty = (-1 + fourt) * n0.y + 4 * (u * n4.y + v * n5.y + w * n6.y);
748 const double ttz = (-1 + fourt) * n0.z + 4 * (u * n4.z + v * n5.z + w * n6.z);
750 const double uux = (-1 + fouru) * n1.x + 4 * (t * n4.x + v * n7.x + w * n8.x);
751 const double uuy = (-1 + fouru) * n1.y + 4 * (t * n4.y + v * n7.y + w * n8.y);
752 const double uuz = (-1 + fouru) * n1.z + 4 * (t * n4.z + v * n7.z + w * n8.z);
755 fourv * n9.x - n3.x + fourw * n3.x + fourt * n6.x + fouru * n8.x;
757 fourv * n9.y - n3.y + fourw * n3.y + fourt * n6.y + fouru * n8.y;
759 fourv * n9.z - n3.z + fourw * n3.z + fourt * n6.z + fouru * n8.z;
762 fourw * n9.x - n2.x + fourv * n2.x + fourt * n5.x + fouru * n7.x;
764 fourw * n9.y - n2.y + fourv * n2.y + fourt * n5.y + fouru * n7.y;
766 fourw * n9.z - n2.z + fourv * n2.z + fourt * n5.z + fouru * n7.z;
768 const double aax = n1.x - fouru * n1.x - n3.x + fourw * n3.x - fourt * n4.x +
769 fourt * n6.x + fourv * (n9.x - n7.x) + fouru * n8.x -
771 const double anx = -fourv * n9.x - n1.x + fouru * n1.x + n3.x - fourw * n3.x +
772 fourt * n4.x - fourt * n6.x + fourv * n7.x - fouru * n8.x +
774 const double aay = n1.y - fouru * n1.y - n3.y + fourw * n3.y - fourt * n4.y +
775 fourt * n6.y + fourv * (n9.y - n7.y) + fouru * n8.y -
777 const double any = -fourv * n9.y - n1.y + fouru * n1.y + n3.y - fourw * n3.y +
778 fourt * n4.y - fourt * n6.y + fourv * n7.y - fouru * n8.y +
781 const double bbx = -fourw * n9.x - n1.x + fouru * n1.x + n2.x - fourv * n2.x +
782 fourt * n4.x - fourt * n5.x - fouru * n7.x + fourv * n7.x +
784 const double bnx = n1.x - fouru * n1.x - n2.x + fourv * n2.x - fourt * n4.x +
785 fourt * n5.x + fouru * n7.x - fourv * n7.x +
786 fourw * (n9.x - n8.x);
787 const double bby = -fourw * n9.y - n1.y + fouru * n1.y + n2.y - fourv * n2.y +
788 fourt * n4.y - fourt * n5.y - fouru * n7.y + fourv * n7.y +
790 const double bny = n1.y - fouru * n1.y - n2.y + fourv * n2.y - fourt * n4.y +
791 fourt * n5.y + fouru * n7.y - fourv * n7.y +
792 fourw * (n9.y - n8.y);
794 const double ccx = -fourv * n9.x + fourw * n9.x - n2.x + fourv * n2.x + n3.x -
795 fourw * n3.x + fourt * n5.x - fourt * n6.x + fouru * n7.x -
797 const double cnx = -fourw * n9.x + fourv * (n9.x - n2.x) + n2.x - n3.x +
798 fourw * n3.x - fourt * n5.x + fourt * n6.x - fouru * n7.x +
800 const double ccy = -fourv * n9.y + fourw * n9.y - n2.y + fourv * n2.y + n3.y -
801 fourw * n3.y + fourt * n5.y - fourt * n6.y + fouru * n7.y -
803 const double cny = -fourw * n9.y + fourv * (n9.y - n2.y) + n2.y - n3.y +
804 fourw * n3.y - fourt * n5.y + fourt * n6.y - fouru * n7.y +
807 const double ddy = (-1 + fourt) * n0.y - fourv * n9.y + n3.y - fourw * n3.y +
808 fouru * n4.y + fourv * n5.y - fourt * n6.y + fourw * n6.y -
810 const double ddx = (-1 + fourt) * n0.x - fourv * n9.x + n3.x - fourw * n3.x +
811 fouru * n4.x + fourv * n5.x - fourt * n6.x + fourw * n6.x -
814 const double eex = (-1 + fourt) * n0.x - fourw * n9.x + n2.x - fourv * n2.x +
815 fouru * n4.x - fourt * n5.x + fourv * n5.x + fourw * n6.x -
817 const double eey = (-1 + fourt) * n0.y - fourw * n9.y + n2.y - fourv * n2.y +
818 fouru * n4.y - fourt * n5.y + fourv * n5.y + fourw * n6.y -
822 (-1 + fourt) * n0.x + n1.x - fouru * n1.x +
823 4 * (-(t * n4.x) + u * n4.x + v * n5.x + w * n6.x - v * n7.x - w * n8.x);
825 (-1 + fourt) * n0.y + n1.y - fouru * n1.y +
826 4 * (-(t * n4.y) + u * n4.y + v * n5.y + w * n6.y - v * n7.y - w * n8.y);
829 det = -(anx * wwy + bnx * vvy + cnx * uuy) * ttz -
830 (aax * tty - ffx * vvy + ddx * uuy) * wwz +
831 (bnx * tty - ffx * wwy + eex * uuy) * vvz +
832 (cnx * tty + ddx * wwy - eex * vvy) * uuz;
834 jac[0][0] = -(uux * vvy - vvx * uuy) * wwz + (uux * wwy - wwx * uuy) * vvz +
835 (-vvx * wwy + wwx * vvy) * uuz;
837 jac[0][1] = aay * wwz + bby * vvz + ccy * uuz;
838 jac[0][2] = anx * wwz + bnx * vvz + cnx * uuz;
839 jac[0][3] = aax * wwy + bbx * vvy + ccx * uuy;
841 jac[1][0] = -(-vvx * wwy + wwx * vvy) * ttz + (-vvx * tty + ttx * vvy) * wwz -
842 (-wwx * tty + ttx * wwy) * vvz;
844 jac[1][1] = cny * ttz + ddy * wwz - eey * vvz;
845 jac[1][2] = ccx * ttz - ddx * wwz + eex * vvz;
846 jac[1][3] = cnx * tty + ddx * wwy - eex * vvy;
848 jac[2][0] = (uux * vvy - vvx * uuy) * ttz + (-uux * tty + ttx * uuy) * vvz -
849 (-vvx * tty + ttx * vvy) * uuz;
851 jac[2][1] = any * ttz + ffy * vvz - ddy * uuz;
852 jac[2][2] = aax * ttz - ffx * vvz + ddx * uuz;
853 jac[2][3] = anx * tty + ffx * vvy - ddx * uuy;
855 jac[3][0] = -(uux * wwy - wwx * uuy) * ttz - (-uux * tty + ttx * uuy) * wwz +
856 (-wwx * tty + ttx * wwy) * uuz;
858 jac[3][1] = bny * ttz - ffy * wwz + eey * uuz;
859 jac[3][2] = bbx * ttz + ffx * wwz - eex * uuz;
860 jac[3][3] = bnx * tty - ffx * wwy + eex * uuy;
863void ComponentFieldMap::JacobianCube(
const Element& element,
const double t1,
864 const double t2,
const double t3,
866 std::vector<TMatrixD*>& dN)
const {
869 std::cerr <<
" Pointer to Jacobian matrix is empty!\n";
875 double N1[3] = {-1 * (1 - t2) * (1 - t3), (1 - t1) * -1 * (1 - t3),
876 (1 - t1) * (1 - t2) * -1};
877 double N2[3] = {+1 * (1 - t2) * (1 - t3), (1 + t1) * -1 * (1 - t3),
878 (1 + t1) * (1 - t2) * -1};
879 double N3[3] = {+1 * (1 + t2) * (1 - t3), (1 + t1) * +1 * (1 - t3),
880 (1 + t1) * (1 + t2) * -1};
881 double N4[3] = {-1 * (1 + t2) * (1 - t3), (1 - t1) * +1 * (1 - t3),
882 (1 - t1) * (1 + t2) * -1};
883 double N5[3] = {-1 * (1 - t2) * (1 + t3), (1 - t1) * -1 * (1 + t3),
884 (1 - t1) * (1 - t2) * +1};
885 double N6[3] = {+1 * (1 - t2) * (1 + t3), (1 + t1) * -1 * (1 + t3),
886 (1 + t1) * (1 - t2) * +1};
887 double N7[3] = {+1 * (1 + t2) * (1 + t3), (1 + t1) * +1 * (1 + t3),
888 (1 + t1) * (1 + t2) * +1};
889 double N8[3] = {-1 * (1 + t2) * (1 + t3), (1 - t1) * +1 * (1 + t3),
890 (1 - t1) * (1 + t2) * +1};
892 TMatrixD* m_N1 =
new TMatrixD(3, 1, N1);
893 *m_N1 = (1. / 8. * (*m_N1));
895 TMatrixD* m_N2 =
new TMatrixD(3, 1, N2);
896 *m_N2 = (1. / 8. * (*m_N2));
898 TMatrixD* m_N3 =
new TMatrixD(3, 1, N3);
899 *m_N3 = (1. / 8. * (*m_N3));
901 TMatrixD* m_N4 =
new TMatrixD(3, 1, N4);
902 *m_N4 = (1. / 8. * (*m_N4));
904 TMatrixD* m_N5 =
new TMatrixD(3, 1, N5);
905 *m_N5 = (1. / 8. * (*m_N5));
907 TMatrixD* m_N6 =
new TMatrixD(3, 1, N6);
908 *m_N6 = (1. / 8. * (*m_N6));
910 TMatrixD* m_N7 =
new TMatrixD(3, 1, N7);
911 *m_N7 = (1. / 8. * (*m_N7));
913 TMatrixD* m_N8 =
new TMatrixD(3, 1, N8);
914 *m_N8 = (1. / 8. * (*m_N8));
917 for (
int j = 0; j < 8; ++j) {
918 const Node& node =
nodes[element.emap[j]];
919 (*jac)(0, 0) += node.x * ((*dN.at(j))(0, 0));
920 (*jac)(0, 1) += node.y * ((*dN.at(j))(0, 0));
921 (*jac)(0, 2) += node.z * ((*dN.at(j))(0, 0));
922 (*jac)(1, 0) += node.x * ((*dN.at(j))(1, 0));
923 (*jac)(1, 1) += node.y * ((*dN.at(j))(1, 0));
924 (*jac)(1, 2) += node.z * ((*dN.at(j))(1, 0));
925 (*jac)(2, 0) += node.x * ((*dN.at(j))(2, 0));
926 (*jac)(2, 1) += node.y * ((*dN.at(j))(2, 0));
927 (*jac)(2, 2) += node.z * ((*dN.at(j))(2, 0));
932 std::cout <<
m_className <<
"::JacobianCube:" << std::endl;
933 std::cout <<
" Det.: " << jac->Determinant() << std::endl;
934 std::cout <<
" Jacobian matrix.: " << std::endl;
935 jac->Print(
"%11.10g");
936 std::cout <<
" Hexahedral coordinates (t, u, v) = (" << t1 <<
"," << t2
937 <<
"," << t3 <<
")" << std::endl;
938 std::cout <<
" Node xyzV" << std::endl;
939 for (
int j = 0; j < 8; ++j) {
940 const Node& node =
nodes[element.emap[j]];
941 std::cout <<
" " << element.emap[j] <<
" " << node.x
942 <<
" " << node.y <<
" " << node.z <<
" "
943 << node.v << std::endl;
948int ComponentFieldMap::Coordinates3(
const double x,
const double y,
949 const double z,
double& t1,
double& t2,
950 double& t3,
double& t4,
double jac[4][4],
951 double& det,
const Element& element)
const {
954 std::cout <<
" Point (" <<
x <<
", " <<
y <<
", " <<
z <<
")\n";
961 t1 = t2 = t3 = t4 = 0;
964 const Node& n0 =
nodes[element.emap[0]];
965 const Node& n1 =
nodes[element.emap[1]];
966 const Node& n2 =
nodes[element.emap[2]];
967 const double tt1 = (
x - n1.x) * (n2.y - n1.y) - (
y - n1.y) * (n2.x - n1.x);
968 const double tt2 = (
x - n2.x) * (n0.y - n2.y) - (
y - n2.y) * (n0.x - n2.x);
969 const double tt3 = (
x - n0.x) * (n1.y - n0.y) - (
y - n0.y) * (n1.x - n0.x);
971 (n0.x - n1.x) * (n2.y - n1.y) - (n2.x - n1.x) * (n0.y - n1.y);
973 (n1.x - n2.x) * (n0.y - n2.y) - (n0.x - n2.x) * (n1.y - n2.y);
975 (n2.x - n0.x) * (n1.y - n0.y) - (n1.x - n0.x) * (n2.y - n0.y);
976 if (f1 == 0 || f2 == 0 || f3 == 0) {
978 std::cerr <<
" Calculation of linear coordinates failed; abandoned.\n";
985 const Node& n3 =
nodes[element.emap[3]];
986 const Node& n4 =
nodes[element.emap[4]];
987 const Node& n5 =
nodes[element.emap[5]];
990 double td1 = t1, td2 = t2, td3 = t3;
991 bool converged =
false;
992 for (
int iter = 0; iter < 10; iter++) {
995 std::cout <<
" Iteration " << iter <<
": (u, v, w) = (" << td1
996 <<
", " << td2 <<
", " << td3 <<
"), sum = " << td1 + td2 + td3
1000 const double xr = n0.x * td1 * (2 * td1 - 1) + n1.x * td2 * (2 * td2 - 1) +
1001 n2.x * td3 * (2 * td3 - 1) + n3.x * 4 * td1 * td2 +
1002 n4.x * 4 * td1 * td3 + n5.x * 4 * td2 * td3;
1003 const double yr = n0.y * td1 * (2 * td1 - 1) + n1.y * td2 * (2 * td2 - 1) +
1004 n2.y * td3 * (2 * td3 - 1) + n3.y * 4 * td1 * td2 +
1005 n4.y * 4 * td1 * td3 + n5.y * 4 * td2 * td3;
1006 const double sr = td1 + td2 + td3;
1008 Jacobian3(element, td1, td2, td3, det, jac);
1010 const double diff[3] = {1 - sr,
x - xr,
y - yr};
1012 const double invdet = 1. / det;
1013 double corr[3] = {0., 0., 0.};
1014 for (
int l = 0; l < 3; l++) {
1015 for (
int k = 0; k < 3; k++) {
1016 corr[l] += jac[l][k] * diff[k] * invdet;
1022 std::cout <<
" Difference vector: (1, x, y) = (" << diff[0] <<
", "
1023 << diff[1] <<
", " << diff[2] <<
").\n";
1024 std::cout <<
" Correction vector: (u, v, w) = (" << corr[0] <<
", "
1025 << corr[1] <<
", " << corr[2] <<
").\n";
1032 if (
fabs(corr[0]) < 1.0e-5 &&
fabs(corr[1]) < 1.0e-5 &&
1033 fabs(corr[2]) < 1.0e-5) {
1035 std::cout <<
m_className <<
"::Coordinates3: Convergence reached.";
1043 const double xmin = std::min({n0.x, n1.x, n2.x});
1044 const double xmax = std::max({n0.x, n1.x, n2.x});
1045 const double ymin = std::min({n0.y, n1.y, n2.y});
1046 const double ymax = std::max({n0.y, n1.y, n2.y});
1047 if (x >= xmin && x <= xmax && y >= ymin && y <= ymax) {
1049 std::cout <<
" No convergence achieved "
1050 <<
"when refining internal isoparametric coordinates\n"
1051 <<
" at position (" <<
x <<
", " <<
y <<
").\n";
1052 t1 = t2 = t3 = t4 = 0;
1064 std::cout <<
" Convergence reached at (t1, t2, t3) = (" << t1 <<
", "
1065 << t2 <<
", " << t3 <<
").\n";
1070 double xr = n0.x * td1 * (2 * td1 - 1) + n1.x * td2 * (2 * td2 - 1) +
1071 n2.x * td3 * (2 * td3 - 1) + n3.x * 4 * td1 * td2 +
1072 n4.x * 4 * td1 * td3 + n5.x * 4 * td2 * td3;
1073 double yr = n0.y * td1 * (2 * td1 - 1) + n1.y * td2 * (2 * td2 - 1) +
1074 n2.y * td3 * (2 * td3 - 1) + n3.y * 4 * td1 * td2 +
1075 n4.y * 4 * td1 * td3 + n5.y * 4 * td2 * td3;
1076 double sr = td1 + td2 + td3;
1078 std::cout <<
" Position requested: (" <<
x <<
", " <<
y <<
")\n";
1079 std::cout <<
" Reconstructed: (" << xr <<
", " << yr <<
")\n";
1080 std::cout <<
" Difference: (" <<
x - xr <<
", " <<
y - yr
1082 std::cout <<
" Checksum - 1: " << sr - 1 <<
"\n";
1090int ComponentFieldMap::Coordinates4(
const double x,
const double y,
1091 const double z,
double& t1,
double& t2,
1092 double& t3,
double& t4,
double jac[4][4],
1093 double& det,
const Element& element)
const {
1097 std::cout <<
" Point (" <<
x <<
", " <<
y <<
", " <<
z <<
")\n";
1104 t1 = t2 = t3 = t4 = 0.;
1106 const Node& n0 =
nodes[element.emap[0]];
1107 const Node& n1 =
nodes[element.emap[1]];
1108 const Node& n2 =
nodes[element.emap[2]];
1109 const Node& n3 =
nodes[element.emap[3]];
1111 const double dd = -(n0.x * n1.y) + n3.x * n2.y - n2.x * n3.y +
1112 x * (-n0.y + n1.y - n2.y + n3.y) + n1.x * (n0.y -
y) +
1113 (n0.x + n2.x - n3.x) *
y;
1114 det = -(-((n0.x - n3.x) * (n1.y - n2.y)) + (n1.x - n2.x) * (n0.y - n3.y)) *
1115 (2 *
x * (-n0.y + n1.y + n2.y - n3.y) -
1116 (n0.x + n3.x) * (n1.y + n2.y - 2 *
y) +
1117 n1.x * (n0.y + n3.y - 2 * y) + n2.x * (n0.y + n3.y - 2 *
y)) +
1125 <<
" No solution found for isoparametric coordinates\n"
1126 <<
" because the determinant " << det <<
" is < 0.\n";
1132 double prod = ((n2.x - n3.x) * (n0.y - n1.y) - (n0.x - n1.x) * (n2.y - n3.y));
1135 ((n0.x - n1.x) * (n0.x - n1.x) + (n0.y - n1.y) * (n0.y - n1.y)) *
1136 ((n2.x - n3.x) * (n2.x - n3.x) + (n2.y - n3.y) * (n2.y - n3.y))) {
1137 t1 = (-(n3.x * n0.y) + x * n0.y + n2.x * n1.y - x * n1.y - n1.x * n2.y +
1138 x * n2.y + n0.x * n3.y - x * n3.y - n0.x * y + n1.x * y - n2.x * y +
1139 n3.x * y +
sqrt(det)) /
1142 double xp = n0.y - n1.y;
1143 double yp = n1.x - n0.x;
1144 double dn =
sqrt(xp * xp + yp * yp);
1147 <<
" Element appears to be degenerate in the 1 - 2 axis.\n";
1152 double dpoint = xp * (
x - n0.x) + yp * (y - n0.y);
1153 double dbox = xp * (n3.x - n0.x) + yp * (n3.y - n0.y);
1156 <<
" Element appears to be degenerate in the 1 - 3 axis.\n";
1159 double t = -1 + 2 * dpoint / dbox;
1160 double xt1 = n0.x + 0.5 * (t + 1) * (n3.x - n0.x);
1161 double yt1 = n0.y + 0.5 * (t + 1) * (n3.y - n0.y);
1162 double xt2 = n1.x + 0.5 * (t + 1) * (n2.x - n1.x);
1163 double yt2 = n1.y + 0.5 * (t + 1) * (n2.y - n1.y);
1164 dn = (xt1 - xt2) * (xt1 - xt2) + (yt1 - yt2) * (yt1 - yt2);
1168 <<
" Coordinate requested at convergence point of element.\n";
1171 t1 = -1 + 2 * ((
x - xt1) * (xt2 - xt1) + (
y - yt1) * (yt2 - yt1)) / dn;
1175 prod = ((n0.x - n3.x) * (n1.y - n2.y) - (n1.x - n2.x) * (n0.y - n3.y));
1178 ((n0.x - n3.x) * (n0.x - n3.x) + (n0.y - n3.y) * (n0.y - n3.y)) *
1179 ((n1.x - n2.x) * (n1.x - n2.x) + (n1.y - n2.y) * (n1.y - n2.y))) {
1180 t2 = (-(n1.x * n0.y) + x * n0.y + n0.x * n1.y - x * n1.y - n3.x * n2.y +
1181 x * n2.y + n2.x * n3.y - x * n3.y - n0.x * y + n1.x * y - n2.x * y +
1182 n3.x * y -
sqrt(det)) /
1185 double xp = n0.y - n3.y;
1186 double yp = n3.x - n0.x;
1187 double dn =
sqrt(xp * xp + yp * yp);
1190 <<
" Element appears to be degenerate in the 1 - 4 axis.\n";
1195 double dpoint = xp * (
x - n0.x) + yp * (y - n0.y);
1196 double dbox = xp * (n1.x - n0.x) + yp * (n1.y - n0.y);
1199 <<
" Element appears to be degenerate in the 1 - 2 axis.\n";
1202 double t = -1 + 2 * dpoint / dbox;
1203 double xt1 = n0.x + 0.5 * (t + 1) * (n1.x - n0.x);
1204 double yt1 = n0.y + 0.5 * (t + 1) * (n1.y - n0.y);
1205 double xt2 = n3.x + 0.5 * (t + 1) * (n2.x - n3.x);
1206 double yt2 = n3.y + 0.5 * (t + 1) * (n2.y - n3.y);
1207 dn = (xt1 - xt2) * (xt1 - xt2) + (yt1 - yt2) * (yt1 - yt2);
1211 <<
" Coordinate requested at convergence point of element.\n";
1214 t2 = -1 + 2 * ((
x - xt1) * (xt2 - xt1) + (
y - yt1) * (yt2 - yt1)) / dn;
1218 std::cout <<
" Isoparametric (u, v): (" << t1 <<
", " << t2 <<
").\n";
1224 n0.x * (1 - t1) * (1 - t2) * 0.25 + n1.x * (1 + t1) * (1 - t2) * 0.25 +
1225 n2.x * (1 + t1) * (1 + t2) * 0.25 + n3.x * (1 - t1) * (1 + t2) * 0.25;
1227 n0.y * (1 - t1) * (1 - t2) * 0.25 + n1.y * (1 + t1) * (1 - t2) * 0.25 +
1228 n2.y * (1 + t1) * (1 + t2) * 0.25 + n3.y * (1 - t1) * (1 + t2) * 0.25;
1230 std::cout <<
" Position requested: (" <<
x <<
", " <<
y <<
")\n";
1231 std::cout <<
" Reconstructed: (" << xr <<
", " << yr <<
")\n";
1232 std::cout <<
" Difference: (" <<
x - xr <<
", " <<
y - yr
1241 jac[0][0] = jac[0][1] = jac[0][2] = jac[0][3] = 0.;
1242 jac[1][0] = jac[1][1] = jac[1][2] = jac[1][3] = 0.;
1243 jac[2][0] = jac[2][1] = jac[2][2] = jac[2][3] = 0.;
1244 jac[3][0] = jac[3][1] = jac[3][2] = jac[3][3] = 0.;
1247int ComponentFieldMap::Coordinates5(
const double x,
const double y,
1248 const double z,
double& t1,
double& t2,
1249 double& t3,
double& t4,
double jac[4][4],
1250 double& det,
const Element& element)
const {
1254 std::cout <<
" Point (" <<
x <<
", " <<
y <<
", " <<
z <<
")\n";
1261 t1 = t2 = t3 = t4 = 0;
1264 if (element.degenerate) {
1266 <<
" Received degenerate element.\n";
1274 if (Coordinates4(x, y, z, t1, t2, t3, t4, jac, det, element) > 0) {
1277 std::cout <<
" Failure to obtain linear estimate of isoparametric "
1284 if (t1 < -(1 + f) || t1 > (1 + f) || t2 < -(1 + f) || t2 > (1 + f)) {
1287 std::cout <<
" Point far outside, (t1,t2) = (" << t1 <<
", " << t2
1294 double td1 = t1, td2 = t2;
1295 const Node& n0 =
nodes[element.emap[0]];
1296 const Node& n1 =
nodes[element.emap[1]];
1297 const Node& n2 =
nodes[element.emap[2]];
1298 const Node& n3 =
nodes[element.emap[3]];
1299 const Node& n4 =
nodes[element.emap[4]];
1300 const Node& n5 =
nodes[element.emap[5]];
1301 const Node& n6 =
nodes[element.emap[6]];
1302 const Node& n7 =
nodes[element.emap[7]];
1303 bool converged =
false;
1304 for (
int iter = 0; iter < 10; iter++) {
1307 std::cout <<
" Iteration " << iter <<
": (t1, t2) = (" << td1
1308 <<
", " << td2 <<
").\n";
1311 const double r0 = (-(1 - td1) * (1 - td2) * (1 + td1 + td2)) * 0.25;
1312 const double r1 = (-(1 + td1) * (1 - td2) * (1 - td1 + td2)) * 0.25;
1313 const double r2 = (-(1 + td1) * (1 + td2) * (1 - td1 - td2)) * 0.25;
1314 const double r3 = (-(1 - td1) * (1 + td2) * (1 + td1 - td2)) * 0.25;
1315 const double r4 = (1 - td1) * (1 + td1) * (1 - td2) * 0.5;
1316 const double r5 = (1 + td1) * (1 + td2) * (1 - td2) * 0.5;
1317 const double r6 = (1 - td1) * (1 + td1) * (1 + td2) * 0.5;
1318 const double r7 = (1 - td1) * (1 + td2) * (1 - td2) * 0.5;
1319 double xr = n0.x * r0 + n1.x * r1 + n2.x * r2 + n3.x * r3 + n4.x * r4 +
1320 n5.x * r5 + n6.x * r6 + n7.x * r7;
1321 double yr = n0.y * r0 + n1.y * r1 + n2.y * r2 + n3.y * r3 + n4.y * r4 +
1322 n5.y * r5 + n6.y * r6 + n7.y * r7;
1324 Jacobian5(element, td1, td2, det, jac);
1326 double diff[2] = {
x - xr,
y - yr};
1328 double corr[2] = {0., 0.};
1329 for (
int l = 0; l < 2; ++l) {
1330 for (
int k = 0; k < 2; ++k) {
1331 corr[l] += jac[l][k] * diff[k] / det;
1337 std::cout <<
" Difference vector: (x, y) = (" << diff[0] <<
", "
1338 << diff[1] <<
").\n";
1339 std::cout <<
" Correction vector: (t1, t2) = (" << corr[0] <<
", "
1340 << corr[1] <<
").\n";
1346 if (
fabs(corr[0]) < 1.0e-5 &&
fabs(corr[1]) < 1.0e-5) {
1349 std::cout <<
" Convergence reached.\n";
1357 double xmin = std::min({n0.x, n1.x, n2.x, n3.x, n4.x, n5.x, n6.x, n7.x});
1358 double xmax = std::max({n0.x, n1.x, n2.x, n3.x, n4.x, n5.x, n6.x, n7.x});
1359 double ymin = std::min({n0.y, n1.y, n2.y, n3.y, n4.y, n5.y, n6.y, n7.y});
1360 double ymax = std::max({n0.y, n1.y, n2.y, n3.y, n4.y, n5.y, n6.y, n7.y});
1361 if (x >= xmin && x <= xmax && y >= ymin && y <= ymax) {
1363 <<
" No convergence achieved "
1364 <<
"when refining internal isoparametric coordinates\n"
1365 <<
" at position (" <<
x <<
", " <<
y <<
").\n";
1378 std::cout <<
" Convergence reached at (t1, t2) = (" << t1 <<
", " << t2
1384 const double r0 = (-(1 - td1) * (1 - td2) * (1 + td1 + td2)) * 0.25;
1385 const double r1 = (-(1 + td1) * (1 - td2) * (1 - td1 + td2)) * 0.25;
1386 const double r2 = (-(1 + td1) * (1 + td2) * (1 - td1 - td2)) * 0.25;
1387 const double r3 = (-(1 - td1) * (1 + td2) * (1 + td1 - td2)) * 0.25;
1388 const double r4 = (1 - td1) * (1 + td1) * (1 - td2) * 0.5;
1389 const double r5 = (1 + td1) * (1 + td2) * (1 - td2) * 0.5;
1390 const double r6 = (1 - td1) * (1 + td1) * (1 + td2) * 0.5;
1391 const double r7 = (1 - td1) * (1 + td2) * (1 - td2) * 0.5;
1392 double xr = n0.x * r0 + n1.x * r1 + n2.x * r2 + n3.x * r3 + n4.x * r4 +
1393 n5.x * r5 + n6.x * r6 + n7.x * r7;
1394 double yr = n0.y * r0 + n1.y * r1 + n2.y * r2 + n3.y * r3 + n4.y * r4 +
1395 n5.y * r5 + n6.y * r6 + n7.y * r7;
1397 std::cout <<
" Position requested: (" <<
x <<
", " <<
y <<
")\n";
1398 std::cout <<
" Reconstructed: (" << xr <<
", " << yr <<
")\n";
1399 std::cout <<
" Difference: (" <<
x - xr <<
", " <<
y - yr
1408int ComponentFieldMap::Coordinates12(
const double x,
const double y,
1409 const double z,
double& t1,
double& t2,
1410 double& t3,
double& t4,
1411 const Element& element)
const {
1414 <<
" Point (" <<
x <<
", " <<
y <<
", " <<
z <<
").\n";
1419 const Node& n0 =
nodes[element.emap[0]];
1420 const Node& n1 =
nodes[element.emap[1]];
1421 const Node& n2 =
nodes[element.emap[2]];
1422 const Node& n3 =
nodes[element.emap[3]];
1425 (n2.y - n1.y) * (n3.z - n1.z) - (n3.y - n1.y) * (n2.z - n1.z);
1427 (n2.z - n1.z) * (n3.x - n1.x) - (n3.z - n1.z) * (n2.x - n1.x);
1429 (n2.x - n1.x) * (n3.y - n1.y) - (n3.x - n1.x) * (n2.y - n1.y);
1430 t1 = (
x - n1.x) * f1x + (y - n1.y) * f1y + (
z - n1.z) * f1z;
1431 t1 = t1 / ((n0.x - n1.x) * f1x + (n0.y - n1.y) * f1y + (n0.z - n1.z) * f1z);
1433 (n0.y - n2.y) * (n3.z - n2.z) - (n3.y - n2.y) * (n0.z - n2.z);
1435 (n0.z - n2.z) * (n3.x - n2.x) - (n3.z - n2.z) * (n0.x - n2.x);
1437 (n0.x - n2.x) * (n3.y - n2.y) - (n3.x - n2.x) * (n0.y - n2.y);
1438 t2 = (
x - n2.x) * f2x + (y - n2.y) * f2y + (
z - n2.z) * f2z;
1439 t2 = t2 / ((n1.x - n2.x) * f2x + (n1.y - n2.y) * f2y + (n1.z - n2.z) * f2z);
1441 (n0.y - n3.y) * (n1.z - n3.z) - (n1.y - n3.y) * (n0.z - n3.z);
1443 (n0.z - n3.z) * (n1.x - n3.x) - (n1.z - n3.z) * (n0.x - n3.x);
1445 (n0.x - n3.x) * (n1.y - n3.y) - (n1.x - n3.x) * (n0.y - n3.y);
1446 t3 = (
x - n3.x) * f3x + (y - n3.y) * f3y + (
z - n3.z) * f3z;
1447 t3 = t3 / ((n2.x - n3.x) * f3x + (n2.y - n3.y) * f3y + (n2.z - n3.z) * f3z);
1449 (n2.y - n0.y) * (n1.z - n0.z) - (n1.y - n0.y) * (n2.z - n0.z);
1451 (n2.z - n0.z) * (n1.x - n0.x) - (n1.z - n0.z) * (n2.x - n0.x);
1453 (n2.x - n0.x) * (n1.y - n0.y) - (n1.x - n0.x) * (n2.y - n0.y);
1454 t4 = (
x - n0.x) * f4x + (y - n0.y) * f4y + (
z - n0.z) * f4z;
1455 t4 = t4 / ((n3.x - n0.x) * f4x + (n3.y - n0.y) * f4y + (n3.z - n0.z) * f4z);
1460 std::cout <<
" Tetrahedral coordinates (t, u, v, w) = (" << t1 <<
", "
1461 << t2 <<
", " << t3 <<
", " << t4
1462 <<
") sum = " << t1 + t2 + t3 + t4 <<
".\n";
1466 const double xr = n0.x * t1 + n1.x * t2 + n2.x * t3 + n3.x * t4;
1467 const double yr = n0.y * t1 + n1.y * t2 + n2.y * t3 + n3.y * t4;
1468 const double zr = n0.z * t1 + n1.z * t2 + n2.z * t3 + n3.z * t4;
1469 const double sr = t1 + t2 + t3 + t4;
1471 std::cout <<
" Position requested: (" <<
x <<
", " <<
y <<
", " <<
z
1473 std::cout <<
" Reconstructed: (" << xr <<
", " << yr <<
", "
1475 std::cout <<
" Difference: (" <<
x - xr <<
", " <<
y - yr
1476 <<
", " <<
z - zr <<
")\n";
1477 std::cout <<
" Checksum - 1: " << sr - 1 <<
"\n";
1485int ComponentFieldMap::Coordinates13(
const double x,
const double y,
1486 const double z,
double& t1,
double& t2,
1487 double& t3,
double& t4,
double jac[4][4],
1489 const Element& element)
const {
1492 std::cout <<
" Point (" <<
x <<
", " <<
y <<
", " <<
z <<
")\n";
1499 t1 = t2 = t3 = t4 = 0.;
1502 if (Coordinates12(x, y, z, t1, t2, t3, t4, element) > 0) {
1505 <<
" Failure to obtain linear estimate of isoparametric "
1512 const double f = 0.5;
1513 if (t1 < -f || t2 < -f || t3 < -f || t4 < -f || t1 > 1 + f || t2 > 1 + f ||
1514 t3 > 1 + f || t4 > 1 + f) {
1517 std::cout <<
" Linear isoparametric coordinates more than\n";
1518 std::cout <<
" f (" << f <<
") out of range.\n";
1525 double td1 = t1, td2 = t2, td3 = t3, td4 = t4;
1528 std::cout <<
" Iteration starts at (t1,t2,t3,t4) = (" << td1 <<
", "
1529 << td2 <<
", " << td3 <<
", " << td4 <<
").\n";
1531 const Node& n0 =
nodes[element.emap[0]];
1532 const Node& n1 =
nodes[element.emap[1]];
1533 const Node& n2 =
nodes[element.emap[2]];
1534 const Node& n3 =
nodes[element.emap[3]];
1535 const Node& n4 =
nodes[element.emap[4]];
1536 const Node& n5 =
nodes[element.emap[5]];
1537 const Node& n6 =
nodes[element.emap[6]];
1538 const Node& n7 =
nodes[element.emap[7]];
1539 const Node& n8 =
nodes[element.emap[8]];
1540 const Node& n9 =
nodes[element.emap[9]];
1543 bool converged =
false;
1544 double diff[4], corr[4];
1545 for (
int iter = 0; iter < 10; iter++) {
1548 std::cout <<
" Iteration " << iter <<
": (t1,t2,t3,t4) = (" << td1
1549 <<
", " << td2 <<
", " << td3 <<
", " << td4 <<
").\n";
1552 const double xr = n0.x * td1 * (2 * td1 - 1) + n1.x * td2 * (2 * td2 - 1) +
1553 n2.x * td3 * (2 * td3 - 1) + n3.x * td4 * (2 * td4 - 1) +
1554 n4.x * 4 * td1 * td2 + n5.x * 4 * td1 * td3 +
1555 n6.x * 4 * td1 * td4 + n7.x * 4 * td2 * td3 +
1556 n8.x * 4 * td2 * td4 + n9.x * 4 * td3 * td4;
1557 const double yr = n0.y * td1 * (2 * td1 - 1) + n1.y * td2 * (2 * td2 - 1) +
1558 n2.y * td3 * (2 * td3 - 1) + n3.y * td4 * (2 * td4 - 1) +
1559 n4.y * 4 * td1 * td2 + n5.y * 4 * td1 * td3 +
1560 n6.y * 4 * td1 * td4 + n7.y * 4 * td2 * td3 +
1561 n8.y * 4 * td2 * td4 + n9.y * 4 * td3 * td4;
1562 const double zr = n0.z * td1 * (2 * td1 - 1) + n1.z * td2 * (2 * td2 - 1) +
1563 n2.z * td3 * (2 * td3 - 1) + n3.z * td4 * (2 * td4 - 1) +
1564 n4.z * 4 * td1 * td2 + n5.z * 4 * td1 * td3 +
1565 n6.z * 4 * td1 * td4 + n7.z * 4 * td2 * td3 +
1566 n8.z * 4 * td2 * td4 + n9.z * 4 * td3 * td4;
1567 const double sr = td1 + td2 + td3 + td4;
1570 Jacobian13(element, td1, td2, td3, td4, det, jac);
1578 const double invdet = 1. / det;
1579 for (
int l = 0; l < 4; ++l) {
1581 for (
int k = 0; k < 4; ++k) {
1582 corr[l] += jac[l][k] * diff[k] * invdet;
1589 std::cout <<
" Difference vector: (1, x, y, z) = (" << diff[0]
1590 <<
", " << diff[1] <<
", " << diff[2] <<
", " << diff[3]
1592 std::cout <<
" Correction vector: (t1,t2,t3,t4) = (" << corr[0]
1593 <<
", " << corr[1] <<
", " << corr[2] <<
", " << corr[3]
1604 if (
fabs(corr[0]) < 1.0e-5 &&
fabs(corr[1]) < 1.0e-5 &&
1605 fabs(corr[2]) < 1.0e-5 &&
fabs(corr[3]) < 1.0e-5) {
1607 std::cout <<
m_className <<
"::Coordinates13: Convergence reached.\n";
1616 const double xmin = std::min({n0.x, n1.x, n2.x, n3.x});
1617 const double xmax = std::max({n0.x, n1.x, n2.x, n3.x});
1618 const double ymin = std::min({n0.y, n1.y, n2.y, n3.y});
1619 const double ymax = std::max({n0.y, n1.y, n2.y, n3.y});
1620 const double zmin = std::min({n0.z, n1.z, n2.z, n3.z});
1621 const double zmax = std::max({n0.z, n1.z, n2.z, n3.z});
1622 if (x >= xmin && x <= xmax && y >= ymin && y <= ymax && z >= zmin &&
1625 <<
" No convergence achieved "
1626 <<
"when refining internal isoparametric coordinates\n"
1627 <<
" at position (" <<
x <<
", " <<
y <<
", " <<
z <<
").\n";
1628 t1 = t2 = t3 = t4 = -1;
1640 std::cout <<
" Convergence reached at (t1, t2, t3, t4) = (" << t1 <<
", "
1641 << t2 <<
", " << t3 <<
", " << t4 <<
").\n";
1647 double xr = n0.x * td1 * (2 * td1 - 1) + n1.x * td2 * (2 * td2 - 1) +
1648 n2.x * td3 * (2 * td3 - 1) + n3.x * td4 * (2 * td4 - 1) +
1649 n4.x * 4 * td1 * td2 + n5.x * 4 * td1 * td3 +
1650 n6.x * 4 * td1 * td4 + n7.x * 4 * td2 * td3 +
1651 n8.x * 4 * td2 * td4 + n9.x * 4 * td3 * td4;
1652 double yr = n0.y * td1 * (2 * td1 - 1) + n1.y * td2 * (2 * td2 - 1) +
1653 n2.y * td3 * (2 * td3 - 1) + n3.y * td4 * (2 * td4 - 1) +
1654 n4.y * 4 * td1 * td2 + n5.y * 4 * td1 * td3 +
1655 n6.y * 4 * td1 * td4 + n7.y * 4 * td2 * td3 +
1656 n8.y * 4 * td2 * td4 + n9.y * 4 * td3 * td4;
1657 double zr = n0.z * td1 * (2 * td1 - 1) + n1.z * td2 * (2 * td2 - 1) +
1658 n2.z * td3 * (2 * td3 - 1) + n3.z * td4 * (2 * td4 - 1) +
1659 n4.z * 4 * td1 * td2 + n5.z * 4 * td1 * td3 +
1660 n6.z * 4 * td1 * td4 + n7.z * 4 * td2 * td3 +
1661 n8.z * 4 * td2 * td4 + n9.z * 4 * td3 * td4;
1662 double sr = td1 + td2 + td3 + td4;
1664 std::cout <<
" Position requested: (" <<
x <<
", " <<
y <<
", " <<
z
1666 std::cout <<
" Reconstructed: (" << xr <<
", " << yr <<
", "
1668 std::cout <<
" Difference: (" <<
x - xr <<
", " <<
y - yr
1669 <<
", " <<
z - zr <<
")\n";
1670 std::cout <<
" Checksum - 1: " << sr - 1 <<
"\n";
1678int ComponentFieldMap::CoordinatesCube(
const double x,
const double y,
1679 const double z,
double& t1,
double& t2,
1680 double& t3, TMatrixD*& jac,
1681 std::vector<TMatrixD*>& dN,
1682 const Element& element)
const {
1700 const Node& n0 =
nodes[element.emap[0]];
1701 const Node& n2 =
nodes[element.emap[2]];
1702 const Node& n3 =
nodes[element.emap[3]];
1703 const Node& n7 =
nodes[element.emap[7]];
1710 t2 = (2. * (
x - n3.x) / (n0.x - n3.x) - 1) * -1.;
1711 t1 = 2. * (
y - n3.y) / (n2.y - n3.y) - 1;
1712 t3 = 2. * (
z - n3.z) / (n7.z - n3.z) - 1;
1716 n[0] = 1. / 8 * (1 - t1) * (1 - t2) * (1 - t3);
1717 n[1] = 1. / 8 * (1 + t1) * (1 - t2) * (1 - t3);
1718 n[2] = 1. / 8 * (1 + t1) * (1 + t2) * (1 - t3);
1719 n[3] = 1. / 8 * (1 - t1) * (1 + t2) * (1 - t3);
1720 n[4] = 1. / 8 * (1 - t1) * (1 - t2) * (1 + t3);
1721 n[5] = 1. / 8 * (1 + t1) * (1 - t2) * (1 + t3);
1722 n[6] = 1. / 8 * (1 + t1) * (1 + t2) * (1 + t3);
1723 n[7] = 1. / 8 * (1 - t1) * (1 + t2) * (1 + t3);
1729 for (
int i = 0; i < 8; i++) {
1730 const Node& node =
nodes[element.emap[i]];
1731 xr += node.x * n[i];
1732 yr += node.y * n[i];
1733 zr += node.z * n[i];
1735 double sr = n[0] + n[1] + n[2] + n[3] + n[4] + n[5] + n[6] + n[7];
1736 std::cout <<
m_className <<
"::CoordinatesCube:\n";
1737 std::cout <<
" Position requested: (" <<
x <<
"," <<
y <<
"," <<
z
1739 std::cout <<
" Position reconstructed: (" << xr <<
"," << yr <<
"," << zr
1741 std::cout <<
" Difference: (" << (
x - xr) <<
"," << (y - yr)
1742 <<
"," << (
z - zr) <<
")\n";
1743 std::cout <<
" Hexahedral coordinates (t, u, v) = (" << t1 <<
"," << t2
1744 <<
"," << t3 <<
")\n";
1745 std::cout <<
" Checksum - 1: " << (sr - 1) <<
"\n";
1747 if (jac != 0) JacobianCube(element, t1, t2, t3, jac, dN);
1756 std::cerr <<
m_className <<
"::UpdatePeriodicityCommon:\n";
1757 std::cerr <<
" No valid field map available.\n";
1761 for (
unsigned int i = 0; i < 3; ++i) {
1764 std::cerr <<
m_className <<
"::UpdatePeriodicityCommon:\n"
1765 <<
" Both simple and mirror periodicity requested. Reset.\n";
1782 <<
" Axial symmetry has been requested but the map\n"
1783 <<
" does not cover an integral fraction of 2 pi. Reset.\n";
1794 std::cerr <<
m_className <<
"::UpdatePeriodicityCommon:\n";
1795 std::cerr <<
" Only 1 rotational symmetry allowed; reset.\n";
1804 std::cerr <<
m_className <<
"::UpdatePeriodicityCommon:\n";
1805 std::cerr <<
" Not allowed to combine rotational symmetry\n";
1806 std::cerr <<
" and axial periodicity; reset.\n";
1816 std::cerr <<
m_className <<
"::UpdatePeriodicityCommon:\n";
1817 std::cerr <<
" Rotational symmetry requested, \n";
1818 std::cerr <<
" but x-range straddles 0; reset.\n";
1825 for (
unsigned int i = 0; i < 3; ++i) {
1894 for (
unsigned int i = 0; i < 3; ++i) {
1908 std::cerr <<
m_className <<
"::UpdatePeriodicity2d:\n";
1909 std::cerr <<
" No valid field map available.\n";
1915 std::cerr <<
m_className <<
"::UpdatePeriodicity2d:\n";
1916 std::cerr <<
" Simple or mirror periodicity along z\n";
1917 std::cerr <<
" requested for a 2d map; reset.\n";
1925 std::cerr <<
m_className <<
"::UpdatePeriodicity2d:\n";
1926 std::cerr <<
" Axial symmetry has been requested \n";
1927 std::cerr <<
" around x or y for a 2D map; reset.\n";
1946 std::cerr <<
" Field map not yet set.\n";
1951 std::cerr <<
" Number of nodes < 1.\n";
1961 for (
const auto& node :
nodes) {
1962 const std::array<double, 3> pos = {{node.x, node.y, node.z}};
1963 for (
unsigned int i = 0; i < 3; ++i) {
1970 if (node.y != 0 || node.z != 0) {
1971 const double ang = atan2(node.z, node.y);
1981 if (node.z != 0 || node.x != 0) {
1982 const double ang = atan2(node.x, node.z);
1992 if (node.x != 0 || node.y != 0) {
1993 const double ang = atan2(node.y, node.x);
2005 for (
unsigned int i = 0; i < 3; ++i) {
2033 std::cout <<
" Dimensions of the elementary block\n";
2039 std::cout <<
" Periodicities\n";
2040 const std::array<std::string, 3> axes = {{
"x",
"y",
"z"}};
2041 for (
unsigned int i = 0; i < 3; ++i) {
2042 std::cout <<
" " << axes[i] <<
":";
2044 std::cout <<
" simple with length " <<
m_cells[i] <<
" cm";
2047 std::cout <<
" mirror with length " <<
m_cells[i] <<
" cm";
2050 std::cout <<
" axial " << int(0.5 +
m_mapna[i]) <<
"-fold repetition";
2055 std::cout <<
" none";
2061 double& xmax,
double& ymax,
2075 bool& xmirrored,
bool& ymirrored,
2076 bool& zmirrored,
double& rcoordinate,
2077 double& rotation)
const {
2083 double auxr, auxphi;
2092 if (nx != 2 * (nx / 2)) {
2099 auxr = sqrt(zpos * zpos + ypos * ypos);
2100 auxphi = atan2(zpos, ypos);
2109 auxphi = auxphi - rotation;
2110 ypos = auxr * cos(auxphi);
2111 zpos = auxr * sin(auxphi);
2123 if (ny != 2 * (ny / 2)) {
2130 auxr = sqrt(xpos * xpos + zpos * zpos);
2131 auxphi = atan2(xpos, zpos);
2140 auxphi = auxphi - rotation;
2141 zpos = auxr * cos(auxphi);
2142 xpos = auxr * sin(auxphi);
2154 if (nz != 2 * (nz / 2)) {
2161 auxr = sqrt(ypos * ypos + xpos * xpos);
2162 auxphi = atan2(ypos, xpos);
2171 auxphi = auxphi - rotation;
2172 xpos = auxr * cos(auxphi);
2173 ypos = auxr * sin(auxphi);
2178 double zcoordinate = 0;
2180 rcoordinate = sqrt(ypos * ypos + zpos * zpos);
2183 rcoordinate = sqrt(xpos * xpos + zpos * zpos);
2186 rcoordinate = sqrt(xpos * xpos + ypos * ypos);
2199 double& xpos,
double& ypos,
double& zpos,
2200 bool& xmirrored,
bool& ymirrored,
2201 bool& zmirrored,
double& rcoordinate,
2202 double& rotation)
const {
2204 if (xmirrored) ex = -ex;
2205 if (ymirrored) ey = -ey;
2206 if (zmirrored) ez = -ez;
2211 er = sqrt(ey * ey + ez * ez);
2212 theta = atan2(ez, ey);
2214 ey = er * cos(theta);
2215 ez = er * sin(theta);
2218 er = sqrt(ez * ez + ex * ex);
2219 theta = atan2(ex, ez);
2221 ez = er * cos(theta);
2222 ex = er * sin(theta);
2225 er = sqrt(ex * ex + ey * ey);
2226 theta = atan2(ey, ex);
2228 ex = er * cos(theta);
2229 ey = er * sin(theta);
2239 if (rcoordinate <= 0) {
2245 ey = er * ypos / rcoordinate;
2246 ez = er * zpos / rcoordinate;
2250 if (rcoordinate <= 0) {
2255 ex = er * xpos / rcoordinate;
2257 ez = er * zpos / rcoordinate;
2261 if (rcoordinate <= 0) {
2266 ex = er * xpos / rcoordinate;
2267 ey = er * ypos / rcoordinate;
2290void ComponentFieldMap::CalculateElementBoundingBoxes(
void) {
2299 const Node& n0 =
nodes[element.emap[0]];
2300 const Node& n1 =
nodes[element.emap[1]];
2301 const Node& n2 =
nodes[element.emap[2]];
2302 const Node& n3 =
nodes[element.emap[3]];
2303 element.xmin = std::min({n0.x, n1.x, n2.x, n3.x});
2304 element.xmax = std::max({n0.x, n1.x, n2.x, n3.x});
2305 element.ymin = std::min({n0.y, n1.y, n2.y, n3.y});
2306 element.ymax = std::max({n0.y, n1.y, n2.y, n3.y});
2307 element.zmin = std::min({n0.z, n1.z, n2.z, n3.z});
2308 element.zmax = std::max({n0.z, n1.z, n2.z, n3.z});
2310 constexpr double f = 0.2;
2311 const double tolx = f * (element.xmax - element.xmin);
2312 element.xmin -= tolx;
2313 element.xmax += tolx;
2314 const double toly = f * (element.ymax - element.ymin);
2315 element.ymin -= toly;
2316 element.ymax += toly;
2317 const double tolz = f * (element.zmax - element.zmin);
2318 element.zmin -= tolz;
2319 element.zmax += tolz;
2323bool ComponentFieldMap::InitializeTetrahedralTree() {
2331 std::cout <<
m_className <<
"::InitializeTetrahedralTree:\n"
2332 <<
" About to initialize the tetrahedral tree.\n";
2336 if (!m_cacheElemBoundingBoxes) CalculateElementBoundingBoxes();
2338 if (
nodes.empty()) {
2339 std::cerr <<
m_className <<
"::InitializeTetrahedralTree: Empty mesh.\n";
2344 double xmin =
nodes.front().x;
2345 double ymin =
nodes.front().y;
2346 double zmin =
nodes.front().z;
2350 for (
unsigned int i = 0; i <
nodes.size(); i++) {
2351 const Node& n =
nodes[i];
2352 xmin = std::min(xmin, n.x);
2353 xmax = std::max(xmax, n.x);
2354 ymin = std::min(ymin, n.y);
2355 ymax = std::max(ymax, n.y);
2356 zmin = std::min(zmin, n.z);
2357 zmax = std::max(zmax, n.z);
2361 std::cout <<
" Bounding box:\n"
2362 << std::scientific <<
"\tx: " << xmin <<
" -> " << xmax <<
"\n"
2363 << std::scientific <<
"\ty: " << ymin <<
" -> " << ymax <<
"\n"
2364 << std::scientific <<
"\tz: " << zmin <<
" -> " << zmax <<
"\n";
2367 const double hx = 0.5 * (xmax - xmin);
2368 const double hy = 0.5 * (ymax - ymin);
2369 const double hz = 0.5 * (zmax - zmin);
2370 m_tetTree =
new TetrahedralTree(Vec3(xmin + hx, ymin + hy, zmin + hz),
2373 if (
m_debug) std::cout <<
" Tree instantiated.\n";
2376 for (
unsigned int i = 0; i <
nodes.size(); i++) {
2377 const Node& n =
nodes[i];
2381 if (
m_debug) std::cout <<
" Tree nodes initialized successfully.\n";
2384 for (
unsigned int i = 0; i <
elements.size(); i++) {
2386 const double bb[6] = {e.xmin, e.ymin, e.zmin, e.xmax, e.ymax, e.zmax};
2390 std::cout <<
m_className <<
"::InitializeTetrahedralTree: Success.\n";
2392 m_isTreeInitialized =
true;
2397 const double y,
const double z,
2398 const double t1,
const double t2,
2399 const double t3,
const double t4,
2401 const unsigned int n,
const int iw)
const {
2402 std::cout <<
m_className <<
"::" << header <<
":\n"
2403 <<
" Global = (" << x <<
", " << y <<
", " << z <<
")\n"
2404 <<
" Local = (" << t1 <<
", " << t2 <<
", " << t3 <<
", " << t4
2406 if (element.
degenerate) std::cout <<
" Element is degenerate.\n";
2407 std::cout <<
" Node x y z V\n";
2408 for (
unsigned int ii = 0; ii < n; ++ii) {
2410 const double v = iw < 0 ? node.
v : node.
w[iw];
2411 printf(
" %-5d %12g %12g %12g %12g\n", element.
emap[ii], node.
x, node.
y,
Abstract base class for components.
std::array< bool, 3 > m_periodic
Simple periodicity in x, y, z.
std::array< bool, 3 > m_rotationSymmetric
Rotation symmetry around x-axis, y-axis, z-axis.
std::array< bool, 3 > m_axiallyPeriodic
Axial periodicity in x, y, z.
bool m_ready
Ready for use?
std::array< bool, 3 > m_mirrorPeriodic
Mirror periodicity in x, y, z.
std::string m_className
Class name.
bool m_debug
Switch on/off debugging messages.
void DriftMedium(const unsigned int imat)
Flag a field map material as a drift medium.
void PrintRange()
Show x, y, z, V and angular ranges.
virtual double GetElementVolume(const unsigned int i)=0
void SetMedium(const unsigned int imat, Medium *medium)
Associate a field map material with a Medium class.
void PrintMaterials()
List all currently defined materials.
std::array< double, 3 > m_mapamin
double ReadDouble(char *token, double def, bool &error)
void MapCoordinates(double &xpos, double &ypos, double &zpos, bool &xmirrored, bool &ymirrored, bool &zmirrored, double &rcoordinate, double &rotation) const
Move (xpos, ypos, zpos) to field map coordinates.
virtual void GetAspectRatio(const unsigned int i, double &dmin, double &dmax)=0
std::array< double, 3 > m_maxBoundingBox
std::array< double, 3 > m_mapmin
std::array< double, 3 > m_minBoundingBox
bool GetBoundingBox(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax) override
Get the bounding box coordinates.
void UpdatePeriodicityCommon()
int ReadInteger(char *token, int def, bool &error)
int FindElementCube(const double x, const double y, const double z, double &t1, double &t2, double &t3, TMatrixD *&jac, std::vector< TMatrixD * > &dN)
Find the element for a point in a cube.
unsigned int m_nMaterials
virtual ~ComponentFieldMap()
Destructor.
std::array< double, 3 > m_mapna
double GetConductivity(const unsigned int imat) const
Return the conductivity of a field map material.
int FindElement5(const double x, const double y, const double z, double &t1, double &t2, double &t3, double &t4, double jac[4][4], double &det)
Find the element for a point in curved quadratic quadrilaterals.
double GetPermittivity(const unsigned int imat) const
Return the permittivity of a field map material.
std::vector< Material > materials
void UpdatePeriodicity2d()
int FindElement13(const double x, const double y, const double z, double &t1, double &t2, double &t3, double &t4, double jac[4][4], double &det)
Find the element for a point in curved quadratic tetrahedra.
Medium * GetMedium(const unsigned int i) const
Return the Medium associated to a field map material.
void NotDriftMedium(const unsigned int imat)
Flag a field map materials as a non-drift medium.
std::vector< Node > nodes
std::array< double, 3 > m_mapamax
void PrintElement(const std::string &header, const double x, const double y, const double z, const double t1, const double t2, const double t3, const double t4, const Element &element, const unsigned int n, const int iw=-1) const
std::array< double, 3 > m_cells
bool GetElement(const unsigned int i, double &vol, double &dmin, double &dmax)
Return the volume and aspect ratio of a mesh element.
std::array< bool, 3 > m_setang
virtual void SetRange()
Calculate x, y, z, V and angular ranges.
std::vector< Element > elements
ComponentFieldMap()
Constructor.
std::array< double, 3 > m_mapmax
void UnmapFields(double &ex, double &ey, double &ez, double &xpos, double &ypos, double &zpos, bool &xmirrored, bool &ymirrored, bool &zmirrored, double &rcoordinate, double &rotation) const
Move (ex, ey, ez) to global coordinates.
void PrintNotReady(const std::string &header) const
Abstract base class for media.
const std::string & GetName() const
Get the medium name/identifier.
std::vector< int > GetTetListInBlock(const Vec3 &point)
void InsertTetrahedron(const double elemBoundingBox[6], const int elemIndex)
void InsertMeshNode(Vec3 point, const int nodeIndex)
DoubleAc fabs(const DoubleAc &f)
DoubleAc sqrt(const DoubleAc &f)