18 std::string mplist, std::string prnsol,
25 constexpr int size = 100;
29 std::ifstream fmplist;
30 fmplist.open(mplist.c_str(), std::ios::in);
38 unsigned int icurrmat = 0;
39 bool readerror =
false;
40 while (fmplist.getline(line, size,
'\n')) {
43 if (strcmp(line,
"1") == 0) {
44 fmplist.getline(line, size,
'\n');
46 fmplist.getline(line, size,
'\n');
48 fmplist.getline(line, size,
'\n');
50 fmplist.getline(line, size,
'\n');
52 fmplist.getline(line, size,
'\n');
58 token = strtok(line,
" ");
60 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
61 strcmp(token,
"TEMPERATURE") == 0 || strcmp(token,
"PROPERTY=") == 0 ||
62 int(token[0]) == 10 ||
int(token[0]) == 13)
65 if (strcmp(token,
"LIST") == 0) {
66 token = strtok(NULL,
" ");
67 token = strtok(NULL,
" ");
68 token = strtok(NULL,
" ");
69 token = strtok(NULL,
" ");
70 const unsigned int nMaterials =
ReadInteger(token, -1, readerror);
73 std::cerr <<
" Error reading file " << mplist <<
" (line " << il
82 material.medium =
nullptr;
85 std::cout <<
m_className <<
"::Initialise: " << nMaterials
88 }
else if (strcmp(token,
"MATERIAL") == 0) {
90 token = strtok(NULL,
" ");
91 token = strtok(NULL,
" ");
93 if (readerror || imat < 0) {
95 std::cerr <<
" Error reading file " << mplist <<
" (line " << il
101 }
else if (strcmp(token,
"TEMP") == 0) {
103 token = strtok(NULL,
" ");
105 if (strncmp(token,
"PERX", 4) == 0) {
107 }
else if (strncmp(token,
"RSVX", 4) == 0) {
111 std::cerr <<
" Found unknown material property flag " << token
113 std::cerr <<
" on material properties file " << mplist <<
" (line "
117 fmplist.getline(line, size,
'\n');
120 token = strtok(line,
" ");
121 if (icurrmat < 1 || icurrmat >
m_materials.size()) {
123 std::cerr <<
" Found out-of-range current material index "
125 std::cerr <<
" in material properties file " << mplist <<
".\n";
128 }
else if (itype == 1) {
130 }
else if (itype == 2) {
135 std::cerr <<
" Error reading file " << mplist <<
" (line " << il
140 }
else if (strcmp(token,
"PROPERTY") == 0) {
142 token = strtok(NULL,
" ");
143 token = strtok(NULL,
" ");
145 if (strcmp(token,
"PERX") == 0) {
147 }
else if (strcmp(token,
"RSVX") == 0) {
151 std::cerr <<
" Found unknown material property flag " << token
153 std::cerr <<
" on material properties file " << mplist <<
" (line "
157 token = strtok(NULL,
" ");
158 token = strtok(NULL,
" ");
162 std::cerr <<
" Error reading file " << mplist <<
" (line " << il
166 }
else if (imat < 1 || imat > (
int)
m_materials.size()) {
168 std::cerr <<
" Found out-of-range current material index " << imat
170 std::cerr <<
" in material properties file " << mplist <<
".\n";
173 fmplist.getline(line, size,
'\n');
175 fmplist.getline(line, size,
'\n');
178 token = strtok(line,
" ");
179 token = strtok(NULL,
" ");
182 }
else if (itype == 2) {
187 std::cerr <<
" Error reading file " << mplist <<
" (line " << il
204 <<
" materials from file " << mplist <<
".\n";
208 std::ifstream felist;
209 felist.open(elist.c_str(), std::ios::in);
220 while (felist.getline(line, size,
'\n')) {
223 if (strstr(line,
"VERSION") != NULL) {
224 felist.getline(line, size,
'\n');
226 felist.getline(line, size,
'\n');
233 token = strtok(line,
" ");
235 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
236 int(token[0]) == 10 ||
int(token[0]) == 13 ||
237 strcmp(token,
"LIST") == 0 || strcmp(token,
"ELEM") == 0 ||
238 strcmp(token,
"ANSYS") == 0 || strcmp(token,
"***") == 0 ||
239 strcmp(token,
"VERSION") == 0) {
244 token = strtok(NULL,
" ");
246 token = strtok(NULL,
" ");
247 token = strtok(NULL,
" ");
248 token = strtok(NULL,
" ");
249 token = strtok(NULL,
" ");
250 token = strtok(NULL,
" ");
251 if (!token) std::cerr <<
"No token available\n";
253 token = strtok(NULL,
" ");
255 token = strtok(NULL,
" ");
257 token = strtok(NULL,
" ");
259 token = strtok(NULL,
" ");
261 token = strtok(NULL,
" ");
263 token = strtok(NULL,
" ");
265 token = strtok(NULL,
" ");
271 std::cerr <<
" Error reading file " << elist <<
" (line " << il
275 }
else if (ielem - 1 != (
int)
m_elements.size() + nbackground) {
277 std::cerr <<
" Synchronisation lost on file " << elist <<
" (line "
279 std::cerr <<
" Element: " << ielem <<
" (expected "
280 <<
m_elements.size() <<
"), material: " << imat
281 <<
", nodes: (" << in0 <<
", " << in1
282 <<
", " << in2 <<
", " << in3 <<
", " << in4 <<
", " << in5
283 <<
", " << in6 <<
", " << in7 <<
")\n";
289 std::cerr <<
" Out-of-range material number on file " << elist
290 <<
" (line " << il <<
").\n";
291 std::cerr <<
" Element: " << ielem <<
", material: " << imat
292 <<
", nodes: (" << in0 <<
", " << in1 <<
", " << in2 <<
", "
293 << in3 <<
", " << in4 <<
", " << in5 <<
", " << in6 <<
", "
299 std::cerr <<
" Element " << ielem <<
" in element list " << elist
300 <<
" uses material " << imat <<
" which\n"
301 <<
" has not been assigned a positive permittivity\n";
302 std::cerr <<
" in material list " << mplist <<
".\n";
306 if (in0 < 1 || in1 < 1 || in2 < 1 || in3 < 1 || in4 < 1 || in5 < 1 ||
307 in6 < 1 || in7 < 1) {
309 std::cerr <<
" Found a node number < 1 on file " << elist <<
" (line "
311 std::cerr <<
" Element: " << ielem <<
", material: " << imat <<
"\n";
314 if (in0 > highestnode) highestnode = in0;
315 if (in1 > highestnode) highestnode = in1;
316 if (in2 > highestnode) highestnode = in2;
317 if (in3 > highestnode) highestnode = in3;
318 if (in4 > highestnode) highestnode = in4;
319 if (in5 > highestnode) highestnode = in5;
320 if (in6 > highestnode) highestnode = in6;
321 if (in7 > highestnode) highestnode = in7;
329 if (in2 == in3 && in3 == in6) {
336 newElement.
matmap = imat - 1;
339 newElement.
emap[0] = in0 - 1;
340 newElement.
emap[1] = in1 - 1;
341 newElement.
emap[2] = in2 - 1;
342 newElement.
emap[3] = in4 - 1;
343 newElement.
emap[4] = in7 - 1;
344 newElement.
emap[5] = in5 - 1;
345 newElement.
emap[6] = in3 - 1;
346 newElement.
emap[7] = in6 - 1;
348 newElement.
emap[0] = in0 - 1;
349 newElement.
emap[1] = in1 - 1;
350 newElement.
emap[2] = in2 - 1;
351 newElement.
emap[3] = in3 - 1;
352 newElement.
emap[4] = in4 - 1;
353 newElement.
emap[5] = in5 - 1;
354 newElement.
emap[6] = in6 - 1;
355 newElement.
emap[7] = in7 - 1;
363 <<
" Read " <<
m_elements.size() <<
" elements from file "
365 std::cout <<
" highest node number: " << highestnode <<
",\n";
366 std::cout <<
" degenerate elements: " << ndegenerate <<
",\n";
367 std::cout <<
" background elements skipped: " << nbackground <<
".\n";
372 <<
" Unknown length unit " << unit <<
".\n";
377 std::cout <<
m_className <<
"::Initialise: Unit scaling factor = "
382 std::ifstream fnlist;
383 fnlist.open(nlist.c_str(), std::ios::in);
391 while (fnlist.getline(line, size,
'\n')) {
394 if (strstr(line,
"VERSION") != NULL) {
395 fnlist.getline(line, size,
'\n');
397 fnlist.getline(line, size,
'\n');
404 token = strtok(line,
" ");
406 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
407 int(token[0]) == 10 ||
int(token[0]) == 13 ||
408 strcmp(token,
"LIST") == 0 || strcmp(token,
"NODE") == 0 ||
409 strcmp(token,
"ANSYS") == 0 || strcmp(token,
"***") == 0 ||
410 strcmp(token,
"FILE") == 0 || strcmp(token,
"Electric") == 0 ||
411 strcmp(token,
"VERSION") == 0) {
416 token = strtok(NULL,
" ");
417 double xnode =
ReadDouble(token, -1, readerror);
418 token = strtok(NULL,
" ");
419 double ynode =
ReadDouble(token, -1, readerror);
420 token = strtok(NULL,
" ");
421 double znode =
ReadDouble(token, -1, readerror);
425 std::cerr <<
" Error reading file " << nlist <<
" (line " << il
431 if (inode - 1 != (
int)
m_nodes.size()) {
433 std::cerr <<
" Synchronisation lost on file " << nlist <<
" (line "
435 std::cerr <<
" Node: " << inode <<
" (expected " <<
m_nodes.size()
436 <<
"), (x,y,z) = (" << xnode <<
", " << ynode <<
", " << znode
443 newNode.
x = xnode * funit;
444 newNode.
y = ynode * funit;
445 newNode.
z = znode * funit;
446 m_nodes.push_back(std::move(newNode));
452 <<
" Read " <<
m_nodes.size() <<
" nodes.\n";
454 if ((
int)
m_nodes.size() != highestnode) {
456 std::cerr <<
" Number of nodes read (" <<
m_nodes.size()
457 <<
") on " << nlist <<
"\n"
458 <<
" does not match element list (" << highestnode <<
").\n";
463 std::ifstream fprnsol;
464 fprnsol.open(prnsol.c_str(), std::ios::in);
465 if (fprnsol.fail()) {
471 unsigned int nread = 0;
473 while (fprnsol.getline(line, size,
'\n')) {
476 if (strstr(line,
"VERSION") != NULL) {
477 fprnsol.getline(line, size,
'\n');
479 fprnsol.getline(line, size,
'\n');
485 token = strtok(line,
" ");
487 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
488 int(token[0]) == 10 ||
int(token[0]) == 13 ||
489 strcmp(token,
"PRINT") == 0 || strcmp(token,
"ANSYS") == 0 ||
490 strcmp(token,
"VERSION") == 0 || strcmp(token,
"NODAL") == 0 ||
491 strcmp(token,
"FILE") == 0 || strcmp(token,
"*****") == 0 ||
492 strcmp(token,
"***") == 0 || strcmp(token,
"LOAD") == 0 ||
493 strcmp(token,
"TIME=") == 0 || strcmp(token,
"MAXIMUM") == 0 ||
494 strcmp(token,
"VALUE") == 0 || strcmp(token,
"NODE") == 0) {
499 token = strtok(NULL,
" ");
500 double volt =
ReadDouble(token, -1, readerror);
504 std::cerr <<
" Error reading file " << prnsol <<
" (line " << il
510 if (inode < 1 || inode > (
int)
m_nodes.size()) {
512 std::cerr <<
" Node number " << inode <<
" out of range\n";
513 std::cerr <<
" on potential file " << prnsol <<
" (line " << il
525 std::cout <<
" Read " << nread <<
" potentials from file " << prnsol
530 std::cerr <<
" Number of nodes read (" << nread <<
") on potential file "
531 << prnsol <<
" does not\n"
532 <<
" match the node list (" <<
m_nodes.size() <<
").\n";
541 <<
" Field map could not be read and cannot be interpolated.\n";
553 std::cerr <<
" Weighting field cannot be added.\n";
558 std::ifstream fprnsol;
559 fprnsol.open(prnsol.c_str(), std::ios::in);
560 if (fprnsol.fail()) {
568 std::cout <<
m_className <<
"::SetWeightingField:\n"
569 <<
" Replacing existing weighting field " << label <<
".\n";
573 constexpr int size = 100;
579 unsigned int nread = 0;
580 bool readerror =
false;
581 while (fprnsol.getline(line, size,
'\n')) {
584 if (strstr(line,
"VERSION") != NULL) {
585 fprnsol.getline(line, size,
'\n');
587 fprnsol.getline(line, size,
'\n');
593 token = strtok(line,
" ");
595 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
596 int(token[0]) == 10 ||
int(token[0]) == 13 ||
597 strcmp(token,
"PRINT") == 0 || strcmp(token,
"*****") == 0 ||
598 strcmp(token,
"LOAD") == 0 || strcmp(token,
"TIME=") == 0 ||
599 strcmp(token,
"MAXIMUM") == 0 || strcmp(token,
"VALUE") == 0 ||
600 strcmp(token,
"NODE") == 0)
604 token = strtok(NULL,
" ");
605 double volt =
ReadDouble(token, -1, readerror);
608 std::cerr <<
m_className <<
"::SetWeightingField:\n";
609 std::cerr <<
" Error reading file " << prnsol <<
" (line " << il
615 if (inode < 1 || inode > (
int)
m_nodes.size()) {
616 std::cerr <<
m_className <<
"::SetWeightingField:\n";
617 std::cerr <<
" Node number " << inode <<
" out of range\n";
618 std::cerr <<
" on potential file " << prnsol <<
" (line " << il
622 m_nodes[inode - 1].w[iw] = volt;
629 std::cout <<
m_className <<
"::SetWeightingField:\n";
630 std::cout <<
" Read " << nread <<
" potentials from file " << prnsol
634 std::cerr <<
m_className <<
"::SetWeightingField:\n"
635 <<
" Number of nodes read from potential file " << prnsol
636 <<
" (" << nread <<
")\n does not match the node list ("
644 std::cerr <<
m_className <<
"::SetWeightingField:\n";
645 std::cerr <<
" Field map could not be read "
646 <<
"and cannot be interpolated.\n";
653 const double z,
double& ex,
double& ey,
654 double& ez,
Medium*& m,
int& status) {
660 const double zin,
double& ex,
double& ey,
661 double& ez,
double& volt,
Medium*& m,
664 double x = xin, y = yin, z = 0.;
667 bool xmirr, ymirr, zmirr;
668 double rcoordinate, rotation;
669 MapCoordinates(x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
672 ex = ey = ez = volt = 0;
691 double t1, t2, t3, t4, jac[4][4], det;
692 const int imap =
FindElement5(x, y, z, t1, t2, t3, t4, jac, det);
696 std::cout <<
" Point (" << x <<
", " << y <<
") not in the mesh.\n";
704 PrintElement(
"ElectricField", x, y, z, t1, t2, t3, t4, element, 8);
714 const double invdet = 1. / det;
716 volt = n0.
v * t1 * (2 * t1 - 1) + n1.
v * t2 * (2 * t2 - 1) +
717 n2.
v * t3 * (2 * t3 - 1) + 4 * n3.
v * t1 * t2 + 4 * n4.
v * t1 * t3 +
719 ex = -(n0.
v * (4 * t1 - 1) * jac[0][1] + n1.
v * (4 * t2 - 1) * jac[1][1] +
720 n2.
v * (4 * t3 - 1) * jac[2][1] +
721 n3.
v * (4 * t2 * jac[0][1] + 4 * t1 * jac[1][1]) +
722 n4.
v * (4 * t3 * jac[0][1] + 4 * t1 * jac[2][1]) +
723 n5.
v * (4 * t3 * jac[1][1] + 4 * t2 * jac[2][1])) *
725 ey = -(n0.
v * (4 * t1 - 1) * jac[0][2] + n1.
v * (4 * t2 - 1) * jac[1][2] +
726 n2.
v * (4 * t3 - 1) * jac[2][2] +
727 n3.
v * (4 * t2 * jac[0][2] + 4 * t1 * jac[1][2]) +
728 n4.
v * (4 * t3 * jac[0][2] + 4 * t1 * jac[2][2]) +
729 n5.
v * (4 * t3 * jac[1][2] + 4 * t2 * jac[2][2])) *
734 volt = -n0.
v * (1 - t1) * (1 - t2) * (1 + t1 + t2) * 0.25 -
735 n1.
v * (1 + t1) * (1 - t2) * (1 - t1 + t2) * 0.25 -
736 n2.
v * (1 + t1) * (1 + t2) * (1 - t1 - t2) * 0.25 -
737 n3.
v * (1 - t1) * (1 + t2) * (1 + t1 - t2) * 0.25 +
738 n4.
v * (1 - t1) * (1 + t1) * (1 - t2) * 0.5 +
739 n5.
v * (1 + t1) * (1 + t2) * (1 - t2) * 0.5 +
740 n6.
v * (1 - t1) * (1 + t1) * (1 + t2) * 0.5 +
741 n7.
v * (1 - t1) * (1 + t2) * (1 - t2) * 0.5;
742 ex = -(n0.
v * ((1 - t2) * (2 * t1 + t2) * jac[0][0] +
743 (1 - t1) * (t1 + 2 * t2) * jac[1][0]) *
745 n1.
v * ((1 - t2) * (2 * t1 - t2) * jac[0][0] -
746 (1 + t1) * (t1 - 2 * t2) * jac[1][0]) *
748 n2.
v * ((1 + t2) * (2 * t1 + t2) * jac[0][0] +
749 (1 + t1) * (t1 + 2 * t2) * jac[1][0]) *
751 n3.
v * ((1 + t2) * (2 * t1 - t2) * jac[0][0] -
752 (1 - t1) * (t1 - 2 * t2) * jac[1][0]) *
754 n4.
v * (t1 * (t2 - 1) * jac[0][0] +
755 (t1 - 1) * (t1 + 1) * jac[1][0] * 0.5) +
756 n5.
v * ((1 - t2) * (1 + t2) * jac[0][0] * 0.5 -
757 (1 + t1) * t2 * jac[1][0]) +
758 n6.
v * (-t1 * (1 + t2) * jac[0][0] +
759 (1 - t1) * (1 + t1) * jac[1][0] * 0.5) +
760 n7.
v * ((t2 - 1) * (t2 + 1) * jac[0][0] * 0.5 +
761 (t1 - 1) * t2 * jac[1][0])) *
763 ey = -(n0.
v * ((1 - t2) * (2 * t1 + t2) * jac[0][1] +
764 (1 - t1) * (t1 + 2 * t2) * jac[1][1]) *
766 n1.
v * ((1 - t2) * (2 * t1 - t2) * jac[0][1] -
767 (1 + t1) * (t1 - 2 * t2) * jac[1][1]) *
769 n2.
v * ((1 + t2) * (2 * t1 + t2) * jac[0][1] +
770 (1 + t1) * (t1 + 2 * t2) * jac[1][1]) *
772 n3.
v * ((1 + t2) * (2 * t1 - t2) * jac[0][1] -
773 (1 - t1) * (t1 - 2 * t2) * jac[1][1]) *
775 n4.
v * (t1 * (t2 - 1) * jac[0][1] +
776 (t1 - 1) * (t1 + 1) * jac[1][1] * 0.5) +
777 n5.
v * ((1 - t2) * (1 + t2) * jac[0][1] * 0.5 -
778 (1 + t1) * t2 * jac[1][1]) +
779 n6.
v * (-t1 * (1 + t2) * jac[0][1] +
780 (1 - t1) * (1 + t1) * jac[1][1] * 0.5) +
781 n7.
v * ((t2 - 1) * (t2 + 1) * jac[0][1] * 0.5 +
782 (t1 - 1) * t2 * jac[1][1])) *
787 UnmapFields(ex, ey, ez, x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
792 std::cout <<
" Material " << element.
matmap <<
", drift flag "
803 const double zin,
double& wx,
double& wy,
804 double& wz,
const std::string& label) {
819 double x = xin, y = yin, z = zin;
822 bool xmirr, ymirr, zmirr;
823 double rcoordinate, rotation;
824 MapCoordinates(x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
829 double t1, t2, t3, t4, jac[4][4], det;
830 const int imap =
FindElement5(x, y, z, t1, t2, t3, t4, jac, det);
832 if (imap < 0)
return;
836 PrintElement(
"WeightingField", x, y, z, t1, t2, t3, t4, element, 8, iw);
845 const double invdet = 1. / det;
847 wx = -(n0.
w[iw] * (4 * t1 - 1) * jac[0][1] +
848 n1.
w[iw] * (4 * t2 - 1) * jac[1][1] +
849 n2.
w[iw] * (4 * t3 - 1) * jac[2][1] +
850 n3.
w[iw] * (4 * t2 * jac[0][1] + 4 * t1 * jac[1][1]) +
851 n4.
w[iw] * (4 * t3 * jac[0][1] + 4 * t1 * jac[2][1]) +
852 n5.
w[iw] * (4 * t3 * jac[1][1] + 4 * t2 * jac[2][1])) *
854 wy = -(n0.
w[iw] * (4 * t1 - 1) * jac[0][2] +
855 n1.
w[iw] * (4 * t2 - 1) * jac[1][2] +
856 n2.
w[iw] * (4 * t3 - 1) * jac[2][2] +
857 n3.
w[iw] * (4 * t2 * jac[0][2] + 4 * t1 * jac[1][2]) +
858 n4.
w[iw] * (4 * t3 * jac[0][2] + 4 * t1 * jac[2][2]) +
859 n5.
w[iw] * (4 * t3 * jac[1][2] + 4 * t2 * jac[2][2])) *
864 wx = -(n0.
w[iw] * ((1 - t2) * (2 * t1 + t2) * jac[0][0] +
865 (1 - t1) * (t1 + 2 * t2) * jac[1][0]) *
867 n1.
w[iw] * ((1 - t2) * (2 * t1 - t2) * jac[0][0] -
868 (1 + t1) * (t1 - 2 * t2) * jac[1][0]) *
870 n2.
w[iw] * ((1 + t2) * (2 * t1 + t2) * jac[0][0] +
871 (1 + t1) * (t1 + 2 * t2) * jac[1][0]) *
873 n3.
w[iw] * ((1 + t2) * (2 * t1 - t2) * jac[0][0] -
874 (1 - t1) * (t1 - 2 * t2) * jac[1][0]) *
876 n4.
w[iw] * (t1 * (t2 - 1) * jac[0][0] +
877 (t1 - 1) * (t1 + 1) * jac[1][0] * 0.5) +
878 n5.
w[iw] * ((1 - t2) * (1 + t2) * jac[0][0] * 0.5 -
879 (1 + t1) * t2 * jac[1][0]) +
880 n6.
w[iw] * (-t1 * (1 + t2) * jac[0][0] +
881 (1 - t1) * (1 + t1) * jac[1][0] * 0.5) +
882 n7.
w[iw] * ((t2 - 1) * (1 + t2) * jac[0][0] * 0.5 +
883 (t1 - 1) * t2 * jac[1][0])) *
885 wy = -(n0.
w[iw] * ((1 - t2) * (2 * t1 + t2) * jac[0][1] +
886 (1 - t1) * (t1 + 2 * t2) * jac[1][1]) *
888 n1.
w[iw] * ((1 - t2) * (2 * t1 - t2) * jac[0][1] -
889 (1 + t1) * (t1 - 2 * t2) * jac[1][1]) *
891 n2.
w[iw] * ((1 + t2) * (2 * t1 + t2) * jac[0][1] +
892 (1 + t1) * (t1 + 2 * t2) * jac[1][1]) *
894 n3.
w[iw] * ((1 + t2) * (2 * t1 - t2) * jac[0][1] -
895 (1 - t1) * (t1 - 2 * t2) * jac[1][1]) *
897 n4.
w[iw] * (t1 * (t2 - 1) * jac[0][1] +
898 (t1 - 1) * (t1 + 1) * jac[1][1] * 0.5) +
899 n5.
w[iw] * ((1 - t2) * (1 + t2) * jac[0][1] * 0.5 -
900 (1 + t1) * t2 * jac[1][1]) +
901 n6.
w[iw] * (-t1 * (1 + t2) * jac[0][1] +
902 (1 - t1) * (1 + t1) * jac[1][1] * 0.5) +
903 n7.
w[iw] * ((t2 - 1) * (t2 + 1) * jac[0][1] * 0.5 +
904 (t1 - 1) * t2 * jac[1][1])) *
909 UnmapFields(wx, wy, wz, x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
914 const std::string& label) {
926 double x = xin, y = yin, z = zin;
929 bool xmirr, ymirr, zmirr;
930 double rcoordinate, rotation;
931 MapCoordinates(x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
936 double t1, t2, t3, t4, jac[4][4], det;
937 const int imap =
FindElement5(x, y, z, t1, t2, t3, t4, jac, det);
939 if (imap < 0)
return 0.;
943 PrintElement(
"WeightingPotential", x, y, z, t1, t2, t3, t4, element, 8, iw);
953 return n0.
w[iw] * t1 * (2 * t1 - 1) + n1.
w[iw] * t2 * (2 * t2 - 1) +
954 n2.
w[iw] * t3 * (2 * t3 - 1) + 4 * n3.
w[iw] * t1 * t2 +
955 4 * n4.
w[iw] * t1 * t3 + 4 * n5.
w[iw] * t2 * t3;
960 return -n0.
w[iw] * (1 - t1) * (1 - t2) * (1 + t1 + t2) * 0.25 -
961 n1.
w[iw] * (1 + t1) * (1 - t2) * (1 - t1 + t2) * 0.25 -
962 n2.
w[iw] * (1 + t1) * (1 + t2) * (1 - t1 - t2) * 0.25 -
963 n3.
w[iw] * (1 - t1) * (1 + t2) * (1 + t1 - t2) * 0.25 +
964 n4.
w[iw] * (1 - t1) * (1 + t1) * (1 - t2) * 0.5 +
965 n5.
w[iw] * (1 + t1) * (1 + t2) * (1 - t2) * 0.5 +
966 n6.
w[iw] * (1 - t1) * (1 + t1) * (1 + t2) * 0.5 +
967 n7.
w[iw] * (1 - t1) * (1 + t2) * (1 - t2) * 0.5;
973 double x = xin, y = yin, z = 0.;
976 bool xmirr, ymirr, zmirr;
977 double rcoordinate, rotation;
978 MapCoordinates(x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
992 double t1, t2, t3, t4, jac[4][4], det;
993 const int imap =
FindElement5(x, y, z, t1, t2, t3, t4, jac, det);
997 std::cerr <<
" Point (" << x <<
", " << y <<
") not in the mesh.\n";
1005 std::cerr <<
" Point (" << x <<
", " << y <<
")"
1006 <<
" has out of range material number " << imap <<
".\n";
1012 PrintElement(
"GetMedium", x, y, z, t1, t2, t3, t4, element, 8);
1020 if (fabs(zmax - zmin) <= 0.) {
1021 std::cerr <<
m_className <<
"::SetRangeZ: Zero range is not permitted.\n";
1042 (fabs((n1.
x - n0.
x) * (n2.
y - n0.
y) - (n2.
x - n0.
x) * (n1.
y - n0.
y)) +
1043 fabs((n3.
x - n0.
x) * (n2.
y - n0.
y) - (n2.
x - n0.
x) * (n3.
y - n0.
y)));
1057 for (
int j = 0; j < np - 1; ++j) {
1059 for (
int k = j + 1; k < np; ++k) {
1062 const double dx = nj.
x - nk.
x;
1063 const double dy = nj.
y - nk.
y;
1064 const double dist = sqrt(dx * dx + dy * dy);
1068 if (dist < dmin) dmin = dist;
1069 if (dist > dmax) dmax = dist;
bool SetWeightingField(std::string prnsol, std::string label)
Import a weighting field map.
void GetAspectRatio(const unsigned int i, double &dmin, double &dmax) override
bool Initialise(std::string elist="ELIST.lis", std::string nlist="NLIST.lis", std::string mplist="MPLIST.lis", std::string prnsol="PRNSOL.lis", std::string unit="cm")
ComponentAnsys121()
Constructor.
void ElectricField(const double x, const double y, const double z, double &ex, double &ey, double &ez, Medium *&m, int &status) override
double GetElementVolume(const unsigned int i) override
void UpdatePeriodicity() override
Verify periodicities.
void SetRangeZ(const double zmin, const double zmax)
Set the limits of the active region along z.
double WeightingPotential(const double x, const double y, const double z, const std::string &label) override
void WeightingField(const double x, const double y, const double z, double &wx, double &wy, double &wz, const std::string &label) override
Medium * GetMedium(const double x, const double y, const double z) override
Get the medium at a given location (x, y, z).
Base class for components based on finite-element field maps.
void PrintMaterials()
List all currently defined materials.
bool SetDefaultDriftMedium()
Find lowest epsilon, check for eps = 0, set default drift media flags.
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.
void PrintWarning(const std::string &header)
std::array< double, 3 > m_maxBoundingBox
std::array< double, 3 > m_mapmin
std::array< double, 3 > m_minBoundingBox
static double ScalingFactor(std::string unit)
void UpdatePeriodicityCommon()
int ReadInteger(char *token, int def, bool &error)
std::vector< Material > m_materials
std::vector< bool > m_wfieldsOk
size_t GetWeightingFieldIndex(const std::string &label) const
std::vector< Node > m_nodes
void PrintCouldNotOpen(const std::string &header, const std::string &filename) const
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.
void UpdatePeriodicity2d()
std::vector< std::string > m_wfields
std::vector< Element > m_elements
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_mapmax
void Reset() override
Reset the component.
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
size_t GetOrCreateWeightingFieldIndex(const std::string &label)
bool m_debug
Switch on/off debugging messages.
std::string m_className
Class name.
bool m_ready
Ready for use?
Abstract base class for media.
bool IsDriftable() const
Is charge carrier transport enabled in this medium?