19 const std::string& nlist,
20 const std::string& mplist,
21 const std::string& prnsol,
22 const std::string& unit) {
28 constexpr int size = 100;
32 std::ifstream fmplist(mplist);
40 unsigned int icurrmat = 0;
41 bool readerror =
false;
42 while (fmplist.getline(line, size,
'\n')) {
45 if (strcmp(line,
"1") == 0) {
46 for (
size_t k = 0; k < 5; ++k) fmplist.getline(line, size,
'\n');
51 char* token = strtok(line,
" ");
53 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
54 strcmp(token,
"TEMPERATURE") == 0 || strcmp(token,
"PROPERTY=") == 0 ||
55 int(token[0]) == 10 ||
int(token[0]) == 13) {
59 if (strcmp(token,
"LIST") == 0) {
60 token = strtok(
nullptr,
" ");
61 token = strtok(
nullptr,
" ");
62 token = strtok(
nullptr,
" ");
63 token = strtok(
nullptr,
" ");
64 const int nMaterials =
ReadInteger(token, -1, readerror);
65 if (readerror || nMaterials < 0) {
67 <<
" Error reading file " << mplist <<
" (line " << il
76 material.medium =
nullptr;
79 std::cout <<
m_className <<
"::Initialise: " << nMaterials
82 }
else if (strcmp(token,
"MATERIAL") == 0) {
84 token = strtok(
nullptr,
" ");
85 token = strtok(
nullptr,
" ");
87 if (readerror || imat < 0) {
89 <<
" Error reading file " << mplist <<
" (line " << il
95 }
else if (strcmp(token,
"TEMP") == 0) {
97 token = strtok(
nullptr,
" ");
99 if (strncmp(token,
"PERX", 4) == 0) {
101 }
else if (strncmp(token,
"RSVX", 4) == 0) {
105 <<
" Unknown material property flag " << token <<
"\n"
106 <<
" in material properties file " << mplist <<
" (line "
111 fmplist.getline(line, size,
'\n');
114 token = strtok(line,
" ");
115 if (icurrmat < 1 || icurrmat >
m_materials.size()) {
117 <<
" Found out-of-range current material index "
119 <<
" in material properties file " << mplist <<
".\n";
125 }
else if (itype == 2) {
130 <<
" Error reading file " << mplist <<
" (line " << il
135 }
else if (strcmp(token,
"PROPERTY") == 0) {
137 token = strtok(
nullptr,
" ");
138 token = strtok(
nullptr,
" ");
140 if (strcmp(token,
"PERX") == 0) {
142 }
else if (strcmp(token,
"RSVX") == 0) {
146 <<
" Unknown material property flag " << token <<
"\n"
147 <<
" in material properties file " << mplist <<
" (line "
151 token = strtok(
nullptr,
" ");
152 token = strtok(
nullptr,
" ");
156 <<
" Error reading file " << mplist <<
" (line " << il
160 }
else if (imat < 1 || imat > (
int)
m_materials.size()) {
162 std::cerr <<
" Found out-of-range current material index " << imat
164 std::cerr <<
" in material properties file " << mplist <<
".\n";
168 fmplist.getline(line, size,
'\n');
170 fmplist.getline(line, size,
'\n');
172 token = strtok(line,
" ");
173 token = strtok(
nullptr,
" ");
176 }
else if (itype == 2) {
181 <<
" Error reading file " << mplist <<
" (line " << il
191 if (!ok)
return false;
199 <<
" materials from file " << mplist <<
".\n";
203 std::ifstream felist(elist);
213 while (felist.getline(line, size,
'\n')) {
216 if (strstr(line,
"VERSION") !=
nullptr) {
217 for (
size_t k = 0; k < 2; ++k) felist.getline(line, size,
'\n');
222 char* token = strtok(line,
" ");
224 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
225 int(token[0]) == 10 ||
int(token[0]) == 13 ||
226 strcmp(token,
"LIST") == 0 || strcmp(token,
"ELEM") == 0 ||
227 strcmp(token,
"ANSYS") == 0 || strcmp(token,
"***") == 0 ||
228 strcmp(token,
"VERSION") == 0) {
233 token = strtok(
nullptr,
" ");
235 token = strtok(
nullptr,
" ");
236 token = strtok(
nullptr,
" ");
237 token = strtok(
nullptr,
" ");
238 token = strtok(
nullptr,
" ");
239 std::vector<int> inode;
240 for (
size_t k = 0; k < 8; ++k) {
241 token = strtok(
nullptr,
" ");
243 if (!readerror) inode.push_back(in);
246 if (inode.size() != 8) {
248 <<
" Error reading file " << elist <<
" (line " << il
250 <<
" Read " << inode.size() <<
" node indices for element"
251 << ielem <<
" (expected 8).\n";
256 if (ielem - 1 != (
int)
m_elements.size() + nbackground) {
258 <<
" Synchronisation lost on file " << elist <<
" (line "
260 <<
" Element: " << ielem <<
" (expected "
268 <<
" Out-of-range material number on file " << elist
269 <<
" (line " << il <<
").\n"
270 <<
" Element: " << ielem <<
", material: " << imat <<
".\n";
276 <<
" Element " << ielem <<
" in " << elist <<
"\n"
277 <<
" uses material " << imat <<
" which does not have\n"
278 <<
" a positive permittivity in " << mplist <<
".\n";
283 for (
size_t k = 0; k < 8; ++k) {
286 <<
" Found a node number < 1 in " << elist <<
" (line "
288 <<
" Element: " << ielem <<
", material: " << imat <<
"\n";
292 if (inode[k] > highestnode) highestnode = inode[k];
300 bool degenerate =
false;
302 if (inode[2] == inode[3] && inode[3] == inode[6]) {
307 element.
matmap = imat - 1;
310 element.
emap[0] = inode[0] - 1;
311 element.
emap[1] = inode[1] - 1;
312 element.
emap[2] = inode[2] - 1;
313 element.
emap[3] = inode[4] - 1;
314 element.
emap[4] = inode[7] - 1;
315 element.
emap[5] = inode[5] - 1;
316 element.
emap[6] = inode[3] - 1;
317 element.
emap[7] = inode[6] - 1;
319 for (
size_t k = 0; k < 8; ++k) element.
emap[k] = inode[k] - 1;
326 if (!ok)
return false;
330 <<
" Found no valid elements in file " << elist <<
".\n";
335 std::cout <<
" Read " <<
m_elements.size() <<
" elements from file "
337 <<
" Highest node number: " << highestnode <<
"\n"
338 <<
" Degenerate elements: " << ndegenerate <<
"\n"
339 <<
" Background elements skipped: " << nbackground <<
".\n";
344 <<
" Unknown length unit " << unit <<
". Will use cm.\n";
348 std::cout <<
m_className <<
"::Initialise: Unit scaling factor = "
353 std::ifstream fnlist(nlist);
360 while (fnlist.getline(line, size,
'\n')) {
363 if (strstr(line,
"VERSION") !=
nullptr) {
364 for (
size_t k = 0; k < 2; ++k) fnlist.getline(line, size,
'\n');
369 char* token = strtok(line,
" ");
371 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
372 int(token[0]) == 10 ||
int(token[0]) == 13 ||
373 strcmp(token,
"LIST") == 0 || strcmp(token,
"NODE") == 0 ||
374 strcmp(token,
"ANSYS") == 0 || strcmp(token,
"***") == 0 ||
375 strcmp(token,
"FILE") == 0 || strcmp(token,
"Electric") == 0 ||
376 strcmp(token,
"VERSION") == 0) {
381 token = strtok(
nullptr,
" ");
382 double xnode =
ReadDouble(token, -1, readerror);
383 token = strtok(
nullptr,
" ");
384 double ynode =
ReadDouble(token, -1, readerror);
385 token = strtok(
nullptr,
" ");
386 double znode =
ReadDouble(token, -1, readerror);
390 <<
" Error reading file " << nlist <<
" (line " << il
396 if (inode - 1 != (
int)
m_nodes.size()) {
398 <<
" Synchronisation lost on file " << nlist <<
" (line "
400 <<
" Node: " << inode <<
" (expected " <<
m_nodes.size()
401 <<
"), (x,y,z) = (" << xnode <<
", " << ynode <<
", " << znode
408 node.
x = xnode * funit;
409 node.
y = ynode * funit;
410 node.
z = znode * funit;
411 m_nodes.push_back(std::move(node));
415 if (!ok)
return false;
418 std::cout <<
" Read " <<
m_nodes.size() <<
" nodes from file "
421 if ((
int)
m_nodes.size() != highestnode) {
423 <<
" Number of nodes read (" <<
m_nodes.size()
424 <<
") on " << nlist <<
"\n"
425 <<
" does not match element list (" << highestnode <<
").\n";
428 if (!LoadPotentials(prnsol,
m_pot))
return false;
435bool ComponentAnsys121::LoadPotentials(
const std::string& prnsol,
436 std::vector<double>& pot) {
438 std::ifstream fprnsol(prnsol);
447 constexpr int size = 100;
453 unsigned int nread = 0;
454 bool readerror =
false;
455 while (fprnsol.getline(line, size,
'\n')) {
458 if (strstr(line,
"VERSION") !=
nullptr) {
459 for (
size_t k = 0; k < 2; ++k) fprnsol.getline(line, size,
'\n');
464 char* token = strtok(line,
" ");
466 if (!token || strcmp(token,
" ") == 0 || strcmp(token,
"\n") == 0 ||
467 int(token[0]) == 10 ||
int(token[0]) == 13 ||
468 strcmp(token,
"PRINT") == 0 || strcmp(token,
"ANSYS") == 0 ||
469 strcmp(token,
"VERSION") == 0 || strcmp(token,
"NODAL") == 0 ||
470 strcmp(token,
"FILE") == 0 || strcmp(token,
"*****") == 0 ||
471 strcmp(token,
"***") == 0 || strcmp(token,
"LOAD") == 0 ||
472 strcmp(token,
"TIME=") == 0 || strcmp(token,
"MAXIMUM") == 0 ||
473 strcmp(token,
"VALUE") == 0 || strcmp(token,
"NODE") == 0) {
478 token = strtok(
nullptr,
" ");
479 double volt =
ReadDouble(token, -1, readerror);
483 <<
" Error reading file " << prnsol <<
" (line " << il
489 if (inode < 1 || inode >
m_nodes.size()) {
491 <<
" Node number " << inode <<
" out of range\n"
492 <<
" on potential file " << prnsol <<
" (line " << il
497 pot[inode - 1] = volt;
503 if (!ok)
return false;
506 std::cout <<
" Read " << nread <<
" potentials from file " << prnsol
511 <<
" Number of nodes read (" << nread <<
") on potential file "
512 << prnsol <<
" does not\n"
513 <<
" match the node list (" <<
m_nodes.size() <<
").\n";
520 const std::string& label) {
523 std::cerr <<
" Weighting field cannot be added.\n";
527 std::cout <<
m_className <<
"::SetWeightingField:\n"
528 <<
" Loading field map for electrode " << label <<
".\n";
530 if (
m_wpot.count(label) > 0) {
531 std::cout <<
" Replacing existing weighting field.\n";
535 std::vector<double> pot(
m_nodes.size(), 0.);
536 if (!LoadPotentials(prnsol, pot))
return false;
537 m_wpot[label] = std::move(pot);
542 if (fabs(zmax - zmin) <= 0.) {
543 std::cerr <<
m_className <<
"::SetRangeZ: Zero range is not permitted.\n";
bool Initialise(const std::string &elist="ELIST.lis", const std::string &nlist="NLIST.lis", const std::string &mplist="MPLIST.lis", const std::string &prnsol="PRNSOL.lis", const std::string &unit="cm")
ComponentAnsys121()
Constructor.
bool SetWeightingField(const std::string &prnsol, const std::string &label)
void SetRangeZ(const double zmin, const double zmax)
Set the limits of the active region along z.
void PrintMaterials()
List all currently defined materials.
bool SetDefaultDriftMedium()
Find lowest epsilon, check for eps = 0, set default drift media flags.
static double ReadDouble(char *token, double def, bool &error)
std::array< double, 3 > m_maxBoundingBox
std::array< double, 3 > m_mapmin
std::vector< double > m_pot
std::array< double, 3 > m_minBoundingBox
static double ScalingFactor(std::string unit)
static int ReadInteger(char *token, int def, bool &error)
std::vector< Material > m_materials
ComponentFieldMap()=delete
Default constructor.
std::vector< Node > m_nodes
void PrintCouldNotOpen(const std::string &header, const std::string &filename) const
std::map< std::string, std::vector< double > > m_wpot
std::vector< Element > m_elements
std::vector< bool > m_degenerate
ElementType m_elementType
std::array< double, 3 > m_mapmax
void Reset() override
Reset the component.
void PrintNotReady(const std::string &header) const
bool m_debug
Switch on/off debugging messages.
std::string m_className
Class name.
bool m_ready
Ready for use?