27 disableFieldComponent[0] =
false;
28 disableFieldComponent[1] =
false;
29 disableFieldComponent[2] =
false;
34 std::string mplist, std::string prnsol,
47 std::ifstream fmplist;
48 fmplist.open(mplist.c_str(), std::ios::in);
50 std::cerr <<
m_className <<
"::Initialise:" << std::endl;
51 std::cerr <<
" Could not open material file " << mplist
52 <<
" for reading." << std::endl,
53 std::cerr <<
" The file perhaps does not exist." << std::endl;
60 bool readerror =
false;
61 while (fmplist.getline(line, size,
'\n')) {
65 token = strtok(line,
" ");
67 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
68 int(token[0]) == 10 ||
int(token[0]) == 13)
72 if (strcmp(token,
"Materials") == 0) {
73 token = strtok(NULL,
" ");
76 std::cerr <<
m_className <<
"::Initialise:" << std::endl;
77 std::cerr <<
" Error reading file " << mplist <<
" (line " << il
90 std::cout <<
m_className <<
"::Initialise:" << std::endl;
91 std::cout <<
" Number of materials: " <<
m_nMaterials <<
""
94 }
else if (strcmp(token,
"Material") == 0) {
95 token = strtok(NULL,
" ");
98 std::cerr <<
m_className <<
"::Initialise:" << std::endl;
99 std::cerr <<
" Error reading file " << mplist <<
" (line " << il
105 std::cerr <<
m_className <<
"::Initialise:" << std::endl;
106 std::cerr <<
" Found out-of-range material index " << imat <<
"in"
108 std::cerr <<
" material properties file " << mplist <<
"."
112 token = strtok(NULL,
" ");
114 if (strcmp(token,
"PERX") == 0) {
116 }
else if (strcmp(token,
"RSVX") == 0) {
119 std::cerr <<
m_className <<
"::Initialise:" << std::endl;
120 std::cerr <<
" Found unknown material property flag " << token
122 std::cerr <<
" on material properties file " << mplist <<
"(line "
123 << il <<
")." << std::endl;
126 token = strtok(NULL,
" ");
129 }
else if (itype == 2) {
131 token = strtok(NULL,
" ");
132 if (strcmp(token,
"PERX") != 0) {
133 std::cerr <<
m_className <<
"::Initialise:" << std::endl;
134 std::cerr <<
" Found unknown material property falg " << token
136 std::cerr <<
" on material file " << mplist <<
" (material "
140 token = strtok(NULL,
" ");
145 std::cerr <<
m_className <<
"::Initialise:" << std::endl;
146 std::cerr <<
" Error reading file " << mplist <<
"(line " << il
147 <<
")." << std::endl;
153 std::cout <<
m_className <<
"::Initialise:" << std::endl;
154 std::cout <<
" Read material properties for material "
155 << (imat - 1) <<
"" << std::endl;
157 std::cout <<
" eps = " <<
materials[imat - 1].eps
158 <<
" ohm = " <<
materials[imat - 1].ohm <<
""
161 std::cout <<
" eps = " <<
materials[imat - 1].eps <<
""
172 unsigned int iepsmin = 0;
173 for (
unsigned int imat = 0; imat <
m_nMaterials; ++imat) {
176 std::cout <<
m_className <<
"::Initialise:" << std::endl;
177 std::cout <<
" Material " << imat
178 <<
" has been assigned a permittivity" << std::endl;
179 std::cout <<
" equal to zero in " << mplist <<
"." << std::endl;
181 }
else if (epsmin < 0. || epsmin >
materials[imat].eps) {
187 std::cerr <<
m_className <<
"::Initialise:" << std::endl;
188 std::cerr <<
" No material with positive permittivity found in"
190 std::cerr <<
" material list " << mplist.c_str() <<
"." << std::endl;
193 for (
unsigned int imat = 0; imat <
m_nMaterials; ++imat) {
194 if (imat == iepsmin) {
202 std::cout <<
m_className <<
"::Initialise:" << std::endl;
203 std::cout <<
" Read properties of " <<
m_nMaterials <<
" materials"
205 std::cout <<
" from file " << mplist <<
"." << std::endl;
210 if (strcmp(unit.c_str(),
"mum") == 0 || strcmp(unit.c_str(),
"micron") == 0 ||
211 strcmp(unit.c_str(),
"micrometer") == 0) {
213 }
else if (strcmp(unit.c_str(),
"mm") == 0 ||
214 strcmp(unit.c_str(),
"millimeter") == 0) {
216 }
else if (strcmp(unit.c_str(),
"cm") == 0 ||
217 strcmp(unit.c_str(),
"centimeter") == 0) {
219 }
else if (strcmp(unit.c_str(),
"m") == 0 ||
220 strcmp(unit.c_str(),
"meter") == 0) {
223 std::cerr <<
m_className <<
"::Initialise:" << std::endl;
224 std::cerr <<
" Unknown length unit " << unit <<
"." << std::endl;
229 std::cout <<
m_className <<
"::Initialise:" << std::endl;
230 std::cout <<
" Unit scaling factor = " << funit <<
"." << std::endl;
234 std::ifstream fnlist;
235 fnlist.open(nlist.c_str(), std::ios::in);
237 std::cerr <<
m_className <<
"::Initialise:" << std::endl;
238 std::cerr <<
" Could not open nodes file " << nlist <<
" for reading."
240 std::cerr <<
" The file perhaps does not exist." << std::endl;
246 int xlines = 0, ylines = 0, zlines = 0;
249 while (fnlist.getline(line, size,
'\n')) {
254 token = strtok(line,
" ");
256 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
257 int(token[0]) == 10 ||
int(token[0]) == 13)
260 if (strcmp(token,
"xmax") == 0) {
261 token = strtok(NULL,
" ");
263 token = strtok(NULL,
" ");
264 token = strtok(NULL,
" ");
266 token = strtok(NULL,
" ");
267 token = strtok(NULL,
" ");
269 if (readerror)
break;
272 if (strcmp(token,
"x-lines\n") == 0 || strcmp(token,
"x-lines") == 0) {
275 std::cout <<
m_className <<
"::Initialise:" << std::endl;
276 std::cout <<
" Reading x-lines from file " << nlist <<
"."
281 if (strcmp(token,
"y-lines\n") == 0 || strcmp(token,
"y-lines") == 0) {
284 std::cout <<
m_className <<
"::Initialise:" << std::endl;
285 std::cout <<
" Reading y-lines from file " << nlist <<
"."
290 if (strcmp(token,
"z-lines\n") == 0 || strcmp(token,
"z-lines") == 0) {
293 std::cout <<
m_className <<
"::Initialise:" << std::endl;
294 std::cout <<
" Reading z-lines from file " << nlist <<
"."
301 m_xlines.push_back(line_tmp * funit);
302 else if (lines_type == 2)
303 m_ylines.push_back(line_tmp * funit);
304 else if (lines_type == 3)
305 m_zlines.push_back(line_tmp * funit);
307 std::cerr <<
m_className <<
"::Initialise:" << std::endl;
308 std::cerr <<
" Line type was not set in " << nlist <<
" (line " << il
309 <<
", token = " << token <<
")." << std::endl;
310 std::cerr <<
" Maybe it is in the wrong format" << std::endl;
311 std::cerr <<
" e.g. missing tailing space after x-lines." << std::endl;
315 if (readerror)
break;
319 std::cerr <<
m_className <<
"::Initialise:" << std::endl;
320 std::cerr <<
" Error reading file " << nlist <<
" (line " << il <<
")."
329 if ((
unsigned)xlines == m_xlines.size() &&
330 (
unsigned)ylines == m_ylines.size() &&
331 (
unsigned)zlines == m_zlines.size()) {
332 std::cout <<
m_className <<
"::Initialise:" << std::endl;
333 std::cout <<
" Found in file " << nlist <<
"\n " << xlines
334 <<
" x-lines\n " << ylines <<
" y-lines\n " << zlines
335 <<
" z-lines" << std::endl;
337 std::cerr <<
m_className <<
"::Initialise:" << std::endl;
338 std::cerr <<
" There should be " << xlines <<
" x-lines, " << ylines
339 <<
" y-lines and " << zlines <<
" z-lines in file " << nlist
340 <<
" but I found :\n " << m_xlines.size() <<
" x-lines, "
341 << m_ylines.size() <<
" x-lines, " << m_zlines.size()
342 <<
" z-lines." << std::endl;
344 m_nx = m_xlines.size();
345 m_ny = m_ylines.size();
346 m_nz = m_zlines.size();
347 nNodes = m_nx * m_ny * m_nz;
348 nElements = (m_nx - 1) * (m_ny - 1) * (m_nz - 1);
351 std::cout <<
m_className <<
"::Initialise:" << std::endl;
352 std::cout <<
" Read " <<
nNodes <<
" nodes from file " << nlist <<
"."
357 std::ifstream felist;
358 felist.open(elist.c_str(), std::ios::in);
360 std::cerr <<
m_className <<
"::Initialise:" << std::endl;
361 std::cerr <<
" Could not open element file " << elist <<
" for reading."
363 std::cerr <<
" The file perhaps does not exist." << std::endl;
369 while (felist.getline(line, size,
'\n')) {
374 token = strtok(line,
" ");
376 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
377 int(token[0]) == 10 ||
int(token[0]) == 13 ||
378 strcmp(token,
"LIST") == 0 || strcmp(token,
"ELEM") == 0)
382 token = strtok(NULL,
" ");
383 unsigned char imat = atoi(token);
385 std::vector<int> node_nb;
389 m_elementMaterial.at(ielem) = (imat - 1);
391 std::cerr <<
m_className <<
"::Initialise:" << std::endl;
392 std::cerr <<
" Error reading file " << elist <<
" (line " << il <<
")."
394 std::cerr <<
" The element index (" << ielem
395 <<
") is not in the expected range: 0 - " <<
nElements
402 std::cerr <<
m_className <<
"::Initialise:" << std::endl;
403 std::cerr <<
" Out-of-range material number on file " << elist
404 <<
" (line " << il <<
")." << std::endl;
405 std::cerr <<
" Element: " << ielem <<
", material: " << imat
410 std::cerr <<
m_className <<
"::Initialise:" << std::endl;
411 std::cerr <<
" Element " << ielem <<
" in element list " << elist
412 <<
" uses material " << imat <<
" which" << std::endl;
413 std::cerr <<
" has not been assigned a positive permittivity"
415 std::cerr <<
" in material list " << mplist <<
"." << std::endl;
422 std::cout <<
m_className <<
"::Initialise:" << std::endl;
423 std::cout <<
" Read " <<
nElements <<
" elements from file " << elist
427 m_potential.resize(
nNodes);
428 std::ifstream fprnsol;
429 fprnsol.open(prnsol.c_str(), std::ios::in);
430 if (fprnsol.fail()) {
431 std::cerr <<
m_className <<
"::Initialise:" << std::endl;
432 std::cerr <<
" Could not open potential file " << prnsol
433 <<
" for reading." << std::endl;
434 std::cerr <<
" The file perhaps does not exist." << std::endl;
441 while (fprnsol.getline(line, size,
'\n')) {
445 token = strtok(line,
" ");
447 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
448 int(token[0]) == 10 ||
int(token[0]) == 13 || strcmp(token,
"Max") == 0)
453 token = strtok(NULL,
" ");
454 double volt =
ReadDouble(token, -1, readerror);
457 m_potential.at(inode - 1) = volt;
460 std::cerr <<
m_className <<
"::Initialise:" << std::endl;
461 std::cerr <<
" Error reading file " << prnsol <<
" (line " << il
462 <<
")." << std::endl;
463 std::cerr <<
" The node index (" << inode - 1
464 <<
") is not in the expected range: 0 - " <<
nNodes
472 std::cout <<
m_className <<
"::Initialise:" << std::endl;
473 std::cout <<
" Read " << nread <<
"/" <<
nNodes
474 <<
" (expected) potentials from file " << prnsol <<
"."
478 std::cerr <<
m_className <<
"::Initialise:" << std::endl;
479 std::cerr <<
" Number of nodes read (" << nread <<
") on potential file "
480 << prnsol <<
" does not" << std::endl;
481 std::cerr <<
" match the node list (" <<
nNodes <<
")." << std::endl;
488 std::cerr <<
m_className <<
"::Initialise:" << std::endl;
489 std::cerr <<
" Field map could not be read and cannot be interpolated."
507 if (strcmp(unit.c_str(),
"mum") == 0 || strcmp(unit.c_str(),
"micron") == 0 ||
508 strcmp(unit.c_str(),
"micrometer") == 0) {
510 }
else if (strcmp(unit.c_str(),
"mm") == 0 ||
511 strcmp(unit.c_str(),
"millimeter") == 0) {
513 }
else if (strcmp(unit.c_str(),
"cm") == 0 ||
514 strcmp(unit.c_str(),
"centimeter") == 0) {
516 }
else if (strcmp(unit.c_str(),
"m") == 0 ||
517 strcmp(unit.c_str(),
"meter") == 0) {
520 std::cerr <<
m_className <<
"::Initialise:" << std::endl;
521 std::cerr <<
" Unknown length unit " << unit <<
"." << std::endl;
526 std::cout <<
m_className <<
"::Initialise:" << std::endl;
527 std::cout <<
" Unit scaling factor = " << funit <<
"." << std::endl;
529 FILE* f = fopen(dataFile.c_str(),
"rb");
531 std::cerr <<
m_className <<
"::Initilise:" << std::endl;
532 std::cerr <<
" Could not open file:" << dataFile.c_str() << std::endl;
536 struct stat fileStatus;
537 stat(dataFile.c_str(), &fileStatus);
538 int fileSize = fileStatus.st_size;
540 if (fileSize < 1000) {
542 std::cerr <<
m_className <<
"::Initilise:" << std::endl;
543 std::cerr <<
" Error. The file is extremely short and does not seem to "
544 "contain a header or data."
549 char header[headerSize];
551 result = fread(header,
sizeof(
char), headerSize, f);
552 if (result != headerSize) {
553 fputs(
"Reading error while reading header.", stderr);
557 int nx = 0, ny = 0, nz = 0;
558 int m_x = 0, m_y = 0, m_z = 0;
559 int n_s = 0, n_x = 0, n_y = 0, n_z = 0;
560 int e_s = 0, e_x = 0, e_y = 0, e_z = 0;
564 filled = std::sscanf(
566 (std::string(
"mesh_nx=%d mesh_ny=%d mesh_nz=%d\n") +
567 std::string(
"mesh_xlines=%d mesh_ylines=%d mesh_zlines=%d\n") +
568 std::string(
"nodes_scalar=%d nodes_vector_x=%d nodes_vector_y=%d "
569 "nodes_vector_z=%d\n") +
570 std::string(
"elements_scalar=%d elements_vector_x=%d "
571 "elements_vector_y=%d elements_vector_z=%d\n") +
572 std::string(
"elements_material=%d\n") + std::string(
"n_materials=%d\n"))
574 &nx, &ny, &nz, &m_x, &m_y, &m_z, &n_s, &n_x, &n_y, &n_z, &e_s, &e_x, &e_y,
578 std::cerr <<
m_className <<
"::Initilise:" << std::endl;
579 std::cerr <<
" Error. File header of " << dataFile.c_str()
580 <<
" is broken." << std::endl;
583 if (fileSize < 1000 + (m_x + m_y + m_z) * 8 +
584 (n_s + n_x + n_y + n_z + e_s + e_x + e_y + e_z) * 4 +
590 std::cout <<
m_className <<
"::Initialise:" << std::endl;
591 std::cout <<
" Information about the data stored in the given binary file:"
593 std::cout <<
" Mesh (nx): " << nx <<
"\t Mesh (ny): " << ny
594 <<
"\t Mesh (nz): " << nz << std::endl;
595 std::cout <<
" Mesh (x_lines): " << m_x <<
"\t Mesh (y_lines): " << m_y
596 <<
"\t Mesh (z_lines): " << m_z << std::endl;
597 std::cout <<
" Nodes (scalar): " << n_s <<
"\t Nodes (x): " << n_x
598 <<
"\t Nodes (y): " << n_y <<
"\t Nodes (z): " << n_z
600 std::cout <<
" Field (scalar): " << e_s <<
"\t Field (x): " << e_x
601 <<
"\t Field (y): " << e_y <<
"\t Field (z): " << e_z
603 std::cout <<
" Elements: " << e_m <<
"\t Materials: " <<
m_nMaterials
609 nNodes = m_nx * m_ny * m_nz;
610 nElements = (m_nx - 1) * (m_ny - 1) * (m_nz - 1);
612 m_xlines.resize(m_x);
613 m_ylines.resize(m_y);
614 m_zlines.resize(m_z);
615 m_potential.resize(n_s);
616 m_elementMaterial.resize(e_m);
619 result = fread(m_xlines.data(),
sizeof(
double), m_xlines.size(), f);
620 if (result != m_xlines.size()) {
621 fputs(
"Reading error while reading xlines.", stderr);
623 }
else if (result == 0) {
624 fputs(
"No xlines are stored in the data file.", stderr);
627 result = fread(m_ylines.data(),
sizeof(
double), m_ylines.size(), f);
628 if (result != m_ylines.size()) {
629 fputs(
"Reading error while reading ylines", stderr);
631 }
else if (result == 0) {
632 fputs(
"No ylines are stored in the data file.", stderr);
635 result = fread(m_zlines.data(),
sizeof(
double), m_zlines.size(), f);
636 if (result != m_zlines.size()) {
637 fputs(
"Reading error while reasing zlines", stderr);
639 }
else if (result == 0) {
640 fputs(
"No zlines are stored in the data file.", stderr);
643 result = fread(m_potential.data(),
sizeof(
float), m_potential.size(), f);
644 if (result != m_potential.size()) {
645 fputs(
"Reading error while reading nodes.", stderr);
647 }
else if (result == 0) {
648 fputs(
"No potentials are stored in the data file.", stderr);
651 fseek(f, e_s *
sizeof(
float), SEEK_CUR);
653 result = fread(m_elementMaterial.data(),
sizeof(
unsigned char),
654 m_elementMaterial.size(), f);
655 if (result != m_elementMaterial.size()) {
656 fputs(
"Reading error while reading element material", stderr);
659 std::stringstream st;
665 for (
unsigned int i = 0; i <
materials.size(); i++) {
667 result = fread(&(
id),
sizeof(
float), 1, f);
669 fputs(
"Input error while reading material id.", stderr);
672 unsigned int description_size = 0;
673 result = fread(&(description_size),
sizeof(
int), 1, f);
675 fputs(
"Input error while reading material description size.", stderr);
678 char* c =
new char[description_size];
679 result = fread(c,
sizeof(
char), description_size, f);
680 if (result != description_size) {
681 fputs(
"Input error while reading material description.", stderr);
684 std::string name = c;
685 st <<
" Read material: " << name.c_str();
686 if (name.compare(
"gas") == 0) {
687 st <<
" (considered as drift medium)";
694 result = fread(&(tmp_eps),
sizeof(
float), 1, f);
697 fputs(
"Reading error while reading eps.", stderr);
709 st <<
"; eps is: " <<
materials.at(
id).eps <<
712 "\t id is: " <<
id << std::endl;
714 fseek(f, 2 *
sizeof(
float), SEEK_CUR);
718 std::cout << st.str();
721 std::cout <<
"Material id: " << std::distance(
materials.begin(), it)
722 <<
" \t driftable: " << (*it).driftmedium << std::endl;
726 std::sort(m_xlines.begin(), m_xlines.end());
727 std::sort(m_ylines.begin(), m_ylines.end());
728 std::sort(m_zlines.begin(), m_zlines.end());
730 std::transform(m_xlines.begin(), m_xlines.end(), m_xlines.begin(), [funit](
double x) { return x * funit;});
731 std::transform(m_ylines.begin(), m_ylines.end(), m_ylines.begin(), [funit](
double x) { return x * funit;});
732 std::transform(m_zlines.begin(), m_zlines.end(), m_zlines.begin(), [funit](
double x) { return x * funit;});
735 std::cout <<
m_className <<
"::Initialise" << std::endl;
736 std::cout <<
" x range: " << *(m_xlines.begin()) <<
" - "
737 << *(m_xlines.end() - 1) << std::endl;
738 std::cout <<
" y range: " << *(m_ylines.begin()) <<
" - "
739 << *(m_ylines.end() - 1) << std::endl;
740 std::cout <<
" z range: " << *(m_zlines.begin()) <<
" - "
741 << *(m_zlines.end() - 1) << std::endl;
747 std::cerr <<
m_className <<
"::Initialise:" << std::endl;
748 std::cerr <<
" Field map could not be read and cannot be interpolated."
760 std::vector<float> potentials(
nNodes);
762 std::cerr <<
m_className <<
"::SetWeightingField:" << std::endl;
763 std::cerr <<
" No valid field map is present." << std::endl;
764 std::cerr <<
" Weighting field cannot be added." << std::endl;
769 std::ifstream fprnsol;
770 fprnsol.open(prnsol.c_str(), std::ios::in);
771 if (fprnsol.fail()) {
772 std::cerr <<
m_className <<
"::SetWeightingField:" << std::endl;
773 std::cerr <<
" Could not open potential file " << prnsol
774 <<
" for reading." << std::endl;
775 std::cerr <<
" The file perhaps does not exist." << std::endl;
779 auto it = m_weightingFields.find(label);
780 if (it != m_weightingFields.end()) {
781 std::cout <<
m_className <<
"::SetWeightingField:" << std::endl;
782 std::cout <<
" Replacing existing weighting field " << label <<
"."
789 if (std::distance(m_weightingFields.begin(), it) !=
792 std::cerr <<
m_className <<
"::SetWeightingField:" << std::endl;
793 std::cerr <<
" Indexes of the weighting fields and the weighting field "
794 "counter are not equal!"
798 unsigned int iField = std::distance(m_weightingFields.begin(), it);
803 std::cout <<
m_className <<
"::SetWeightingField:" << std::endl;
804 std::cout <<
" Reading weighting field from binary file:"
805 << prnsol.c_str() << std::endl;
806 FILE* f = fopen(prnsol.c_str(),
"rb");
808 std::cerr <<
m_className <<
"::Initilise:" << std::endl;
809 std::cerr <<
" Could not open file:" << prnsol.c_str() << std::endl;
813 struct stat fileStatus;
814 stat(prnsol.c_str(), &fileStatus);
815 int fileSize = fileStatus.st_size;
817 if (fileSize < 1000) {
819 std::cerr <<
m_className <<
"::SetWeightingField:" << std::endl;
820 std::cerr <<
" Error. The file is extremely short and does not seem "
821 "to contain a header or data."
826 char header[headerSize];
828 result = fread(header,
sizeof(
char), headerSize, f);
829 if (result != headerSize) {
830 fputs(
"Reading error while reading header.", stderr);
834 int nx = 0, ny = 0, nz = 0;
835 int m_x = 0, m_y = 0, m_z = 0;
836 int n_x = 0, n_y = 0, n_z = 0;
837 int e_s = 0, e_x = 0, e_y = 0, e_z = 0;
841 filled = std::sscanf(
843 (std::string(
"mesh_nx=%d mesh_ny=%d mesh_nz=%d\n") +
844 std::string(
"mesh_xlines=%d mesh_ylines=%d mesh_zlines=%d\n") +
845 std::string(
"nodes_scalar=%d nodes_vector_x=%d nodes_vector_y=%d "
846 "nodes_vector_z=%d\n") +
847 std::string(
"elements_scalar=%d elements_vector_x=%d "
848 "elements_vector_y=%d elements_vector_z=%d\n") +
849 std::string(
"elements_material=%d\n") +
850 std::string(
"n_materials=%d\n"))
852 &nx, &ny, &nz, &m_x, &m_y, &m_z, &nread, &n_x, &n_y, &n_z, &e_s, &e_x,
856 std::cerr <<
m_className <<
"::SetWeightingField:" << std::endl;
857 std::cerr <<
" Error. File header of " << prnsol.c_str()
858 <<
" is broken." << std::endl;
861 if (fileSize < 1000 + (m_x + m_y + m_z) * 8 +
862 (nread + n_x + n_y + n_z + e_s + e_x + e_y + e_z) * 4 +
868 std::cout <<
m_className <<
"::SetWeightingField:" << std::endl;
870 <<
" Information about the data stored in the given binary file:"
872 std::cout <<
" Mesh (nx): " << nx <<
"\t Mesh (ny): " << ny
873 <<
"\t Mesh (nz): " << nz << std::endl;
874 std::cout <<
" Mesh (x_lines): " << m_x <<
"\t Mesh (y_lines): " << m_y
875 <<
"\t Mesh (z_lines): " << m_z << std::endl;
876 std::cout <<
" Nodes (scalar): " << nread <<
"\t Nodes (x): " << n_x
877 <<
"\t Nodes (y): " << n_y <<
"\t Nodes (z): " << n_z
879 std::cout <<
" Field (scalar): " << e_s <<
"\t Field (x): " << e_x
880 <<
"\t Field (y): " << e_y <<
"\t Field (z): " << e_z
882 std::cout <<
" Elements: " << e_m <<
"\t Materials: " <<
m_nMaterials
886 fseek(f, m_x *
sizeof(
double), SEEK_CUR);
887 fseek(f, m_y *
sizeof(
double), SEEK_CUR);
888 fseek(f, m_z *
sizeof(
double), SEEK_CUR);
889 result = fread(potentials.data(),
sizeof(
float), potentials.size(), f);
890 if (result != potentials.size()) {
891 fputs(
"Reading error while reading nodes.", stderr);
893 }
else if (result == 0) {
894 fputs(
"No wighting potentials are stored in the data file.", stderr);
899 std::cout <<
m_className <<
"::SetWeightingField:" << std::endl;
900 std::cout <<
" Reading weighting field from text file:" << prnsol.c_str()
903 const int size = 100;
909 bool readerror =
false;
910 while (fprnsol.getline(line, size,
'\n')) {
914 token = strtok(line,
" ");
916 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
917 int(token[0]) == 10 ||
int(token[0]) == 13 ||
918 strcmp(token,
"PRINT") == 0 || strcmp(token,
"*****") == 0 ||
919 strcmp(token,
"LOAD") == 0 || strcmp(token,
"TIME=") == 0 ||
920 strcmp(token,
"MAXIMUM") == 0 || strcmp(token,
"VALUE") == 0 ||
921 strcmp(token,
"NODE") == 0)
925 token = strtok(NULL,
" ");
926 double volt =
ReadDouble(token, -1, readerror);
928 potentials.at(inode - 1) = volt;
931 std::cerr <<
m_className <<
"::SetWeightingField:" << std::endl;
932 std::cerr <<
" Node number " << inode <<
" out of range."
934 std::cerr <<
" on potential file " << prnsol <<
" (line " << il
935 <<
")." << std::endl;
936 std::cerr <<
" Size of the potential vector is: "
937 << potentials.size() << std::endl;
945 std::cout <<
m_className <<
"::SetWeightingField:" << std::endl;
946 std::cout <<
" Read " << nread <<
"/" <<
nNodes
947 <<
" (expected) potentials from file " << prnsol <<
"."
951 std::cerr <<
m_className <<
"::SetWeightingField:" << std::endl;
952 std::cerr <<
" Number of nodes read (" << nread <<
")"
953 <<
" on potential file (" << prnsol <<
")" << std::endl;
954 std::cerr <<
" does not match the node list (" <<
nNodes <<
")."
959 std::cerr <<
m_className <<
"::SetWeightingField:" << std::endl;
960 std::cerr <<
" Field map could not be read "
961 <<
"and cannot be interpolated." << std::endl;
965 m_weightingFields[label] = potentials;
973 const double zShift) {
974 std::transform(m_xlines.begin(), m_xlines.end(), m_xlines.begin(), [xShift](
double x) { return x + xShift;});
975 std::transform(m_ylines.begin(), m_ylines.end(), m_ylines.begin(), [yShift](
double x) { return x + yShift;});
976 std::transform(m_zlines.begin(), m_zlines.end(), m_zlines.begin(), [zShift](
double x) { return x + zShift;});
980 std::cout <<
m_className <<
"::ShiftComponent:" << std::endl;
981 std::cout <<
" Shifted component in x-direction: " << xShift
982 <<
"\t y-direction: " << yShift <<
"\t z-direction: " << zShift
987 const double zin,
double& ex,
double& ey,
988 double& ez,
Medium*& m,
int& status) {
990 ElectricFieldBinary(xin, yin, zin, ex, ey, ez, volt, m, status);
994 const double zin,
double& ex,
double& ey,
995 double& ez,
double& volt,
Medium*& m,
997 ElectricFieldBinary(xin, yin, zin, ex, ey, ez, volt, m, status,
true);
1001 const double zin,
double& wx,
double& wy,
1002 double& wz,
const std::string& label) {
1010 auto it = m_weightingFields.find(label);
1011 if (it == m_weightingFields.end()) {
1013 std::cerr <<
"No weighting field named " << label.c_str() <<
" found!"
1019 if (!
wfieldsOk[std::distance(m_weightingFields.begin(), it)])
return;
1022 double x = xin, y = yin, z = zin;
1026 double rcoordinate, rotation;
1027 unsigned int i, j, k;
1028 double position_mapped[3] = {0., 0., 0.};
1030 rcoordinate, rotation))
1033 double rx = (position_mapped[0] - m_xlines.at(i)) /
1034 (m_xlines.at(i + 1) - m_xlines.at(i));
1035 double ry = (position_mapped[1] - m_ylines.at(j)) /
1036 (m_ylines.at(j + 1) - m_ylines.at(j));
1037 double rz = (position_mapped[2] - m_zlines.at(k)) /
1038 (m_zlines.at(k + 1) - m_zlines.at(k));
1040 float fwx, fwy, fwz;
1041 if (!disableFieldComponent[0])
1042 fwx = GetFieldComponent(i, j, k, rx, ry, rz,
'x', &((*it).second));
1043 if (!disableFieldComponent[1])
1044 fwy = GetFieldComponent(i, j, k, rx, ry, rz,
'y', &((*it).second));
1045 if (!disableFieldComponent[2])
1046 fwz = GetFieldComponent(i, j, k, rx, ry, rz,
'z', &((*it).second));
1048 if (m_elementMaterial.size() > 0 && doShaping) {
1049 ShapeField(fwx, fwy, fwz, rx, ry, rz, i, j, k, &((*it).second));
1051 if (mirrored[0]) fwx *= -1.;
1052 if (mirrored[1]) fwy *= -1.;
1053 if (mirrored[2]) fwz *= -1.;
1056 if (!disableFieldComponent[0]) wx = fwx;
1057 if (!disableFieldComponent[1]) wy = fwy;
1058 if (!disableFieldComponent[2]) wz = fwz;
1064 const std::string& label) {
1069 auto it = m_weightingFields.find(label);
1070 if (it == m_weightingFields.end()) {
1072 std::cerr <<
"No weighting field named " << label.c_str() <<
" found!"
1078 if (!
wfieldsOk[std::distance(m_weightingFields.begin(), it)])
return 0.;
1081 double x = xin, y = yin, z = zin;
1085 double rcoordinate, rotation;
1086 unsigned int i, j, k;
1087 double position_mapped[3] = {0., 0., 0.};
1089 rcoordinate, rotation))
1092 double rx = (position_mapped[0] - m_xlines.at(i)) /
1093 (m_xlines.at(i + 1) - m_xlines.at(i));
1094 double ry = (position_mapped[1] - m_ylines.at(j)) /
1095 (m_ylines.at(j + 1) - m_ylines.at(j));
1096 double rz = (position_mapped[2] - m_zlines.at(k)) /
1097 (m_zlines.at(k + 1) - m_zlines.at(k));
1099 double potential = GetPotential(i, j, k, rx, ry, rz, &((*it).second));
1102 std::cout <<
m_className <<
"::WeightingPotential:" << std::endl;
1103 std::cout <<
" Global: (" << x <<
"," << y <<
"," << z <<
"),"
1105 std::cout <<
" Local: (" << rx <<
"," << ry <<
"," << rz
1106 <<
") in element with indexes: i=" << i <<
", j=" << j
1107 <<
", k=" << k << std::endl;
1108 std::cout <<
" Node xyzV:" << std::endl;
1109 std::cout <<
"Node 0 position: " << Index2Node(i + 1, j, k)
1110 <<
"\t potential: " << ((*it).second).at(Index2Node(i + 1, j, k))
1111 <<
"Node 1 position: " << Index2Node(i + 1, j + 1, k)
1113 << ((*it).second).at(Index2Node(i + 1, j + 1, k))
1114 <<
"Node 2 position: " << Index2Node(i, j + 1, k)
1115 <<
"\t potential: " << ((*it).second).at(Index2Node(i, j + 1, k))
1116 <<
"Node 3 position: " << Index2Node(i, j, k)
1117 <<
"\t potential: " << ((*it).second).at(Index2Node(i, j, k))
1118 <<
"Node 4 position: " << Index2Node(i + 1, j, k + 1)
1120 << ((*it).second).at(Index2Node(i + 1, j, k + 1))
1121 <<
"Node 5 position: " << Index2Node(i + 1, j + 1, k + 1)
1123 << ((*it).second).at(Index2Node(i + 1, j + 1, k + 1))
1124 <<
"Node 6 position: " << Index2Node(i, j + 1, k + 1)
1126 << ((*it).second).at(Index2Node(i, j + 1, k + 1))
1127 <<
"Node 7 position: " << Index2Node(i, j, k + 1)
1128 <<
"\t potential: " << ((*it).second).at(Index2Node(i, j, k))
1135 unsigned int& n_z) {
1136 n_x = m_xlines.size();
1137 n_y = m_ylines.size();
1138 n_z = m_zlines.size();
1142 double& xmax,
double& ymin,
1143 double& ymax,
double& zmin,
1145 unsigned int i, j, k;
1146 Element2Index(element, i, j, k);
1147 xmin = m_xlines.at(i);
1148 xmax = m_xlines.at(i + 1);
1149 ymin = m_ylines.at(j);
1150 ymax = m_ylines.at(j + 1);
1151 zmin = m_zlines.at(k);
1152 zmax = m_zlines.at(k + 1);
1157 unsigned int i, j, k;
1160 std::cout <<
m_className <<
"::GetMedium:" << std::endl;
1161 std::cout <<
" Found position (" << xin <<
", " << yin <<
", " << zin
1162 <<
"): " << std::endl;
1163 std::cout <<
" Indexes are: x: " << i <<
"/" << m_xlines.size()
1164 <<
"\t y: " << j <<
"/" << m_ylines.size() <<
"\t z: " << k <<
"/"
1165 << m_zlines.size() << std::endl;
1166 std::cout <<
" Element material index: " <<
Index2Element(i, j, k)
1168 std::cout <<
" Element index: "
1169 << (int)m_elementMaterial.at(
Index2Element(i, j, k)) << std::endl;
1177 m_mapmax[0] = *(m_xlines.end() - 1);
1179 m_mapmax[1] = *(m_ylines.end() - 1);
1181 m_mapmax[2] = *(m_zlines.end() - 1);
1182 m_mapvmin = *std::min_element(m_potential.begin(), m_potential.end());
1183 m_mapvmax = *std::max_element(m_potential.begin(), m_potential.end());
1201 if (fabs(zmax - zmin) <= 0.) {
1202 std::cerr <<
m_className <<
"::SetRangeZ:" << std::endl;
1203 std::cerr <<
" Zero range is not permitted." << std::endl;
1211 const double z,
unsigned int& i,
1212 unsigned int& j,
unsigned int& k) {
1213 bool mirrored[3] = {
false,
false,
false};
1214 double position_mapped[3] = {0., 0., 0.};
1215 double rcoordinate, rotation;
1217 rcoordinate, rotation);
1221 const unsigned int k) {
1222 if (i > m_nx - 2 || j > m_ny - 2 || k > m_nz - 2) {
1223 throw "FieldMap::ElementByIndex: Error. Element indexes out of bounds.";
1225 return i + j * (m_nx - 1) + k * (m_nx - 1) * (m_ny - 1);
1229 const double zin,
unsigned int& i,
1230 unsigned int& j,
unsigned int& k,
1231 double* position_mapped,
bool* mirrored,
1232 double& rcoordinate,
double& rotation) {
1234 position_mapped[0] = xin;
1235 position_mapped[1] = yin;
1236 position_mapped[2] = zin;
1237 MapCoordinates(position_mapped[0], position_mapped[1], position_mapped[2],
1238 mirrored[0], mirrored[1], mirrored[2], rcoordinate, rotation);
1241 std::lower_bound(m_xlines.begin(), m_xlines.end(), position_mapped[0]);
1243 std::lower_bound(m_ylines.begin(), m_ylines.end(), position_mapped[1]);
1245 std::lower_bound(m_zlines.begin(), m_zlines.end(), position_mapped[2]);
1246 if (it_x == m_xlines.end() || it_y == m_ylines.end() ||
1247 it_z == m_zlines.end() || position_mapped[0] < m_xlines.at(0) ||
1248 position_mapped[1] < m_ylines.at(0) ||
1249 position_mapped[2] < m_zlines.at(0)) {
1251 std::cerr <<
m_className <<
"::ElectricFieldBinary:" << std::endl;
1252 std::cerr <<
" Could not find the given coordinate!" << std::endl;
1253 std::cerr <<
" You ask for the following position: " << xin <<
", "
1254 << yin <<
", " << zin << std::endl;
1255 std::cerr <<
" The mapped position is: " << position_mapped[0] <<
", "
1256 << position_mapped[1] <<
", " << position_mapped[2]
1268 if (it_x == m_xlines.begin())
1271 i = std::distance(m_xlines.begin(), it_x - 1);
1272 if (it_y == m_ylines.begin())
1275 j = std::distance(m_ylines.begin(), it_y - 1);
1276 if (it_z == m_zlines.begin())
1279 k = std::distance(m_zlines.begin(), it_z - 1);
1294 unsigned int i, j, k;
1295 Element2Index(element, i, j, k);
1296 std::vector<double> distances;
1297 distances.push_back(m_xlines.at(i + 1) - m_xlines.at(i));
1298 distances.push_back(m_ylines.at(j + 1) - m_ylines.at(j));
1299 distances.push_back(m_zlines.at(k + 1) - m_zlines.at(k));
1300 std::sort(distances.begin(), distances.end());
1301 dmin = distances.at(0);
1302 dmax = distances.at(2);
1306 if ((
int)element >=
nElements)
return 0.;
1307 unsigned int i, j, k;
1308 Element2Index(element, i, j, k);
1309 const double volume = fabs((m_xlines.at(i + 1) - m_xlines.at(i)) *
1310 (m_xlines.at(j + 1) - m_ylines.at(j)) *
1311 (m_xlines.at(k + 1) - m_zlines.at(k)));
1315void ComponentCST::ElectricFieldBinary(
const double xin,
const double yin,
1316 const double zin,
double& ex,
double& ey,
1317 double& ez,
double& volt,
Medium*& m,
1318 int& status,
bool calculatePotential) {
1320 double x = xin, y = yin, z = zin;
1325 double rcoordinate, rotation;
1326 unsigned int i, j, k;
1327 double position_mapped[3] = {0., 0., 0.};
1329 rcoordinate, rotation))
1332 double rx = (position_mapped[0] - m_xlines.at(i)) /
1333 (m_xlines.at(i + 1) - m_xlines.at(i));
1334 double ry = (position_mapped[1] - m_ylines.at(j)) /
1335 (m_ylines.at(j + 1) - m_ylines.at(j));
1336 double rz = (position_mapped[2] - m_zlines.at(k)) /
1337 (m_zlines.at(k + 1) - m_zlines.at(k));
1339 float fex = GetFieldComponent(i, j, k, rx, ry, rz,
'x', &m_potential);
1340 float fey = GetFieldComponent(i, j, k, rx, ry, rz,
'y', &m_potential);
1341 float fez = GetFieldComponent(i, j, k, rx, ry, rz,
'z', &m_potential);
1343 if (m_elementMaterial.size() > 0 && doShaping) {
1344 ShapeField(fex, fey, fez, rx, ry, rz, i, j, k, &m_potential);
1346 if (mirrored[0]) fex *= -1.;
1347 if (mirrored[1]) fey *= -1.;
1348 if (mirrored[2]) fez *= -1.;
1350 std::cout <<
m_className <<
"::ElectricFieldBinary:" << std::endl;
1351 std::cout <<
" Found position (" <<
x <<
", " <<
y <<
", " <<
z
1352 <<
"): " << std::endl;
1353 std::cout <<
" Indexes are: x: " << i <<
"/" << m_xlines.size()
1354 <<
"\t y: " << j <<
"/" << m_ylines.size() <<
"\t z: " << k <<
"/"
1355 << m_zlines.size() << std::endl;
1356 if (i != 0 && j != 0 && k != 0) {
1357 std::cout <<
" index: " << i <<
"\t x before: " << m_xlines.at(i - 1)
1358 <<
"\t x behind: " << m_xlines.at(i) <<
"\t r = " << rx
1359 <<
"\n index: " << j <<
"\t y before: " << m_ylines.at(j - 1)
1360 <<
"\t y behind: " << m_ylines.at(j) <<
"\t r = " << ry
1361 <<
"\n index: " << k <<
"\t z before: " << m_zlines.at(k - 1)
1362 <<
"\t z behind: " << m_zlines.at(k) <<
"\t r = " << rz
1365 std::cout <<
" Electric field is: " << fex <<
", " << fey <<
", " << fez
1366 <<
"): " << std::endl;
1378 if (!disableFieldComponent[0]) ex = fex;
1379 if (!disableFieldComponent[1]) ey = fey;
1380 if (!disableFieldComponent[2]) ez = fez;
1381 if (calculatePotential)
1382 volt = GetPotential(i, j, k, rx, ry, rz, &m_potential);
1385float ComponentCST::GetFieldComponent(
const unsigned int i,
1386 const unsigned int j,
1387 const unsigned int k,
const double rx,
1388 const double ry,
const double rz,
1389 const char component,
1390 const std::vector<float>* potentials) {
1391 float dv1 = 0, dv2 = 0, dv3 = 0, dv4 = 0;
1392 float dv11 = 0, dv21 = 0, dv = 0;
1394 if (component ==
'x') {
1395 dv1 = potentials->at(Index2Node(i + 1, j, k)) -
1396 potentials->at(Index2Node(i, j, k));
1397 dv2 = potentials->at(Index2Node(i + 1, j + 1, k)) -
1398 potentials->at(Index2Node(i, j + 1, k));
1399 dv3 = potentials->at(Index2Node(i + 1, j + 1, k + 1)) -
1400 potentials->at(Index2Node(i, j + 1, k + 1));
1401 dv4 = potentials->at(Index2Node(i + 1, j, k + 1)) -
1402 potentials->at(Index2Node(i, j, k + 1));
1404 dv11 = dv1 + (dv4 - dv1) * rz;
1405 dv21 = dv2 + (dv3 - dv2) * rz;
1406 dv = dv11 + (dv21 - dv11) * ry;
1407 e = -1 * dv / (m_xlines.at(i + 1) - m_xlines.at(i));
1409 if (component ==
'y') {
1410 dv1 = potentials->at(Index2Node(i, j + 1, k)) -
1411 potentials->at(Index2Node(i, j, k));
1412 dv2 = potentials->at(Index2Node(i, j + 1, k + 1)) -
1413 potentials->at(Index2Node(i, j, k + 1));
1414 dv3 = potentials->at(Index2Node(i + 1, j + 1, k + 1)) -
1415 potentials->at(Index2Node(i + 1, j, k + 1));
1416 dv4 = potentials->at(Index2Node(i + 1, j + 1, k)) -
1417 potentials->at(Index2Node(i + 1, j, k));
1419 dv11 = dv1 + (dv4 - dv1) * rx;
1420 dv21 = dv2 + (dv3 - dv2) * rx;
1421 dv = dv11 + (dv21 - dv11) * rz;
1422 e = -1 * dv / (m_ylines.at(j + 1) - m_ylines.at(j));
1424 if (component ==
'z') {
1425 dv1 = potentials->at(Index2Node(i, j, k + 1)) -
1426 potentials->at(Index2Node(i, j, k));
1427 dv2 = potentials->at(Index2Node(i + 1, j, k + 1)) -
1428 potentials->at(Index2Node(i + 1, j, k));
1429 dv3 = potentials->at(Index2Node(i + 1, j + 1, k + 1)) -
1430 potentials->at(Index2Node(i + 1, j + 1, k));
1431 dv4 = potentials->at(Index2Node(i, j + 1, k + 1)) -
1432 potentials->at(Index2Node(i, j + 1, k));
1434 dv11 = dv1 + (dv4 - dv1) * ry;
1435 dv21 = dv2 + (dv3 - dv2) * ry;
1436 dv = dv11 + (dv21 - dv11) * rx;
1437 e = -1 * dv / (m_zlines.at(k + 1) - m_zlines.at(k));
1442float ComponentCST::GetPotential(
const unsigned int i,
const unsigned int j,
1443 const unsigned int k,
const double rx,
1444 const double ry,
const double rz,
1445 const std::vector<float>* potentials) {
1446 double t1 = rx * 2. - 1;
1447 double t2 = ry * 2. - 1;
1448 double t3 = rz * 2. - 1;
1449 return (potentials->at(Index2Node(i + 1, j, k)) * (1 - t1) * (1 - t2) *
1451 potentials->at(Index2Node(i + 1, j + 1, k)) * (1 + t1) * (1 - t2) *
1453 potentials->at(Index2Node(i, j + 1, k)) * (1 + t1) * (1 + t2) *
1455 potentials->at(Index2Node(i, j, k)) * (1 - t1) * (1 + t2) * (1 - t3) +
1456 potentials->at(Index2Node(i + 1, j, k + 1)) * (1 - t1) * (1 - t2) *
1458 potentials->at(Index2Node(i + 1, j + 1, k + 1)) * (1 + t1) *
1459 (1 - t2) * (1 + t3) +
1460 potentials->at(Index2Node(i, j + 1, k + 1)) * (1 + t1) * (1 + t2) *
1462 potentials->at(Index2Node(i, j, k + 1)) * (1 - t1) * (1 + t2) *
1467void ComponentCST::ShapeField(
float& ex,
float& ey,
float& ez,
const double rx,
1468 const double ry,
const double rz,
1469 const unsigned int i,
const unsigned int j,
1470 const unsigned int k,
1471 std::vector<float>* potentials) {
1473 if ((i == 0 && rx >= 0.5) || (i == m_xlines.size() - 2 && rx < 0.5) ||
1474 (i > 0 && i < m_xlines.size() - 2)) {
1480 GetFieldComponent(i + 1, j, k, 0.5, ry, rz,
'x', potentials);
1482 (rx - 0.5) * (ex_next - ex) *
1483 (m_xlines.at(i + 1) - m_xlines.at(i)) /
1484 (m_xlines.at(i + 2) - m_xlines.at(i + 1));
1490 GetFieldComponent(i - 1, j, k, 0.5, ry, rz,
'x', potentials);
1492 (rx + 0.5) * (ex - ex_before) *
1493 (m_xlines.at(i) - m_xlines.at(i - 1)) /
1494 (m_xlines.at(i + 1) - m_xlines.at(i));
1499 if ((j == 0 && ry >= 0.5) || (j == m_ylines.size() - 2 && ry < 0.5) ||
1500 (j > 0 && j < m_ylines.size() - 2)) {
1506 GetFieldComponent(i, j + 1, k, rx, 0.5, rz,
'y', potentials);
1508 (ry - 0.5) * (ey_next - ey) *
1509 (m_ylines.at(j + 1) - m_ylines.at(j)) /
1510 (m_ylines.at(j + 2) - m_ylines.at(j + 1));
1516 GetFieldComponent(i, j - 1, k, rx, 0.5, rz,
'y', potentials);
1518 (ry + 0.5) * (ey - ey_next) *
1519 (m_ylines.at(j) - m_ylines.at(j - 1)) /
1520 (m_ylines.at(j + 1) - m_ylines.at(j));
1525 if ((k == 0 && rz >= 0.5) || (k == m_zlines.size() - 2 && rz < 0.5) ||
1526 (k > 0 && k < m_zlines.size() - 2)) {
1532 GetFieldComponent(i, j, k + 1, rx, ry, 0.5,
'z', potentials);
1534 (rz - 0.5) * (ez_next - ez) *
1535 (m_zlines.at(k + 1) - m_zlines.at(k)) /
1536 (m_zlines.at(k + 2) - m_zlines.at(k + 1));
1542 GetFieldComponent(i, j, k - 1, rx, ry, 0.5,
'z', potentials);
1544 (rz + 0.5) * (ez - ez_next) *
1545 (m_zlines.at(k) - m_zlines.at(k - 1)) /
1546 (m_zlines.at(k + 1) - m_zlines.at(k));
1552void ComponentCST::Element2Index(
int element,
unsigned int& i,
unsigned int& j,
1555 k = element / ((m_xlines.size() - 1) * (m_ylines.size() - 1));
1556 tmp -= k * (m_xlines.size() - 1) * (m_ylines.size() - 1);
1557 j = tmp / (m_xlines.size() - 1);
1558 i = element - j * (m_xlines.size() - 1) -
1559 k * (m_xlines.size() - 1) * (m_ylines.size() - 1);
1562int ComponentCST::Index2Node(
const unsigned int i,
const unsigned int j,
1563 const unsigned int k) {
1564 if (i > m_nx - 1 || j > m_ny - 1 || k > m_nz - 1) {
1565 throw "FieldMap::NodeByIndex: Error. Node indexes out of bounds.";
1567 return i + j * m_nx + k * m_nx * m_ny;
bool m_ready
Ready for use?
std::string m_className
Class name.
bool m_debug
Switch on/off debugging messages.
bool Coordinate2Index(const double x, const double y, const double z, unsigned int &i, unsigned int &j, unsigned int &k)
void GetNumberOfMeshLines(unsigned int &n_x, unsigned int &n_y, unsigned int &n_z)
void UpdatePeriodicity() override
Verify periodicities.
void ElectricField(const double x, const double y, const double z, double &ex, double &ey, double &ez, Medium *&m, int &status) override
int Index2Element(const unsigned int i, const unsigned int j, const unsigned int k)
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
bool Initialise(std::string elist, std::string nlist, std::string mplist, std::string prnsol, std::string unit="cm")
Medium * GetMedium(const double x, const double y, const double z) override
Get the medium at a given location (x, y, z).
bool SetWeightingField(std::string prnsol, std::string label, bool isBinary=true)
double WeightingPotential(const double x, const double y, const double z, const std::string &label) override
void ShiftComponent(const double xShift, const double yShift, const double zShift)
void SetRange() override
Calculate x, y, z, V and angular ranges.
void GetElementBoundaries(unsigned int element, double &xmin, double &xmax, double &ymin, double &ymax, double &zmin, double &zmax)
void GetAspectRatio(const unsigned int i, double &dmin, double &dmax) override
void SetRangeZ(const double zmin, const double zmax)
ComponentCST()
Constructor.
Base class for components based on finite-element field maps.
void PrintRange()
Show x, y, z, V and angular ranges.
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
std::vector< Material > materials
void UpdatePeriodicity2d()
std::array< double, 3 > m_mapmax
std::vector< std::string > wfields
Abstract base class for media.
bool IsDriftable() const
Is charge carrier transport enabled in this medium?