21 std::string nlist, std::string mplist,
22 std::string volt, std::string unit)
26 Initialise(header, elist, nlist, mplist, volt, unit);
30 std::string nlist, std::string mplist,
31 std::string volt, std::string unit) {
44 std::ifstream fheader;
45 fheader.open(header.c_str(), std::ios::in);
48 std::cerr <<
" Could not open header file " << header
54 bool readerror =
false;
55 bool readstop =
false;
59 fheader.getline(line, size,
'\n');
60 token = strtok(line,
" ");
62 token = strtok(NULL,
" ");
64 std::cout <<
"ComponentElmer::Initialise:\n";
66 <<
" elements from file " << header <<
".\n";
69 std::cerr <<
" Error reading file " << header <<
" (line " << il
81 fnodes.open(nlist.c_str(), std::ios::in);
84 std::cerr <<
" Could not open nodes file " << nlist <<
" for reading.\n";
89 if (strcmp(unit.c_str(),
"mum") == 0 || strcmp(unit.c_str(),
"micron") == 0 ||
90 strcmp(unit.c_str(),
"micrometer") == 0) {
92 }
else if (strcmp(unit.c_str(),
"mm") == 0 ||
93 strcmp(unit.c_str(),
"millimeter") == 0) {
95 }
else if (strcmp(unit.c_str(),
"cm") == 0 ||
96 strcmp(unit.c_str(),
"centimeter") == 0) {
98 }
else if (strcmp(unit.c_str(),
"m") == 0 ||
99 strcmp(unit.c_str(),
"meter") == 0) {
103 std::cerr <<
" Unknown length unit " << unit <<
".\n";
108 std::cout <<
"ComponentElmer::Initialise:\n";
109 std::cout <<
" Unit scaling factor = " << funit <<
".\n";
115 for (il = 0; il <
nNodes; il++) {
118 fnodes.getline(line, size,
'\n');
121 token = strtok(line,
" ");
122 token = strtok(NULL,
" ");
125 token = strtok(NULL,
" ");
126 double xnode =
ReadDouble(token, -1, readerror);
127 token = strtok(NULL,
" ");
128 double ynode =
ReadDouble(token, -1, readerror);
129 token = strtok(NULL,
" ");
130 double znode =
ReadDouble(token, -1, readerror);
133 std::cerr <<
" Error reading file " << nlist <<
" (line " << il
141 newNode.
x = xnode * funit;
142 newNode.
y = ynode * funit;
143 newNode.
z = znode * funit;
144 nodes.push_back(newNode);
152 fvolt.open(volt.c_str(), std::ios::in);
155 std::cerr <<
" Could not open result file " << volt <<
" for reading.\n";
162 while (!readstop && fvolt.getline(line, size,
'\n')) {
163 token = strtok(line,
" ");
164 if (strcmp(token,
"Perm:") == 0) readstop =
true;
171 std::cerr <<
" Error reading past header of potentials file " << volt
179 for (
int tl = 0; tl <
nNodes; tl++) {
180 fvolt.getline(line, size,
'\n');
185 for (
int tl = 0; tl <
nNodes; tl++) {
187 fvolt.getline(line, size,
'\n');
188 token = strtok(line,
" ");
192 std::cerr <<
" Error reading file " << volt <<
" (line " << il
206 std::ifstream fmplist;
207 fmplist.open(mplist.c_str(), std::ios::in);
208 if (fmplist.fail()) {
210 std::cerr <<
" Could not open result file " << mplist
211 <<
" for reading.\n";
215 fmplist.getline(line, size,
'\n');
216 token = strtok(line,
" ");
219 std::cerr <<
" Error reading number of materials from " << mplist
233 fmplist.getline(line, size,
'\n');
234 token = strtok(line,
" ");
236 token = strtok(NULL,
" ");
237 double dc =
ReadDouble(token, -1.0, readerror);
240 std::cerr <<
" Error reading file " << mplist <<
" (line " << il
248 std::cout <<
" Set material " << il - 2 <<
" of " <<
nMaterials
249 <<
" to eps " << dc <<
".\n";
258 for (
int imat = 0; imat <
nMaterials; ++imat) {
262 std::cerr <<
" Material " << imat
263 <<
" has been assigned a permittivity\n";
264 std::cerr <<
" equal to zero in " << mplist <<
".\n";
266 }
else if (iepsmin < 0 || epsmin >
materials[imat].eps) {
274 std::cerr <<
" No material with positive permittivity found \n";
275 std::cerr <<
" in material list " << mplist <<
".\n";
278 for (
int imat = 0; imat <
nMaterials; ++imat) {
279 if (imat == iepsmin) {
288 std::ifstream felems;
289 felems.open(elist.c_str(), std::ios::in);
292 std::cerr <<
" Could not open result file " << elist
293 <<
" for reading.\n";
303 felems.getline(line, size,
'\n');
306 token = strtok(line,
" ");
314 token = strtok(NULL,
" ");
316 token = strtok(NULL,
" ");
317 token = strtok(NULL,
" ");
319 token = strtok(NULL,
" ");
321 token = strtok(NULL,
" ");
323 token = strtok(NULL,
" ");
325 token = strtok(NULL,
" ");
327 token = strtok(NULL,
" ");
329 token = strtok(NULL,
" ");
331 token = strtok(NULL,
" ");
333 token = strtok(NULL,
" ");
335 token = strtok(NULL,
" ");
338 if (
debug && il < 10) {
339 std::cout <<
" Read nodes " << in0 <<
", " << in1 <<
", " << in2
340 <<
", " << in3 <<
", ... from element " << il + 1 <<
" of "
341 <<
nElements <<
" with mat " << imat <<
".\n";
347 std::cerr <<
" Error reading file " << elist <<
" (line " << il
357 std::cerr <<
" Out-of-range material number on file " << elist
358 <<
" (line " << il <<
").\n";
359 std::cerr <<
" Element: " << il <<
", material: " << imat <<
"\n";
360 std::cerr <<
" nodes: (" << in0 <<
", " << in1 <<
", " << in2 <<
", "
361 << in3 <<
", " << in4 <<
", " << in5 <<
", " << in6 <<
", "
362 << in7 <<
", " << in8 <<
", " << in9 <<
")\n";
367 std::cerr <<
" Element " << il <<
" in element list " << elist <<
"\n";
368 std::cerr <<
" uses material " << imat
369 <<
" which has not been assigned\n";
370 std::cerr <<
" a positive permittivity in material list " << mplist
376 if (in0 < 1 || in1 < 1 || in2 < 1 || in3 < 1 || in4 < 1 || in5 < 1 ||
377 in6 < 1 || in7 < 1 || in8 < 1 || in9 < 1) {
379 std::cerr <<
" Found a node number < 1 on file " << elist <<
" (line "
381 std::cerr <<
" Element: " << il <<
", material: " << imat <<
"\n";
382 std::cerr <<
" nodes: (" << in0 <<
", " << in1 <<
", " << in2 <<
", "
383 << in3 <<
", " << in4 <<
", " << in5 <<
", " << in6 <<
", "
384 << in7 <<
", " << in8 <<
", " << in9 <<
")\n";
387 if (in0 > highestnode) highestnode = in0;
388 if (in1 > highestnode) highestnode = in1;
389 if (in2 > highestnode) highestnode = in2;
390 if (in3 > highestnode) highestnode = in3;
391 if (in4 > highestnode) highestnode = in4;
392 if (in5 > highestnode) highestnode = in5;
393 if (in6 > highestnode) highestnode = in6;
394 if (in7 > highestnode) highestnode = in7;
395 if (in8 > highestnode) highestnode = in8;
396 if (in9 > highestnode) highestnode = in9;
399 if (in0 == in1 || in0 == in2 || in0 == in3 || in0 == in4 || in0 == in5 ||
400 in0 == in6 || in0 == in7 || in0 == in8 || in0 == in9 || in1 == in2 ||
401 in1 == in3 || in1 == in4 || in1 == in5 || in1 == in6 || in1 == in7 ||
402 in1 == in8 || in1 == in9 || in2 == in3 || in2 == in4 || in2 == in5 ||
403 in2 == in6 || in2 == in7 || in2 == in8 || in2 == in9 || in3 == in4 ||
404 in3 == in5 || in3 == in6 || in3 == in7 || in3 == in8 || in3 == in9 ||
405 in4 == in5 || in4 == in6 || in4 == in7 || in4 == in8 || in4 == in9 ||
406 in5 == in6 || in5 == in7 || in5 == in8 || in5 == in9 || in6 == in7 ||
407 in6 == in8 || in6 == in9 || in7 == in8 || in7 == in9 || in8 == in9) {
409 std::cerr <<
" Element " << il <<
" of file " << elist
410 <<
" is degenerate,\n";
411 std::cerr <<
" no such elements allowed in this type of map.\n";
421 newElement.
emap[0] = in0 - 1;
422 newElement.
emap[1] = in1 - 1;
423 newElement.
emap[2] = in2 - 1;
424 newElement.
emap[3] = in3 - 1;
425 newElement.
emap[4] = in4 - 1;
426 newElement.
emap[7] = in5 - 1;
427 newElement.
emap[5] = in6 - 1;
428 newElement.
emap[6] = in7 - 1;
429 newElement.
emap[8] = in8 - 1;
430 newElement.
emap[9] = in9 - 1;
443 <<
" Field map could not be read and can not be interpolated.\n";
447 std::cout <<
"ComponentElmer::Initialise:\n";
448 std::cout <<
" Finished.\n";
464 std::cerr <<
m_className <<
"::SetWeightingField:\n";
465 std::cerr <<
" No valid field map is present.\n";
466 std::cerr <<
" Weighting field cannot be added.\n";
474 std::ifstream fwvolt;
475 fwvolt.open(wvolt.c_str(), std::ios::in);
477 std::cerr <<
m_className <<
"::SetWeightingField:\n";
478 std::cerr <<
" Could not open potential file " << wvolt
479 <<
" for reading.\n";
480 std::cerr <<
" The file perhaps does not exist.\n";
496 for (
int j =
nNodes; j--;) {
500 std::cout <<
m_className <<
"::SetWeightingField:\n";
501 std::cout <<
" Replacing existing weighting field " << label <<
".\n";
507 const int size = 100;
510 bool readerror =
false;
511 bool readstop =
false;
515 while (!readstop && fwvolt.getline(line, size,
'\n')) {
516 token = strtok(line,
" ");
517 if (strcmp(token,
"Perm:") == 0) readstop =
true;
524 std::cerr <<
" Error reading past header of potentials file " << wvolt
532 for (
int tl = 0; tl <
nNodes; tl++) {
533 fwvolt.getline(line, size,
'\n');
538 for (
int tl = 0; tl <
nNodes; tl++) {
540 fwvolt.getline(line, size,
'\n');
541 token = strtok(line,
" ");
545 std::cerr <<
" Error reading file " << wvolt <<
" (line " << il
557 std::cout <<
m_className <<
"::SetWeightingField:\n";
558 std::cout <<
" Read potentials from file " << wvolt.c_str() <<
".\n";
563 std::cerr <<
m_className <<
"::SetWeightingField:\n";
564 std::cerr <<
" Field map could not be read "
565 <<
"and cannot be interpolated.\n";
572 const double z,
double& ex,
double& ey,
573 double& ez,
Medium*& m,
int& status) {
580 const double zin,
double& ex,
double& ey,
581 double& ez,
double& volt,
Medium*& m,
585 double x = xin, y = yin, z = zin;
588 bool xmirrored, ymirrored, zmirrored;
589 double rcoordinate, rotation;
590 MapCoordinates(x, y, z, xmirrored, ymirrored, zmirrored, rcoordinate,
594 ex = ey = ez = volt = 0.;
602 std::cerr <<
" Field map not available for interpolation.\n";
608 std::cerr <<
" Warnings have been issued for this field map.\n";
612 double t1, t2, t3, t4, jac[4][4], det;
617 std::cout <<
" Point (" << x <<
", " << y <<
", " << z
618 <<
" not in the mesh.\n";
626 std::cout <<
" Global: (" << x <<
", " << y <<
", " << z <<
"),\n";
627 std::cout <<
" Local: (" << t1 <<
", " << t2 <<
", " << t3 <<
", " << t4
628 <<
" in element " << imap <<
"\n";
630 <<
" Node x y z V\n";
631 for (
int i = 0; i < 10; i++) {
632 printf(
" %-5d %12g %12g %12g %12g\n",
elements[imap].emap[i],
649 ex = -(
nodes[
elements[imap].emap[0]].v * (4 * t1 - 1) * jac[0][1] +
654 (4 * t2 * jac[0][1] + 4 * t1 * jac[1][1]) +
656 (4 * t3 * jac[0][1] + 4 * t1 * jac[2][1]) +
658 (4 * t4 * jac[0][1] + 4 * t1 * jac[3][1]) +
660 (4 * t3 * jac[1][1] + 4 * t2 * jac[2][1]) +
662 (4 * t4 * jac[1][1] + 4 * t2 * jac[3][1]) +
664 (4 * t4 * jac[2][1] + 4 * t3 * jac[3][1])) /
666 ey = -(
nodes[
elements[imap].emap[0]].v * (4 * t1 - 1) * jac[0][2] +
671 (4 * t2 * jac[0][2] + 4 * t1 * jac[1][2]) +
673 (4 * t3 * jac[0][2] + 4 * t1 * jac[2][2]) +
675 (4 * t4 * jac[0][2] + 4 * t1 * jac[3][2]) +
677 (4 * t3 * jac[1][2] + 4 * t2 * jac[2][2]) +
679 (4 * t4 * jac[1][2] + 4 * t2 * jac[3][2]) +
681 (4 * t4 * jac[2][2] + 4 * t3 * jac[3][2])) /
683 ez = -(
nodes[
elements[imap].emap[0]].v * (4 * t1 - 1) * jac[0][3] +
688 (4 * t2 * jac[0][3] + 4 * t1 * jac[1][3]) +
690 (4 * t3 * jac[0][3] + 4 * t1 * jac[2][3]) +
692 (4 * t4 * jac[0][3] + 4 * t1 * jac[3][3]) +
694 (4 * t3 * jac[1][3] + 4 * t2 * jac[2][3]) +
696 (4 * t4 * jac[1][3] + 4 * t2 * jac[3][3]) +
698 (4 * t4 * jac[2][3] + 4 * t3 * jac[3][3])) /
702 UnmapFields(ex, ey, ez, x, y, z, xmirrored, ymirrored, zmirrored, rcoordinate,
708 std::cout <<
" Material " <<
elements[imap].matmap <<
", drift flag "
721 const double zin,
double& wx,
double& wy,
722 double& wz,
const std::string label) {
747 double x = xin, y = yin, z = zin;
750 bool xmirrored, ymirrored, zmirrored;
751 double rcoordinate, rotation;
752 MapCoordinates(x, y, z, xmirrored, ymirrored, zmirrored, rcoordinate,
757 std::cerr <<
" Warnings have been issued for this field map.\n";
761 double t1, t2, t3, t4, jac[4][4], det;
764 if (imap < 0)
return;
768 std::cout <<
" Global: (" << x <<
", " << y <<
", " << z <<
"),\n";
769 std::cout <<
" Local: (" << t1 <<
", " << t2 <<
", " << t3 <<
", " << t4
770 <<
" in element " << imap <<
"\n";
772 <<
" Node x y z V\n";
773 for (
int i = 0; i < 10; i++) {
774 printf(
" %-5d %12g %12g %12g %12g\n",
elements[imap].emap[i],
782 wx = -(
nodes[
elements[imap].emap[0]].w[iw] * (4 * t1 - 1) * jac[0][1] +
783 nodes[
elements[imap].emap[1]].w[iw] * (4 * t2 - 1) * jac[1][1] +
784 nodes[
elements[imap].emap[2]].w[iw] * (4 * t3 - 1) * jac[2][1] +
785 nodes[
elements[imap].emap[3]].w[iw] * (4 * t4 - 1) * jac[3][1] +
787 (4 * t2 * jac[0][1] + 4 * t1 * jac[1][1]) +
789 (4 * t3 * jac[0][1] + 4 * t1 * jac[2][1]) +
791 (4 * t4 * jac[0][1] + 4 * t1 * jac[3][1]) +
793 (4 * t3 * jac[1][1] + 4 * t2 * jac[2][1]) +
795 (4 * t4 * jac[1][1] + 4 * t2 * jac[3][1]) +
797 (4 * t4 * jac[2][1] + 4 * t3 * jac[3][1])) /
800 wy = -(
nodes[
elements[imap].emap[0]].w[iw] * (4 * t1 - 1) * jac[0][2] +
801 nodes[
elements[imap].emap[1]].w[iw] * (4 * t2 - 1) * jac[1][2] +
802 nodes[
elements[imap].emap[2]].w[iw] * (4 * t3 - 1) * jac[2][2] +
803 nodes[
elements[imap].emap[3]].w[iw] * (4 * t4 - 1) * jac[3][2] +
805 (4 * t2 * jac[0][2] + 4 * t1 * jac[1][2]) +
807 (4 * t3 * jac[0][2] + 4 * t1 * jac[2][2]) +
809 (4 * t4 * jac[0][2] + 4 * t1 * jac[3][2]) +
811 (4 * t3 * jac[1][2] + 4 * t2 * jac[2][2]) +
813 (4 * t4 * jac[1][2] + 4 * t2 * jac[3][2]) +
815 (4 * t4 * jac[2][2] + 4 * t3 * jac[3][2])) /
818 wz = -(
nodes[
elements[imap].emap[0]].w[iw] * (4 * t1 - 1) * jac[0][3] +
819 nodes[
elements[imap].emap[1]].w[iw] * (4 * t2 - 1) * jac[1][3] +
820 nodes[
elements[imap].emap[2]].w[iw] * (4 * t3 - 1) * jac[2][3] +
821 nodes[
elements[imap].emap[3]].w[iw] * (4 * t4 - 1) * jac[3][3] +
823 (4 * t2 * jac[0][3] + 4 * t1 * jac[1][3]) +
825 (4 * t3 * jac[0][3] + 4 * t1 * jac[2][3]) +
827 (4 * t4 * jac[0][3] + 4 * t1 * jac[3][3]) +
829 (4 * t3 * jac[1][3] + 4 * t2 * jac[2][3]) +
831 (4 * t4 * jac[1][3] + 4 * t2 * jac[3][3]) +
833 (4 * t4 * jac[2][3] + 4 * t3 * jac[3][3])) /
837 UnmapFields(wx, wy, wz, x, y, z, xmirrored, ymirrored, zmirrored, rcoordinate,
843 const std::string label) {
846 if (!
ready)
return 0.;
860 if (!found)
return 0.;
865 double x = xin, y = yin, z = zin;
868 bool xmirrored, ymirrored, zmirrored;
869 double rcoordinate, rotation;
870 MapCoordinates(x, y, z, xmirrored, ymirrored, zmirrored, rcoordinate,
874 std::cerr <<
m_className <<
"::WeightingPotential:\n";
875 std::cerr <<
" Warnings have been issued for this field map.\n";
879 double t1, t2, t3, t4, jac[4][4], det;
881 if (imap < 0)
return 0.;
884 std::cout <<
m_className <<
"::WeightingPotential:\n";
885 std::cout <<
" Global: (" << x <<
", " << y <<
", " << z <<
"),\n";
886 std::cout <<
" Local: (" << t1 <<
", " << t2 <<
", " << t3 <<
", " << t4
887 <<
" in element " << imap <<
"\n";
889 <<
" Node x y z V\n";
890 for (
int i = 0; i < 10; i++) {
891 printf(
" %-5d %12g %12g %12g %12g\n",
elements[imap].emap[i],
898 return nodes[
elements[imap].emap[0]].w[iw] * t1 * (2 * t1 - 1) +
914 double x = xin, y = yin, z = zin;
917 bool xmirrored, ymirrored, zmirrored;
918 double rcoordinate, rotation;
919 MapCoordinates(x, y, z, xmirrored, ymirrored, zmirrored, rcoordinate,
925 std::cerr <<
" Field map not available for interpolation.\n";
930 std::cerr <<
" Warnings have been issued for this field map.\n";
934 double t1, t2, t3, t4, jac[4][4], det;
939 std::cout <<
" Point (" << x <<
", " << y <<
", " << z
940 <<
") not in the mesh.\n";
947 std::cerr <<
" Point (" << x <<
", " << y
948 <<
") has out of range material number " << imap <<
".\n";
955 std::cout <<
" Global: (" << x <<
", " << y <<
", " << z <<
"),\n";
956 std::cout <<
" Local: (" << t1 <<
", " << t2 <<
", " << t3 <<
", " << t4
957 <<
" in element " << imap <<
"\n";
959 <<
" Node x y z V\n";
960 for (
int ii = 0; ii < 10; ++ii) {
961 printf(
" %-5d %12g %12g %12g %12g\n",
elements[imap].emap[ii],
1012 for (
int j = 0; j < np - 1; ++j) {
1013 for (
int k = j + 1; k < np; ++k) {
1015 const double dist =
sqrt(
1023 if (dist < dmin) dmin = dist;
1024 if (dist > dmax) dmax = dist;
DoubleAc pow(const DoubleAc &f, double p)
DoubleAc sqrt(const DoubleAc &f)
DoubleAc fabs(const DoubleAc &f)
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)
double WeightingPotential(const double x, const double y, const double z, const std::string label)
void GetAspectRatio(const int i, double &dmin, double &dmax)
bool Initialise(std::string header="mesh.header", std::string elist="mesh.elements", std::string nlist="mesh.nodes", std::string mplist="dielectrics.dat", std::string volt="out.result", std::string unit="cm")
void WeightingField(const double x, const double y, const double z, double &wx, double &wy, double &wz, const std::string label)
double GetElementVolume(const int i)
Medium * GetMedium(const double &x, const double &y, const double &z)
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
std::vector< material > materials
void UnmapFields(double &ex, double &ey, double &ez, double &xpos, double &ypos, double &zpos, bool &xmirrored, bool &ymirrored, bool &zmirrored, double &rcoordinate, double &rotation)
int ReadInteger(char *token, int def, bool &error)
std::vector< element > elements
std::vector< node > nodes
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)
std::vector< std::string > wfields