19 std::string mplist, std::string prnsol,
32 std::ifstream fmplist;
33 fmplist.open(mplist.c_str(), std::ios::in);
36 <<
" Could not open material file " << mplist
37 <<
" for reading. The file perhaps does not exist.\n";
44 unsigned int icurrmat = 0;
45 bool readerror =
false;
46 while (fmplist.getline(line, size,
'\n')) {
49 if (strcmp(line,
"1") == 0) {
50 fmplist.getline(line, size,
'\n');
52 fmplist.getline(line, size,
'\n');
54 fmplist.getline(line, size,
'\n');
56 fmplist.getline(line, size,
'\n');
58 fmplist.getline(line, size,
'\n');
64 token = strtok(line,
" ");
66 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
67 strcmp(token,
"TEMPERATURE") == 0 || strcmp(token,
"PROPERTY=") == 0 ||
68 int(token[0]) == 10 ||
int(token[0]) == 13)
72 if (strcmp(token,
"LIST") == 0) {
73 token = strtok(NULL,
" ");
74 token = strtok(NULL,
" ");
75 token = strtok(NULL,
" ");
76 token = strtok(NULL,
" ");
80 std::cerr <<
" Error reading file " << mplist <<
" (line " << il
94 std::cout <<
" Number of materials: " <<
m_nMaterials <<
"\n";
96 }
else if (strcmp(token,
"MATERIAL") == 0) {
98 token = strtok(NULL,
" ");
99 token = strtok(NULL,
" ");
100 const int imat =
ReadInteger(token, -1, readerror);
101 if (readerror || imat < 0) {
103 std::cerr <<
" Error reading file " << mplist <<
" (line " << il
110 }
else if (strcmp(token,
"TEMP") == 0) {
112 token = strtok(NULL,
" ");
114 if (strncmp(token,
"PERX", 4) == 0) {
116 }
else if (strncmp(token,
"RSVX", 4) == 0) {
120 std::cerr <<
" Found unknown material property flag " << token
122 std::cerr <<
" on material properties file " << mplist <<
" (line "
126 fmplist.getline(line, size,
'\n');
129 token = strtok(line,
" ");
132 std::cerr <<
" Found out-of-range current material index "
134 std::cerr <<
" in material properties file " << mplist <<
".\n";
137 }
else if (itype == 1) {
139 }
else if (itype == 2) {
144 std::cerr <<
" Error reading file " << mplist <<
" (line " << il
150 }
else if (strcmp(token,
"PROPERTY") == 0) {
152 token = strtok(NULL,
" ");
153 token = strtok(NULL,
" ");
155 if (strcmp(token,
"PERX") == 0) {
157 }
else if (strcmp(token,
"RSVX") == 0) {
162 std::cerr <<
" Found unknown material property flag " << token
164 std::cerr <<
" on material properties file " << mplist <<
" (line "
168 token = strtok(NULL,
" ");
169 token = strtok(NULL,
" ");
173 std::cerr <<
" Error reading file " << mplist <<
" (line " << il
180 std::cerr <<
" Found out-of-range current material index " << imat
182 std::cerr <<
" in material properties file " << mplist <<
".\n";
185 fmplist.getline(line, size,
'\n');
187 fmplist.getline(line, size,
'\n');
190 token = strtok(line,
" ");
191 token = strtok(NULL,
" ");
194 }
else if (itype == 2) {
199 std::cerr <<
" Error reading file " << mplist <<
" (line " << il
214 unsigned int iepsmin = 0;
215 for (
unsigned int imat = 0; imat <
m_nMaterials; ++imat) {
219 std::cerr <<
" Material " << imat
220 <<
" has been assigned a permittivity\n";
221 std::cerr <<
" equal to zero in " << mplist <<
".\n";
223 }
else if (epsmin < 0. || epsmin >
materials[imat].eps) {
231 std::cerr <<
" No material with positive permittivity found \n";
232 std::cerr <<
" in material list " << mplist <<
".\n";
235 for (
unsigned int imat = 0; imat <
m_nMaterials; ++imat) {
236 if (imat == iepsmin) {
247 <<
" materials from file " << mplist <<
".\n";
251 std::ifstream felist;
252 felist.open(elist.c_str(), std::ios::in);
255 std::cerr <<
" Could not open element file " << elist
256 <<
" for reading.\n";
257 std::cerr <<
" The file perhaps does not exist.\n";
268 while (felist.getline(line, size,
'\n')) {
273 token = strtok(line,
" ");
275 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
276 int(token[0]) == 10 ||
int(token[0]) == 13 ||
277 strcmp(token,
"LIST") == 0 || strcmp(token,
"ELEM") == 0)
281 token = strtok(NULL,
" ");
283 token = strtok(NULL,
" ");
284 token = strtok(NULL,
" ");
285 token = strtok(NULL,
" ");
286 token = strtok(NULL,
" ");
287 token = strtok(NULL,
" ");
288 if (!token) std::cerr <<
"No token available\n";
290 token = strtok(NULL,
" ");
292 token = strtok(NULL,
" ");
294 token = strtok(NULL,
" ");
296 token = strtok(NULL,
" ");
298 token = strtok(NULL,
" ");
300 token = strtok(NULL,
" ");
302 token = strtok(NULL,
" ");
308 std::cerr <<
" Error reading file " << elist <<
" (line " << il
313 }
else if (ielem - 1 !=
nElements + nbackground) {
315 std::cerr <<
" Synchronisation lost on file " << elist <<
" (line "
317 std::cerr <<
" Element: " << ielem <<
" (expected " <<
nElements
318 <<
"), material: " << imat <<
", nodes: (" << in0 <<
", " << in1
319 <<
", " << in2 <<
", " << in3 <<
", " << in4 <<
", " << in5
320 <<
", " << in6 <<
", " << in7 <<
")\n";
326 std::cerr <<
" Out-of-range material number on file " << elist
327 <<
" (line " << il <<
").\n";
328 std::cerr <<
" Element: " << ielem <<
", material: " << imat
329 <<
", nodes: (" << in0 <<
", " << in1 <<
", " << in2 <<
", "
330 << in3 <<
", " << in4 <<
", " << in5 <<
", " << in6 <<
", "
336 std::cerr <<
" Element " << ielem <<
" in element list " << elist
337 <<
" uses material " << imat <<
" which\n",
338 std::cerr <<
" has not been assigned a positive permittivity\n";
339 std::cerr <<
" in material list " << mplist <<
".\n";
343 if (in0 < 1 || in1 < 1 || in2 < 1 || in3 < 1 || in4 < 1 || in5 < 1 ||
344 in6 < 1 || in7 < 1) {
346 std::cerr <<
" Found a node number < 1 on file " << elist <<
" (line "
348 std::cerr <<
" Element: " << ielem <<
", material: " << imat <<
"\n";
351 if (in0 > highestnode) highestnode = in0;
352 if (in1 > highestnode) highestnode = in1;
353 if (in2 > highestnode) highestnode = in2;
354 if (in3 > highestnode) highestnode = in3;
355 if (in4 > highestnode) highestnode = in4;
356 if (in5 > highestnode) highestnode = in5;
357 if (in6 > highestnode) highestnode = in6;
358 if (in7 > highestnode) highestnode = in7;
365 if (in2 == in3 && in3 == in6) {
372 newElement.
matmap = imat - 1;
375 newElement.
emap[0] = in0 - 1;
376 newElement.
emap[1] = in1 - 1;
377 newElement.
emap[2] = in2 - 1;
378 newElement.
emap[3] = in4 - 1;
379 newElement.
emap[4] = in7 - 1;
380 newElement.
emap[5] = in5 - 1;
381 newElement.
emap[6] = in3 - 1;
382 newElement.
emap[7] = in6 - 1;
384 newElement.
emap[0] = in0 - 1;
385 newElement.
emap[1] = in1 - 1;
386 newElement.
emap[2] = in2 - 1;
387 newElement.
emap[3] = in3 - 1;
388 newElement.
emap[4] = in4 - 1;
389 newElement.
emap[5] = in5 - 1;
390 newElement.
emap[6] = in6 - 1;
391 newElement.
emap[7] = in7 - 1;
400 std::cout <<
" Read " <<
nElements <<
" elements from file " << elist
402 std::cout <<
" highest node number: " << highestnode <<
",\n";
403 std::cout <<
" degenerate elements: " << ndegenerate <<
",\n";
404 std::cout <<
" background elements skipped: " << nbackground <<
".\n";
407 if (strcmp(unit.c_str(),
"mum") == 0 || strcmp(unit.c_str(),
"micron") == 0 ||
408 strcmp(unit.c_str(),
"micrometer") == 0) {
410 }
else if (strcmp(unit.c_str(),
"mm") == 0 ||
411 strcmp(unit.c_str(),
"millimeter") == 0) {
413 }
else if (strcmp(unit.c_str(),
"cm") == 0 ||
414 strcmp(unit.c_str(),
"centimeter") == 0) {
416 }
else if (strcmp(unit.c_str(),
"m") == 0 ||
417 strcmp(unit.c_str(),
"meter") == 0) {
421 std::cerr <<
" Unknown length unit " << unit <<
".\n";
427 std::cout <<
" Unit scaling factor = " << funit <<
".\n";
431 std::ifstream fnlist;
432 fnlist.open(nlist.c_str(), std::ios::in);
435 std::cerr <<
" Could not open nodes file " << nlist <<
" for reading.\n";
436 std::cerr <<
" The file perhaps does not exist.\n";
445 while (fnlist.getline(line, size,
'\n')) {
450 token = strtok(line,
" ");
452 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
453 int(token[0]) == 10 ||
int(token[0]) == 13 ||
454 strcmp(token,
"LIST") == 0 || strcmp(token,
"NODE") == 0)
458 token = strtok(NULL,
" ");
459 double xnode =
ReadDouble(token, -1, readerror);
460 token = strtok(NULL,
" ");
461 double ynode =
ReadDouble(token, -1, readerror);
462 token = strtok(NULL,
" ");
463 double znode =
ReadDouble(token, -1, readerror);
467 std::cerr <<
" Error reading file " << nlist <<
" (line " << il
474 if (inode - 1 !=
nNodes) {
476 std::cerr <<
" Synchronisation lost on file " << nlist <<
" (line "
478 std::cerr <<
" Node: " << inode <<
" (expected " <<
nNodes
479 <<
"), (x,y,z) = (" << xnode <<
", " << ynode <<
", " << znode
485 newNode.
x = xnode * funit;
486 newNode.
y = ynode * funit;
487 newNode.
z = znode * funit;
488 nodes.push_back(newNode);
495 std::cout <<
" Read " <<
nNodes <<
" nodes from file " << nlist <<
".\n";
497 if (
nNodes != highestnode) {
499 std::cerr <<
" Number of nodes read (" <<
nNodes <<
") on " << nlist
501 std::cerr <<
" does not match element list (" << highestnode <<
").\n";
506 std::ifstream fprnsol;
507 fprnsol.open(prnsol.c_str(), std::ios::in);
508 if (fprnsol.fail()) {
510 std::cerr <<
" Could not open potential file " << prnsol
511 <<
" for reading.\n";
512 std::cerr <<
" The file perhaps does not exist.\n";
519 while (fprnsol.getline(line, size,
'\n')) {
523 token = strtok(line,
" ");
525 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
526 int(token[0]) == 10 ||
int(token[0]) == 13 ||
527 strcmp(token,
"PRINT") == 0 || strcmp(token,
"*****") == 0 ||
528 strcmp(token,
"LOAD") == 0 || strcmp(token,
"TIME=") == 0 ||
529 strcmp(token,
"MAXIMUM") == 0 || strcmp(token,
"VALUE") == 0 ||
530 strcmp(token,
"NODE") == 0)
534 token = strtok(NULL,
" ");
535 double volt =
ReadDouble(token, -1, readerror);
539 std::cerr <<
" Error reading file " << prnsol <<
" (line " << il
546 if (inode < 1 || inode >
nNodes) {
548 std::cerr <<
" Node number " << inode <<
" out of range\n";
549 std::cerr <<
" on potential file " << prnsol <<
" (line " << il
553 nodes[inode - 1].v = volt;
561 std::cout <<
" Read " << nread <<
" potentials from file " << prnsol
566 std::cerr <<
" Number of nodes read (" << nread <<
") on potential file "
567 << prnsol <<
" does not\n",
568 std::cerr <<
" match the node list (" <<
nNodes <<
").\n";
577 <<
" Field map could not be read and cannot be interpolated.\n";
596 std::cerr <<
" Weighting field cannot be added.\n";
601 std::ifstream fprnsol;
602 fprnsol.open(prnsol.c_str(), std::ios::in);
603 if (fprnsol.fail()) {
604 std::cerr <<
m_className <<
"::SetWeightingField:\n";
605 std::cerr <<
" Could not open potential file " << prnsol
606 <<
" for reading.\n";
607 std::cerr <<
" The file perhaps does not exist.\n";
623 for (
int j =
nNodes; j--;) {
627 std::cout <<
m_className <<
"::SetWeightingField:\n";
628 std::cout <<
" Replacing existing weighting field " << label <<
".\n";
634 const int size = 100;
641 bool readerror =
false;
642 while (fprnsol.getline(line, size,
'\n')) {
646 token = strtok(line,
" ");
648 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
649 int(token[0]) == 10 ||
int(token[0]) == 13 ||
650 strcmp(token,
"PRINT") == 0 || strcmp(token,
"*****") == 0 ||
651 strcmp(token,
"LOAD") == 0 || strcmp(token,
"TIME=") == 0 ||
652 strcmp(token,
"MAXIMUM") == 0 || strcmp(token,
"VALUE") == 0 ||
653 strcmp(token,
"NODE") == 0)
657 token = strtok(NULL,
" ");
658 double volt =
ReadDouble(token, -1, readerror);
661 std::cerr <<
m_className <<
"::SetWeightingField:\n";
662 std::cerr <<
" Error reading file " << prnsol <<
" (line " << il
668 if (inode < 1 || inode >
nNodes) {
669 std::cerr <<
m_className <<
"::SetWeightingField:\n";
670 std::cerr <<
" Node number " << inode <<
" out of range\n";
671 std::cerr <<
" on potential file " << prnsol <<
" (line " << il
675 nodes[inode - 1].w[iw] = volt;
682 std::cout <<
m_className <<
"::SetWeightingField:\n";
683 std::cout <<
" Read " << nread <<
" potentials from file " << prnsol
687 std::cerr <<
m_className <<
"::SetWeightingField:\n";
688 std::cerr <<
" Number of nodes read (" << nread <<
") "
689 <<
" on potential file " << prnsol <<
"\n";
690 std::cerr <<
" does not match the node list (" <<
nNodes <<
").\n";
697 std::cerr <<
m_className <<
"::SetWeightingField:\n";
698 std::cerr <<
" Field map could not be read "
699 <<
"and cannot be interpolated.\n";
706 const double z,
double& ex,
double& ey,
707 double& ez,
Medium*& m,
int& status) {
713 const double zin,
double& ex,
double& ey,
714 double& ez,
double& volt,
Medium*& m,
717 double x = xin, y = yin, z = 0.;
720 bool xmirr, ymirr, zmirr;
721 double rcoordinate, rotation;
722 MapCoordinates(x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
725 ex = ey = ez = volt = 0;
744 double t1, t2, t3, t4, jac[4][4], det;
745 const int imap =
FindElement5(x, y, z, t1, t2, t3, t4, jac, det);
749 std::cout <<
" Point (" << x <<
", " << y <<
") not in the mesh.\n";
757 PrintElement(
"ElectricField", x, y, z, t1, t2, t3, t4, element, 8);
767 const double invdet = 1. / det;
769 volt = n0.
v * t1 * (2 * t1 - 1) + n1.
v * t2 * (2 * t2 - 1) +
770 n2.
v * t3 * (2 * t3 - 1) + 4 * n3.
v * t1 * t2 + 4 * n4.
v * t1 * t3 +
772 ex = -(n0.
v * (4 * t1 - 1) * jac[0][1] + n1.
v * (4 * t2 - 1) * jac[1][1] +
773 n2.
v * (4 * t3 - 1) * jac[2][1] +
774 n3.
v * (4 * t2 * jac[0][1] + 4 * t1 * jac[1][1]) +
775 n4.
v * (4 * t3 * jac[0][1] + 4 * t1 * jac[2][1]) +
776 n5.
v * (4 * t3 * jac[1][1] + 4 * t2 * jac[2][1])) *
778 ey = -(n0.
v * (4 * t1 - 1) * jac[0][2] + n1.
v * (4 * t2 - 1) * jac[1][2] +
779 n2.
v * (4 * t3 - 1) * jac[2][2] +
780 n3.
v * (4 * t2 * jac[0][2] + 4 * t1 * jac[1][2]) +
781 n4.
v * (4 * t3 * jac[0][2] + 4 * t1 * jac[2][2]) +
782 n5.
v * (4 * t3 * jac[1][2] + 4 * t2 * jac[2][2])) *
787 volt = -n0.
v * (1 - t1) * (1 - t2) * (1 + t1 + t2) * 0.25 -
788 n1.
v * (1 + t1) * (1 - t2) * (1 - t1 + t2) * 0.25 -
789 n2.
v * (1 + t1) * (1 + t2) * (1 - t1 - t2) * 0.25 -
790 n3.
v * (1 - t1) * (1 + t2) * (1 + t1 - t2) * 0.25 +
791 n4.
v * (1 - t1) * (1 + t1) * (1 - t2) * 0.5 +
792 n5.
v * (1 + t1) * (1 + t2) * (1 - t2) * 0.5 +
793 n6.
v * (1 - t1) * (1 + t1) * (1 + t2) * 0.5 +
794 n7.
v * (1 - t1) * (1 + t2) * (1 - t2) * 0.5;
795 ex = -(n0.
v * ((1 - t2) * (2 * t1 + t2) * jac[0][0] +
796 (1 - t1) * (t1 + 2 * t2) * jac[1][0]) *
798 n1.
v * ((1 - t2) * (2 * t1 - t2) * jac[0][0] -
799 (1 + t1) * (t1 - 2 * t2) * jac[1][0]) *
801 n2.
v * ((1 + t2) * (2 * t1 + t2) * jac[0][0] +
802 (1 + t1) * (t1 + 2 * t2) * jac[1][0]) *
804 n3.
v * ((1 + t2) * (2 * t1 - t2) * jac[0][0] -
805 (1 - t1) * (t1 - 2 * t2) * jac[1][0]) *
807 n4.
v * (t1 * (t2 - 1) * jac[0][0] +
808 (t1 - 1) * (t1 + 1) * jac[1][0] * 0.5) +
809 n5.
v * ((1 - t2) * (1 + t2) * jac[0][0] * 0.5 -
810 (1 + t1) * t2 * jac[1][0]) +
811 n6.
v * (-t1 * (1 + t2) * jac[0][0] +
812 (1 - t1) * (1 + t1) * jac[1][0] * 0.5) +
813 n7.
v * ((t2 - 1) * (t2 + 1) * jac[0][0] * 0.5 +
814 (t1 - 1) * t2 * jac[1][0])) *
816 ey = -(n0.
v * ((1 - t2) * (2 * t1 + t2) * jac[0][1] +
817 (1 - t1) * (t1 + 2 * t2) * jac[1][1]) *
819 n1.
v * ((1 - t2) * (2 * t1 - t2) * jac[0][1] -
820 (1 + t1) * (t1 - 2 * t2) * jac[1][1]) *
822 n2.
v * ((1 + t2) * (2 * t1 + t2) * jac[0][1] +
823 (1 + t1) * (t1 + 2 * t2) * jac[1][1]) *
825 n3.
v * ((1 + t2) * (2 * t1 - t2) * jac[0][1] -
826 (1 - t1) * (t1 - 2 * t2) * jac[1][1]) *
828 n4.
v * (t1 * (t2 - 1) * jac[0][1] +
829 (t1 - 1) * (t1 + 1) * jac[1][1] * 0.5) +
830 n5.
v * ((1 - t2) * (1 + t2) * jac[0][1] * 0.5 -
831 (1 + t1) * t2 * jac[1][1]) +
832 n6.
v * (-t1 * (1 + t2) * jac[0][1] +
833 (1 - t1) * (1 + t1) * jac[1][1] * 0.5) +
834 n7.
v * ((t2 - 1) * (t2 + 1) * jac[0][1] * 0.5 +
835 (t1 - 1) * t2 * jac[1][1])) *
840 UnmapFields(ex, ey, ez, x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
845 std::cout <<
" Material " << element.
matmap <<
", drift flag "
856 const double zin,
double& wx,
double& wy,
857 double& wz,
const std::string& label) {
881 double x = xin, y = yin, z = zin;
884 bool xmirr, ymirr, zmirr;
885 double rcoordinate, rotation;
886 MapCoordinates(x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
891 double t1, t2, t3, t4, jac[4][4], det;
892 const int imap =
FindElement5(x, y, z, t1, t2, t3, t4, jac, det);
894 if (imap < 0)
return;
898 PrintElement(
"WeightingField", x, y, z, t1, t2, t3, t4, element, 8, iw);
907 const double invdet = 1. / det;
909 wx = -(n0.
w[iw] * (4 * t1 - 1) * jac[0][1] +
910 n1.
w[iw] * (4 * t2 - 1) * jac[1][1] +
911 n2.
w[iw] * (4 * t3 - 1) * jac[2][1] +
912 n3.
w[iw] * (4 * t2 * jac[0][1] + 4 * t1 * jac[1][1]) +
913 n4.
w[iw] * (4 * t3 * jac[0][1] + 4 * t1 * jac[2][1]) +
914 n5.
w[iw] * (4 * t3 * jac[1][1] + 4 * t2 * jac[2][1])) *
916 wy = -(n0.
w[iw] * (4 * t1 - 1) * jac[0][2] +
917 n1.
w[iw] * (4 * t2 - 1) * jac[1][2] +
918 n2.
w[iw] * (4 * t3 - 1) * jac[2][2] +
919 n3.
w[iw] * (4 * t2 * jac[0][2] + 4 * t1 * jac[1][2]) +
920 n4.
w[iw] * (4 * t3 * jac[0][2] + 4 * t1 * jac[2][2]) +
921 n5.
w[iw] * (4 * t3 * jac[1][2] + 4 * t2 * jac[2][2])) *
926 wx = -(n0.
w[iw] * ((1 - t2) * (2 * t1 + t2) * jac[0][0] +
927 (1 - t1) * (t1 + 2 * t2) * jac[1][0]) *
929 n1.
w[iw] * ((1 - t2) * (2 * t1 - t2) * jac[0][0] -
930 (1 + t1) * (t1 - 2 * t2) * jac[1][0]) *
932 n2.
w[iw] * ((1 + t2) * (2 * t1 + t2) * jac[0][0] +
933 (1 + t1) * (t1 + 2 * t2) * jac[1][0]) *
935 n3.
w[iw] * ((1 + t2) * (2 * t1 - t2) * jac[0][0] -
936 (1 - t1) * (t1 - 2 * t2) * jac[1][0]) *
938 n4.
w[iw] * (t1 * (t2 - 1) * jac[0][0] +
939 (t1 - 1) * (t1 + 1) * jac[1][0] * 0.5) +
940 n5.
w[iw] * ((1 - t2) * (1 + t2) * jac[0][0] * 0.5 -
941 (1 + t1) * t2 * jac[1][0]) +
942 n6.
w[iw] * (-t1 * (1 + t2) * jac[0][0] +
943 (1 - t1) * (1 + t1) * jac[1][0] * 0.5) +
944 n7.
w[iw] * ((t2 - 1) * (1 + t2) * jac[0][0] * 0.5 +
945 (t1 - 1) * t2 * jac[1][0])) *
947 wy = -(n0.
w[iw] * ((1 - t2) * (2 * t1 + t2) * jac[0][1] +
948 (1 - t1) * (t1 + 2 * t2) * jac[1][1]) *
950 n1.
w[iw] * ((1 - t2) * (2 * t1 - t2) * jac[0][1] -
951 (1 + t1) * (t1 - 2 * t2) * jac[1][1]) *
953 n2.
w[iw] * ((1 + t2) * (2 * t1 + t2) * jac[0][1] +
954 (1 + t1) * (t1 + 2 * t2) * jac[1][1]) *
956 n3.
w[iw] * ((1 + t2) * (2 * t1 - t2) * jac[0][1] -
957 (1 - t1) * (t1 - 2 * t2) * jac[1][1]) *
959 n4.
w[iw] * (t1 * (t2 - 1) * jac[0][1] +
960 (t1 - 1) * (t1 + 1) * jac[1][1] * 0.5) +
961 n5.
w[iw] * ((1 - t2) * (1 + t2) * jac[0][1] * 0.5 -
962 (1 + t1) * t2 * jac[1][1]) +
963 n6.
w[iw] * (-t1 * (1 + t2) * jac[0][1] +
964 (1 - t1) * (1 + t1) * jac[1][1] * 0.5) +
965 n7.
w[iw] * ((t2 - 1) * (t2 + 1) * jac[0][1] * 0.5 +
966 (t1 - 1) * t2 * jac[1][1])) *
971 UnmapFields(wx, wy, wz, x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
976 const std::string& label) {
992 if (!found)
return 0.;
997 double x = xin, y = yin, z = zin;
1000 bool xmirr, ymirr, zmirr;
1001 double rcoordinate, rotation;
1002 MapCoordinates(x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
1007 double t1, t2, t3, t4, jac[4][4], det;
1008 const int imap =
FindElement5(x, y, z, t1, t2, t3, t4, jac, det);
1010 if (imap < 0)
return 0.;
1014 PrintElement(
"WeightingPotential", x, y, z, t1, t2, t3, t4, element, 8, iw);
1024 return n0.
w[iw] * t1 * (2 * t1 - 1) + n1.
w[iw] * t2 * (2 * t2 - 1) +
1025 n2.
w[iw] * t3 * (2 * t3 - 1) + 4 * n3.
w[iw] * t1 * t2 +
1026 4 * n4.
w[iw] * t1 * t3 + 4 * n5.
w[iw] * t2 * t3;
1031 return -n0.
w[iw] * (1 - t1) * (1 - t2) * (1 + t1 + t2) * 0.25 -
1032 n1.
w[iw] * (1 + t1) * (1 - t2) * (1 - t1 + t2) * 0.25 -
1033 n2.
w[iw] * (1 + t1) * (1 + t2) * (1 - t1 - t2) * 0.25 -
1034 n3.
w[iw] * (1 - t1) * (1 + t2) * (1 + t1 - t2) * 0.25 +
1035 n4.
w[iw] * (1 - t1) * (1 + t1) * (1 - t2) * 0.5 +
1036 n5.
w[iw] * (1 + t1) * (1 + t2) * (1 - t2) * 0.5 +
1037 n6.
w[iw] * (1 - t1) * (1 + t1) * (1 + t2) * 0.5 +
1038 n7.
w[iw] * (1 - t1) * (1 + t2) * (1 - t2) * 0.5;
1044 double x = xin, y = yin, z = 0.;
1047 bool xmirr, ymirr, zmirr;
1048 double rcoordinate, rotation;
1049 MapCoordinates(x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
1063 double t1, t2, t3, t4, jac[4][4], det;
1064 const int imap =
FindElement5(x, y, z, t1, t2, t3, t4, jac, det);
1068 std::cerr <<
" Point (" << x <<
", " << y <<
") not in the mesh.\n";
1076 std::cerr <<
" Point (" << x <<
", " << y <<
")"
1077 <<
" has out of range material number " << imap <<
".\n";
1083 PrintElement(
"GetMedium", x, y, z, t1, t2, t3, t4, element, 8);
1091 if (fabs(zmax - zmin) <= 0.) {
1092 std::cerr <<
m_className <<
"::SetRangeZ: Zero range is not permitted.\n";
1105 if (i >=
elements.size())
return 0.;
1113 (fabs((n1.
x - n0.
x) * (n2.
y - n0.
y) - (n2.
x - n0.
x) * (n1.
y - n0.
y)) +
1114 fabs((n3.
x - n0.
x) * (n2.
y - n0.
y) - (n2.
x - n0.
x) * (n3.
y - n0.
y)));
1128 for (
int j = 0; j < np - 1; ++j) {
1130 for (
int k = j + 1; k < np; ++k) {
1133 const double dx = nj.
x - nk.
x;
1134 const double dy = nj.
y - nk.
y;
1135 const double dist = sqrt(dx * dx + dy * dy);
1139 if (dist < dmin) dmin = dist;
1140 if (dist > dmax) dmax = dist;
bool SetWeightingField(std::string prnsol, std::string label)
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)
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).
bool m_ready
Ready for use?
std::string m_className
Class name.
bool m_debug
Switch on/off debugging messages.
Base class for components based on finite-element field maps.
void PrintMaterials()
List all currently defined materials.
double ReadDouble(char *token, double def, bool &error)
std::vector< bool > wfieldsOk
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
void UpdatePeriodicityCommon()
int ReadInteger(char *token, int def, bool &error)
unsigned int m_nMaterials
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.
std::vector< Material > materials
void UpdatePeriodicity2d()
std::vector< Node > nodes
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
virtual void SetRange()
Calculate x, y, z, V and angular ranges.
std::vector< Element > elements
std::array< double, 3 > m_mapmax
std::vector< std::string > wfields
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.
bool IsDriftable() const
Is charge carrier transport enabled in this medium?