24 m_hasPotential(false),
33 const double zin,
double& ex,
double& ey,
34 double& ez,
double& p,
Medium*& m,
41 std::cerr <<
" Field map is not available for interpolation.\n";
47 bool xMirrored, yMirrored, zMirrored;
48 if (!
GetElement(xin, yin, zin, i, j, k, xMirrored, yMirrored, zMirrored)) {
54 ex = m_mesh[i][j][k].ex;
55 ey = m_mesh[i][j][k].ey;
56 ez = m_mesh[i][j][k].ez;
57 p = m_mesh[i][j][k].v;
58 if (xMirrored) ex = -ex;
59 if (yMirrored) ey = -ey;
60 if (zMirrored) ez = -ez;
62 int region = m_mesh[i][j][k].region;
63 if (m_media.count(region) < 1) {
69 if (m == NULL) status = -5;
73 const double z,
double& ex,
double& ey,
74 double& ez,
Medium*& m,
int& status) {
86 std::cerr <<
" Field map not available for interpolation.\n";
91 bool xMirrored, yMirrored, zMirrored;
92 if (!
GetElement(xin, yin, zin, i, j, k, xMirrored, yMirrored, zMirrored)) {
95 if (m_media.count(m_mesh[i][j][k].region) < 1) {
98 return m_media[m_mesh[i][j][k].region];
102 const unsigned int nz,
const double xmin,
103 const double xmax,
const double ymin,
104 const double ymax,
const double zmin,
108 if (nx == 0 || ny == 0 || nz == 0) {
110 std::cerr <<
" Number of mesh elements must be positive.\n";
115 std::cerr <<
" Invalid x range.\n";
117 }
else if (ymin >= ymax) {
119 std::cerr <<
" Invalid y range.\n";
121 }
else if (zmin >= zmax) {
123 std::cerr <<
" Invalid z range.\n";
137 for (
unsigned int i = 0; i < m_nX; ++i) {
138 m_mesh[i].resize(m_nY);
139 for (
unsigned int j = 0; j < m_nY; ++j) {
140 m_mesh[i][j].resize(m_nZ);
141 for (
unsigned int k = 0; k < m_nZ; ++k) {
142 m_mesh[i][j][k].ex = 0.;
143 m_mesh[i][j][k].ey = 0.;
144 m_mesh[i][j][k].ez = 0.;
145 m_mesh[i][j][k].v = 0.;
146 m_mesh[i][j][k].region = -1;
154 const bool withPotential,
const bool withRegion,
155 const double scaleX,
const double scaleE,
156 const double scaleP) {
160 std::cerr <<
" Mesh is not set. Call SetMesh first.\n";
164 m_hasPotential = m_hasField =
false;
165 m_pMin = m_pMax = 0.;
171 unsigned int nValues = 0;
172 std::vector<std::vector<std::vector<bool> > > isSet;
174 for (
unsigned int i = 0; i < m_nX; ++i) {
175 isSet[i].resize(m_nY);
176 for (
unsigned int j = 0; j < m_nY; ++j) {
177 isSet[i][j].resize(m_nZ,
false);
180 std::ifstream infile;
181 infile.open(filename.c_str(), std::ios::in);
184 std::cerr <<
" Could not open file " << filename <<
".\n";
188 std::transform(format.begin(), format.end(), format.begin(), toupper);
189 unsigned int fmt = 0;
190 if (format ==
"XY") {
192 }
else if (format ==
"XYZ") {
194 }
else if (format ==
"IJ") {
196 }
else if (format ==
"IJK") {
200 std::cerr <<
" Unkown format (" << format <<
").\n";
204 unsigned int nLines = 0;
206 while (!infile.fail()) {
208 std::getline(infile, line);
211 line.erase(line.begin(),
212 std::find_if(line.begin(), line.end(),
213 not1(std::ptr_fun<int, int>(isspace))));
215 if (line.empty())
continue;
217 if (line[0] ==
'#')
continue;
218 if (line[0] ==
'/' && line[1] ==
'/')
continue;
227 std::istringstream data;
235 std::cerr <<
" Error reading line " << nLines <<
".\n";
236 std::cerr <<
" Cannot retrieve element coordinates.\n";
242 const double z = 0.5 * (m_zMin + m_zMax);
243 bool xMirrored, yMirrored, zMirrored;
244 if (!
GetElement(x, y, z, i, j, k, xMirrored, yMirrored, zMirrored)) {
246 std::cerr <<
" Error reading line " << nLines <<
".\n";
247 std::cerr <<
" Point is outside mesh.\n";
251 }
else if (fmt == 2) {
257 std::cerr <<
" Error reading line " << nLines <<
".\n";
258 std::cerr <<
" Cannot retrieve element coordinates.\n";
265 bool xMirrored, yMirrored, zMirrored;
266 if (!
GetElement(x, y, z, i, j, k, xMirrored, yMirrored, zMirrored)) {
268 std::cerr <<
" Error reading line " << nLines <<
".\n";
269 std::cerr <<
" Point is outside mesh.\n";
273 }
else if (fmt == 3) {
279 std::cerr <<
" Error reading line " << nLines <<
".\n";
280 std::cerr <<
" Cannot retrieve element index.\n";
284 }
else if (fmt == 4) {
289 std::cerr <<
" Error reading line " << nLines <<
".\n";
290 std::cerr <<
" Cannot retrieve element index.\n";
296 if (i >= m_nX || j >= m_nY || k >= m_nZ) {
298 std::cerr <<
" Error reading line " << nLines <<
".\n";
299 std::cerr <<
" Index (" << i <<
", " << j <<
", " << k
300 <<
") out of range.\n";
303 if (isSet[i][j][k]) {
305 std::cerr <<
" Error reading line " << nLines <<
".\n";
306 std::cerr <<
" Mesh element (" << i <<
", " << j <<
", " << k
307 <<
") has already been set.\n";
311 if (fmt == 1 || fmt == 3) {
316 data >> ex >> ey >> ez;
320 std::cerr <<
" Error reading line " << nLines <<
".\n";
321 std::cerr <<
" Cannot read electric field values.\n";
332 std::cerr <<
" Error reading line " << nLines <<
".\n";
333 std::cerr <<
" Cannot read potential.\n";
338 if (m_pMin > m_pMax) {
343 if (v < m_pMin) m_pMin = v;
344 if (v > m_pMax) m_pMax = v;
351 std::cerr <<
" Error reading line " << nLines <<
".\n";
352 std::cerr <<
" Cannot read region.\n";
357 if (fmt == 1 || fmt == 3) {
359 for (
unsigned int kk = 0; kk < m_nZ; ++kk) {
360 m_mesh[i][j][kk].ex = ex;
361 m_mesh[i][j][kk].ey = ey;
362 m_mesh[i][j][kk].ez = ez;
363 m_mesh[i][j][kk].v = v;
364 m_mesh[i][j][kk].region = region;
365 isSet[i][j][kk] =
true;
368 m_mesh[i][j][k].ex = ex;
369 m_mesh[i][j][k].ey = ey;
370 m_mesh[i][j][k].ez = ez;
371 m_mesh[i][j][k].v = v;
372 m_mesh[i][j][k].region = region;
373 isSet[i][j][k] =
true;
377 if (bad)
return false;
379 std::cout <<
" Read " << nValues <<
" values from file " << filename
381 unsigned int nExpected = m_nX * m_nY;
382 if (fmt == 2 || fmt == 4) nExpected *= m_nZ;
383 if (nExpected != nValues) {
385 std::cerr <<
" Expected " << nExpected <<
" values.\n";
392 double& xmax,
double& ymax,
double& zmax) {
394 if (!
ready)
return false;
423 if (!
ready)
return false;
430 double& eymin,
double& eymax,
431 double& ezmin,
double& ezmax) {
434 std::cerr <<
m_className <<
"::GetElectricFieldRange:\n";
435 std::cerr <<
" Field map not available.\n";
438 bool gotValue =
false;
439 for (
unsigned int i = 0; i < m_nX; ++i) {
440 for (
unsigned int j = 0; j < m_nY; ++j) {
441 for (
unsigned int k = 0; k < m_nZ; ++k) {
443 exmin = m_mesh[i][j][k].ex;
444 exmax = m_mesh[i][j][k].ex;
445 eymin = m_mesh[i][j][k].ey;
446 eymax = m_mesh[i][j][k].ey;
447 ezmin = m_mesh[i][j][k].ez;
448 ezmax = m_mesh[i][j][k].ez;
452 if (m_mesh[i][j][k].ex < exmin) exmin = m_mesh[i][j][k].ex;
453 if (m_mesh[i][j][k].ex > exmax) exmax = m_mesh[i][j][k].ex;
454 if (m_mesh[i][j][k].ey < eymin) eymin = m_mesh[i][j][k].ey;
455 if (m_mesh[i][j][k].ey > eymax) eymax = m_mesh[i][j][k].ey;
456 if (m_mesh[i][j][k].ez < ezmin) ezmin = m_mesh[i][j][k].ez;
457 if (m_mesh[i][j][k].ez > ezmax) ezmax = m_mesh[i][j][k].ez;
469 std::cerr <<
" Field map not yet initialised.\n";
473 if (m_media.size() < 1) {
475 std::cerr <<
" No regions are currently defined.\n";
480 if (m_media.size() == 1) {
481 std::cout <<
" 1 region is defined.\n";
483 std::cout <<
" " << m_media.size() <<
" regions are defined.\n";
485 std::cout <<
" Index Medium\n";
486 std::map<int, Medium*>::iterator it;
487 for (it = m_media.begin(); it != m_media.end(); ++it) {
488 const int i = (*it).first;
490 std::cout <<
" " << i <<
" ";
492 std::cout <<
" none\n";
494 std::cout <<
" " << m->
GetName() <<
"\n";
503 std::cerr <<
" Warning: medium pointer is null.\n";
510 if (m_media.count(i) < 1) {
512 std::cerr <<
" Medium " << i <<
" does not exist.\n";
520 const double zi,
unsigned int& i,
521 unsigned int& j,
unsigned int& k,
522 bool& xMirrored,
bool& yMirrored,
527 std::cerr <<
" Mesh is not set.\n";
531 double x = xi, y = yi, z = zi;
532 xMirrored = yMirrored = zMirrored =
false;
534 const double cellsx = m_xMax - m_xMin;
536 x = m_xMin + fmod(x - m_xMin, cellsx);
537 if (x < m_xMin) x += cellsx;
539 double xNew = m_xMin + fmod(x - m_xMin, cellsx);
540 if (xNew < m_xMin) xNew += cellsx;
541 int nx = int(floor(0.5 + (xNew - x) / cellsx));
542 if (nx != 2 * (nx / 2)) {
543 xNew = m_xMin + m_xMax - xNew;
549 if (x < m_xMin || x > m_xMax)
return false;
551 const double cellsy = m_yMax - m_yMin;
553 y = m_yMin + fmod(y - m_yMin, cellsy);
554 if (y < m_yMin) y += cellsy;
556 double yNew = m_yMin + fmod(y - m_yMin, cellsy);
557 if (yNew < m_yMin) yNew += cellsy;
558 int ny = int(floor(0.5 + (yNew - y) / cellsy));
559 if (ny != 2 * (ny / 2)) {
560 yNew = m_yMin + m_yMax - yNew;
566 if (y < m_yMin || y > m_yMax)
return false;
568 const double cellsz = m_zMax - m_xMin;
570 z = m_zMin + fmod(z - m_zMin, cellsz);
571 if (z < m_zMin) z += cellsz;
573 double zNew = m_zMin + fmod(z - m_zMin, cellsz);
574 if (zNew < m_zMin) zNew += cellsz;
575 int nz = int(floor(0.5 + (zNew - z) / cellsz));
576 if (nz != 2 * (nz / 2)) {
577 zNew = m_zMin + m_zMax - zNew;
583 if (z < m_zMin || z > m_zMax)
return false;
586 const double dx = (m_xMax - m_xMin) / m_nX;
587 const double dy = (m_yMax - m_yMin) / m_nY;
588 const double dz = (m_zMax - m_zMin) / m_nZ;
589 i = (
unsigned int)((x - m_xMin) / dx);
590 j = (
unsigned int)((y - m_yMin) / dy);
591 k = (
unsigned int)((z - m_zMin) / dz);
592 if (i >= m_nX) i = m_nX - 1;
593 if (j >= m_nY) j = m_nY - 1;
594 if (k >= m_nZ) k = m_nZ - 1;
599 const unsigned int k,
double& v,
double& ex,
600 double& ey,
double& ez) {
602 v = ex = ey = ez = 0.;
606 std::cerr <<
" Mesh not set.\n";
610 std::cerr <<
" Fiel map not set.\n";
613 if (i >= m_nX || j >= m_nY || k >= m_nZ) {
615 std::cerr <<
" Element index out of range.\n";
618 v = m_mesh[i][j][k].v;
619 ex = m_mesh[i][j][k].ex;
620 ey = m_mesh[i][j][k].ey;
621 ez = m_mesh[i][j][k].ez;
625void ComponentVoxel::Reset() {
628 m_nX = m_nY = m_nZ = 0;
629 m_xMin = m_yMin = m_zMin = 0.;
630 m_xMax = m_yMax = m_zMax = 0.;
631 m_pMin = m_pMax = 0.;
635 m_hasPotential =
false;
641void ComponentVoxel::UpdatePeriodicity() {
644 std::cerr <<
m_className <<
"::UpdatePeriodicity:\n";
645 std::cerr <<
" Field map not available.\n";
651 std::cerr <<
m_className <<
"::UpdatePeriodicity:\n";
652 std::cerr <<
" Both simple and mirror periodicity\n";
653 std::cerr <<
" along x requested; reset.\n";
658 std::cerr <<
m_className <<
"::UpdatePeriodicity:\n";
659 std::cerr <<
" Both simple and mirror periodicity\n";
660 std::cerr <<
" along y requested; reset.\n";
665 std::cerr <<
m_className <<
"::UpdatePeriodicity:\n";
666 std::cerr <<
" Both simple and mirror periodicity\n";
667 std::cerr <<
" along z requested; reset.\n";
672 std::cerr <<
m_className <<
"::UpdatePeriodicity:\n";
673 std::cerr <<
" Axial symmetry is not supported; reset.\n";
678 std::cerr <<
m_className <<
"::UpdatePeriodicity:\n";
679 std::cerr <<
" Rotation symmetry is not supported; reset.\n";
void SetMedium(const int i, Medium *m)
bool GetBoundingBox(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax)
Medium * GetMedium(const double &x, const double &y, const double &z)
bool GetElectricFieldRange(double &exmin, double &exmax, double &eymin, double &eymax, double &ezmin, double &ezmax)
bool GetVoltageRange(double &vmin, double &vmax)
bool GetElement(const double xi, const double yi, const double zi, unsigned int &i, unsigned int &j, unsigned int &k, bool &xMirrored, bool &yMirrored, bool &zMirrored)
void ElectricField(const double x, const double y, const double z, double &ex, double &ey, double &ez, double &v, Medium *&m, int &status)
void SetMesh(const unsigned int nx, const unsigned int ny, const unsigned int nz, const double xmin, const double xmax, const double ymin, const double ymax, const double zmin, const double zmax)
bool LoadData(const std::string filename, std::string format, const bool withPotential, const bool withRegion, const double scaleX=1., const double scaleE=1., const double scaleP=1.)
std::string GetName() const