19 cacheElemBoundingBoxes(false),
23 hasBoundingBox(false),
24 deleteBackground(true),
25 checkMultipleElement(false),
42 std::cerr <<
" Field map not yet initialised.\n";
48 std::cerr <<
" No materials are currently defined.\n";
53 std::cout <<
" Currently " <<
nMaterials <<
" materials are defined.\n";
54 std::cout <<
" Index Permittivity Resistivity Notes\n";
58 std::string name =
materials[i].medium->GetName();
59 std::cout <<
" " << name;
64 std::cout <<
" (drift medium)\n";
76 std::cerr <<
" Field map not yet initialised.\n";
77 std::cerr <<
" Drift medium cannot be selected.\n";
84 std::cerr <<
" Material index " << imat <<
" is out of range.\n";
97 std::cerr <<
" Field map not yet initialised.\n";
98 std::cerr <<
" Drift medium cannot be selected.\n";
105 std::cerr <<
" Material index " << imat <<
" is out of range.\n";
116 std::cerr <<
m_className <<
"::GetPermittivity:\n";
117 std::cerr <<
" Material index " << imat <<
" is out of range.\n";
127 std::cerr <<
m_className <<
"::GetConductivity:\n";
128 std::cerr <<
" Material index " << imat <<
" is out of range.\n";
139 std::cerr <<
" Material index " << imat <<
" is out of range.\n";
145 std::cerr <<
" Medium pointer is null.\n";
150 std::string name = m->
GetName();
152 std::cout <<
" Associated material " << imat <<
" with medium " << name
163 std::cerr <<
" Material index " << imat <<
" is out of range.\n";
175 std::cerr <<
" Element index (" << i <<
") out of range.\n";
185 double const z,
double& t1,
double& t2,
186 double& t3,
double& t4,
double jac[4][4],
192 std::cerr <<
" Caching the bounding box calculations of all elements.\n";
199 double jacbak[4][4], detbak = 1.;
200 double t1bak = 0., t2bak = 0., t3bak = 0., t4bak = 0.;
204 t1 = t2 = t3 = t4 = 0;
211 if (rc == 0 && t1 >= 0 && t1 <= +1 && t2 >= 0 && t2 <= +1 && t3 >= 0 &&
216 if (rc == 0 && t1 >= -1 && t1 <= +1 && t2 >= -1 && t2 <= +1)
226 const double f = 0.2;
238 rc =
Coordinates3(x, y, z, t1, t2, t3, t4, jac, det, i);
239 if (rc == 0 && t1 >= 0 && t1 <= +1 && t2 >= 0 && t2 <= +1 && t3 >= 0 &&
246 std::cout <<
" Found matching degenerate element " << i <<
".\n";
249 for (
int j = 0; j < 4; ++j) {
250 for (
int k = 0; k < 4; ++k) jacbak[j][k] = jac[j][k];
260 std::cout <<
" Global = (" << x <<
", " << y <<
")\n";
261 std::cout <<
" Local = (" << t1 <<
", " << t2 <<
", " << t3 <<
", "
263 std::cout <<
" Element = " << imap
264 <<
" (degenerate: " <<
elements[imap].degenerate <<
")\n";
265 std::cout <<
" Node x "
267 for (
int ii = 0; ii < 6; ++ii) {
268 printf(
" %-5d %12g %12g %12g\n",
277 rc =
Coordinates5(x, y, z, t1, t2, t3, t4, jac, det, i);
278 if (rc == 0 && t1 >= -1 && t1 <= +1 && t2 >= -1 && t2 <= +1) {
284 std::cout <<
" Found matching non-degenerate element " << i
288 for (
int j = 0; j < 4; ++j) {
289 for (
int k = 0; k < 4; ++k) jacbak[j][k] = jac[j][k];
299 std::cout <<
" Global = (" << x <<
", " << y <<
")\n";
300 std::cout <<
" Local = (" << t1 <<
", " << t2 <<
", " << t3 <<
", "
302 std::cout <<
" Element = " << imap
303 <<
" (degenerate: " <<
elements[imap].degenerate <<
")\n";
304 std::cout <<
" Node x "
306 for (
int ii = 0; ii < 8; ++ii) {
307 printf(
" %-5d %12g %12g %12g\n",
322 std::cout <<
" No element matching point (" << x <<
", " << y
330 std::cout <<
" Found " << nfound <<
" elements matching point (" << x
331 <<
", " << y <<
").\n";
334 for (
int j = 0; j < 4; ++j) {
335 for (
int k = 0; k < 4; ++k) jac[j][k] = jacbak[j][k];
350 std::cout <<
" No element matching point (" << x <<
", " << y
357 const double z,
double& t1,
double& t2,
358 double& t3,
double& t4,
double jac[4][4],
363 std::cerr <<
" Caching the bounding box calculations of all elements.\n";
372 double t1bak = 0., t2bak = 0., t3bak = 0., t4bak = 0.;
376 t1 = t2 = t3 = t4 = 0.;
382 if (rc == 0 && t1 >= 0 && t1 <= +1 && t2 >= 0 && t2 <= +1 && t3 >= 0 &&
383 t3 <= +1 && t4 >= 0 && t4 <= +1)
392 const double f = 0.2;
404 if (rc == 0 && t1 >= 0 && t1 <= +1 && t2 >= 0 && t2 <= +1 && t3 >= 0 &&
405 t3 <= +1 && t4 >= 0 && t4 <= +1) {
411 std::cout <<
" Found matching element " << i <<
".\n";
414 for (
int j = 0; j < 4; ++j) {
415 for (
int k = 0; k < 4; ++k) jacbak[j][k] = jac[j][k];
425 std::cout <<
" Global = (" << x <<
", " << y <<
")\n";
426 std::cout <<
" Local = (" << t1 <<
", " << t2 <<
", " << t3 <<
", "
428 std::cout <<
" Element = " << imap <<
"\n";
429 std::cout <<
" Node x "
431 for (
int ii = 0; ii < 10; ++ii) {
432 printf(
" %-5d %12g %12g %12g %12g\n",
447 std::cout <<
" No element matching point (" << x <<
", " << y <<
", "
448 << z <<
") found.\n";
455 std::cerr <<
" Found << " << nfound <<
" elements matching point ("
456 << x <<
", " << y <<
", " << z <<
").\n";
459 for (
int j = 0; j < 4; ++j) {
460 for (
int k = 0; k < 4; ++k) jac[j][k] = jacbak[j][k];
475 std::cout <<
" No element matching point (" << x <<
", " << y <<
", "
476 << z <<
") found.\n";
482 const double z,
double& t1,
double& t2,
483 double& t3, TMatrixD*& jac,
484 std::vector<TMatrixD*>& dN) {
514 std::cout <<
m_className <<
"::FindElementCube:\n";
515 std::cout <<
" Point (" << x <<
"," << y <<
"," << z
516 <<
") not in the mesh, it is background or PEC.\n";
517 std::cout <<
" First node (" <<
nodes[
elements[0].emap[3]].x <<
","
530 <<
") in the mesh.\n";
543 std::cout <<
m_className <<
"::FindElementCube:\n";
544 std::cout <<
"Global: (" << x <<
"," << y <<
"," << z <<
") in element "
545 << imap <<
" (degenerate: " <<
elements[imap].degenerate <<
")\n";
546 std::cout <<
" Node xyzV\n";
547 for (
int i = 0; i < 8; i++) {
548 std::cout <<
" " <<
elements[imap].emap[i] <<
" "
559 double& det,
double jac[4][4]) {
571 std::cerr <<
" Element " << i <<
" out of range.\n";
709 std::cerr <<
" Element " << i <<
" out of range.\n";
1234 double w,
double& det,
double jac[4][4]) {
1238 for (
int j = 0; j < 4; ++j) {
1239 for (
int k = 0; k < 4; ++k) jac[j][k] = 0;
1245 std::cerr <<
" Element " << i <<
" out of range.\n";
2129 double t3, TMatrixD*& jac,
2130 std::vector<TMatrixD*>& dN) {
2133 std::cerr <<
" Pointer to Jacobian matrix is empty!\n";
2138 if (element < 0 || element >=
nElements) {
2140 std::cerr <<
" Element " <<
element <<
" out of range.\n";
2144 double N1[3] = {-1 * (1 - t2) * (1 - t3), (1 - t1) * -1 * (1 - t3),
2145 (1 - t1) * (1 - t2) * -1};
2146 double N2[3] = {+1 * (1 - t2) * (1 - t3), (1 + t1) * -1 * (1 - t3),
2147 (1 + t1) * (1 - t2) * -1};
2148 double N3[3] = {+1 * (1 + t2) * (1 - t3), (1 + t1) * +1 * (1 - t3),
2149 (1 + t1) * (1 + t2) * -1};
2150 double N4[3] = {-1 * (1 + t2) * (1 - t3), (1 - t1) * +1 * (1 - t3),
2151 (1 - t1) * (1 + t2) * -1};
2152 double N5[3] = {-1 * (1 - t2) * (1 + t3), (1 - t1) * -1 * (1 + t3),
2153 (1 - t1) * (1 - t2) * +1};
2154 double N6[3] = {+1 * (1 - t2) * (1 + t3), (1 + t1) * -1 * (1 + t3),
2155 (1 + t1) * (1 - t2) * +1};
2156 double N7[3] = {+1 * (1 + t2) * (1 + t3), (1 + t1) * +1 * (1 + t3),
2157 (1 + t1) * (1 + t2) * +1};
2158 double N8[3] = {-1 * (1 + t2) * (1 + t3), (1 - t1) * +1 * (1 + t3),
2159 (1 - t1) * (1 + t2) * +1};
2161 TMatrixD* m_N1 =
new TMatrixD(3, 1, N1);
2162 *m_N1 = (1. / 8. * (*m_N1));
2164 TMatrixD* m_N2 =
new TMatrixD(3, 1, N2);
2165 *m_N2 = (1. / 8. * (*m_N2));
2167 TMatrixD* m_N3 =
new TMatrixD(3, 1, N3);
2168 *m_N3 = (1. / 8. * (*m_N3));
2170 TMatrixD* m_N4 =
new TMatrixD(3, 1, N4);
2171 *m_N4 = (1. / 8. * (*m_N4));
2173 TMatrixD* m_N5 =
new TMatrixD(3, 1, N5);
2174 *m_N5 = (1. / 8. * (*m_N5));
2176 TMatrixD* m_N6 =
new TMatrixD(3, 1, N6);
2177 *m_N6 = (1. / 8. * (*m_N6));
2179 TMatrixD* m_N7 =
new TMatrixD(3, 1, N7);
2180 *m_N7 = (1. / 8. * (*m_N7));
2182 TMatrixD* m_N8 =
new TMatrixD(3, 1, N8);
2183 *m_N8 = (1. / 8. * (*m_N8));
2209 std::cout <<
m_className <<
"::JacobianCube:" << std::endl;
2210 std::cout <<
" Det.: " << jac->Determinant() << std::endl;
2211 std::cout <<
" Jacobian matrix.: " << std::endl;
2212 jac->Print(
"%11.10g");
2213 std::cout <<
" Hexahedral coordinates (t, u, v) = (" << t1 <<
"," << t2
2214 <<
"," << t3 <<
")" << std::endl;
2215 std::cout <<
" Node xyzV" << std::endl;
2227 double& t2,
double& t3,
double& t4,
2228 double jac[4][4],
double& det,
int imap) {
2232 std::cout <<
" Point (" << x <<
", " << y <<
", " << z <<
")\n";
2239 t1 = t2 = t3 = t4 = 0;
2282 std::cerr <<
" Calculation of linear coordinates failed; abandoned.\n";
2310 double td1 = t1, td2 = t2, td3 = t3;
2313 std::cout <<
" Linear estimate: (u, v, w) = (" << td1 <<
", " << td2
2314 <<
", " << td3 <<
"), sum = " << td1 + td2 + td3 <<
".\n";
2318 bool converged =
false;
2319 double diff[3] = {0., 0., 0.};
2320 double corr[3] = {0., 0., 0.};
2321 for (
int iter = 0; iter < 10; iter++) {
2324 std::cout <<
" Iteration " << iter <<
": (u, v, w) = (" << td1
2325 <<
", " << td2 <<
", " << td3 <<
"), sum = " << td1 + td2 + td3
2329 double xr =
nodes[
elements[imap].emap[0]].x * td1 * (2 * td1 - 1) +
2335 double yr =
nodes[
elements[imap].emap[0]].y * td1 * (2 * td1 - 1) +
2341 double sr = td1 + td2 + td3;
2343 Jacobian3(imap, td1, td2, td3, det, jac);
2349 for (
int l = 0; l < 3; l++) {
2351 for (
int k = 0; k < 3; k++) {
2352 corr[l] += jac[l][k] * diff[k] / det;
2358 std::cout <<
" Difference vector: (1, x, y) = (" << diff[0] <<
", "
2359 << diff[1] <<
", " << diff[2] <<
").\n";
2360 std::cout <<
" Correction vector: (u, v, w) = (" << corr[0] <<
", "
2361 << corr[1] <<
", " << corr[2] <<
").\n";
2368 if (
fabs(corr[0]) < 1.0e-5 &&
fabs(corr[1]) < 1.0e-5 &&
2369 fabs(corr[2]) < 1.0e-5) {
2372 std::cout <<
" Convergence reached.\n";
2380 double xmin, ymin, xmax, ymax;
2410 if (x >= xmin && x <= xmax && y >= ymin && y <= ymax) {
2412 std::cout <<
" No convergence achieved "
2413 <<
"when refining internal isoparametric coordinates\n";
2414 std::cout <<
" in element " << imap <<
" at position (" << x <<
", "
2416 t1 = t2 = t3 = t4 = 0;
2428 std::cout <<
" Convergence reached at (t1, t2, t3) = (" << t1 <<
", "
2429 << t2 <<
", " << t3 <<
").\n";
2434 double xr =
nodes[
elements[imap].emap[0]].x * td1 * (2 * td1 - 1) +
2440 double yr =
nodes[
elements[imap].emap[0]].y * td1 * (2 * td1 - 1) +
2446 double sr = td1 + td2 + td3;
2448 std::cout <<
" Position requested: (" << x <<
", " << y <<
")\n";
2449 std::cout <<
" Reconstructed: (" << xr <<
", " << yr <<
")\n";
2450 std::cout <<
" Difference: (" << x - xr <<
", " << y - yr
2452 std::cout <<
" Checksum - 1: " << sr - 1 <<
"\n";
2461 double& t2,
double& t3,
double& t4,
2462 double jac[4][4],
double& det,
int imap) {
2467 std::cout <<
" Point (" << x <<
", " << y <<
", " << z <<
")\n";
2474 t1 = t2 = t3 = t4 = 0.;
2518 std::cerr <<
" No solution found for isoparametric coordinates\n";
2519 std::cerr <<
" in element " << imap <<
" because the determinant "
2520 << det <<
" is < 0.\n";
2563 double dn =
sqrt(xp * xp + yp * yp);
2566 std::cerr <<
" Element " << imap
2567 <<
" appears to be degenerate in the 1 - 2 axis.\n";
2572 double dpoint = xp * (x -
nodes[
elements[imap].emap[0]].x) +
2580 std::cerr <<
" Element " << imap
2581 <<
" appears to be degenerate in the 1 - 3 axis.\n";
2584 double t = -1 + 2 * dpoint / dbox;
2597 dn = (xt1 - xt2) * (xt1 - xt2) + (yt1 - yt2) * (yt1 - yt2);
2600 std::cout <<
" Coordinate requested at convergence point of element "
2604 t1 = -1 + 2 * ((x - xt1) * (xt2 - xt1) + (y - yt1) * (yt2 - yt1)) / dn;
2645 double dn =
sqrt(xp * xp + yp * yp);
2648 std::cerr <<
" Element " << imap
2649 <<
" appears to be degenerate in the 1 - 4 axis.\n";
2654 double dpoint = xp * (x -
nodes[
elements[imap].emap[0]].x) +
2662 std::cerr <<
" Element " << imap
2663 <<
" appears to be degenerate in the 1 - 2 axis.\n";
2666 double t = -1 + 2 * dpoint / dbox;
2679 dn = (xt1 - xt2) * (xt1 - xt2) + (yt1 - yt2) * (yt1 - yt2);
2682 std::cout <<
" Coordinate requested at convergence point of element "
2686 t2 = -1 + 2 * ((x - xt1) * (xt2 - xt1) + (y - yt1) * (yt2 - yt1)) / dn;
2690 std::cout <<
" Isoparametric (u, v): (" << t1 <<
", " << t2 <<
").\n";
2695 double xr =
nodes[
elements[imap].emap[0]].x * (1 - t1) * (1 - t2) / 4 +
2699 double yr =
nodes[
elements[imap].emap[0]].y * (1 - t1) * (1 - t2) / 4 +
2704 std::cout <<
" Position requested: (" << x <<
", " << y <<
")\n";
2705 std::cout <<
" Reconstructed: (" << xr <<
", " << yr <<
")\n";
2706 std::cout <<
" Difference: (" << x - xr <<
", " << y - yr
2715 jac[0][0] = jac[0][1] = jac[0][2] = jac[0][3] = 0.;
2716 jac[1][0] = jac[1][1] = jac[1][2] = jac[1][3] = 0.;
2717 jac[2][0] = jac[2][1] = jac[2][2] = jac[2][3] = 0.;
2718 jac[3][0] = jac[3][1] = jac[3][2] = jac[3][3] = 0.;
2722 double& t2,
double& t3,
double& t4,
2723 double jac[4][4],
double& det,
int imap) {
2728 std::cout <<
" Point (" << x <<
", " << y <<
", " << z <<
")\n";
2735 t1 = t2 = t3 = t4 = 0;
2740 std::cerr <<
" Received degenerate element " << imap <<
".\n";
2748 int rc =
Coordinates4(x, y, z, t1, t2, t3, t4, jac, det, imap);
2752 std::cout <<
" Failure to obtain linear estimate of isoparametric "
2754 std::cout <<
" in element " << imap <<
".\n";
2760 if (t1 < -(1 + f) || t1 > (1 + f) || t2 < -(1 + f) || t2 > (1 + f)) {
2763 std::cout <<
" Point far outside, (t1,t2) = (" << t1 <<
", " << t2
2770 double td1 = t1, td2 = t2;
2773 std::cout <<
" Iteration starts at (t1,t2) = (" << td1 <<
", " << td2
2777 bool converged =
false;
2778 double diff[2], corr[2];
2779 for (
int iter = 0; iter < 10; iter++) {
2782 std::cout <<
" Iteration " << iter <<
": (t1, t2) = (" << td1
2783 <<
", " << td2 <<
").\n";
2788 (-(1 - td1) * (1 - td2) * (1 + td1 + td2)) / 4 +
2790 (-(1 + td1) * (1 - td2) * (1 - td1 + td2)) / 4 +
2792 (-(1 + td1) * (1 + td2) * (1 - td1 - td2)) / 4 +
2794 (-(1 - td1) * (1 + td2) * (1 + td1 - td2)) / 4 +
2795 nodes[
elements[imap].emap[4]].x * (1 - td1) * (1 + td1) * (1 - td2) /
2797 nodes[
elements[imap].emap[5]].x * (1 + td1) * (1 + td2) * (1 - td2) /
2799 nodes[
elements[imap].emap[6]].x * (1 - td1) * (1 + td1) * (1 + td2) /
2801 nodes[
elements[imap].emap[7]].x * (1 - td1) * (1 + td2) * (1 - td2) / 2;
2804 (-(1 - td1) * (1 - td2) * (1 + td1 + td2)) / 4 +
2806 (-(1 + td1) * (1 - td2) * (1 - td1 + td2)) / 4 +
2808 (-(1 + td1) * (1 + td2) * (1 - td1 - td2)) / 4 +
2810 (-(1 - td1) * (1 + td2) * (1 + td1 - td2)) / 4 +
2811 nodes[
elements[imap].emap[4]].y * (1 - td1) * (1 + td1) * (1 - td2) /
2813 nodes[
elements[imap].emap[5]].y * (1 + td1) * (1 + td2) * (1 - td2) /
2815 nodes[
elements[imap].emap[6]].y * (1 - td1) * (1 + td1) * (1 + td2) /
2817 nodes[
elements[imap].emap[7]].y * (1 - td1) * (1 + td2) * (1 - td2) / 2;
2824 for (
int l = 0; l < 2; ++l) {
2826 for (
int k = 0; k < 2; ++k) {
2827 corr[l] += jac[l][k] * diff[k] / det;
2833 std::cout <<
" Difference vector: (x, y) = (" << diff[0] <<
", "
2834 << diff[1] <<
").\n";
2835 std::cout <<
" Correction vector: (t1, t2) = (" << corr[0] <<
", "
2836 << corr[1] <<
").\n";
2842 if (
fabs(corr[0]) < 1.0e-5 &&
fabs(corr[1]) < 1.0e-5) {
2845 std::cout <<
" Convergence reached.\n";
2853 double xmin, ymin, xmax, ymax;
2943 if (x >= xmin && x <= xmax && y >= ymin && y <= ymax) {
2945 std::cout <<
" No convergence achieved "
2946 <<
"when refining internal isoparametric coordinates\n";
2947 std::cout <<
" in element " << imap <<
" at position (" << x <<
", "
2961 std::cout <<
" Convergence reached at (t1, t2) = (" << t1 <<
", " << t2
2969 (-(1 - t1) * (1 - t2) * (1 + t1 + t2)) / 4 +
2971 (-(1 + t1) * (1 - t2) * (1 - t1 + t2)) / 4 +
2973 (-(1 + t1) * (1 + t2) * (1 - t1 - t2)) / 4 +
2975 (-(1 - t1) * (1 + t2) * (1 + t1 - t2)) / 4 +
2976 nodes[
elements[imap].emap[4]].x * (1 - t1) * (1 + t1) * (1 - t2) / 2 +
2977 nodes[
elements[imap].emap[5]].x * (1 + t1) * (1 + t2) * (1 - t2) / 2 +
2978 nodes[
elements[imap].emap[6]].x * (1 - t1) * (1 + t1) * (1 + t2) / 2 +
2979 nodes[
elements[imap].emap[7]].x * (1 - t1) * (1 + t2) * (1 - t2) / 2;
2982 (-(1 - t1) * (1 - t2) * (1 + t1 + t2)) / 4 +
2984 (-(1 + t1) * (1 - t2) * (1 - t1 + t2)) / 4 +
2986 (-(1 + t1) * (1 + t2) * (1 - t1 - t2)) / 4 +
2988 (-(1 - t1) * (1 + t2) * (1 + t1 - t2)) / 4 +
2989 nodes[
elements[imap].emap[4]].y * (1 - t1) * (1 + t1) * (1 - t2) / 2 +
2990 nodes[
elements[imap].emap[5]].y * (1 + t1) * (1 + t2) * (1 - t2) / 2 +
2991 nodes[
elements[imap].emap[6]].y * (1 - t1) * (1 + t1) * (1 + t2) / 2 +
2992 nodes[
elements[imap].emap[7]].y * (1 - t1) * (1 + t2) * (1 - t2) / 2;
2994 std::cout <<
" Position requested: (" << x <<
", " << y <<
")\n";
2995 std::cout <<
" Reconstructed: (" << xr <<
", " << yr <<
")\n";
2996 std::cout <<
" Difference: (" << x - xr <<
", " << y - yr
3006 double& t2,
double& t3,
double& t4,
3011 std::cout <<
" Point (" << x <<
", " << y <<
", " << z <<
") for element "
3223 std::cout <<
" Tetrahedral coordinates (t, u, v, w) = (" << t1 <<
", "
3224 << t2 <<
", " << t3 <<
", " << t4
3225 <<
") sum = " << t1 + t2 + t3 + t4 <<
".\n";
3241 double sr = t1 + t2 + t3 + t4;
3243 std::cout <<
" Position requested: (" << x <<
", " << y <<
", " << z
3245 std::cout <<
" Reconstructed: (" << xr <<
", " << yr <<
", "
3247 std::cout <<
" Difference: (" << x - xr <<
", " << y - yr
3248 <<
", " << z - zr <<
")\n";
3249 std::cout <<
" Checksum - 1: " << sr - 1 <<
"\n";
3258 double& t2,
double& t3,
double& t4,
3259 double jac[4][4],
double& det,
int imap) {
3263 std::cout <<
" Point (" << x <<
", " << y <<
", " << z <<
")\n";
3270 t1 = t2 = t3 = t4 = 0.;
3280 std::cout <<
" Failure to obtain linear estimate of isoparametric "
3282 std::cout <<
" in element " << imap <<
".\n";
3286 if (t1 < -f || t2 < -f || t3 < -f || t4 < -f || t1 > 1 + f || t2 > 1 + f ||
3287 t3 > 1 + f || t4 > 1 + f) {
3290 std::cout <<
" Linear isoparametric coordinates more than\n";
3291 std::cout <<
" f (" << f <<
") out of range in element " << imap
3299 double td1 = t1, td2 = t2, td3 = t3, td4 = t4;
3302 std::cout <<
" Iteration starts at (t1,t2,t3,t4) = (" << td1 <<
", "
3303 << td2 <<
", " << td3 <<
", " << td4 <<
").\n";
3306 bool converged =
false;
3307 double diff[4], corr[4];
3308 for (
int iter = 0; iter < 10; iter++) {
3311 std::cout <<
" Iteration " << iter <<
": (t1,t2,t3,t4) = (" << td1
3312 <<
", " << td2 <<
", " << td3 <<
", " << td4 <<
").\n";
3315 double xr =
nodes[
elements[imap].emap[0]].x * td1 * (2 * td1 - 1) +
3325 double yr =
nodes[
elements[imap].emap[0]].y * td1 * (2 * td1 - 1) +
3335 double zr =
nodes[
elements[imap].emap[0]].z * td1 * (2 * td1 - 1) +
3345 double sr = td1 + td2 + td3 + td4;
3348 Jacobian13(imap, td1, td2, td3, td4, det, jac);
3356 for (
int l = 0; l < 4; ++l) {
3358 for (
int k = 0; k < 4; ++k) {
3359 corr[l] += jac[l][k] * diff[k] / det;
3366 std::cout <<
" Difference vector: (1, x, y, z) = (" << diff[0]
3367 <<
", " << diff[1] <<
", " << diff[2] <<
", " << diff[3]
3369 std::cout <<
" Correction vector: (t1,t2,t3,t4) = (" << corr[0]
3370 <<
", " << corr[1] <<
", " << corr[2] <<
", " << corr[3]
3381 if (
fabs(corr[0]) < 1.0e-5 &&
fabs(corr[1]) < 1.0e-5 &&
3382 fabs(corr[2]) < 1.0e-5 &&
fabs(corr[3]) < 1.0e-5) {
3385 std::cout <<
" Convergence reached.\n";
3394 double xmin, ymin, zmin, xmax, ymax, zmax;
3456 if (x >= xmin && x <= xmax && y >= ymin && y <= ymax && z >= zmin &&
3459 std::cout <<
" No convergence achieved "
3460 <<
"when refining internal isoparametric coordinates\n";
3461 std::cout <<
" in element " << imap <<
" at position (" << x <<
", "
3462 << y <<
", " << z <<
").\n";
3463 t1 = t2 = t3 = t4 = -1;
3475 std::cout <<
" Convergence reached at (t1, t2, t3, t4) = (" << t1 <<
", "
3476 << t2 <<
", " << t3 <<
", " << t4 <<
").\n";
3482 double xr =
nodes[
elements[imap].emap[0]].x * td1 * (2 * td1 - 1) +
3492 double yr =
nodes[
elements[imap].emap[0]].y * td1 * (2 * td1 - 1) +
3502 double zr =
nodes[
elements[imap].emap[0]].z * td1 * (2 * td1 - 1) +
3512 double sr = td1 + td2 + td3 + td4;
3514 std::cout <<
" Position requested: (" << x <<
", " << y <<
", " << z
3516 std::cout <<
" Reconstructed: (" << xr <<
", " << yr <<
", "
3518 std::cout <<
" Difference: (" << x - xr <<
", " << y - yr
3519 <<
", " << z - zr <<
")\n";
3520 std::cout <<
" Checksum - 1: " << sr - 1 <<
"\n";
3529 double& t2,
double& t3, TMatrixD*& jac,
3530 std::vector<TMatrixD*>& dN,
int imap) {
3568 n[0] = 1. / 8 * (1 - t1) * (1 - t2) * (1 - t3);
3569 n[1] = 1. / 8 * (1 + t1) * (1 - t2) * (1 - t3);
3570 n[2] = 1. / 8 * (1 + t1) * (1 + t2) * (1 - t3);
3571 n[3] = 1. / 8 * (1 - t1) * (1 + t2) * (1 - t3);
3572 n[4] = 1. / 8 * (1 - t1) * (1 - t2) * (1 + t3);
3573 n[5] = 1. / 8 * (1 + t1) * (1 - t2) * (1 + t3);
3574 n[6] = 1. / 8 * (1 + t1) * (1 + t2) * (1 + t3);
3575 n[7] = 1. / 8 * (1 - t1) * (1 + t2) * (1 + t3);
3581 for (
int i = 0; i < 8; i++) {
3586 double sr = n[0] + n[1] + n[2] + n[3] + n[4] + n[5] + n[6] + n[7];
3587 std::cout <<
m_className <<
"::CoordinatesCube:\n";
3588 std::cout <<
" Position requested: (" << x <<
"," << y <<
"," << z
3590 std::cout <<
" Position reconstructed: (" << xr <<
"," << yr <<
"," << zr
3592 std::cout <<
" Difference: (" << (x - xr) <<
"," << (y - yr)
3593 <<
"," << (z - zr) <<
")\n";
3594 std::cout <<
" Hexahedral coordinates (t, u, v) = (" << t1 <<
"," << t2
3595 <<
"," << t3 <<
")\n";
3596 std::cout <<
" Checksum - 1: " << (sr - 1) <<
"\n";
3608 std::cerr <<
m_className <<
"::UpdatePeriodicityCommon:\n";
3609 std::cerr <<
" No valid field map available.\n";
3615 std::cerr <<
m_className <<
"::UpdatePeriodicityCommon:\n";
3616 std::cerr <<
" Both simple and mirror periodicity\n";
3617 std::cerr <<
" along x requested; reset.\n";
3623 std::cerr <<
m_className <<
"::UpdatePeriodicityCommon:\n";
3624 std::cerr <<
" Both simple and mirror periodicity\n";
3625 std::cerr <<
" along y requested; reset.\n";
3631 std::cerr <<
m_className <<
"::UpdatePeriodicityCommon:\n";
3632 std::cerr <<
" Both simple and mirror periodicity\n";
3633 std::cerr <<
" along z requested; reset.\n";
3648 std::cerr <<
m_className <<
"::UpdatePeriodicityCommon:\n";
3649 std::cerr <<
" X-axial symmetry has been requested but the map\n";
3650 std::cerr <<
" does not cover an integral fraction of 2 pi; reset.\n";
3663 std::cerr <<
m_className <<
"::UpdatePeriodicityCommon:\n";
3664 std::cerr <<
" Y-axial symmetry has been requested but the map\n";
3665 std::cerr <<
" does not cover an integral fraction of 2 pi; reset.\n";
3678 std::cerr <<
m_className <<
"::UpdatePeriodicityCommon:\n";
3679 std::cerr <<
" Z-axial symmetry has been requested but the map\n";
3680 std::cerr <<
" does not cover an integral fraction of 2 pi; reset.\n";
3690 std::cerr <<
m_className <<
"::UpdatePeriodicityCommon:\n";
3691 std::cerr <<
" Only 1 rotational symmetry allowed; reset.\n";
3701 std::cerr <<
m_className <<
"::UpdatePeriodicityCommon:\n";
3702 std::cerr <<
" Not allowed to combine rotational symmetry\n";
3703 std::cerr <<
" and axial periodicity; reset.\n";
3716 std::cerr <<
m_className <<
"::UpdatePeriodicityCommon:\n";
3717 std::cerr <<
" Rotational symmetry requested, \n";
3718 std::cerr <<
" but x-range straddles 0; reset.\n";
3809 std::cerr <<
m_className <<
"::UpdatePeriodicity2d:\n";
3810 std::cerr <<
" No valid field map available.\n";
3816 std::cerr <<
m_className <<
"::UpdatePeriodicity2d:\n";
3817 std::cerr <<
" Simple or mirror periodicity along z\n";
3818 std::cerr <<
" requested for a 2d map; reset.\n";
3826 std::cerr <<
m_className <<
"::UpdatePeriodicity2d:\n";
3827 std::cerr <<
" Axial symmetry has been requested \n";
3828 std::cerr <<
" around x or y for a 2D map; reset.\n";
3848 std::cerr <<
" Field map not yet set.\n";
3853 std::cerr <<
" Number of nodes < 1.\n";
3864 for (
int i = 1; i <
nNodes; i++) {
3953 std::cout <<
" Dimensions of the elementary block\n";
3959 std::cout <<
" Periodicities\n";
3963 std::cout <<
" simple with length " <<
cellsx <<
" cm";
3966 std::cout <<
" mirror with length " <<
cellsx <<
" cm";
3969 std::cout <<
" axial " << int(0.5 +
mapnxa) <<
"-fold repetition";
3973 std::cout <<
" none";
3978 std::cout <<
" simple with length " <<
cellsy <<
" cm";
3981 std::cout <<
" mirror with length " <<
cellsy <<
" cm";
3984 std::cout <<
" axial " << int(0.5 +
mapnya) <<
"-fold repetition";
3987 std::cout <<
" rotational symmetry";
3990 std::cout <<
" none";
3995 std::cout <<
" simple with length " <<
cellsz <<
" cm";
3998 std::cout <<
" mirror with length " <<
cellsz <<
" cm";
4001 std::cout <<
" axial " << int(0.5 +
mapnza) <<
"-fold repetition";
4004 std::cout <<
" rotational symmetry";
4007 std::cout <<
" none";
4022 double& xmax,
double& ymax,
4025 if (!
ready)
return false;
4037 bool& xmirrored,
bool& ymirrored,
4038 bool& zmirrored,
double& rcoordinate,
4039 double& rotation)
const {
4046 double auxr, auxphi;
4054 if (nx != 2 * (nx / 2)) {
4061 auxr =
sqrt(zpos * zpos + ypos * ypos);
4062 auxphi = atan2(zpos, ypos);
4070 auxphi = auxphi - rotation;
4071 ypos = auxr *
cos(auxphi);
4072 zpos = auxr *
sin(auxphi);
4083 if (ny != 2 * (ny / 2)) {
4090 auxr =
sqrt(xpos * xpos + zpos * zpos);
4091 auxphi = atan2(xpos, zpos);
4099 auxphi = auxphi - rotation;
4100 zpos = auxr *
cos(auxphi);
4101 xpos = auxr *
sin(auxphi);
4112 if (nz != 2 * (nz / 2)) {
4119 auxr =
sqrt(ypos * ypos + xpos * xpos);
4120 auxphi = atan2(ypos, xpos);
4128 auxphi = auxphi - rotation;
4129 xpos = auxr *
cos(auxphi);
4130 ypos = auxr *
sin(auxphi);
4135 double zcoordinate = 0;
4137 rcoordinate =
sqrt(ypos * ypos + zpos * zpos);
4140 rcoordinate =
sqrt(xpos * xpos + zpos * zpos);
4143 rcoordinate =
sqrt(xpos * xpos + ypos * ypos);
4155 double& xpos,
double& ypos,
double& zpos,
4156 bool& xmirrored,
bool& ymirrored,
4157 bool& zmirrored,
double& rcoordinate,
4161 if (xmirrored) ex = -ex;
4162 if (ymirrored) ey = -ey;
4163 if (zmirrored) ez = -ez;
4168 er =
sqrt(ey * ey + ez * ez);
4169 theta = atan2(ez, ey);
4171 ey = er *
cos(theta);
4172 ez = er *
sin(theta);
4175 er =
sqrt(ez * ez + ex * ex);
4176 theta = atan2(ex, ez);
4178 ez = er *
cos(theta);
4179 ex = er *
sin(theta);
4182 er =
sqrt(ex * ex + ey * ey);
4183 theta = atan2(ey, ex);
4185 ex = er *
cos(theta);
4186 ey = er *
sin(theta);
4196 if (rcoordinate <= 0) {
4202 ey = er * ypos / rcoordinate;
4203 ez = er * zpos / rcoordinate;
4207 if (rcoordinate <= 0) {
4212 ex = er * xpos / rcoordinate;
4214 ez = er * zpos / rcoordinate;
4218 if (rcoordinate <= 0) {
4223 ex = er * xpos / rcoordinate;
4224 ey = er * ypos / rcoordinate;
4253 std::cerr <<
m_className <<
"::CalculateElementBoundingBoxes:\n";
4254 std::cerr <<
" Field map not yet initialised.\n";
4255 std::cerr <<
" Bounding boxes of elements cannot be computed.\n";
4262 elem.
xmin = std::min(
4265 elem.
xmax = std::max(
4268 elem.
ymin = std::min(
4271 elem.
ymax = std::max(
4274 elem.
zmin = std::min(
4277 elem.
zmax = std::max(
DoubleAc cos(const DoubleAc &f)
DoubleAc pow(const DoubleAc &f, double p)
DoubleAc sqrt(const DoubleAc &f)
DoubleAc sin(const DoubleAc &f)
DoubleAc fabs(const DoubleAc &f)
void CalculateElementBoundingBoxes(void)
void DriftMedium(int imat)
double GetPermittivity(const int imat)
int Coordinates13(double x, double y, double z, double &t1, double &t2, double &t3, double &t4, double jac[4][4], double &det, int imap)
int Coordinates5(double x, double y, double z, double &t1, double &t2, double &t3, double &t4, double jac[4][4], double &det, int imap)
void NotDriftMedium(int imat)
double ReadDouble(char *token, double def, bool &error)
void Jacobian5(int i, double u, double v, double &det, double jac[4][4])
virtual bool GetBoundingBox(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax)
std::vector< bool > wfieldsOk
void MapCoordinates(double &xpos, double &ypos, double &zpos, bool &xmirrored, bool &ymirrored, bool &zmirrored, double &rcoordinate, double &rotation) const
std::vector< material > materials
Medium * GetMedium(const unsigned int &i) const
int Coordinates12(double x, double y, double z, double &t1, double &t2, double &t3, double &t4, int imap)
void UnmapFields(double &ex, double &ey, double &ez, double &xpos, double &ypos, double &zpos, bool &xmirrored, bool &ymirrored, bool &zmirrored, double &rcoordinate, double &rotation)
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)
bool GetElement(const int i, double &vol, double &dmin, double &dmax)
void JacobianCube(int i, double t1, double t2, double t3, TMatrixD *&jac, std::vector< TMatrixD * > &dN)
int Coordinates4(double x, double y, double z, double &t1, double &t2, double &t3, double &t4, double jac[4][4], double &det, int imap)
virtual double GetElementVolume(const int i)=0
std::vector< element > elements
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)
void Jacobian3(int i, double u, double v, double w, double &det, double jac[4][4])
bool checkMultipleElement
std::vector< node > nodes
int Coordinates3(double x, double y, double z, double &t1, double &t2, double &t3, double &t4, double jac[4][4], double &det, int imap)
virtual bool IsInBoundingBox(const double x, const double y, const double z)
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)
virtual void GetAspectRatio(const int i, double &dmin, double &dmax)=0
void Jacobian13(int i, double t, double u, double v, double w, double &det, double jac[4][4])
void SetMedium(const int imat, Medium *medium)
bool cacheElemBoundingBoxes
std::vector< std::string > wfields
int CoordinatesCube(double x, double y, double z, double &t1, double &t2, double &t3, TMatrixD *&jac, std::vector< TMatrixD * > &dN, int imap)
double GetConductivity(const int imat)
std::string GetName() const