16 std::string mplist, std::string prnsol,
30 std::ifstream fmplist;
31 fmplist.open(mplist.c_str(), std::ios::in);
34 std::cerr <<
" Could not open material file " << mplist
36 std::cerr <<
" The file perhaps does not exist.\n";
43 unsigned int icurrmat = 0;
44 bool readerror =
false;
45 while (fmplist.getline(line, size,
'\n')) {
48 if (strcmp(line,
"1") == 0) {
49 fmplist.getline(line, size,
'\n');
51 fmplist.getline(line, size,
'\n');
53 fmplist.getline(line, size,
'\n');
55 fmplist.getline(line, size,
'\n');
57 fmplist.getline(line, size,
'\n');
63 token = strtok(line,
" ");
65 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
66 strcmp(token,
"TEMPERATURE") == 0 || strcmp(token,
"PROPERTY=") == 0 ||
67 int(token[0]) == 10 ||
int(token[0]) == 13)
71 if (strcmp(token,
"LIST") == 0) {
72 token = strtok(NULL,
" ");
73 token = strtok(NULL,
" ");
74 token = strtok(NULL,
" ");
75 token = strtok(NULL,
" ");
79 std::cerr <<
" Error reading file " << mplist <<
" (line " << il
93 std::cout <<
" Number of materials: " <<
m_nMaterials <<
"\n";
95 }
else if (strcmp(token,
"MATERIAL") == 0) {
97 token = strtok(NULL,
" ");
98 token = strtok(NULL,
" ");
100 if (readerror || imat < 0) {
102 std::cerr <<
" Error reading file " << mplist <<
" (line " << il
109 }
else if (strcmp(token,
"TEMP") == 0) {
111 token = strtok(NULL,
" ");
113 if (strncmp(token,
"PERX", 4) == 0) {
115 }
else if (strncmp(token,
"RSVX", 4) == 0) {
119 std::cerr <<
" Found unknown material property flag " << token
121 std::cerr <<
" on material properties file " << mplist <<
" (line "
125 fmplist.getline(line, size,
'\n');
128 token = strtok(line,
" ");
131 std::cerr <<
" Found out-of-range current material index "
133 std::cerr <<
" in material properties file " << mplist <<
".\n";
136 }
else if (itype == 1) {
138 }
else if (itype == 2) {
143 std::cerr <<
" Error reading file " << mplist <<
" line " << il
149 }
else if (strcmp(token,
"PROPERTY") == 0) {
151 token = strtok(NULL,
" ");
152 token = strtok(NULL,
" ");
154 if (strcmp(token,
"PERX") == 0) {
156 }
else if (strcmp(token,
"RSVX") == 0) {
160 std::cerr <<
" Found unknown material property flag " << token
162 std::cerr <<
" on material properties file " << mplist <<
" (line "
166 token = strtok(NULL,
" ");
167 token = strtok(NULL,
" ");
171 std::cerr <<
" Error reading file " << mplist <<
" (line " << il
178 std::cerr <<
" Found out-of-range material index " << imat <<
"\n";
179 std::cerr <<
" in material properties file " << mplist <<
".\n";
182 fmplist.getline(line, size,
'\n');
184 fmplist.getline(line, size,
'\n');
187 token = strtok(line,
" ");
188 token = strtok(NULL,
" ");
191 }
else if (itype == 2) {
196 std::cerr <<
" Error reading file " << mplist <<
" (line " << il
211 unsigned int iepsmin = 0;
212 for (
unsigned int imat = 0; imat <
m_nMaterials; ++imat) {
216 std::cerr <<
" Material " << imat
217 <<
" has been assigned a permittivity\n";
218 std::cerr <<
" equal to zero in " << mplist <<
".\n";
220 }
else if (epsmin < 0. || epsmin >
materials[imat].eps) {
228 std::cerr <<
" No material with positive permittivity found \n";
229 std::cerr <<
" in material list " << mplist <<
".\n";
232 for (
unsigned int imat = 0; imat <
m_nMaterials; ++imat) {
233 if (imat == iepsmin) {
244 <<
" materials from file " << mplist <<
".\n";
248 std::ifstream felist;
249 felist.open(elist.c_str(), std::ios::in);
252 std::cerr <<
" Could not open element file " << elist
253 <<
" for reading.\n";
254 std::cerr <<
" The file perhaps does not exist.\n";
265 while (felist.getline(line, size,
'\n')) {
268 if (strcmp(line,
"1") == 0) {
269 felist.getline(line, size,
'\n');
271 felist.getline(line, size,
'\n');
273 felist.getline(line, size,
'\n');
275 felist.getline(line, size,
'\n');
277 felist.getline(line, size,
'\n');
284 token = strtok(line,
" ");
286 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
287 int(token[0]) == 10 ||
int(token[0]) == 13 ||
288 strcmp(token,
"LIST") == 0 || strcmp(token,
"ELEM") == 0) {
293 token = strtok(NULL,
" ");
295 token = strtok(NULL,
" ");
296 token = strtok(NULL,
" ");
297 token = strtok(NULL,
" ");
298 token = strtok(NULL,
" ");
299 token = strtok(NULL,
" ");
301 token = strtok(NULL,
" ");
303 token = strtok(NULL,
" ");
305 token = strtok(NULL,
" ");
307 token = strtok(NULL,
" ");
309 token = strtok(NULL,
" ");
311 token = strtok(NULL,
" ");
313 token = strtok(NULL,
" ");
315 if (!felist.getline(line, size,
'\n')) {
317 std::cerr <<
" Error reading element " << ielem <<
".\n";
323 token = strtok(line,
" ");
325 token = strtok(NULL,
" ");
331 std::cerr <<
" Error reading file " << elist <<
" (line " << il
336 }
else if (ielem - 1 !=
nElements + nbackground) {
338 std::cerr <<
" Synchronisation lost on file " << elist <<
" (line "
340 std::cerr <<
" Element: " << ielem <<
" (expected " <<
nElements
341 <<
"), material: " << imat <<
",\n";
342 std::cerr <<
" nodes: (" << in0 <<
", " << in1 <<
", " << in2 <<
", "
343 << in3 <<
", " << in4 <<
", " << in5 <<
", " << in6 <<
", "
344 << in7 <<
", " << in8 <<
", " << in9 <<
")\n";
351 std::cerr <<
" Out-of-range material number on file " << elist
352 <<
" (line " << il <<
").\n";
353 std::cerr <<
" Element: " << ielem <<
", material: " << imat <<
",\n";
354 std::cerr <<
" nodes: (" << in0 <<
", " << in1 <<
", " << in2 <<
", "
355 << in3 <<
", " << in4 <<
", " << in5 <<
", " << in6 <<
", "
356 << in7 <<
", " << in8 <<
", " << in9 <<
")\n";
361 std::cerr <<
" Element " << ielem <<
" in element list " << elist
363 std::cerr <<
" uses material " << imat
364 <<
" which has not been assigned\n";
365 std::cerr <<
" a positive permittivity in material list " << mplist
371 if (in0 < 1 || in1 < 1 || in2 < 1 || in3 < 1 || in4 < 1 || in5 < 1 ||
372 in6 < 1 || in7 < 1 || in8 < 1 || in9 < 1) {
374 std::cerr <<
" Found a node number < 1 on file " << elist <<
" (line "
376 std::cerr <<
" Element: " << ielem <<
", material: " << imat <<
",\n";
377 std::cerr <<
" nodes: (" << in0 <<
", " << in1 <<
", " << in2 <<
", "
378 << in3 <<
", " << in4 <<
", " << in5 <<
", " << in6 <<
", "
379 << in7 <<
", " << in8 <<
", " << in9 <<
")\n";
382 if (in0 > highestnode) highestnode = in0;
383 if (in1 > highestnode) highestnode = in1;
384 if (in2 > highestnode) highestnode = in2;
385 if (in3 > highestnode) highestnode = in3;
386 if (in4 > highestnode) highestnode = in4;
387 if (in5 > highestnode) highestnode = in5;
388 if (in6 > highestnode) highestnode = in6;
389 if (in7 > highestnode) highestnode = in7;
390 if (in8 > highestnode) highestnode = in8;
391 if (in9 > highestnode) highestnode = in9;
400 if (in0 == in1 || in0 == in2 || in0 == in3 || in0 == in4 || in0 == in5 ||
401 in0 == in6 || in0 == in7 || in0 == in8 || in0 == in9 || in1 == in2 ||
402 in1 == in3 || in1 == in4 || in1 == in5 || in1 == in6 || in1 == in7 ||
403 in1 == in8 || in1 == in9 || in2 == in3 || in2 == in4 || in2 == in5 ||
404 in2 == in6 || in2 == in7 || in2 == in8 || in2 == in9 || in3 == in4 ||
405 in3 == in5 || in3 == in6 || in3 == in7 || in3 == in8 || in3 == in9 ||
406 in4 == in5 || in4 == in6 || in4 == in7 || in4 == in8 || in4 == in9 ||
407 in5 == in6 || in5 == in7 || in5 == in8 || in5 == in9 || in6 == in7 ||
408 in6 == in8 || in6 == in9 || in7 == in8 || in7 == in9 || in8 == in9) {
410 std::cerr <<
" Element " << ielem <<
" of file " << elist
411 <<
" is degenerate,\n";
412 std::cerr <<
" no such elements allowed in this type of map.\n";
419 newElement.
matmap = imat - 1;
422 newElement.
emap[0] = in0 - 1;
423 newElement.
emap[1] = in1 - 1;
424 newElement.
emap[2] = in2 - 1;
425 newElement.
emap[3] = in3 - 1;
426 newElement.
emap[4] = in4 - 1;
427 newElement.
emap[7] = in5 - 1;
428 newElement.
emap[5] = in6 - 1;
429 newElement.
emap[6] = in7 - 1;
430 newElement.
emap[8] = in8 - 1;
431 newElement.
emap[9] = in9 - 1;
440 std::cout <<
" Read " <<
nElements <<
" elements from file " << elist
442 std::cout <<
" highest node number: " << highestnode <<
",\n";
443 std::cout <<
" background elements skipped: " << nbackground <<
"\n";
446 if (strcmp(unit.c_str(),
"mum") == 0 || strcmp(unit.c_str(),
"micron") == 0 ||
447 strcmp(unit.c_str(),
"micrometer") == 0) {
449 }
else if (strcmp(unit.c_str(),
"mm") == 0 ||
450 strcmp(unit.c_str(),
"millimeter") == 0) {
452 }
else if (strcmp(unit.c_str(),
"cm") == 0 ||
453 strcmp(unit.c_str(),
"centimeter") == 0) {
455 }
else if (strcmp(unit.c_str(),
"m") == 0 ||
456 strcmp(unit.c_str(),
"meter") == 0) {
460 std::cerr <<
" Unknown length unit " << unit <<
".\n";
466 std::cout <<
" Unit scaling factor = " << funit <<
".\n";
470 std::ifstream fnlist;
471 fnlist.open(nlist.c_str(), std::ios::in);
474 std::cerr <<
" Could not open nodes file " << nlist <<
" for reading.\n";
475 std::cerr <<
" The file perhaps does not exist.\n";
485 while (fnlist.getline(line, size,
'\n')) {
488 if (strcmp(line,
"1") == 0) {
489 fnlist.getline(line, size,
'\n');
491 fnlist.getline(line, size,
'\n');
493 fnlist.getline(line, size,
'\n');
495 fnlist.getline(line, size,
'\n');
497 fnlist.getline(line, size,
'\n');
503 token = strtok(line,
" ");
505 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
506 int(token[0]) == 10 ||
int(token[0]) == 13 ||
507 strcmp(token,
"LIST") == 0 || strcmp(token,
"NODE") == 0)
511 token = strtok(NULL,
" ");
512 double xnode =
ReadDouble(token, -1, readerror);
513 token = strtok(NULL,
" ");
514 double ynode =
ReadDouble(token, -1, readerror);
515 token = strtok(NULL,
" ");
516 double znode =
ReadDouble(token, -1, readerror);
520 std::cerr <<
" Error reading file " << nlist <<
" (line " << il
527 if (inode - 1 !=
nNodes) {
529 std::cerr <<
" Synchronisation lost on file " << nlist <<
" (line "
531 std::cerr <<
" Node: " << inode <<
" (expected " <<
nNodes
532 <<
"), (x,y,z) = (" << xnode <<
", " << ynode <<
", " << znode
537 newNode.
x = xnode * funit;
538 newNode.
y = ynode * funit;
539 newNode.
z = znode * funit;
540 nodes.push_back(newNode);
547 std::cout <<
" Read " <<
nNodes <<
" nodes from file " << nlist <<
".\n";
549 if (
nNodes != highestnode) {
551 std::cerr <<
" Number of nodes read (" <<
nNodes <<
") on " << nlist
553 std::cerr <<
" does not match element list (" << highestnode <<
").\n";
558 std::ifstream fprnsol;
559 fprnsol.open(prnsol.c_str(), std::ios::in);
560 if (fprnsol.fail()) {
562 std::cerr <<
" Could not open potential file " << prnsol
563 <<
" for reading.\n";
564 std::cerr <<
" The file perhaps does not exist.\n";
571 while (fprnsol.getline(line, size,
'\n')) {
574 if (strcmp(line,
"1") == 0) {
575 fprnsol.getline(line, size,
'\n');
577 fprnsol.getline(line, size,
'\n');
579 fprnsol.getline(line, size,
'\n');
581 fprnsol.getline(line, size,
'\n');
583 fprnsol.getline(line, size,
'\n');
589 token = strtok(line,
" ");
591 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
592 int(token[0]) == 10 ||
int(token[0]) == 13 ||
593 strcmp(token,
"PRINT") == 0 || strcmp(token,
"*****") == 0 ||
594 strcmp(token,
"LOAD") == 0 || strcmp(token,
"TIME=") == 0 ||
595 strcmp(token,
"MAXIMUM") == 0 || strcmp(token,
"VALUE") == 0 ||
596 strcmp(token,
"NODE") == 0)
600 token = strtok(NULL,
" ");
601 double volt =
ReadDouble(token, -1, readerror);
605 std::cerr <<
" Error reading file " << prnsol <<
" (line << " << il
612 if (inode < 1 || inode > highestnode) {
614 std::cerr <<
" Node number " << inode <<
" out of range\n";
615 std::cerr <<
" on potential file " << prnsol <<
" (line " << il
619 nodes[inode - 1].v = volt;
627 std::cout <<
" Read " << nread <<
" potentials from file " << prnsol
632 std::cerr <<
" Number of nodes read (" << nread <<
") on potential file "
634 std::cerr <<
" does not match the node list (" <<
nNodes <<
").\n";
644 <<
" Field map could not be read and can not be interpolated.\n";
664 std::cerr <<
" Weighting field cannot be added.\n";
669 std::ifstream fprnsol;
670 fprnsol.open(prnsol.c_str(), std::ios::in);
671 if (fprnsol.fail()) {
672 std::cerr <<
m_className <<
"::SetWeightingField:\n";
673 std::cerr <<
" Could not open potential file " << prnsol
674 <<
" for reading.\n";
675 std::cerr <<
" The file perhaps does not exist.\n";
691 for (
int j =
nNodes; j--;) {
695 std::cout <<
m_className <<
"::SetWeightingField:\n";
696 std::cout <<
" Replacing existing weighting field " << label <<
".\n";
702 const int size = 100;
709 bool readerror =
false;
711 while (fprnsol.getline(line, size,
'\n')) {
714 if (strcmp(line,
"1") == 0) {
715 fprnsol.getline(line, size,
'\n');
717 fprnsol.getline(line, size,
'\n');
719 fprnsol.getline(line, size,
'\n');
721 fprnsol.getline(line, size,
'\n');
723 fprnsol.getline(line, size,
'\n');
729 token = strtok(line,
" ");
731 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
732 int(token[0]) == 10 ||
int(token[0]) == 13 ||
733 strcmp(token,
"PRINT") == 0 || strcmp(token,
"*****") == 0 ||
734 strcmp(token,
"LOAD") == 0 || strcmp(token,
"TIME=") == 0 ||
735 strcmp(token,
"MAXIMUM") == 0 || strcmp(token,
"VALUE") == 0 ||
736 strcmp(token,
"NODE") == 0)
740 token = strtok(NULL,
" ");
741 double volt =
ReadDouble(token, -1, readerror);
744 std::cerr <<
m_className <<
"::SetWeightingField:\n";
745 std::cerr <<
" Error reading file " << prnsol.c_str() <<
" (line "
751 if (inode < 1 || inode >
nNodes) {
752 std::cerr <<
m_className <<
"::SetWeightingField:\n";
753 std::cerr <<
" Node number " << inode <<
" out of range\n";
754 std::cerr <<
" on potential file " << prnsol.c_str() <<
" (line " << il
758 nodes[inode - 1].w[iw] = volt;
765 std::cout <<
m_className <<
"::SetWeightingField:\n";
766 std::cout <<
" Read " << nread <<
" potentials from file "
767 << prnsol.c_str() <<
".\n";
770 std::cerr <<
m_className <<
"::SetWeightingField:\n";
771 std::cerr <<
" Number of nodes read (" << nread <<
") "
772 <<
" on potential file " << prnsol.c_str() <<
"\n";
773 std::cerr <<
" does not match the node list (" <<
nNodes <<
").\n";
780 std::cerr <<
m_className <<
"::SetWeightingField:\n";
781 std::cerr <<
" Field map could not be read "
782 <<
"and cannot be interpolated.\n";
789 const double z,
double& ex,
double& ey,
790 double& ez,
Medium*& m,
int& status) {
797 const double zin,
double& ex,
double& ey,
798 double& ez,
double& volt,
Medium*& m,
802 double x = xin, y = yin, z = zin;
805 bool xmirr, ymirr, zmirr;
806 double rcoordinate, rotation;
807 MapCoordinates(x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
810 ex = ey = ez = volt = 0.;
824 double t1, t2, t3, t4, jac[4][4], det;
825 const int imap =
FindElement13(x, y, z, t1, t2, t3, t4, jac, det);
829 std::cerr <<
" Point (" << x <<
", " << y <<
", " << z
830 <<
") not in the mesh.\n";
837 PrintElement(
"ElectricField", x, y, z, t1, t2, t3, t4, imap, 10);
852 const double invdet = 1. / det;
853 volt = n0.
v * t1 * (2 * t1 - 1) + n1.
v * t2 * (2 * t2 - 1) +
854 n2.
v * t3 * (2 * t3 - 1) + n3.
v * t4 * (2 * t4 - 1) +
855 4 * n4.
v * t1 * t2 + 4 * n5.
v * t1 * t3 + 4 * n6.
v * t1 * t4 +
856 4 * n7.
v * t2 * t3 + 4 * n8.
v * t2 * t4 + 4 * n9.
v * t3 * t4;
858 ex = -(n0.
v * (4 * t1 - 1) * jac[0][1] + n1.
v * (4 * t2 - 1) * jac[1][1] +
859 n2.
v * (4 * t3 - 1) * jac[2][1] + n3.
v * (4 * t4 - 1) * jac[3][1] +
860 n4.
v * (4 * t2 * jac[0][1] + 4 * t1 * jac[1][1]) +
861 n5.
v * (4 * t3 * jac[0][1] + 4 * t1 * jac[2][1]) +
862 n6.
v * (4 * t4 * jac[0][1] + 4 * t1 * jac[3][1]) +
863 n7.
v * (4 * t3 * jac[1][1] + 4 * t2 * jac[2][1]) +
864 n8.
v * (4 * t4 * jac[1][1] + 4 * t2 * jac[3][1]) +
865 n9.
v * (4 * t4 * jac[2][1] + 4 * t3 * jac[3][1])) * invdet;
867 ey = -(n0.
v * (4 * t1 - 1) * jac[0][2] + n1.
v * (4 * t2 - 1) * jac[1][2] +
868 n2.
v * (4 * t3 - 1) * jac[2][2] + n3.
v * (4 * t4 - 1) * jac[3][2] +
869 n4.
v * (4 * t2 * jac[0][2] + 4 * t1 * jac[1][2]) +
870 n5.
v * (4 * t3 * jac[0][2] + 4 * t1 * jac[2][2]) +
871 n6.
v * (4 * t4 * jac[0][2] + 4 * t1 * jac[3][2]) +
872 n7.
v * (4 * t3 * jac[1][2] + 4 * t2 * jac[2][2]) +
873 n8.
v * (4 * t4 * jac[1][2] + 4 * t2 * jac[3][2]) +
874 n9.
v * (4 * t4 * jac[2][2] + 4 * t3 * jac[3][2])) * invdet;
876 ez = -(n0.
v * (4 * t1 - 1) * jac[0][3] + n1.
v * (4 * t2 - 1) * jac[1][3] +
877 n2.
v * (4 * t3 - 1) * jac[2][3] + n3.
v * (4 * t4 - 1) * jac[3][3] +
878 n4.
v * (4 * t2 * jac[0][3] + 4 * t1 * jac[1][3]) +
879 n5.
v * (4 * t3 * jac[0][3] + 4 * t1 * jac[2][3]) +
880 n6.
v * (4 * t4 * jac[0][3] + 4 * t1 * jac[3][3]) +
881 n7.
v * (4 * t3 * jac[1][3] + 4 * t2 * jac[2][3]) +
882 n8.
v * (4 * t4 * jac[1][3] + 4 * t2 * jac[3][3]) +
883 n9.
v * (4 * t4 * jac[2][3] + 4 * t3 * jac[3][3])) * invdet;
886 UnmapFields(ex, ey, ez, x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
891 std::cout <<
" Material " << element.
matmap <<
", drift flag "
902 const double zin,
double& wx,
double& wy,
903 double& wz,
const std::string& label) {
928 double x = xin, y = yin, z = zin;
931 bool xmirr, ymirr, zmirr;
932 double rcoordinate, rotation;
933 MapCoordinates(x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
938 double t1, t2, t3, t4, jac[4][4], det;
939 const int imap =
FindElement13(x, y, z, t1, t2, t3, t4, jac, det);
941 if (imap < 0)
return;
944 PrintElement(
"WeightingField", x, y, z, t1, t2, t3, t4, imap, 10, iw);
959 const double invdet = 1. / det;
960 wx = -(n0.
w[iw] * (4 * t1 - 1) * jac[0][1] +
961 n1.
w[iw] * (4 * t2 - 1) * jac[1][1] +
962 n2.
w[iw] * (4 * t3 - 1) * jac[2][1] +
963 n3.
w[iw] * (4 * t4 - 1) * jac[3][1] +
964 n4.
w[iw] * (4 * t2 * jac[0][1] + 4 * t1 * jac[1][1]) +
965 n5.
w[iw] * (4 * t3 * jac[0][1] + 4 * t1 * jac[2][1]) +
966 n6.
w[iw] * (4 * t4 * jac[0][1] + 4 * t1 * jac[3][1]) +
967 n7.
w[iw] * (4 * t3 * jac[1][1] + 4 * t2 * jac[2][1]) +
968 n8.
w[iw] * (4 * t4 * jac[1][1] + 4 * t2 * jac[3][1]) +
969 n9.
w[iw] * (4 * t4 * jac[2][1] + 4 * t3 * jac[3][1])) * invdet;
971 wy = -(n0.
w[iw] * (4 * t1 - 1) * jac[0][2] +
972 n1.
w[iw] * (4 * t2 - 1) * jac[1][2] +
973 n2.
w[iw] * (4 * t3 - 1) * jac[2][2] +
974 n3.
w[iw] * (4 * t4 - 1) * jac[3][2] +
975 n4.
w[iw] * (4 * t2 * jac[0][2] + 4 * t1 * jac[1][2]) +
976 n5.
w[iw] * (4 * t3 * jac[0][2] + 4 * t1 * jac[2][2]) +
977 n6.
w[iw] * (4 * t4 * jac[0][2] + 4 * t1 * jac[3][2]) +
978 n7.
w[iw] * (4 * t3 * jac[1][2] + 4 * t2 * jac[2][2]) +
979 n8.
w[iw] * (4 * t4 * jac[1][2] + 4 * t2 * jac[3][2]) +
980 n9.
w[iw] * (4 * t4 * jac[2][2] + 4 * t3 * jac[3][2])) * invdet;
982 wz = -(n0.
w[iw] * (4 * t1 - 1) * jac[0][3] +
983 n1.
w[iw] * (4 * t2 - 1) * jac[1][3] +
984 n2.
w[iw] * (4 * t3 - 1) * jac[2][3] +
985 n3.
w[iw] * (4 * t4 - 1) * jac[3][3] +
986 n4.
w[iw] * (4 * t2 * jac[0][3] + 4 * t1 * jac[1][3]) +
987 n5.
w[iw] * (4 * t3 * jac[0][3] + 4 * t1 * jac[2][3]) +
988 n6.
w[iw] * (4 * t4 * jac[0][3] + 4 * t1 * jac[3][3]) +
989 n7.
w[iw] * (4 * t3 * jac[1][3] + 4 * t2 * jac[2][3]) +
990 n8.
w[iw] * (4 * t4 * jac[1][3] + 4 * t2 * jac[3][3]) +
991 n9.
w[iw] * (4 * t4 * jac[2][3] + 4 * t3 * jac[3][3])) * invdet;
994 UnmapFields(wx, wy, wz, x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
999 const std::string& label) {
1016 if (!found)
return 0.;
1021 double x = xin, y = yin, z = zin;
1024 bool xmirr, ymirr, zmirr;
1025 double rcoordinate, rotation;
1026 MapCoordinates(x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
1031 double t1, t2, t3, t4, jac[4][4], det;
1032 const int imap =
FindElement13(x, y, z, t1, t2, t3, t4, jac, det);
1033 if (imap < 0)
return 0.;
1036 PrintElement(
"WeightingPotential", x, y, z, t1, t2, t3, t4, imap, 10, iw);
1050 return n0.
w[iw] * t1 * (2 * t1 - 1) + n1.
w[iw] * t2 * (2 * t2 - 1) +
1051 n2.
w[iw] * t3 * (2 * t3 - 1) + n3.
w[iw] * t4 * (2 * t4 - 1) +
1052 4 * n4.
w[iw] * t1 * t2 + 4 * n5.
w[iw] * t1 * t3 +
1053 4 * n6.
w[iw] * t1 * t4 + 4 * n7.
w[iw] * t2 * t3 +
1054 4 * n8.
w[iw] * t2 * t4 + 4 * n9.
w[iw] * t3 * t4;
1061 double x = xin, y = yin, z = zin;
1064 bool xmirr, ymirr, zmirr;
1065 double rcoordinate, rotation;
1066 MapCoordinates(x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
1071 std::cerr <<
" Field map not available for interpolation.\n";
1077 double t1, t2, t3, t4, jac[4][4], det;
1078 const int imap =
FindElement13(x, y, z, t1, t2, t3, t4, jac, det);
1082 std::cerr <<
" Point (" << x <<
", " << y <<
", " << z
1083 <<
") not in the mesh.\n";
1091 std::cerr <<
" Point (" << x <<
", " << y <<
", " << z <<
")"
1092 <<
" has out of range material number " << imap <<
".\n";
1098 PrintElement(
"GetMedium", x, y, z, t1, t2, t3, t4, imap, 10);
1107 if (i >=
elements.size())
return 0.;
1114 fabs((n3.
x - n0.
x) *
1115 ((n1.
y - n0.
y) * (n2.
z - n0.
z) - (n2.
y - n0.
y) * (n1.
z - n0.
z)) +
1117 ((n1.
z - n0.
z) * (n2.
x - n0.
x) - (n2.
z - n0.
z) * (n1.
x - n0.
x)) +
1118 (n3.
z - n0.
z) * ((n1.
x - n0.
x) * (n2.
y - n0.
y) -
1119 (n3.
x - n0.
x) * (n1.
y - n0.
y))) /
1135 for (
int j = 0; j < np - 1; ++j) {
1137 for (
int k = j + 1; k < np; ++k) {
1140 const double dx = nj.
x - nk.
x;
1141 const double dy = nj.
y - nk.
y;
1142 const double dz = nj.
z - nk.
z;
1143 const double dist = sqrt(dx * dx + dy * dy + dz * dz);
1147 if (dist < dmin) dmin = dist;
1148 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")
void GetAspectRatio(const unsigned int i, double &dmin, double &dmax)
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 WeightingPotential(const double x, const double y, const double z, const std::string &label)
double GetElementVolume(const unsigned int i)
void UpdatePeriodicity()
Verify periodicities.
void ElectricField(const double x, const double y, const double z, double &ex, double &ey, double &ez, Medium *&m, int &status)
bool SetWeightingField(std::string prnsol, std::string label)
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
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
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
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.