13 std::string mplist, std::string prnsol,
20 constexpr int size = 100;
24 std::ifstream fmplist;
25 fmplist.open(mplist.c_str(), std::ios::in);
33 unsigned int icurrmat = 0;
34 bool readerror =
false;
35 while (fmplist.getline(line, size,
'\n')) {
38 if (strcmp(line,
"1") == 0) {
39 fmplist.getline(line, size,
'\n');
41 fmplist.getline(line, size,
'\n');
43 fmplist.getline(line, size,
'\n');
45 fmplist.getline(line, size,
'\n');
47 fmplist.getline(line, size,
'\n');
53 token = strtok(line,
" ");
55 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
56 strcmp(token,
"TEMPERATURE") == 0 || strcmp(token,
"PROPERTY=") == 0 ||
57 int(token[0]) == 10 ||
int(token[0]) == 13)
60 if (strcmp(token,
"LIST") == 0) {
61 token = strtok(NULL,
" ");
62 token = strtok(NULL,
" ");
63 token = strtok(NULL,
" ");
64 token = strtok(NULL,
" ");
65 const unsigned int nMaterials =
ReadInteger(token, -1, readerror);
68 std::cerr <<
" Error reading file " << mplist <<
" (line " << il
77 material.medium =
nullptr;
80 std::cout <<
m_className <<
"::Initialise: " << nMaterials
83 }
else if (strcmp(token,
"MATERIAL") == 0) {
85 token = strtok(NULL,
" ");
86 token = strtok(NULL,
" ");
88 if (readerror || imat < 0) {
90 std::cerr <<
" Error reading file " << mplist <<
" (line " << il
96 }
else if (strcmp(token,
"TEMP") == 0) {
98 token = strtok(NULL,
" ");
100 if (strncmp(token,
"PERX", 4) == 0) {
102 }
else if (strncmp(token,
"RSVX", 4) == 0) {
106 std::cerr <<
" Found unknown material property flag " << token
108 std::cerr <<
" on material properties file " << mplist <<
" (line "
112 fmplist.getline(line, size,
'\n');
115 token = strtok(line,
" ");
116 if (icurrmat < 1 || icurrmat >
m_materials.size()) {
118 std::cerr <<
" Found out-of-range current material index "
120 std::cerr <<
" in material properties file " << mplist <<
".\n";
123 }
else if (itype == 1) {
125 }
else if (itype == 2) {
130 std::cerr <<
" Error reading file " << mplist <<
" line " << il
135 }
else if (strcmp(token,
"PROPERTY") == 0) {
137 token = strtok(NULL,
" ");
138 token = strtok(NULL,
" ");
140 if (strcmp(token,
"PERX") == 0) {
142 }
else if (strcmp(token,
"RSVX") == 0) {
146 std::cerr <<
" Found unknown material property flag " << token
148 std::cerr <<
" on material properties file " << mplist <<
" (line "
152 token = strtok(NULL,
" ");
153 token = strtok(NULL,
" ");
157 std::cerr <<
" Error reading file " << mplist <<
" (line " << il
161 }
else if (imat < 1 || imat > (
int)
m_materials.size()) {
163 std::cerr <<
" Found out-of-range material index " << imat <<
"\n";
164 std::cerr <<
" in material properties file " << mplist <<
".\n";
167 fmplist.getline(line, size,
'\n');
169 fmplist.getline(line, size,
'\n');
172 token = strtok(line,
" ");
173 token = strtok(NULL,
" ");
176 }
else if (itype == 2) {
181 std::cerr <<
" Error reading file " << mplist <<
" (line " << il
198 <<
" materials from file " << mplist <<
".\n";
202 std::ifstream felist;
203 felist.open(elist.c_str(), std::ios::in);
214 while (felist.getline(line, size,
'\n')) {
217 if (strcmp(line,
"1") == 0) {
218 felist.getline(line, size,
'\n');
220 felist.getline(line, size,
'\n');
222 felist.getline(line, size,
'\n');
224 felist.getline(line, size,
'\n');
226 felist.getline(line, size,
'\n');
231 if (strstr(line,
"***") != NULL) {
232 felist.getline(line, size,
'\n');
234 felist.getline(line, size,
'\n');
236 felist.getline(line, size,
'\n');
243 token = strtok(line,
" ");
245 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
246 int(token[0]) == 10 ||
int(token[0]) == 13 ||
247 strcmp(token,
"LIST") == 0 || strcmp(token,
"ELEM") == 0) {
252 token = strtok(NULL,
" ");
254 token = strtok(NULL,
" ");
255 token = strtok(NULL,
" ");
256 token = strtok(NULL,
" ");
257 token = strtok(NULL,
" ");
258 token = strtok(NULL,
" ");
260 token = strtok(NULL,
" ");
262 token = strtok(NULL,
" ");
264 token = strtok(NULL,
" ");
266 token = strtok(NULL,
" ");
268 token = strtok(NULL,
" ");
270 token = strtok(NULL,
" ");
272 token = strtok(NULL,
" ");
274 if (!felist.getline(line, size,
'\n')) {
276 std::cerr <<
" Error reading element " << ielem <<
".\n";
282 token = strtok(line,
" ");
284 token = strtok(NULL,
" ");
290 std::cerr <<
" Error reading file " << elist <<
" (line " << il
294 }
else if (ielem - 1 != (
int)
m_elements.size() + nbackground) {
296 std::cerr <<
" Synchronisation lost on file " << elist <<
" (line "
298 std::cerr <<
" Element: " << ielem <<
" (expected "
299 <<
m_elements.size() <<
"), material: " << imat <<
",\n"
300 <<
" nodes: (" << in0 <<
", " << in1 <<
", " << in2 <<
", "
301 << in3 <<
", " << in4 <<
", " << in5 <<
", " << in6 <<
", "
302 << in7 <<
", " << in8 <<
", " << in9 <<
")\n";
309 std::cerr <<
" Out-of-range material number on file " << elist
310 <<
" (line " << il <<
").\n";
311 std::cerr <<
" Element: " << ielem <<
", material: " << imat <<
",\n";
312 std::cerr <<
" nodes: (" << in0 <<
", " << in1 <<
", " << in2 <<
", "
313 << in3 <<
", " << in4 <<
", " << in5 <<
", " << in6 <<
", "
314 << in7 <<
", " << in8 <<
", " << in9 <<
")\n";
319 std::cerr <<
" Element " << ielem <<
" in element list " << elist
321 std::cerr <<
" uses material " << imat
322 <<
" which has not been assigned\n";
323 std::cerr <<
" a positive permittivity in material list " << mplist
329 if (in0 < 1 || in1 < 1 || in2 < 1 || in3 < 1 || in4 < 1 || in5 < 1 ||
330 in6 < 1 || in7 < 1 || in8 < 1 || in9 < 1) {
332 std::cerr <<
" Found a node number < 1 on file " << elist <<
" (line "
334 std::cerr <<
" Element: " << ielem <<
", material: " << imat <<
",\n";
335 std::cerr <<
" nodes: (" << in0 <<
", " << in1 <<
", " << in2 <<
", "
336 << in3 <<
", " << in4 <<
", " << in5 <<
", " << in6 <<
", "
337 << in7 <<
", " << in8 <<
", " << in9 <<
")\n";
340 if (in0 > highestnode) highestnode = in0;
341 if (in1 > highestnode) highestnode = in1;
342 if (in2 > highestnode) highestnode = in2;
343 if (in3 > highestnode) highestnode = in3;
344 if (in4 > highestnode) highestnode = in4;
345 if (in5 > highestnode) highestnode = in5;
346 if (in6 > highestnode) highestnode = in6;
347 if (in7 > highestnode) highestnode = in7;
348 if (in8 > highestnode) highestnode = in8;
349 if (in9 > highestnode) highestnode = in9;
358 if (in0 == in1 || in0 == in2 || in0 == in3 || in0 == in4 || in0 == in5 ||
359 in0 == in6 || in0 == in7 || in0 == in8 || in0 == in9 || in1 == in2 ||
360 in1 == in3 || in1 == in4 || in1 == in5 || in1 == in6 || in1 == in7 ||
361 in1 == in8 || in1 == in9 || in2 == in3 || in2 == in4 || in2 == in5 ||
362 in2 == in6 || in2 == in7 || in2 == in8 || in2 == in9 || in3 == in4 ||
363 in3 == in5 || in3 == in6 || in3 == in7 || in3 == in8 || in3 == in9 ||
364 in4 == in5 || in4 == in6 || in4 == in7 || in4 == in8 || in4 == in9 ||
365 in5 == in6 || in5 == in7 || in5 == in8 || in5 == in9 || in6 == in7 ||
366 in6 == in8 || in6 == in9 || in7 == in8 || in7 == in9 || in8 == in9) {
368 std::cerr <<
" Element " << ielem <<
" of file " << elist
369 <<
" is degenerate,\n";
370 std::cerr <<
" no such elements allowed in this type of map.\n";
377 newElement.
matmap = imat - 1;
380 newElement.
emap[0] = in0 - 1;
381 newElement.
emap[1] = in1 - 1;
382 newElement.
emap[2] = in2 - 1;
383 newElement.
emap[3] = in3 - 1;
384 newElement.
emap[4] = in4 - 1;
385 newElement.
emap[7] = in5 - 1;
386 newElement.
emap[5] = in6 - 1;
387 newElement.
emap[6] = in7 - 1;
388 newElement.
emap[8] = in8 - 1;
389 newElement.
emap[9] = in9 - 1;
397 <<
" Read " <<
m_elements.size() <<
" elements from file "
399 std::cout <<
" highest node number: " << highestnode <<
",\n";
400 std::cout <<
" background elements skipped: " << nbackground <<
"\n";
405 <<
" Unknown length unit " << unit <<
".\n";
410 std::cout <<
m_className <<
":Initialise: Unit scaling factor = "
415 std::ifstream fnlist;
416 fnlist.open(nlist.c_str(), std::ios::in);
425 while (fnlist.getline(line, size,
'\n')) {
428 if (strcmp(line,
"1") == 0) {
429 fnlist.getline(line, size,
'\n');
431 fnlist.getline(line, size,
'\n');
433 fnlist.getline(line, size,
'\n');
435 fnlist.getline(line, size,
'\n');
437 fnlist.getline(line, size,
'\n');
442 if (strstr(line,
"***") != NULL) {
443 fnlist.getline(line, size,
'\n');
445 fnlist.getline(line, size,
'\n');
447 fnlist.getline(line, size,
'\n');
453 token = strtok(line,
" ");
455 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
456 int(token[0]) == 10 ||
int(token[0]) == 13 ||
457 strcmp(token,
"LIST") == 0 || strcmp(token,
"NODE") == 0)
461 token = strtok(NULL,
" ");
462 double xnode =
ReadDouble(token, -1, readerror);
463 token = strtok(NULL,
" ");
464 double ynode =
ReadDouble(token, -1, readerror);
465 token = strtok(NULL,
" ");
466 double znode =
ReadDouble(token, -1, readerror);
470 std::cerr <<
" Error reading file " << nlist <<
" (line " << il
476 if (inode - 1 != (
int)
m_nodes.size()) {
478 std::cerr <<
" Synchronisation lost on file " << nlist <<
" (line "
480 std::cerr <<
" Node: " << inode <<
" (expected " <<
m_nodes.size()
481 <<
"), (x,y,z) = (" << xnode <<
", " << ynode <<
", " << znode
488 newNode.
x = xnode * funit;
489 newNode.
y = ynode * funit;
490 newNode.
z = znode * funit;
491 m_nodes.push_back(std::move(newNode));
497 std::cout <<
" Read " <<
m_nodes.size() <<
" nodes from file " << nlist <<
".\n";
499 if ((
int)
m_nodes.size() != highestnode) {
501 std::cerr <<
" Number of nodes read (" <<
m_nodes.size() <<
") on " << nlist
503 std::cerr <<
" does not match element list (" << highestnode <<
").\n";
508 std::ifstream fprnsol;
509 fprnsol.open(prnsol.c_str(), std::ios::in);
510 if (fprnsol.fail()) {
517 unsigned int nread = 0;
518 while (fprnsol.getline(line, size,
'\n')) {
521 if (strcmp(line,
"1") == 0) {
522 fprnsol.getline(line, size,
'\n');
524 fprnsol.getline(line, size,
'\n');
526 fprnsol.getline(line, size,
'\n');
528 fprnsol.getline(line, size,
'\n');
530 fprnsol.getline(line, size,
'\n');
535 if (strstr(line,
"***") != NULL) {
536 fprnsol.getline(line, size,
'\n');
538 fprnsol.getline(line, size,
'\n');
540 fprnsol.getline(line, size,
'\n');
546 token = strtok(line,
" ");
548 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
549 int(token[0]) == 10 ||
int(token[0]) == 13 ||
550 strcmp(token,
"PRINT") == 0 || strcmp(token,
"*****") == 0 ||
551 strcmp(token,
"LOAD") == 0 || strcmp(token,
"TIME=") == 0 ||
552 strcmp(token,
"MAXIMUM") == 0 || strcmp(token,
"VALUE") == 0 ||
553 strcmp(token,
"NODE") == 0)
557 token = strtok(NULL,
" ");
558 double volt =
ReadDouble(token, -1, readerror);
562 std::cerr <<
" Error reading file " << prnsol <<
" (line << " << il
568 if (inode < 1 || inode > highestnode) {
570 std::cerr <<
" Node number " << inode <<
" out of range\n";
571 std::cerr <<
" on potential file " << prnsol <<
" (line " << il
582 std::cout <<
m_className <<
"::Initialise:\n Read "
583 << nread <<
" potentials from file " << prnsol <<
".\n";
587 std::cerr <<
" Number of nodes read (" << nread <<
") on potential file "
589 std::cerr <<
" does not match the node list (" <<
m_nodes.size() <<
").\n";
599 <<
" Field map could not be read and can not be interpolated.\n";
610 std::cerr <<
" Weighting field cannot be added.\n";
615 std::ifstream fprnsol;
616 fprnsol.open(prnsol.c_str(), std::ios::in);
617 if (fprnsol.fail()) {
625 std::cout <<
m_className <<
"::SetWeightingField:\n"
626 <<
" Replacing existing weighting field " << label <<
".\n";
631 constexpr int size = 100;
637 unsigned int nread = 0;
638 bool readerror =
false;
639 while (fprnsol.getline(line, size,
'\n')) {
642 if (strcmp(line,
"1") == 0) {
643 fprnsol.getline(line, size,
'\n');
645 fprnsol.getline(line, size,
'\n');
647 fprnsol.getline(line, size,
'\n');
649 fprnsol.getline(line, size,
'\n');
651 fprnsol.getline(line, size,
'\n');
656 if (strstr(line,
"***") != NULL) {
657 fprnsol.getline(line, size,
'\n');
659 fprnsol.getline(line, size,
'\n');
661 fprnsol.getline(line, size,
'\n');
667 token = strtok(line,
" ");
669 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
670 int(token[0]) == 10 ||
int(token[0]) == 13 ||
671 strcmp(token,
"PRINT") == 0 || strcmp(token,
"*****") == 0 ||
672 strcmp(token,
"LOAD") == 0 || strcmp(token,
"TIME=") == 0 ||
673 strcmp(token,
"MAXIMUM") == 0 || strcmp(token,
"VALUE") == 0 ||
674 strcmp(token,
"NODE") == 0)
678 token = strtok(NULL,
" ");
679 double volt =
ReadDouble(token, -1, readerror);
682 std::cerr <<
m_className <<
"::SetWeightingField:\n";
683 std::cerr <<
" Error reading file " << prnsol.c_str() <<
" (line "
689 if (inode < 1 || inode > (
int)
m_nodes.size()) {
690 std::cerr <<
m_className <<
"::SetWeightingField:\n";
691 std::cerr <<
" Node number " << inode <<
" out of range\n";
692 std::cerr <<
" on potential file " << prnsol.c_str() <<
" (line " << il
696 m_nodes[inode - 1].w[iw] = volt;
703 std::cout <<
m_className <<
"::SetWeightingField:\n"
704 <<
" Read " << nread <<
" potentials from file "
708 std::cerr <<
m_className <<
"::SetWeightingField:\n"
709 <<
" Number of nodes read from potential file " << prnsol
710 <<
" (" << nread <<
")\n does not match the node list ("
718 std::cerr <<
m_className <<
"::SetWeightingField:\n";
719 std::cerr <<
" Field map could not be read "
720 <<
"and cannot be interpolated.\n";
727 const double z,
double& ex,
double& ey,
728 double& ez,
Medium*& m,
int& status) {
734 const double zin,
double& ex,
double& ey,
735 double& ez,
double& volt,
Medium*& m,
738 double x = xin, y = yin, z = zin;
741 bool xmirr, ymirr, zmirr;
742 double rcoordinate, rotation;
743 MapCoordinates(x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
746 ex = ey = ez = volt = 0.;
760 double t1, t2, t3, t4, jac[4][4], det;
761 const int imap =
FindElement13(x, y, z, t1, t2, t3, t4, jac, det);
764 std::cerr <<
m_className <<
"::ElectricField: Point (" << x <<
", " << y
765 <<
", " << z <<
") not in the mesh.\n";
773 PrintElement(
"ElectricField", x, y, z, t1, t2, t3, t4, element, 10);
786 const double fourt1 = 4 * t1;
787 const double fourt2 = 4 * t2;
788 const double fourt3 = 4 * t3;
789 const double fourt4 = 4 * t4;
790 const double invdet = 1. / det;
792 volt = n0.
v * t1 * (2 * t1 - 1) + n1.
v * t2 * (2 * t2 - 1) +
793 n2.
v * t3 * (2 * t3 - 1) + n3.
v * t4 * (2 * t4 - 1) +
794 n4.
v * fourt1 * t2 + n5.
v * fourt1 * t3 + n6.
v * fourt1 * t4 +
795 n7.
v * fourt2 * t3 + n8.
v * fourt2 * t4 + n9.
v * fourt3 * t4;
796 ex = -(n0.
v * (fourt1 - 1) * jac[0][1] + n1.
v * (fourt2 - 1) * jac[1][1] +
797 n2.
v * (fourt3 - 1) * jac[2][1] + n3.
v * (fourt4 - 1) * jac[3][1] +
798 n4.
v * (fourt2 * jac[0][1] + fourt1 * jac[1][1]) +
799 n5.
v * (fourt3 * jac[0][1] + fourt1 * jac[2][1]) +
800 n6.
v * (fourt4 * jac[0][1] + fourt1 * jac[3][1]) +
801 n7.
v * (fourt3 * jac[1][1] + fourt2 * jac[2][1]) +
802 n8.
v * (fourt4 * jac[1][1] + fourt2 * jac[3][1]) +
803 n9.
v * (fourt4 * jac[2][1] + fourt3 * jac[3][1])) *
806 ey = -(n0.
v * (fourt1 - 1) * jac[0][2] + n1.
v * (fourt2 - 1) * jac[1][2] +
807 n2.
v * (fourt3 - 1) * jac[2][2] + n3.
v * (fourt4 - 1) * jac[3][2] +
808 n4.
v * (fourt2 * jac[0][2] + fourt1 * jac[1][2]) +
809 n5.
v * (fourt3 * jac[0][2] + fourt1 * jac[2][2]) +
810 n6.
v * (fourt4 * jac[0][2] + fourt1 * jac[3][2]) +
811 n7.
v * (fourt3 * jac[1][2] + fourt2 * jac[2][2]) +
812 n8.
v * (fourt4 * jac[1][2] + fourt2 * jac[3][2]) +
813 n9.
v * (fourt4 * jac[2][2] + fourt3 * jac[3][2])) *
816 ez = -(n0.
v * (fourt1 - 1) * jac[0][3] + n1.
v * (fourt2 - 1) * jac[1][3] +
817 n2.
v * (fourt3 - 1) * jac[2][3] + n3.
v * (fourt4 - 1) * jac[3][3] +
818 n4.
v * (fourt2 * jac[0][3] + fourt1 * jac[1][3]) +
819 n5.
v * (fourt3 * jac[0][3] + fourt1 * jac[2][3]) +
820 n6.
v * (fourt4 * jac[0][3] + fourt1 * jac[3][3]) +
821 n7.
v * (fourt3 * jac[1][3] + fourt2 * jac[2][3]) +
822 n8.
v * (fourt4 * jac[1][3] + fourt2 * jac[3][3]) +
823 n9.
v * (fourt4 * jac[2][3] + fourt3 * jac[3][3])) *
827 UnmapFields(ex, ey, ez, x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
832 std::cout <<
" Material " << element.
matmap <<
", drift flag "
843 const double zin,
double& wx,
double& wy,
844 double& wz,
const std::string& label) {
859 double x = xin, y = yin, z = zin;
862 bool xmirr, ymirr, zmirr;
863 double rcoordinate, rotation;
864 MapCoordinates(x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
869 double t1, t2, t3, t4, jac[4][4], det;
870 const int imap =
FindElement13(x, y, z, t1, t2, t3, t4, jac, det);
872 if (imap < 0)
return;
876 PrintElement(
"WeightingField", x, y, z, t1, t2, t3, t4, element, 10, iw);
889 const double invdet = 1. / det;
890 const double fourt1 = 4 * t1;
891 const double fourt2 = 4 * t2;
892 const double fourt3 = 4 * t3;
893 const double fourt4 = 4 * t4;
894 wx = -(n0.
w[iw] * (fourt1 - 1) * jac[0][1] +
895 n1.
w[iw] * (fourt2 - 1) * jac[1][1] +
896 n2.
w[iw] * (fourt3 - 1) * jac[2][1] +
897 n3.
w[iw] * (fourt4 - 1) * jac[3][1] +
898 n4.
w[iw] * (fourt2 * jac[0][1] + fourt1 * jac[1][1]) +
899 n5.
w[iw] * (fourt3 * jac[0][1] + fourt1 * jac[2][1]) +
900 n6.
w[iw] * (fourt4 * jac[0][1] + fourt1 * jac[3][1]) +
901 n7.
w[iw] * (fourt3 * jac[1][1] + fourt2 * jac[2][1]) +
902 n8.
w[iw] * (fourt4 * jac[1][1] + fourt2 * jac[3][1]) +
903 n9.
w[iw] * (fourt4 * jac[2][1] + fourt3 * jac[3][1])) *
906 wy = -(n0.
w[iw] * (fourt1 - 1) * jac[0][2] +
907 n1.
w[iw] * (fourt2 - 1) * jac[1][2] +
908 n2.
w[iw] * (fourt3 - 1) * jac[2][2] +
909 n3.
w[iw] * (fourt4 - 1) * jac[3][2] +
910 n4.
w[iw] * (fourt2 * jac[0][2] + fourt1 * jac[1][2]) +
911 n5.
w[iw] * (fourt3 * jac[0][2] + fourt1 * jac[2][2]) +
912 n6.
w[iw] * (fourt4 * jac[0][2] + fourt1 * jac[3][2]) +
913 n7.
w[iw] * (fourt3 * jac[1][2] + fourt2 * jac[2][2]) +
914 n8.
w[iw] * (fourt4 * jac[1][2] + fourt2 * jac[3][2]) +
915 n9.
w[iw] * (fourt4 * jac[2][2] + fourt3 * jac[3][2])) *
918 wz = -(n0.
w[iw] * (fourt1 - 1) * jac[0][3] +
919 n1.
w[iw] * (fourt2 - 1) * jac[1][3] +
920 n2.
w[iw] * (fourt3 - 1) * jac[2][3] +
921 n3.
w[iw] * (fourt4 - 1) * jac[3][3] +
922 n4.
w[iw] * (fourt2 * jac[0][3] + fourt1 * jac[1][3]) +
923 n5.
w[iw] * (fourt3 * jac[0][3] + fourt1 * jac[2][3]) +
924 n6.
w[iw] * (fourt4 * jac[0][3] + fourt1 * jac[3][3]) +
925 n7.
w[iw] * (fourt3 * jac[1][3] + fourt2 * jac[2][3]) +
926 n8.
w[iw] * (fourt4 * jac[1][3] + fourt2 * jac[3][3]) +
927 n9.
w[iw] * (fourt4 * jac[2][3] + fourt3 * jac[3][3])) *
931 UnmapFields(wx, wy, wz, x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
936 const std::string& label) {
948 double x = xin, y = yin, z = zin;
951 bool xmirr, ymirr, zmirr;
952 double rcoordinate, rotation;
953 MapCoordinates(x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
958 double t1, t2, t3, t4, jac[4][4], det;
959 const int imap =
FindElement13(x, y, z, t1, t2, t3, t4, jac, det);
960 if (imap < 0)
return 0.;
964 PrintElement(
"WeightingPotential", x, y, z, t1, t2, t3, t4, element, 10,
977 return n0.
w[iw] * t1 * (2 * t1 - 1) + n1.
w[iw] * t2 * (2 * t2 - 1) +
978 n2.
w[iw] * t3 * (2 * t3 - 1) + n3.
w[iw] * t4 * (2 * t4 - 1) +
979 4 * n4.
w[iw] * t1 * t2 + 4 * n5.
w[iw] * t1 * t3 +
980 4 * n6.
w[iw] * t1 * t4 + 4 * n7.
w[iw] * t2 * t3 +
981 4 * n8.
w[iw] * t2 * t4 + 4 * n9.
w[iw] * t3 * t4;
987 double x = xin, y = yin, z = zin;
990 bool xmirr, ymirr, zmirr;
991 double rcoordinate, rotation;
992 MapCoordinates(x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
997 std::cerr <<
" Field map not available for interpolation.\n";
1003 double t1, t2, t3, t4, jac[4][4], det;
1004 const int imap =
FindElement13(x, y, z, t1, t2, t3, t4, jac, det);
1008 std::cerr <<
" Point (" << x <<
", " << y <<
", " << z
1009 <<
") not in the mesh.\n";
1017 std::cerr <<
" Point (" << x <<
", " << y <<
", " << z <<
")"
1018 <<
" has out of range material number " << imap <<
".\n";
1024 PrintElement(
"GetMedium", x, y, z, t1, t2, t3, t4, element, 10);
1039 fabs((n3.
x - n0.
x) *
1040 ((n1.
y - n0.
y) * (n2.
z - n0.
z) - (n2.
y - n0.
y) * (n1.
z - n0.
z)) +
1042 ((n1.
z - n0.
z) * (n2.
x - n0.
x) - (n2.
z - n0.
z) * (n1.
x - n0.
x)) +
1043 (n3.
z - n0.
z) * ((n1.
x - n0.
x) * (n2.
y - n0.
y) -
1044 (n3.
x - n0.
x) * (n1.
y - n0.
y))) /
1059 for (
int j = 0; j < np - 1; ++j) {
1061 for (
int k = j + 1; k < np; ++k) {
1064 const double dx = nj.
x - nk.
x;
1065 const double dy = nj.
y - nk.
y;
1066 const double dz = nj.
z - nk.
z;
1067 const double dist = sqrt(dx * dx + dy * dy + dz * dz);
1071 if (dist < dmin) dmin = dist;
1072 if (dist > dmax) dmax = dist;
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")
ComponentAnsys123()
Constructor.
double GetElementVolume(const unsigned int i) override
void WeightingField(const double x, const double y, const double z, double &wx, double &wy, double &wz, const std::string &label) override
double WeightingPotential(const double x, const double y, const double z, const std::string &label) override
void GetAspectRatio(const unsigned int i, double &dmin, double &dmax) override
bool SetWeightingField(std::string prnsol, std::string label)
void ElectricField(const double x, const double y, const double z, double &ex, double &ey, double &ez, Medium *&m, int &status) 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)
static double ScalingFactor(std::string unit)
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
std::vector< std::string > m_wfields
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.
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
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?