14bool ends_with(std::string s, std::string t) {
15 if (!s.empty() && s.back() ==
'\r') s.pop_back();
16 return s.size() >= t.size() && s.substr(s.size() - t.size(), t.size()) == t;
19bool isComment(
const std::string& line) {
20 if (line.empty())
return false;
21 if (line[0] ==
'%')
return true;
25int readInt(std::string s) {
26 std::istringstream iss(s);
32void PrintProgress(
const double f) {
34 constexpr unsigned int width = 70;
35 const unsigned int n =
static_cast<unsigned int>(std::floor(width * f));
36 std::string bar =
"[";
38 bar += std::string(width,
' ');
39 }
else if (n >= width) {
40 bar += std::string(width,
'=');
42 bar += std::string(n,
'=') +
">" + std::string(width - n - 1,
' ');
45 std::cout << bar <<
"\r" << std::flush;
55 const std::string& mplist,
56 const std::string& field,
57 const std::string& unit)
63 const std::string& mplist,
64 const std::string& field,
65 const std::string& unit) {
71 std::cerr <<
m_className <<
"::Initialise:\n Unknown length unit "
72 << unit <<
". Will use default (m).\n";
77 std::ifstream fmplist;
78 fmplist.open(mplist.c_str(), std::ios::in);
83 unsigned int nMaterials;
84 fmplist >> nMaterials;
85 for (
unsigned int i = 0; i < nMaterials; ++i) {
90 fmplist >> material.
eps;
98 material.
eps = material.
ohm = -1;
102 std::map<int, int> domain2material;
105 for (
int i = 0; i < d2msize; ++i) {
108 fmplist >> domain2material[domain];
117 fmesh.open(mesh.c_str(), std::ios::in);
125 if (!std::getline(fmesh, line)) {
127 <<
" Could not read number of nodes from " << mesh <<
".\n";
131 }
while (!ends_with(line,
"# number of mesh points") &&
132 !ends_with(line,
"# number of mesh vertices"));
133 const int nNodes = readInt(line);
135 std::cout <<
m_className <<
"::Initialise: " << nNodes <<
" nodes.\n";
137 if (!std::getline(fmesh, line)) {
139 <<
" Error parsing " << mesh <<
".\n";
143 }
while (line.find(
"# Mesh point coordinates") == std::string::npos &&
144 line.find(
"# Mesh vertex coordinates") == std::string::npos);
145 for (
int i = 0; i < nNodes; ++i) {
147 fmesh >> newNode.
x >> newNode.
y >> newNode.
z;
151 m_nodes.push_back(std::move(newNode));
155 if (!std::getline(fmesh, line)) {
157 <<
" Error parsing " << mesh <<
".\n";
161 }
while (line.find(
"4 tet2 # type name") == std::string::npos);
163 if (!std::getline(fmesh, line)) {
165 <<
" Error parsing " << mesh <<
".\n";
169 }
while (!ends_with(line,
"# number of elements"));
170 const int nElements = readInt(line);
172 std::cout <<
m_className <<
"::Initialise: " << nElements <<
" elements.\n";
173 std::getline(fmesh, line);
176 int perm[10] = {0, 1, 2, 3, 4, 5, 7, 6, 8, 9};
177 for (
int i = 0; i < nElements; ++i) {
180 for (
int j = 0; j < 10; ++j) {
181 fmesh >> newElement.
emap[perm[j]];
187 if (!std::getline(fmesh, line)) {
189 <<
" Error parsing " << mesh <<
".\n";
193 }
while (line.find(
"# Geometric entity indices") == std::string::npos);
197 element.matmap = domain2material.count(domain) ? domain2material[domain]
202 std::ifstream ffield;
203 ffield.open(field.c_str(), std::ios::in);
209 const std::string hdr1 =
213 const std::string hdr2 =
216 if (!std::getline(ffield, line)) {
218 <<
" Error parsing " << field <<
".\n";
222 }
while (line.find(hdr1) == std::string::npos &&
223 line.find(hdr2) == std::string::npos);
224 std::istringstream sline(line);
234 while (sline >> token) {
236 <<
" Reading data for weighting field " << token <<
".\n";
241 const size_t nWeightingFields =
m_wfields.size();
243 const unsigned int nPrint =
244 std::pow(10,
static_cast<unsigned int>(
245 std::max(std::floor(std::log10(nNodes)) - 1, 1.)));
246 std::cout <<
m_className <<
"::Initialise: Reading potentials.\n";
249 std::vector<std::vector<double> > points;
250 for (
const auto& node :
m_nodes) {
251 std::vector<double> point = {node.x, node.y, node.z};
252 points.push_back(std::move(point));
255 std::vector<bool> used(nNodes,
false);
256 for (
int i = 0; i < nNodes; ++i) {
258 ffield >> x >> y >> z >> v;
262 std::vector<double> w;
263 for (
size_t j = 0; j < nWeightingFields; ++j) {
268 const std::vector<double> pt = {x, y, z};
269 std::vector<KDTreeResult> res;
272 std::cerr << std::endl
274 <<
" Could not find a matching mesh node for point (" << x
275 <<
", " << y <<
", " << z <<
")\n.";
279 const size_t k = res[0].idx;
283 if ((i + 1) % nPrint == 0) PrintProgress(
double(i + 1) / nNodes);
287 auto nMissing = std::count(used.begin(), used.end(),
false);
289 std::cerr << std::endl
291 <<
" Missing potentials for " << nMissing <<
" nodes.\n";
297 std::cout << std::endl <<
m_className <<
"::Initialise: Done.\n";
302 const std::string& label) {
304 std::cerr <<
m_className <<
"::SetWeightingField:\n"
305 <<
" No valid field map is present.\n"
306 <<
" Weighting fields cannot be added.\n";
311 std::ifstream ffield;
312 ffield.open(field.c_str(), std::ios::in);
321 std::cout <<
m_className <<
"::SetWeightingField:\n"
322 <<
" Replacing existing weighting field " << label <<
".\n";
327 std::vector<std::vector<double> > points;
328 for (
const auto& node :
m_nodes) {
329 std::vector<double> point = {node.x, node.y, node.z};
330 points.push_back(std::move(point));
334 const std::string hdr =
339 if (!std::getline(ffield, line)) {
340 std::cerr <<
m_className <<
"::SetWeightingField:\n"
341 <<
" Error parsing " << field <<
".\n";
345 }
while (line.find(hdr) == std::string::npos);
346 const int nNodes =
m_nodes.size();
347 for (
int i = 0; i < nNodes; ++i) {
349 ffield >> x >> y >> z >> v;
354 const std::vector<double> pt = {x, y, z};
355 std::vector<KDTreeResult> res;
358 std::cerr <<
m_className <<
"::SetWeightingField:\n"
359 <<
" Could not find a matching mesh node for point (" << x
360 <<
", " << y <<
", " << z <<
")\n.";
364 const size_t k = res[0].idx;
372 const double z,
double& ex,
double& ey,
373 double& ez,
Medium*& m,
int& status) {
379 const double zin,
double& ex,
double& ey,
380 double& ez,
double& volt,
Medium*& m,
383 double x = xin, y = yin, z = zin;
386 bool xmirr, ymirr, zmirr;
387 double rcoordinate, rotation;
388 MapCoordinates(x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
391 ex = ey = ez = volt = 0.;
405 double t1, t2, t3, t4, jac[4][4], det;
406 const int imap =
FindElement13(x, y, z, t1, t2, t3, t4, jac, det);
410 <<
" Point (" << x <<
", " << y <<
", " << z
411 <<
" not in the mesh.\n";
419 PrintElement(
"ElectricField", x, y, z, t1, t2, t3, t4, element, 10);
432 volt = n0.
v * t1 * (2 * t1 - 1) + n1.
v * t2 * (2 * t2 - 1) +
433 n2.
v * t3 * (2 * t3 - 1) + n3.
v * t4 * (2 * t4 - 1) +
434 4 * n4.
v * t1 * t2 + 4 * n5.
v * t1 * t3 + 4 * n6.
v * t1 * t4 +
435 4 * n7.
v * t2 * t3 + 4 * n8.
v * t2 * t4 + 4 * n9.
v * t3 * t4;
436 ex = -(n0.
v * (4 * t1 - 1) * jac[0][1] + n1.
v * (4 * t2 - 1) * jac[1][1] +
437 n2.
v * (4 * t3 - 1) * jac[2][1] + n3.
v * (4 * t4 - 1) * jac[3][1] +
438 n4.
v * (4 * t2 * jac[0][1] + 4 * t1 * jac[1][1]) +
439 n5.
v * (4 * t3 * jac[0][1] + 4 * t1 * jac[2][1]) +
440 n6.
v * (4 * t4 * jac[0][1] + 4 * t1 * jac[3][1]) +
441 n7.
v * (4 * t3 * jac[1][1] + 4 * t2 * jac[2][1]) +
442 n8.
v * (4 * t4 * jac[1][1] + 4 * t2 * jac[3][1]) +
443 n9.
v * (4 * t4 * jac[2][1] + 4 * t3 * jac[3][1])) /
445 ey = -(n0.
v * (4 * t1 - 1) * jac[0][2] + n1.
v * (4 * t2 - 1) * jac[1][2] +
446 n2.
v * (4 * t3 - 1) * jac[2][2] + n3.
v * (4 * t4 - 1) * jac[3][2] +
447 n4.
v * (4 * t2 * jac[0][2] + 4 * t1 * jac[1][2]) +
448 n5.
v * (4 * t3 * jac[0][2] + 4 * t1 * jac[2][2]) +
449 n6.
v * (4 * t4 * jac[0][2] + 4 * t1 * jac[3][2]) +
450 n7.
v * (4 * t3 * jac[1][2] + 4 * t2 * jac[2][2]) +
451 n8.
v * (4 * t4 * jac[1][2] + 4 * t2 * jac[3][2]) +
452 n9.
v * (4 * t4 * jac[2][2] + 4 * t3 * jac[3][2])) /
454 ez = -(n0.
v * (4 * t1 - 1) * jac[0][3] + n1.
v * (4 * t2 - 1) * jac[1][3] +
455 n2.
v * (4 * t3 - 1) * jac[2][3] + n3.
v * (4 * t4 - 1) * jac[3][3] +
456 n4.
v * (4 * t2 * jac[0][3] + 4 * t1 * jac[1][3]) +
457 n5.
v * (4 * t3 * jac[0][3] + 4 * t1 * jac[2][3]) +
458 n6.
v * (4 * t4 * jac[0][3] + 4 * t1 * jac[3][3]) +
459 n7.
v * (4 * t3 * jac[1][3] + 4 * t2 * jac[2][3]) +
460 n8.
v * (4 * t4 * jac[1][3] + 4 * t2 * jac[3][3]) +
461 n9.
v * (4 * t4 * jac[2][3] + 4 * t3 * jac[3][3])) /
465 UnmapFields(ex, ey, ez, x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
470 <<
" Material " << element.
matmap <<
", drift flag "
481 const double zin,
double& wx,
double& wy,
482 double& wz,
const std::string& label) {
497 double x = xin, y = yin, z = zin;
500 bool xmirr, ymirr, zmirr;
501 double rcoordinate, rotation;
502 MapCoordinates(x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
507 double t1, t2, t3, t4, jac[4][4], det;
508 const int imap =
FindElement13(x, y, z, t1, t2, t3, t4, jac, det);
510 if (imap < 0)
return;
514 PrintElement(
"WeightingField", x, y, z, t1, t2, t3, t4, element, 10, iw);
527 wx = -(n0.
w[iw] * (4 * t1 - 1) * jac[0][1] +
528 n1.
w[iw] * (4 * t2 - 1) * jac[1][1] +
529 n2.
w[iw] * (4 * t3 - 1) * jac[2][1] +
530 n3.
w[iw] * (4 * t4 - 1) * jac[3][1] +
531 n4.
w[iw] * (4 * t2 * jac[0][1] + 4 * t1 * jac[1][1]) +
532 n5.
w[iw] * (4 * t3 * jac[0][1] + 4 * t1 * jac[2][1]) +
533 n6.
w[iw] * (4 * t4 * jac[0][1] + 4 * t1 * jac[3][1]) +
534 n7.
w[iw] * (4 * t3 * jac[1][1] + 4 * t2 * jac[2][1]) +
535 n8.
w[iw] * (4 * t4 * jac[1][1] + 4 * t2 * jac[3][1]) +
536 n9.
w[iw] * (4 * t4 * jac[2][1] + 4 * t3 * jac[3][1])) /
539 wy = -(n0.
w[iw] * (4 * t1 - 1) * jac[0][2] +
540 n1.
w[iw] * (4 * t2 - 1) * jac[1][2] +
541 n2.
w[iw] * (4 * t3 - 1) * jac[2][2] +
542 n3.
w[iw] * (4 * t4 - 1) * jac[3][2] +
543 n4.
w[iw] * (4 * t2 * jac[0][2] + 4 * t1 * jac[1][2]) +
544 n5.
w[iw] * (4 * t3 * jac[0][2] + 4 * t1 * jac[2][2]) +
545 n6.
w[iw] * (4 * t4 * jac[0][2] + 4 * t1 * jac[3][2]) +
546 n7.
w[iw] * (4 * t3 * jac[1][2] + 4 * t2 * jac[2][2]) +
547 n8.
w[iw] * (4 * t4 * jac[1][2] + 4 * t2 * jac[3][2]) +
548 n9.
w[iw] * (4 * t4 * jac[2][2] + 4 * t3 * jac[3][2])) /
551 wz = -(n0.
w[iw] * (4 * t1 - 1) * jac[0][3] +
552 n1.
w[iw] * (4 * t2 - 1) * jac[1][3] +
553 n2.
w[iw] * (4 * t3 - 1) * jac[2][3] +
554 n3.
w[iw] * (4 * t4 - 1) * jac[3][3] +
555 n4.
w[iw] * (4 * t2 * jac[0][3] + 4 * t1 * jac[1][3]) +
556 n5.
w[iw] * (4 * t3 * jac[0][3] + 4 * t1 * jac[2][3]) +
557 n6.
w[iw] * (4 * t4 * jac[0][3] + 4 * t1 * jac[3][3]) +
558 n7.
w[iw] * (4 * t3 * jac[1][3] + 4 * t2 * jac[2][3]) +
559 n8.
w[iw] * (4 * t4 * jac[1][3] + 4 * t2 * jac[3][3]) +
560 n9.
w[iw] * (4 * t4 * jac[2][3] + 4 * t3 * jac[3][3])) /
564 UnmapFields(wx, wy, wz, x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
569 const std::string& label) {
581 double x = xin, y = yin, z = zin;
584 bool xmirr, ymirr, zmirr;
585 double rcoordinate, rotation;
586 MapCoordinates(x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
591 double t1, t2, t3, t4, jac[4][4], det;
592 const int imap =
FindElement13(x, y, z, t1, t2, t3, t4, jac, det);
593 if (imap < 0)
return 0.;
597 PrintElement(
"WeightingPotential", x, y, z, t1, t2, t3, t4, element, 10,
611 return n0.
w[iw] * t1 * (2 * t1 - 1) + n1.
w[iw] * t2 * (2 * t2 - 1) +
612 n2.
w[iw] * t3 * (2 * t3 - 1) + n3.
w[iw] * t4 * (2 * t4 - 1) +
613 4 * n4.
w[iw] * t1 * t2 + 4 * n5.
w[iw] * t1 * t3 +
614 4 * n6.
w[iw] * t1 * t4 + 4 * n7.
w[iw] * t2 * t3 +
615 4 * n8.
w[iw] * t2 * t4 + 4 * n9.
w[iw] * t3 * t4;
621 double x = xin, y = yin, z = zin;
624 bool xmirr, ymirr, zmirr;
625 double rcoordinate, rotation;
626 MapCoordinates(x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
636 double t1, t2, t3, t4, jac[4][4], det;
637 const int imap =
FindElement13(x, y, z, t1, t2, t3, t4, jac, det);
641 <<
" Point (" << x <<
", " << y <<
", " << z
642 <<
") not in the mesh.\n";
650 <<
" Point (" << x <<
", " << y <<
", " << z
651 <<
") has out of range material number " << imap <<
".\n";
657 PrintElement(
"GetMedium", x, y, z, t1, t2, t3, t4, element, 10);
675 ((n1.
y - n0.
y) * (n2.
z - n0.
z) - (n2.
y - n0.
y) * (n1.
z - n0.
z)) +
677 ((n1.
z - n0.
z) * (n2.
x - n0.
x) - (n2.
z - n0.
z) * (n1.
x - n0.
x)) +
678 (n3.
z - n0.
z) * ((n1.
x - n0.
x) * (n2.
y - n0.
y) -
679 (n3.
x - n0.
x) * (n1.
y - n0.
y))) /
694 for (
int j = 0; j < np - 1; ++j) {
696 for (
int k = j + 1; k < np; ++k) {
699 const double dx = nj.
x - nk.
x;
700 const double dy = nj.
y - nk.
y;
701 const double dz = nj.
z - nk.
z;
702 const double dist = sqrt(dx * dx + dy * dy + dz * dz);
706 if (dist < dmin) dmin = dist;
707 if (dist > dmax) dmax = dist;
714 const std::string& label) {
716 std::cerr <<
m_className <<
"::SetDelayedWeightingField:\n"
717 <<
" No valid field map is present.\n"
718 <<
" Weighting fields cannot be added.\n";
722 if (!GetTimeInterval(field))
return false;
725 std::cerr <<
m_className <<
"::SetDelayedWeightingField:\n"
726 <<
" No valid times slices of potential set.\n"
727 <<
" Please add the time slices.\n";
736 std::ifstream ffield;
737 ffield.open(field.c_str(), std::ios::in);
743 std::cout <<
m_className <<
"::SetDelayedWeightingField:\n"
744 <<
" Replacing existing weighting field " << label <<
".\n";
751 std::vector<std::vector<double> > points;
752 for (
const auto& node :
m_nodes) {
753 std::vector<double> point = {node.x, node.y, node.z};
754 points.push_back(std::move(point));
761 const int nNodes =
m_nodes.size();
762 const unsigned int nPrint =
763 std::pow(10,
static_cast<unsigned int>(
764 std::max(std::floor(std::log10(nNodes)) - 1, 1.)));
765 std::cout <<
m_className <<
"::SetDelayedWeightingField:\n"
766 <<
" Reading weighting potentials.\n";
769 while (std::getline(ffield, line)) {
771 if (line.empty())
continue;
773 if (isComment(line))
continue;
775 std::vector<double> pvect;
777 std::istringstream data;
783 const std::vector<double> pt = {x, y, z};
784 std::vector<KDTreeResult> res;
788 std::cerr <<
m_className <<
"::SetDelayedWeightingField:\n"
789 <<
" Could not find a matching mesh node for point (" << x
790 <<
", " << y <<
", " << z <<
")\n.";
796 double pholder0 = 0.;
797 for (
int i = 0; i < T; i++) {
799 if (i == 0) pholder0 = pholder;
800 pvect.push_back(pholder - pholder0);
802 const size_t k = res[0].idx;
806 if ((Linecount + 1) % nPrint == 0)
807 PrintProgress(
double(Linecount + 1) / nNodes);
812 std::cout << std::endl
813 <<
m_className <<
"::SetDelayedWeightingField: Done.\n";
822 const std::string& label) {
836 double x = xin, y = yin, z = zin;
839 bool xmirr, ymirr, zmirr;
840 double rcoordinate, rotation;
841 MapCoordinates(x, y, z, xmirr, ymirr, zmirr, rcoordinate, rotation);
846 double t1, t2, t3, t4, jac[4][4], det;
847 const int imap =
FindElement13(x, y, z, t1, t2, t3, t4, jac, det);
848 if (imap < 0)
return 0.;
851 PrintElement(
"WeightingPotential", x, y, z, t1, t2, t3, t4, element, 10,
867 const auto it0 = std::prev(it1);
869 const double dt = t - *it0;
870 const unsigned int i0 = it0 -
m_wdtimes.cbegin();
872 n0.
dw[iw][i0] * t1 * (2 * t1 - 1) + n1.
dw[iw][i0] * t2 * (2 * t2 - 1) +
873 n2.
dw[iw][i0] * t3 * (2 * t3 - 1) + n3.
dw[iw][i0] * t4 * (2 * t4 - 1) +
874 4 * n4.
dw[iw][i0] * t1 * t2 + 4 * n5.
dw[iw][i0] * t1 * t3 +
875 4 * n6.
dw[iw][i0] * t1 * t4 + 4 * n7.
dw[iw][i0] * t2 * t3 +
876 4 * n8.
dw[iw][i0] * t2 * t4 + 4 * n9.
dw[iw][i0] * t3 * t4;
878 const unsigned int i1 = it1 -
m_wdtimes.cbegin();
881 n0.
dw[iw][i1] * t1 * (2 * t1 - 1) + n1.
dw[iw][i1] * t2 * (2 * t2 - 1) +
882 n2.
dw[iw][i1] * t3 * (2 * t3 - 1) + n3.
dw[iw][i1] * t4 * (2 * t4 - 1) +
883 4 * n4.
dw[iw][i1] * t1 * t2 + 4 * n5.
dw[iw][i1] * t1 * t3 +
884 4 * n6.
dw[iw][i1] * t1 * t4 + 4 * n7.
dw[iw][i1] * t2 * t3 +
885 4 * n8.
dw[iw][i1] * t2 * t4 + 4 * n9.
dw[iw][i1] * t3 * t4;
887 const double f1 = dt / (*it1 - *it0);
888 const double f0 = 1. - f1;
890 return f0 * dp0 + f1 * dp1;
894 const double stept) {
895 std::cout << std::endl
897 <<
"::SetTimeInterval: Overwriting time interval of weighting "
909 std::cout << std::endl
911 <<
"::SetTimeInterval: Time of weighting potential set for t in ["
912 << mint <<
"," << maxt <<
"].\n";
915bool ComponentComsol::GetTimeInterval(
const std::string& field) {
918 std::ifstream ffield;
919 ffield.open(field.c_str(), std::ios::in);
926 std::string strtime =
"t=";
932 bool searching =
true;
933 while (std::getline(ffield, line)) {
935 if (line.empty())
continue;
937 if (line[0] ==
'%' && line[2] !=
'x')
continue;
940 found = line.find(strtime, found + 1);
944 if (found != std::string::npos) {
949 std::string holder =
"";
952 holder += line[found + i];
955 if (found + i == line.size())
break;
956 if (line[found + i] ==
' ')
break;
966 std::cout << std::endl
968 <<
"::GetTimeInterval: Time of weighting potential set for t in ["
Component for importing and interpolating Comsol field maps.
bool SetDelayedWeightingPotential(const std::string &file, const std::string &label)
Import the time-dependent weighting field maps.
void SetTimeInterval(const double mint, const double maxt, const double stept)
Set the time interval of the time-dependent weighting field.
bool Initialise(const std::string &header="mesh.mphtxt", const std::string &mplist="dielectrics.dat", const std::string &field="field.txt", const std::string &unit="m")
Medium * GetMedium(const double x, const double y, const double z) override
Get the medium at a given location (x, y, z).
void WeightingField(const double x, const double y, const double z, double &wx, double &wy, double &wz, const std::string &label) override
bool SetWeightingField(const std::string &file, const std::string &label)
Import the time-independent weighting field maps.
double WeightingPotential(const double x, const double y, const double z, const std::string &label) override
double DelayedWeightingPotential(const double x, const double y, const double z, const double t, const std::string &label) override
ComponentComsol()
Default constructor.
void ElectricField(const double x, const double y, const double z, double &ex, double &ey, double &ez, Medium *&m, int &status) override
double GetElementVolume(const unsigned int i) override
void GetAspectRatio(const unsigned int i, double &dmin, double &dmax) override
Base class for components based on finite-element field maps.
bool SetDefaultDriftMedium()
Find lowest epsilon, check for eps = 0, set default drift media flags.
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)
static double ScalingFactor(std::string unit)
std::vector< Material > m_materials
std::vector< bool > m_wfieldsOk
size_t GetWeightingFieldIndex(const std::string &label) const
std::vector< Node > m_nodes
void PrintCouldNotOpen(const std::string &header, const std::string &filename) const
std::vector< double > m_wdtimes
std::vector< std::string > m_wfields
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< Element > m_elements
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 Element &element, const unsigned int n, const int iw=-1) const
void Reset() override
Reset the component.
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
size_t GetOrCreateWeightingFieldIndex(const std::string &label)
bool m_debug
Switch on/off debugging messages.
std::string m_className
Class name.
bool m_ready
Ready for use?
void n_nearest(const std::vector< double > &qv, const unsigned int nn, std::vector< KDTreeResult > &result) const
Abstract base class for media.
bool IsDriftable() const
Is charge carrier transport enabled in this medium?
std::vector< std::vector< double > > dw