15 std::string mplist, std::string prnsol,
28 std::ifstream fmplist;
29 fmplist.open(mplist.c_str(), std::ios::in);
32 std::cerr <<
" Could not open material file " << mplist
34 std::cerr <<
" The file perhaps does not exist.\n";
41 unsigned int icurrmat = 0;
42 bool readerror =
false;
43 while (fmplist.getline(line, size,
'\n')) {
46 if (strcmp(line,
"1") == 0) {
47 fmplist.getline(line, size,
'\n');
49 fmplist.getline(line, size,
'\n');
51 fmplist.getline(line, size,
'\n');
53 fmplist.getline(line, size,
'\n');
55 fmplist.getline(line, size,
'\n');
61 token = strtok(line,
" ");
63 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
64 strcmp(token,
"TEMPERATURE") == 0 || strcmp(token,
"PROPERTY=") == 0 ||
65 int(token[0]) == 10 ||
int(token[0]) == 13)
69 if (strcmp(token,
"LIST") == 0) {
70 token = strtok(NULL,
" ");
71 token = strtok(NULL,
" ");
72 token = strtok(NULL,
" ");
73 token = strtok(NULL,
" ");
77 std::cerr <<
" Error reading file " << mplist <<
" (line " << il
91 std::cout <<
" Number of materials: " <<
m_nMaterials <<
"\n";
93 }
else if (strcmp(token,
"MATERIAL") == 0) {
95 token = strtok(NULL,
" ");
96 token = strtok(NULL,
" ");
98 if (readerror || imat < 0) {
100 std::cerr <<
" Error reading file " << mplist <<
" (line " << il
107 }
else if (strcmp(token,
"TEMP") == 0) {
109 token = strtok(NULL,
" ");
111 if (strncmp(token,
"PERX", 4) == 0) {
113 }
else if (strncmp(token,
"RSVX", 4) == 0) {
117 std::cerr <<
" Found unknown material property flag " << token
119 std::cerr <<
" on material properties file " << mplist <<
" (line "
123 fmplist.getline(line, size,
'\n');
126 token = strtok(line,
" ");
129 std::cerr <<
" Found out-of-range current material index "
131 std::cerr <<
" in material properties file " << mplist <<
".\n";
134 }
else if (itype == 1) {
136 }
else if (itype == 2) {
141 std::cerr <<
" Error reading file " << mplist <<
" line " << il
147 }
else if (strcmp(token,
"PROPERTY") == 0) {
149 token = strtok(NULL,
" ");
150 token = strtok(NULL,
" ");
152 if (strcmp(token,
"PERX") == 0) {
154 }
else if (strcmp(token,
"RSVX") == 0) {
158 std::cerr <<
" Found unknown material property flag " << token
160 std::cerr <<
" on material properties file " << mplist <<
" (line "
164 token = strtok(NULL,
" ");
165 token = strtok(NULL,
" ");
169 std::cerr <<
" Error reading file " << mplist <<
" (line " << il
176 std::cerr <<
" Found out-of-range material index " << imat <<
"\n";
177 std::cerr <<
" in material properties file " << mplist <<
".\n";
180 fmplist.getline(line, size,
'\n');
182 fmplist.getline(line, size,
'\n');
185 token = strtok(line,
" ");
186 token = strtok(NULL,
" ");
189 }
else if (itype == 2) {
194 std::cerr <<
" Error reading file " << mplist <<
" (line " << il
209 unsigned int iepsmin = 0;
210 for (
unsigned int imat = 0; imat <
m_nMaterials; ++imat) {
214 std::cerr <<
" Material " << imat
215 <<
" has been assigned a permittivity\n";
216 std::cerr <<
" equal to zero in " << mplist <<
".\n";
218 }
else if (epsmin < 0. || epsmin >
materials[imat].eps) {
226 std::cerr <<
" No material with positive permittivity found \n";
227 std::cerr <<
" in material list " << mplist <<
".\n";
230 for (
unsigned int imat = 0; imat <
m_nMaterials; ++imat) {
231 if (imat == iepsmin) {
242 <<
" materials from file " << mplist <<
".\n";
246 std::ifstream felist;
247 felist.open(elist.c_str(), std::ios::in);
250 std::cerr <<
" Could not open element file " << elist
251 <<
" for reading.\n";
252 std::cerr <<
" The file perhaps does not exist.\n";
263 while (felist.getline(line, size,
'\n')) {
266 if (strcmp(line,
"1") == 0) {
267 felist.getline(line, size,
'\n');
269 felist.getline(line, size,
'\n');
271 felist.getline(line, size,
'\n');
273 felist.getline(line, size,
'\n');
275 felist.getline(line, size,
'\n');
280 if (strstr(line,
"***") != NULL) {
281 felist.getline(line, size,
'\n');
283 felist.getline(line, size,
'\n');
285 felist.getline(line, size,
'\n');
292 token = strtok(line,
" ");
294 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
295 int(token[0]) == 10 ||
int(token[0]) == 13 ||
296 strcmp(token,
"LIST") == 0 || strcmp(token,
"ELEM") == 0) {
301 token = strtok(NULL,
" ");
303 token = strtok(NULL,
" ");
304 token = strtok(NULL,
" ");
305 token = strtok(NULL,
" ");
306 token = strtok(NULL,
" ");
307 token = strtok(NULL,
" ");
309 token = strtok(NULL,
" ");
311 token = strtok(NULL,
" ");
313 token = strtok(NULL,
" ");
315 token = strtok(NULL,
" ");
317 token = strtok(NULL,
" ");
319 token = strtok(NULL,
" ");
321 token = strtok(NULL,
" ");
323 if (!felist.getline(line, size,
'\n')) {
325 std::cerr <<
" Error reading element " << ielem <<
".\n";
331 token = strtok(line,
" ");
333 token = strtok(NULL,
" ");
339 std::cerr <<
" Error reading file " << elist <<
" (line " << il
344 }
else if (ielem - 1 !=
nElements + nbackground) {
346 std::cerr <<
" Synchronisation lost on file " << elist <<
" (line "
348 std::cerr <<
" Element: " << ielem <<
" (expected " <<
nElements
349 <<
"), material: " << imat <<
",\n";
350 std::cerr <<
" nodes: (" << in0 <<
", " << in1 <<
", " << in2 <<
", "
351 << in3 <<
", " << in4 <<
", " << in5 <<
", " << in6 <<
", "
352 << in7 <<
", " << in8 <<
", " << in9 <<
")\n";
359 std::cerr <<
" Out-of-range material number on file " << elist
360 <<
" (line " << il <<
").\n";
361 std::cerr <<
" Element: " << ielem <<
", material: " << imat <<
",\n";
362 std::cerr <<
" nodes: (" << in0 <<
", " << in1 <<
", " << in2 <<
", "
363 << in3 <<
", " << in4 <<
", " << in5 <<
", " << in6 <<
", "
364 << in7 <<
", " << in8 <<
", " << in9 <<
")\n";
369 std::cerr <<
" Element " << ielem <<
" in element list " << elist
371 std::cerr <<
" uses material " << imat
372 <<
" which has not been assigned\n";
373 std::cerr <<
" a positive permittivity in material list " << mplist
379 if (in0 < 1 || in1 < 1 || in2 < 1 || in3 < 1 || in4 < 1 || in5 < 1 ||
380 in6 < 1 || in7 < 1 || in8 < 1 || in9 < 1) {
382 std::cerr <<
" Found a node number < 1 on file " << elist <<
" (line "
384 std::cerr <<
" Element: " << ielem <<
", material: " << imat <<
",\n";
385 std::cerr <<
" nodes: (" << in0 <<
", " << in1 <<
", " << in2 <<
", "
386 << in3 <<
", " << in4 <<
", " << in5 <<
", " << in6 <<
", "
387 << in7 <<
", " << in8 <<
", " << in9 <<
")\n";
390 if (in0 > highestnode) highestnode = in0;
391 if (in1 > highestnode) highestnode = in1;
392 if (in2 > highestnode) highestnode = in2;
393 if (in3 > highestnode) highestnode = in3;
394 if (in4 > highestnode) highestnode = in4;
395 if (in5 > highestnode) highestnode = in5;
396 if (in6 > highestnode) highestnode = in6;
397 if (in7 > highestnode) highestnode = in7;
398 if (in8 > highestnode) highestnode = in8;
399 if (in9 > highestnode) highestnode = in9;
408 if (in0 == in1 || in0 == in2 || in0 == in3 || in0 == in4 || in0 == in5 ||
409 in0 == in6 || in0 == in7 || in0 == in8 || in0 == in9 || in1 == in2 ||
410 in1 == in3 || in1 == in4 || in1 == in5 || in1 == in6 || in1 == in7 ||
411 in1 == in8 || in1 == in9 || in2 == in3 || in2 == in4 || in2 == in5 ||
412 in2 == in6 || in2 == in7 || in2 == in8 || in2 == in9 || in3 == in4 ||
413 in3 == in5 || in3 == in6 || in3 == in7 || in3 == in8 || in3 == in9 ||
414 in4 == in5 || in4 == in6 || in4 == in7 || in4 == in8 || in4 == in9 ||
415 in5 == in6 || in5 == in7 || in5 == in8 || in5 == in9 || in6 == in7 ||
416 in6 == in8 || in6 == in9 || in7 == in8 || in7 == in9 || in8 == in9) {
418 std::cerr <<
" Element " << ielem <<
" of file " << elist
419 <<
" is degenerate,\n";
420 std::cerr <<
" no such elements allowed in this type of map.\n";
427 newElement.
matmap = imat - 1;
430 newElement.
emap[0] = in0 - 1;
431 newElement.
emap[1] = in1 - 1;
432 newElement.
emap[2] = in2 - 1;
433 newElement.
emap[3] = in3 - 1;
434 newElement.
emap[4] = in4 - 1;
435 newElement.
emap[7] = in5 - 1;
436 newElement.
emap[5] = in6 - 1;
437 newElement.
emap[6] = in7 - 1;
438 newElement.
emap[8] = in8 - 1;
439 newElement.
emap[9] = in9 - 1;
448 std::cout <<
" Read " <<
nElements <<
" elements from file " << elist
450 std::cout <<
" highest node number: " << highestnode <<
",\n";
451 std::cout <<
" background elements skipped: " << nbackground <<
"\n";
454 if (strcmp(unit.c_str(),
"mum") == 0 || strcmp(unit.c_str(),
"micron") == 0 ||
455 strcmp(unit.c_str(),
"micrometer") == 0) {
457 }
else if (strcmp(unit.c_str(),
"mm") == 0 ||
458 strcmp(unit.c_str(),
"millimeter") == 0) {
460 }
else if (strcmp(unit.c_str(),
"cm") == 0 ||
461 strcmp(unit.c_str(),
"centimeter") == 0) {
463 }
else if (strcmp(unit.c_str(),
"m") == 0 ||
464 strcmp(unit.c_str(),
"meter") == 0) {
468 std::cerr <<
" Unknown length unit " << unit <<
".\n";
474 std::cout <<
" Unit scaling factor = " << funit <<
".\n";
478 std::ifstream fnlist;
479 fnlist.open(nlist.c_str(), std::ios::in);
482 std::cerr <<
" Could not open nodes file " << nlist <<
" for reading.\n";
483 std::cerr <<
" The file perhaps does not exist.\n";
493 while (fnlist.getline(line, size,
'\n')) {
496 if (strcmp(line,
"1") == 0) {
497 fnlist.getline(line, size,
'\n');
499 fnlist.getline(line, size,
'\n');
501 fnlist.getline(line, size,
'\n');
503 fnlist.getline(line, size,
'\n');
505 fnlist.getline(line, size,
'\n');
510 if (strstr(line,
"***") != NULL) {
511 fnlist.getline(line, size,
'\n');
513 fnlist.getline(line, size,
'\n');
515 fnlist.getline(line, size,
'\n');
521 token = strtok(line,
" ");
523 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
524 int(token[0]) == 10 ||
int(token[0]) == 13 ||
525 strcmp(token,
"LIST") == 0 || strcmp(token,
"NODE") == 0)
529 token = strtok(NULL,
" ");
530 double xnode =
ReadDouble(token, -1, readerror);
531 token = strtok(NULL,
" ");
532 double ynode =
ReadDouble(token, -1, readerror);
533 token = strtok(NULL,
" ");
534 double znode =
ReadDouble(token, -1, readerror);
538 std::cerr <<
" Error reading file " << nlist <<
" (line " << il
545 if (inode - 1 !=
nNodes) {
547 std::cerr <<
" Synchronisation lost on file " << nlist <<
" (line "
549 std::cerr <<
" Node: " << inode <<
" (expected " <<
nNodes
550 <<
"), (x,y,z) = (" << xnode <<
", " << ynode <<
", " << znode
555 newNode.
x = xnode * funit;
556 newNode.
y = ynode * funit;
557 newNode.
z = znode * funit;
558 nodes.push_back(newNode);
565 std::cout <<
" Read " <<
nNodes <<
" nodes from file " << nlist <<
".\n";
567 if (
nNodes != highestnode) {
569 std::cerr <<
" Number of nodes read (" <<
nNodes <<
") on " << nlist
571 std::cerr <<
" does not match element list (" << highestnode <<
").\n";
576 std::ifstream fprnsol;
577 fprnsol.open(prnsol.c_str(), std::ios::in);
578 if (fprnsol.fail()) {
580 std::cerr <<
" Could not open potential file " << prnsol
581 <<
" for reading.\n";
582 std::cerr <<
" The file perhaps does not exist.\n";
589 while (fprnsol.getline(line, size,
'\n')) {
592 if (strcmp(line,
"1") == 0) {
593 fprnsol.getline(line, size,
'\n');
595 fprnsol.getline(line, size,
'\n');
597 fprnsol.getline(line, size,
'\n');
599 fprnsol.getline(line, size,
'\n');
601 fprnsol.getline(line, size,
'\n');
606 if (strstr(line,
"***") != NULL) {
607 fprnsol.getline(line, size,
'\n');
609 fprnsol.getline(line, size,
'\n');
611 fprnsol.getline(line, size,
'\n');
617 token = strtok(line,
" ");
619 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
620 int(token[0]) == 10 ||
int(token[0]) == 13 ||
621 strcmp(token,
"PRINT") == 0 || strcmp(token,
"*****") == 0 ||
622 strcmp(token,
"LOAD") == 0 || strcmp(token,
"TIME=") == 0 ||
623 strcmp(token,
"MAXIMUM") == 0 || strcmp(token,
"VALUE") == 0 ||
624 strcmp(token,
"NODE") == 0)
628 token = strtok(NULL,
" ");
629 double volt =
ReadDouble(token, -1, readerror);
633 std::cerr <<
" Error reading file " << prnsol <<
" (line << " << il
640 if (inode < 1 || inode > highestnode) {
642 std::cerr <<
" Node number " << inode <<
" out of range\n";
643 std::cerr <<
" on potential file " << prnsol <<
" (line " << il
647 nodes[inode - 1].v = volt;
655 std::cout <<
" Read " << nread <<
" potentials from file " << prnsol
660 std::cerr <<
" Number of nodes read (" << nread <<
") on potential file "
662 std::cerr <<
" does not match the node list (" <<
nNodes <<
").\n";
672 <<
" Field map could not be read and can not be interpolated.\n";
691 std::cerr <<
" Weighting field cannot be added.\n";
696 std::ifstream fprnsol;
697 fprnsol.open(prnsol.c_str(), std::ios::in);
698 if (fprnsol.fail()) {
699 std::cerr <<
m_className <<
"::SetWeightingField:\n";
700 std::cerr <<
" Could not open potential file " << prnsol
701 <<
" for reading.\n";
702 std::cerr <<
" The file perhaps does not exist.\n";
718 for (
int j =
nNodes; j--;) {
722 std::cout <<
m_className <<
"::SetWeightingField:\n";
723 std::cout <<
" Replacing existing weighting field " << label <<
".\n";
729 const int size = 100;
736 bool readerror =
false;
738 while (fprnsol.getline(line, size,
'\n')) {
741 if (strcmp(line,
"1") == 0) {
742 fprnsol.getline(line, size,
'\n');
744 fprnsol.getline(line, size,
'\n');
746 fprnsol.getline(line, size,
'\n');
748 fprnsol.getline(line, size,
'\n');
750 fprnsol.getline(line, size,
'\n');
756 token = strtok(line,
" ");
758 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
759 int(token[0]) == 10 ||
int(token[0]) == 13 ||
760 strcmp(token,
"PRINT") == 0 || strcmp(token,
"*****") == 0 ||
761 strcmp(token,
"LOAD") == 0 || strcmp(token,
"TIME=") == 0 ||
762 strcmp(token,
"MAXIMUM") == 0 || strcmp(token,
"VALUE") == 0 ||
763 strcmp(token,
"NODE") == 0)
767 token = strtok(NULL,
" ");
768 double volt =
ReadDouble(token, -1, readerror);
771 std::cerr <<
m_className <<
"::SetWeightingField:\n";
772 std::cerr <<
" Error reading file " << prnsol.c_str() <<
" (line "
778 if (inode < 1 || inode >
nNodes) {
779 std::cerr <<
m_className <<
"::SetWeightingField:\n";
780 std::cerr <<
" Node number " << inode <<
" out of range\n";
781 std::cerr <<
" on potential file " << prnsol.c_str() <<
" (line " << il
785 nodes[inode - 1].w[iw] = volt;
792 std::cout <<
m_className <<
"::SetWeightingField:\n";
793 std::cout <<
" Read " << nread <<
" potentials from file "
794 << prnsol.c_str() <<
".\n";
797 std::cerr <<
m_className <<
"::SetWeightingField:\n";
798 std::cerr <<
" Number of nodes read (" << nread <<
") "
799 <<
" on potential file " << prnsol.c_str() <<
"\n";
800 std::cerr <<
" does not match the node list (" <<
nNodes <<
").\n";
807 std::cerr <<
m_className <<
"::SetWeightingField:\n";
808 std::cerr <<
" Field map could not be read "
809 <<
"and cannot be interpolated.\n";
816 const double z,
double& ex,
double& ey,
817 double& ez,
Medium*& m,
int& status) {
823 const double zin,
double& ex,
double& ey,
824 double& ez,
double& volt,
Medium*& m,
827 double x = xin, y = yin, z = zin;
830 bool xmirr, ymirr, zmirr;
831 double rcoordinate, rotation;
832 MapCoordinates(x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
835 ex = ey = ez = volt = 0.;
849 double t1, t2, t3, t4, jac[4][4], det;
850 const int imap =
FindElement13(x, y, z, t1, t2, t3, t4, jac, det);
853 std::cerr <<
m_className <<
"::ElectricField: Point (" << x <<
", " << y
854 <<
", " << z <<
") not in the mesh.\n";
862 PrintElement(
"ElectricField", x, y, z, t1, t2, t3, t4, element, 10);
875 const double fourt1 = 4 * t1;
876 const double fourt2 = 4 * t2;
877 const double fourt3 = 4 * t3;
878 const double fourt4 = 4 * t4;
879 const double invdet = 1. / det;
881 volt = n0.
v * t1 * (2 * t1 - 1) + n1.
v * t2 * (2 * t2 - 1) +
882 n2.
v * t3 * (2 * t3 - 1) + n3.
v * t4 * (2 * t4 - 1) +
883 n4.
v * fourt1 * t2 + n5.
v * fourt1 * t3 + n6.
v * fourt1 * t4 +
884 n7.
v * fourt2 * t3 + n8.
v * fourt2 * t4 + n9.
v * fourt3 * t4;
885 ex = -(n0.
v * (fourt1 - 1) * jac[0][1] + n1.
v * (fourt2 - 1) * jac[1][1] +
886 n2.
v * (fourt3 - 1) * jac[2][1] + n3.
v * (fourt4 - 1) * jac[3][1] +
887 n4.
v * (fourt2 * jac[0][1] + fourt1 * jac[1][1]) +
888 n5.
v * (fourt3 * jac[0][1] + fourt1 * jac[2][1]) +
889 n6.
v * (fourt4 * jac[0][1] + fourt1 * jac[3][1]) +
890 n7.
v * (fourt3 * jac[1][1] + fourt2 * jac[2][1]) +
891 n8.
v * (fourt4 * jac[1][1] + fourt2 * jac[3][1]) +
892 n9.
v * (fourt4 * jac[2][1] + fourt3 * jac[3][1])) *
895 ey = -(n0.
v * (fourt1 - 1) * jac[0][2] + n1.
v * (fourt2 - 1) * jac[1][2] +
896 n2.
v * (fourt3 - 1) * jac[2][2] + n3.
v * (fourt4 - 1) * jac[3][2] +
897 n4.
v * (fourt2 * jac[0][2] + fourt1 * jac[1][2]) +
898 n5.
v * (fourt3 * jac[0][2] + fourt1 * jac[2][2]) +
899 n6.
v * (fourt4 * jac[0][2] + fourt1 * jac[3][2]) +
900 n7.
v * (fourt3 * jac[1][2] + fourt2 * jac[2][2]) +
901 n8.
v * (fourt4 * jac[1][2] + fourt2 * jac[3][2]) +
902 n9.
v * (fourt4 * jac[2][2] + fourt3 * jac[3][2])) *
905 ez = -(n0.
v * (fourt1 - 1) * jac[0][3] + n1.
v * (fourt2 - 1) * jac[1][3] +
906 n2.
v * (fourt3 - 1) * jac[2][3] + n3.
v * (fourt4 - 1) * jac[3][3] +
907 n4.
v * (fourt2 * jac[0][3] + fourt1 * jac[1][3]) +
908 n5.
v * (fourt3 * jac[0][3] + fourt1 * jac[2][3]) +
909 n6.
v * (fourt4 * jac[0][3] + fourt1 * jac[3][3]) +
910 n7.
v * (fourt3 * jac[1][3] + fourt2 * jac[2][3]) +
911 n8.
v * (fourt4 * jac[1][3] + fourt2 * jac[3][3]) +
912 n9.
v * (fourt4 * jac[2][3] + fourt3 * jac[3][3])) *
916 UnmapFields(ex, ey, ez, x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
921 std::cout <<
" Material " << element.
matmap <<
", drift flag "
932 const double zin,
double& wx,
double& wy,
933 double& wz,
const std::string& label) {
957 double x = xin, y = yin, z = zin;
960 bool xmirr, ymirr, zmirr;
961 double rcoordinate, rotation;
962 MapCoordinates(x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
967 double t1, t2, t3, t4, jac[4][4], det;
968 const int imap =
FindElement13(x, y, z, t1, t2, t3, t4, jac, det);
970 if (imap < 0)
return;
974 PrintElement(
"WeightingField", x, y, z, t1, t2, t3, t4, element, 10, iw);
987 const double invdet = 1. / det;
988 const double fourt1 = 4 * t1;
989 const double fourt2 = 4 * t2;
990 const double fourt3 = 4 * t3;
991 const double fourt4 = 4 * t4;
992 wx = -(n0.
w[iw] * (fourt1 - 1) * jac[0][1] +
993 n1.
w[iw] * (fourt2 - 1) * jac[1][1] +
994 n2.
w[iw] * (fourt3 - 1) * jac[2][1] +
995 n3.
w[iw] * (fourt4 - 1) * jac[3][1] +
996 n4.
w[iw] * (fourt2 * jac[0][1] + fourt1 * jac[1][1]) +
997 n5.
w[iw] * (fourt3 * jac[0][1] + fourt1 * jac[2][1]) +
998 n6.
w[iw] * (fourt4 * jac[0][1] + fourt1 * jac[3][1]) +
999 n7.
w[iw] * (fourt3 * jac[1][1] + fourt2 * jac[2][1]) +
1000 n8.
w[iw] * (fourt4 * jac[1][1] + fourt2 * jac[3][1]) +
1001 n9.
w[iw] * (fourt4 * jac[2][1] + fourt3 * jac[3][1])) *
1004 wy = -(n0.
w[iw] * (fourt1 - 1) * jac[0][2] +
1005 n1.
w[iw] * (fourt2 - 1) * jac[1][2] +
1006 n2.
w[iw] * (fourt3 - 1) * jac[2][2] +
1007 n3.
w[iw] * (fourt4 - 1) * jac[3][2] +
1008 n4.
w[iw] * (fourt2 * jac[0][2] + fourt1 * jac[1][2]) +
1009 n5.
w[iw] * (fourt3 * jac[0][2] + fourt1 * jac[2][2]) +
1010 n6.
w[iw] * (fourt4 * jac[0][2] + fourt1 * jac[3][2]) +
1011 n7.
w[iw] * (fourt3 * jac[1][2] + fourt2 * jac[2][2]) +
1012 n8.
w[iw] * (fourt4 * jac[1][2] + fourt2 * jac[3][2]) +
1013 n9.
w[iw] * (fourt4 * jac[2][2] + fourt3 * jac[3][2])) *
1016 wz = -(n0.
w[iw] * (fourt1 - 1) * jac[0][3] +
1017 n1.
w[iw] * (fourt2 - 1) * jac[1][3] +
1018 n2.
w[iw] * (fourt3 - 1) * jac[2][3] +
1019 n3.
w[iw] * (fourt4 - 1) * jac[3][3] +
1020 n4.
w[iw] * (fourt2 * jac[0][3] + fourt1 * jac[1][3]) +
1021 n5.
w[iw] * (fourt3 * jac[0][3] + fourt1 * jac[2][3]) +
1022 n6.
w[iw] * (fourt4 * jac[0][3] + fourt1 * jac[3][3]) +
1023 n7.
w[iw] * (fourt3 * jac[1][3] + fourt2 * jac[2][3]) +
1024 n8.
w[iw] * (fourt4 * jac[1][3] + fourt2 * jac[3][3]) +
1025 n9.
w[iw] * (fourt4 * jac[2][3] + fourt3 * jac[3][3])) *
1029 UnmapFields(wx, wy, wz, x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
1034 const std::string& label) {
1050 if (!found)
return 0.;
1055 double x = xin, y = yin, z = zin;
1058 bool xmirr, ymirr, zmirr;
1059 double rcoordinate, rotation;
1060 MapCoordinates(x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
1065 double t1, t2, t3, t4, jac[4][4], det;
1066 const int imap =
FindElement13(x, y, z, t1, t2, t3, t4, jac, det);
1067 if (imap < 0)
return 0.;
1071 PrintElement(
"WeightingPotential", x, y, z, t1, t2, t3, t4, element, 10,
1084 return n0.
w[iw] * t1 * (2 * t1 - 1) + n1.
w[iw] * t2 * (2 * t2 - 1) +
1085 n2.
w[iw] * t3 * (2 * t3 - 1) + n3.
w[iw] * t4 * (2 * t4 - 1) +
1086 4 * n4.
w[iw] * t1 * t2 + 4 * n5.
w[iw] * t1 * t3 +
1087 4 * n6.
w[iw] * t1 * t4 + 4 * n7.
w[iw] * t2 * t3 +
1088 4 * n8.
w[iw] * t2 * t4 + 4 * n9.
w[iw] * t3 * t4;
1094 double x = xin, y = yin, z = zin;
1097 bool xmirr, ymirr, zmirr;
1098 double rcoordinate, rotation;
1099 MapCoordinates(x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
1104 std::cerr <<
" Field map not available for interpolation.\n";
1110 double t1, t2, t3, t4, jac[4][4], det;
1111 const int imap =
FindElement13(x, y, z, t1, t2, t3, t4, jac, det);
1115 std::cerr <<
" Point (" << x <<
", " << y <<
", " << z
1116 <<
") not in the mesh.\n";
1124 std::cerr <<
" Point (" << x <<
", " << y <<
", " << z <<
")"
1125 <<
" has out of range material number " << imap <<
".\n";
1131 PrintElement(
"GetMedium", x, y, z, t1, t2, t3, t4, element, 10);
1139 if (i >=
elements.size())
return 0.;
1146 fabs((n3.
x - n0.
x) *
1147 ((n1.
y - n0.
y) * (n2.
z - n0.
z) - (n2.
y - n0.
y) * (n1.
z - n0.
z)) +
1149 ((n1.
z - n0.
z) * (n2.
x - n0.
x) - (n2.
z - n0.
z) * (n1.
x - n0.
x)) +
1150 (n3.
z - n0.
z) * ((n1.
x - n0.
x) * (n2.
y - n0.
y) -
1151 (n3.
x - n0.
x) * (n1.
y - n0.
y))) /
1166 for (
int j = 0; j < np - 1; ++j) {
1168 for (
int k = j + 1; k < np; ++k) {
1171 const double dx = nj.
x - nk.
x;
1172 const double dy = nj.
y - nk.
y;
1173 const double dz = nj.
z - nk.
z;
1174 const double dist = sqrt(dx * dx + dy * dy + dz * dz);
1178 if (dist < dmin) dmin = dist;
1179 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 UpdatePeriodicity() override
Verify periodicities.
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).
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)
int ReadInteger(char *token, int def, bool &error)
unsigned int m_nMaterials
std::vector< Material > materials
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< 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::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?