20 std::string mplist, std::string prnsol,
34 std::ifstream fmplist;
35 fmplist.open(mplist.c_str(), std::ios::in);
38 std::cerr <<
" Could not open material file " << mplist
40 std::cerr <<
" The file perhaps does not exist.\n";
47 unsigned int icurrmat = 0;
48 bool readerror =
false;
49 while (fmplist.getline(line, size,
'\n')) {
52 if (strcmp(line,
"1") == 0) {
53 fmplist.getline(line, size,
'\n');
55 fmplist.getline(line, size,
'\n');
57 fmplist.getline(line, size,
'\n');
59 fmplist.getline(line, size,
'\n');
61 fmplist.getline(line, size,
'\n');
67 token = strtok(line,
" ");
69 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
70 strcmp(token,
"TEMPERATURE") == 0 || strcmp(token,
"PROPERTY=") == 0 ||
71 int(token[0]) == 10 ||
int(token[0]) == 13)
75 if (strcmp(token,
"LIST") == 0) {
76 token = strtok(NULL,
" ");
77 token = strtok(NULL,
" ");
78 token = strtok(NULL,
" ");
79 token = strtok(NULL,
" ");
83 std::cerr <<
" Error reading file " << mplist <<
" (line " << il
97 std::cout <<
" Number of materials: " <<
m_nMaterials <<
"\n";
99 }
else if (strcmp(token,
"MATERIAL") == 0) {
101 token = strtok(NULL,
" ");
102 token = strtok(NULL,
" ");
103 const int imat =
ReadInteger(token, -1, readerror);
104 if (readerror || imat < 0) {
106 std::cerr <<
" Error reading file " << mplist <<
" (line " << il
113 }
else if (strcmp(token,
"TEMP") == 0) {
115 token = strtok(NULL,
" ");
117 if (strncmp(token,
"PERX", 4) == 0) {
119 }
else if (strncmp(token,
"RSVX", 4) == 0) {
123 std::cerr <<
" Found unknown material property flag " << token
125 std::cerr <<
" on material properties file " << mplist <<
" (line "
129 fmplist.getline(line, size,
'\n');
132 token = strtok(line,
" ");
135 std::cerr <<
" Found out-of-range current material index "
137 std::cerr <<
" in material properties file " << mplist <<
".\n";
140 }
else if (itype == 1) {
142 }
else if (itype == 2) {
147 std::cerr <<
" Error reading file " << mplist <<
" (line " << il
153 }
else if (strcmp(token,
"PROPERTY") == 0) {
155 token = strtok(NULL,
" ");
156 token = strtok(NULL,
" ");
158 if (strcmp(token,
"PERX") == 0) {
160 }
else if (strcmp(token,
"RSVX") == 0) {
165 std::cerr <<
" Found unknown material property flag " << token
167 std::cerr <<
" on material properties file " << mplist <<
" (line "
171 token = strtok(NULL,
" ");
172 token = strtok(NULL,
" ");
176 std::cerr <<
" Error reading file " << mplist <<
" (line " << il
183 std::cerr <<
" Found out-of-range current material index " << imat
185 std::cerr <<
" in material properties file " << mplist <<
".\n";
188 fmplist.getline(line, size,
'\n');
190 fmplist.getline(line, size,
'\n');
193 token = strtok(line,
" ");
194 token = strtok(NULL,
" ");
197 }
else if (itype == 2) {
202 std::cerr <<
" Error reading file " << mplist <<
" (line " << il
217 unsigned int iepsmin = 0;
218 for (
unsigned int imat = 0; imat <
m_nMaterials; ++imat) {
222 std::cerr <<
" Material " << imat
223 <<
" has been assigned a permittivity\n";
224 std::cerr <<
" equal to zero in " << mplist <<
".\n";
226 }
else if (epsmin < 0. || epsmin >
materials[imat].eps) {
234 std::cerr <<
" No material with positive permittivity found \n";
235 std::cerr <<
" in material list " << mplist <<
".\n";
238 for (
unsigned int imat = 0; imat <
m_nMaterials; ++imat) {
239 if (imat == iepsmin) {
250 <<
" materials from file " << mplist <<
".\n";
254 std::ifstream felist;
255 felist.open(elist.c_str(), std::ios::in);
258 std::cerr <<
" Could not open element file " << elist
259 <<
" for reading.\n";
260 std::cerr <<
" The file perhaps does not exist.\n";
271 while (felist.getline(line, size,
'\n')) {
276 token = strtok(line,
" ");
278 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
279 int(token[0]) == 10 ||
int(token[0]) == 13 ||
280 strcmp(token,
"LIST") == 0 || strcmp(token,
"ELEM") == 0)
284 token = strtok(NULL,
" ");
286 token = strtok(NULL,
" ");
287 token = strtok(NULL,
" ");
288 token = strtok(NULL,
" ");
289 token = strtok(NULL,
" ");
290 token = strtok(NULL,
" ");
291 if (!token) std::cerr <<
"No token available\n";
293 token = strtok(NULL,
" ");
295 token = strtok(NULL,
" ");
297 token = strtok(NULL,
" ");
299 token = strtok(NULL,
" ");
301 token = strtok(NULL,
" ");
303 token = strtok(NULL,
" ");
305 token = strtok(NULL,
" ");
311 std::cerr <<
" Error reading file " << elist <<
" (line " << il
316 }
else if (ielem - 1 !=
nElements + nbackground) {
318 std::cerr <<
" Synchronisation lost on file " << elist <<
" (line "
320 std::cerr <<
" Element: " << ielem <<
" (expected " <<
nElements
321 <<
"), material: " << imat <<
", nodes: (" << in0 <<
", " << in1
322 <<
", " << in2 <<
", " << in3 <<
", " << in4 <<
", " << in5
323 <<
", " << in6 <<
", " << in7 <<
")\n";
329 std::cerr <<
" Out-of-range material number on file " << elist
330 <<
" (line " << il <<
").\n";
331 std::cerr <<
" Element: " << ielem <<
", material: " << imat
332 <<
", nodes: (" << in0 <<
", " << in1 <<
", " << in2 <<
", "
333 << in3 <<
", " << in4 <<
", " << in5 <<
", " << in6 <<
", "
339 std::cerr <<
" Element " << ielem <<
" in element list " << elist
340 <<
" uses material " << imat <<
" which\n",
341 std::cerr <<
" has not been assigned a positive permittivity\n";
342 std::cerr <<
" in material list " << mplist <<
".\n";
346 if (in0 < 1 || in1 < 1 || in2 < 1 || in3 < 1 || in4 < 1 || in5 < 1 ||
347 in6 < 1 || in7 < 1) {
349 std::cerr <<
" Found a node number < 1 on file " << elist <<
" (line "
351 std::cerr <<
" Element: " << ielem <<
", material: " << imat <<
"\n";
354 if (in0 > highestnode) highestnode = in0;
355 if (in1 > highestnode) highestnode = in1;
356 if (in2 > highestnode) highestnode = in2;
357 if (in3 > highestnode) highestnode = in3;
358 if (in4 > highestnode) highestnode = in4;
359 if (in5 > highestnode) highestnode = in5;
360 if (in6 > highestnode) highestnode = in6;
361 if (in7 > highestnode) highestnode = in7;
368 if (in2 == in3 && in3 == in6) {
375 newElement.
matmap = imat - 1;
378 newElement.
emap[0] = in0 - 1;
379 newElement.
emap[1] = in1 - 1;
380 newElement.
emap[2] = in2 - 1;
381 newElement.
emap[3] = in4 - 1;
382 newElement.
emap[4] = in7 - 1;
383 newElement.
emap[5] = in5 - 1;
384 newElement.
emap[6] = in3 - 1;
385 newElement.
emap[7] = in6 - 1;
387 newElement.
emap[0] = in0 - 1;
388 newElement.
emap[1] = in1 - 1;
389 newElement.
emap[2] = in2 - 1;
390 newElement.
emap[3] = in3 - 1;
391 newElement.
emap[4] = in4 - 1;
392 newElement.
emap[5] = in5 - 1;
393 newElement.
emap[6] = in6 - 1;
394 newElement.
emap[7] = in7 - 1;
403 std::cout <<
" Read " <<
nElements <<
" elements from file " << elist
405 std::cout <<
" highest node number: " << highestnode <<
",\n";
406 std::cout <<
" degenerate elements: " << ndegenerate <<
",\n";
407 std::cout <<
" background elements skipped: " << nbackground <<
".\n";
410 if (strcmp(unit.c_str(),
"mum") == 0 || strcmp(unit.c_str(),
"micron") == 0 ||
411 strcmp(unit.c_str(),
"micrometer") == 0) {
413 }
else if (strcmp(unit.c_str(),
"mm") == 0 ||
414 strcmp(unit.c_str(),
"millimeter") == 0) {
416 }
else if (strcmp(unit.c_str(),
"cm") == 0 ||
417 strcmp(unit.c_str(),
"centimeter") == 0) {
419 }
else if (strcmp(unit.c_str(),
"m") == 0 ||
420 strcmp(unit.c_str(),
"meter") == 0) {
424 std::cerr <<
" Unknown length unit " << unit <<
".\n";
430 std::cout <<
" Unit scaling factor = " << funit <<
".\n";
434 std::ifstream fnlist;
435 fnlist.open(nlist.c_str(), std::ios::in);
438 std::cerr <<
" Could not open nodes file " << nlist <<
" for reading.\n";
439 std::cerr <<
" The file perhaps does not exist.\n";
448 while (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
477 if (inode - 1 !=
nNodes) {
479 std::cerr <<
" Synchronisation lost on file " << nlist <<
" (line "
481 std::cerr <<
" Node: " << inode <<
" (expected " <<
nNodes
482 <<
"), (x,y,z) = (" << xnode <<
", " << ynode <<
", " << znode
488 newNode.
x = xnode * funit;
489 newNode.
y = ynode * funit;
490 newNode.
z = znode * funit;
491 nodes.push_back(newNode);
498 std::cout <<
" Read " <<
nNodes <<
" nodes from file " << nlist <<
".\n";
500 if (
nNodes != highestnode) {
502 std::cerr <<
" Number of nodes read (" <<
nNodes <<
") on " << nlist
504 std::cerr <<
" does not match element list (" << highestnode <<
").\n";
509 std::ifstream fprnsol;
510 fprnsol.open(prnsol.c_str(), std::ios::in);
511 if (fprnsol.fail()) {
513 std::cerr <<
" Could not open potential file " << prnsol
514 <<
" for reading.\n";
515 std::cerr <<
" The file perhaps does not exist.\n";
522 while (fprnsol.getline(line, size,
'\n')) {
526 token = strtok(line,
" ");
528 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
529 int(token[0]) == 10 ||
int(token[0]) == 13 ||
530 strcmp(token,
"PRINT") == 0 || strcmp(token,
"*****") == 0 ||
531 strcmp(token,
"LOAD") == 0 || strcmp(token,
"TIME=") == 0 ||
532 strcmp(token,
"MAXIMUM") == 0 || strcmp(token,
"VALUE") == 0 ||
533 strcmp(token,
"NODE") == 0)
537 token = strtok(NULL,
" ");
538 double volt =
ReadDouble(token, -1, readerror);
542 std::cerr <<
" Error reading file " << prnsol <<
" (line " << il
549 if (inode < 1 || inode >
nNodes) {
551 std::cerr <<
" Node number " << inode <<
" out of range\n";
552 std::cerr <<
" on potential file " << prnsol <<
" (line " << il
556 nodes[inode - 1].v = volt;
564 std::cout <<
" Read " << nread <<
" potentials from file " << prnsol
569 std::cerr <<
" Number of nodes read (" << nread <<
") on potential file "
570 << prnsol <<
" does not\n",
571 std::cerr <<
" match the node list (" <<
nNodes <<
").\n";
580 <<
" Field map could not be read and cannot be interpolated.\n";
600 std::cerr <<
" Weighting field cannot be added.\n";
605 std::ifstream fprnsol;
606 fprnsol.open(prnsol.c_str(), std::ios::in);
607 if (fprnsol.fail()) {
608 std::cerr <<
m_className <<
"::SetWeightingField:\n";
609 std::cerr <<
" Could not open potential file " << prnsol
610 <<
" for reading.\n";
611 std::cerr <<
" The file perhaps does not exist.\n";
627 for (
int j =
nNodes; j--;) {
631 std::cout <<
m_className <<
"::SetWeightingField:\n";
632 std::cout <<
" Replacing existing weighting field " << label <<
".\n";
638 const int size = 100;
645 bool readerror =
false;
646 while (fprnsol.getline(line, size,
'\n')) {
650 token = strtok(line,
" ");
652 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
653 int(token[0]) == 10 ||
int(token[0]) == 13 ||
654 strcmp(token,
"PRINT") == 0 || strcmp(token,
"*****") == 0 ||
655 strcmp(token,
"LOAD") == 0 || strcmp(token,
"TIME=") == 0 ||
656 strcmp(token,
"MAXIMUM") == 0 || strcmp(token,
"VALUE") == 0 ||
657 strcmp(token,
"NODE") == 0)
661 token = strtok(NULL,
" ");
662 double volt =
ReadDouble(token, -1, readerror);
665 std::cerr <<
m_className <<
"::SetWeightingField:\n";
666 std::cerr <<
" Error reading file " << prnsol <<
" (line " << il
672 if (inode < 1 || inode >
nNodes) {
673 std::cerr <<
m_className <<
"::SetWeightingField:\n";
674 std::cerr <<
" Node number " << inode <<
" out of range\n";
675 std::cerr <<
" on potential file " << prnsol <<
" (line " << il
679 nodes[inode - 1].w[iw] = volt;
686 std::cout <<
m_className <<
"::SetWeightingField:\n";
687 std::cout <<
" Read " << nread <<
" potentials from file " << prnsol
691 std::cerr <<
m_className <<
"::SetWeightingField:\n";
692 std::cerr <<
" Number of nodes read (" << nread <<
") "
693 <<
" on potential file " << prnsol <<
"\n";
694 std::cerr <<
" does not match the node list (" <<
nNodes <<
").\n";
701 std::cerr <<
m_className <<
"::SetWeightingField:\n";
702 std::cerr <<
" Field map could not be read "
703 <<
"and cannot be interpolated.\n";
710 const double z,
double& ex,
double& ey,
711 double& ez,
Medium*& m,
int& status) {
718 const double zin,
double& ex,
double& ey,
719 double& ez,
double& volt,
Medium*& m,
723 double x = xin, y = yin, z = 0.;
726 bool xmirr, ymirr, zmirr;
727 double rcoordinate, rotation;
728 MapCoordinates(x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
731 ex = ey = ez = volt = 0;
750 double t1, t2, t3, t4, jac[4][4], det;
751 const int imap =
FindElement5(x, y, z, t1, t2, t3, t4, jac, det);
755 std::cout <<
" Point (" << x <<
", " << y <<
") not in the mesh.\n";
762 PrintElement(
"ElectricField", x, y, z, t1, t2, t3, t4, imap, 8);
773 const double invdet = 1. / det;
775 volt = n0.
v * t1 * (2 * t1 - 1) + n1.
v * t2 * (2 * t2 - 1) +
776 n2.
v * t3 * (2 * t3 - 1) + 4 * n3.
v * t1 * t2 + 4 * n4.
v * t1 * t3 +
778 ex = -(n0.
v * (4 * t1 - 1) * jac[0][1] +
779 n1.
v * (4 * t2 - 1) * jac[1][1] +
780 n2.
v * (4 * t3 - 1) * jac[2][1] +
781 n3.
v * (4 * t2 * jac[0][1] + 4 * t1 * jac[1][1]) +
782 n4.
v * (4 * t3 * jac[0][1] + 4 * t1 * jac[2][1]) +
783 n5.
v * (4 * t3 * jac[1][1] + 4 * t2 * jac[2][1])) * invdet;
784 ey = -(n0.
v * (4 * t1 - 1) * jac[0][2] +
785 n1.
v * (4 * t2 - 1) * jac[1][2] +
786 n2.
v * (4 * t3 - 1) * jac[2][2] +
787 n3.
v * (4 * t2 * jac[0][2] + 4 * t1 * jac[1][2]) +
788 n4.
v * (4 * t3 * jac[0][2] + 4 * t1 * jac[2][2]) +
789 n5.
v * (4 * t3 * jac[1][2] + 4 * t2 * jac[2][2])) * invdet;
793 volt = -n0.
v * (1 - t1) * (1 - t2) * (1 + t1 + t2) * 0.25 -
794 n1.
v * (1 + t1) * (1 - t2) * (1 - t1 + t2) * 0.25 -
795 n2.
v * (1 + t1) * (1 + t2) * (1 - t1 - t2) * 0.25 -
796 n3.
v * (1 - t1) * (1 + t2) * (1 + t1 - t2) * 0.25 +
797 n4.
v * (1 - t1) * (1 + t1) * (1 - t2) * 0.5 +
798 n5.
v * (1 + t1) * (1 + t2) * (1 - t2) * 0.5 +
799 n6.
v * (1 - t1) * (1 + t1) * (1 + t2) * 0.5 +
800 n7.
v * (1 - t1) * (1 + t2) * (1 - t2) * 0.5;
801 ex = -(n0.
v * ((1 - t2) * (2 * t1 + t2) * jac[0][0] +
802 (1 - t1) * (t1 + 2 * t2) * jac[1][0]) * 0.25 +
803 n1.
v * ((1 - t2) * (2 * t1 - t2) * jac[0][0] -
804 (1 + t1) * (t1 - 2 * t2) * jac[1][0]) * 0.25 +
805 n2.
v * ((1 + t2) * (2 * t1 + t2) * jac[0][0] +
806 (1 + t1) * (t1 + 2 * t2) * jac[1][0]) * 0.25 +
807 n3.
v * ((1 + t2) * (2 * t1 - t2) * jac[0][0] -
808 (1 - t1) * (t1 - 2 * t2) * jac[1][0]) * 0.25 +
809 n4.
v * (t1 * (t2 - 1) * jac[0][0] +
810 (t1 - 1) * (t1 + 1) * jac[1][0] * 0.5) +
811 n5.
v * ((1 - t2) * (1 + t2) * jac[0][0] * 0.5 -
812 (1 + t1) * t2 * jac[1][0]) +
813 n6.
v * (-t1 * (1 + t2) * jac[0][0] +
814 (1 - t1) * (1 + t1) * jac[1][0] * 0.5) +
815 n7.
v * ((t2 - 1) * (t2 + 1) * jac[0][0] * 0.5 +
816 (t1 - 1) * t2 * jac[1][0])) * invdet;
817 ey = -(n0.
v * ((1 - t2) * (2 * t1 + t2) * jac[0][1] +
818 (1 - t1) * (t1 + 2 * t2) * jac[1][1]) * 0.25 +
819 n1.
v * ((1 - t2) * (2 * t1 - t2) * jac[0][1] -
820 (1 + t1) * (t1 - 2 * t2) * jac[1][1]) * 0.25 +
821 n2.
v * ((1 + t2) * (2 * t1 + t2) * jac[0][1] +
822 (1 + t1) * (t1 + 2 * t2) * jac[1][1]) * 0.25 +
823 n3.
v * ((1 + t2) * (2 * t1 - t2) * jac[0][1] -
824 (1 - t1) * (t1 - 2 * t2) * jac[1][1]) * 0.25 +
825 n4.
v * (t1 * (t2 - 1) * jac[0][1] +
826 (t1 - 1) * (t1 + 1) * jac[1][1] * 0.5) +
827 n5.
v * ((1 - t2) * (1 + t2) * jac[0][1] * 0.5 -
828 (1 + t1) * t2 * jac[1][1]) +
829 n6.
v * (-t1 * (1 + t2) * jac[0][1] +
830 (1 - t1) * (1 + t1) * jac[1][1] * 0.5) +
831 n7.
v * ((t2 - 1) * (t2 + 1) * jac[0][1] * 0.5 +
832 (t1 - 1) * t2 * jac[1][1])) * invdet;
836 UnmapFields(ex, ey, ez, x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
841 std::cout <<
" Material " << element.
matmap <<
", drift flag "
852 const double zin,
double& wx,
double& wy,
853 double& wz,
const std::string& label) {
878 double x = xin, y = yin, z = zin;
881 bool xmirr, ymirr, zmirr;
882 double rcoordinate, rotation;
883 MapCoordinates(x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
888 double t1, t2, t3, t4, jac[4][4], det;
889 const int imap =
FindElement5(x, y, z, t1, t2, t3, t4, jac, det);
891 if (imap < 0)
return;
894 PrintElement(
"WeightingField", x, y, z, t1, t2, t3, t4, imap, 8, iw);
905 const double invdet = 1. / det;
907 wx = -(n0.
w[iw] * (4 * t1 - 1) * jac[0][1] +
908 n1.
w[iw] * (4 * t2 - 1) * jac[1][1] +
909 n2.
w[iw] * (4 * t3 - 1) * jac[2][1] +
910 n3.
w[iw] * (4 * t2 * jac[0][1] + 4 * t1 * jac[1][1]) +
911 n4.
w[iw] * (4 * t3 * jac[0][1] + 4 * t1 * jac[2][1]) +
912 n5.
w[iw] * (4 * t3 * jac[1][1] + 4 * t2 * jac[2][1])) * invdet;
913 wy = -(n0.
w[iw] * (4 * t1 - 1) * jac[0][2] +
914 n1.
w[iw] * (4 * t2 - 1) * jac[1][2] +
915 n2.
w[iw] * (4 * t3 - 1) * jac[2][2] +
916 n3.
w[iw] * (4 * t2 * jac[0][2] + 4 * t1 * jac[1][2]) +
917 n4.
w[iw] * (4 * t3 * jac[0][2] + 4 * t1 * jac[2][2]) +
918 n5.
w[iw] * (4 * t3 * jac[1][2] + 4 * t2 * jac[2][2])) * invdet;
922 wx = -(n0.
w[iw] * ((1 - t2) * (2 * t1 + t2) * jac[0][0] +
923 (1 - t1) * (t1 + 2 * t2) * jac[1][0]) * 0.25 +
924 n1.
w[iw] * ((1 - t2) * (2 * t1 - t2) * jac[0][0] -
925 (1 + t1) * (t1 - 2 * t2) * jac[1][0]) * 0.25 +
926 n2.
w[iw] * ((1 + t2) * (2 * t1 + t2) * jac[0][0] +
927 (1 + t1) * (t1 + 2 * t2) * jac[1][0]) * 0.25 +
928 n3.
w[iw] * ((1 + t2) * (2 * t1 - t2) * jac[0][0] -
929 (1 - t1) * (t1 - 2 * t2) * jac[1][0]) * 0.25 +
930 n4.
w[iw] * (t1 * (t2 - 1) * jac[0][0] +
931 (t1 - 1) * (t1 + 1) * jac[1][0] * 0.5) +
932 n5.
w[iw] * ((1 - t2) * (1 + t2) * jac[0][0] * 0.5 -
933 (1 + t1) * t2 * jac[1][0]) +
934 n6.
w[iw] * (-t1 * (1 + t2) * jac[0][0] +
935 (1 - t1) * (1 + t1) * jac[1][0] * 0.5) +
936 n7.
w[iw] * ((t2 - 1) * (1 + t2) * jac[0][0] * 0.5 +
937 (t1 - 1) * t2 * jac[1][0])) * invdet;
938 wy = -(n0.
w[iw] * ((1 - t2) * (2 * t1 + t2) * jac[0][1] +
939 (1 - t1) * (t1 + 2 * t2) * jac[1][1]) * 0.25 +
940 n1.
w[iw] * ((1 - t2) * (2 * t1 - t2) * jac[0][1] -
941 (1 + t1) * (t1 - 2 * t2) * jac[1][1]) * 0.25 +
942 n2.
w[iw] * ((1 + t2) * (2 * t1 + t2) * jac[0][1] +
943 (1 + t1) * (t1 + 2 * t2) * jac[1][1]) * 0.25 +
944 n3.
w[iw] * ((1 + t2) * (2 * t1 - t2) * jac[0][1] -
945 (1 - t1) * (t1 - 2 * t2) * jac[1][1]) * 0.25 +
946 n4.
w[iw] * (t1 * (t2 - 1) * jac[0][1] +
947 (t1 - 1) * (t1 + 1) * jac[1][1] * 0.5) +
948 n5.
w[iw] * ((1 - t2) * (1 + t2) * jac[0][1] * 0.5 -
949 (1 + t1) * t2 * jac[1][1]) +
950 n6.
w[iw] * (-t1 * (1 + t2) * jac[0][1] +
951 (1 - t1) * (1 + t1) * jac[1][1] * 0.5) +
952 n7.
w[iw] * ((t2 - 1) * (t2 + 1) * jac[0][1] * 0.5 +
953 (t1 - 1) * t2 * jac[1][1])) * invdet;
957 UnmapFields(wx, wy, wz, x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
962 const std::string& label) {
979 if (!found)
return 0.;
984 double x = xin, y = yin, z = zin;
987 bool xmirr, ymirr, zmirr;
988 double rcoordinate, rotation;
989 MapCoordinates(x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
994 double t1, t2, t3, t4, jac[4][4], det;
995 const int imap =
FindElement5(x, y, z, t1, t2, t3, t4, jac, det);
997 if (imap < 0)
return 0.;
1000 PrintElement(
"WeightingPotential", x, y, z, t1, t2, t3, t4, imap, 8, iw);
1012 return n0.
w[iw] * t1 * (2 * t1 - 1) + n1.
w[iw] * t2 * (2 * t2 - 1) +
1013 n2.
w[iw] * t3 * (2 * t3 - 1) + 4 * n3.
w[iw] * t1 * t2 +
1014 4 * n4.
w[iw] * t1 * t3 + 4 * n5.
w[iw] * t2 * t3;
1019 return -n0.
w[iw] * (1 - t1) * (1 - t2) * (1 + t1 + t2) * 0.25 -
1020 n1.
w[iw] * (1 + t1) * (1 - t2) * (1 - t1 + t2) * 0.25 -
1021 n2.
w[iw] * (1 + t1) * (1 + t2) * (1 - t1 - t2) * 0.25 -
1022 n3.
w[iw] * (1 - t1) * (1 + t2) * (1 + t1 - t2) * 0.25 +
1023 n4.
w[iw] * (1 - t1) * (1 + t1) * (1 - t2) * 0.5 +
1024 n5.
w[iw] * (1 + t1) * (1 + t2) * (1 - t2) * 0.5 +
1025 n6.
w[iw] * (1 - t1) * (1 + t1) * (1 + t2) * 0.5 +
1026 n7.
w[iw] * (1 - t1) * (1 + t2) * (1 - t2) * 0.5;
1033 double x = xin, y = yin, z = 0.;
1036 bool xmirr, ymirr, zmirr;
1037 double rcoordinate, rotation;
1038 MapCoordinates(x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
1052 double t1, t2, t3, t4, jac[4][4], det;
1053 const int imap =
FindElement5(x, y, z, t1, t2, t3, t4, jac, det);
1057 std::cerr <<
" Point (" << x <<
", " << y <<
") not in the mesh.\n";
1065 std::cerr <<
" Point (" << x <<
", " << y <<
")"
1066 <<
" has out of range material number " << imap <<
".\n";
1072 PrintElement(
"GetMedium", x, y, z, t1, t2, t3, t4, imap, 8);
1081 if (fabs(zmax - zmin) <= 0.) {
1083 std::cerr <<
" Zero range is not permitted.\n";
1098 if (i >=
elements.size())
return 0.;
1104 const double surf = 0.5 *
1105 (fabs((n1.
x - n0.
x) * (n2.
y - n0.
y) - (n2.
x - n0.
x) * (n1.
y - n0.
y)) +
1106 fabs((n3.
x - n0.
x) * (n2.
y - n0.
y) - (n2.
x - n0.
x) * (n3.
y - n0.
y)));
1121 for (
int j = 0; j < np - 1; ++j) {
1123 for (
int k = j + 1; k < np; ++k) {
1126 const double dx = nj.
x - nk.
x;
1127 const double dy = nj.
y - nk.
y;
1128 const double dist = sqrt(dx * dx + dy * dy);
1132 if (dist < dmin) dmin = dist;
1133 if (dist > dmax) dmax = dist;
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)
void UpdatePeriodicity()
Verify periodicities.
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 GetAspectRatio(const unsigned int i, double &dmin, double &dmax)
double WeightingPotential(const double x, const double y, const double z, const std::string &label)
void SetRangeZ(const double zmin, const double zmax)
void WeightingField(const double x, const double y, const double z, double &wx, double &wy, double &wz, const std::string &label)
Medium * GetMedium(const double x, const double y, const double z)
Get the medium at a given location (x, y, z).
double GetElementVolume(const unsigned int i)
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)
void UpdatePeriodicityCommon()
int ReadInteger(char *token, int def, bool &error)
unsigned int m_nMaterials
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 unsigned int i, const unsigned int n, const int iw=-1) 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.
std::vector< Material > materials
void UpdatePeriodicity2d()
std::vector< Node > nodes
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.