57 const std::string &mplist,
58 const std::string &field,
59 const std::string &unit) {
62 std::vector<int> nodeIndices;
67 std::cerr <<
m_className <<
"::Initialise:\n Unknown length unit "
68 << unit <<
". Will use default (m).\n";
73 std::ifstream fmplist(mplist);
78 unsigned int nMaterials;
79 fmplist >> nMaterials;
80 for (
unsigned int i = 0; i < nMaterials; ++i) {
85 fmplist >> material.
eps;
93 material.
eps = material.
ohm = -1;
97 std::map<int, int> domain2material;
100 for (
int i = 0; i < d2msize; ++i) {
102 fmplist >> domain >> mat;
103 domain2material[domain] = mat;
111 std::ifstream fmesh(mesh);
119 if (!std::getline(fmesh, line)) {
121 <<
" Could not read number of nodes from " << mesh <<
".\n";
125 }
while (!ends_with(line,
"# number of mesh points") &&
126 !ends_with(line,
"# number of mesh vertices"));
128 const int nNodes = std::stoi(line);
130 std::cout <<
m_className <<
"::Initialise: " << nNodes <<
" nodes.\n";
132 if (!std::getline(fmesh, line)) {
134 <<
" Error parsing " << mesh <<
".\n";
138 }
while (line.find(
"# Mesh point coordinates") == std::string::npos &&
139 line.find(
"# Mesh vertex coordinates") == std::string::npos);
141 std::vector<Node> allNodes;
142 for (
int i = 0; i < nNodes; ++i) {
144 fmesh >> node.
x >> node.
y >> node.
z;
149 allNodes.push_back(std::move(node));
150 if (CheckInRange(node.
x, node.
y, node.
z)) nInRange++;
152 m_nodes.push_back(std::move(node));
158 if (!std::getline(fmesh, line)) {
160 <<
" Error parsing " << mesh <<
".\n";
164 }
while (line.find(
"4 tet2 # type name") == std::string::npos);
166 if (!std::getline(fmesh, line)) {
168 <<
" Error parsing " << mesh <<
".\n";
172 }
while (!ends_with(line,
"# number of elements"));
174 const int nElements = std::stoi(line);
175 std::cout <<
m_className <<
"::Initialise: " << nElements <<
" elements.\n";
176 std::getline(fmesh, line);
177 std::vector<Element> allElements;
180 int perm[10] = {0, 1, 2, 3, 4, 5, 7, 6, 8, 9};
181 for (
int i = 0; i < nElements; ++i) {
183 for (
int j = 0; j < 10; ++j) {
184 fmesh >> element.
emap[perm[j]];
186 allElements.push_back(std::move(element));
190 if (!std::getline(fmesh, line)) {
192 <<
" Error parsing " << mesh <<
".\n";
196 }
while (line.find(
"# Geometric entity indices") == std::string::npos);
197 for (
auto& element : allElements) {
200 if (domain2material.count(domain) > 0) {
201 element.matmap = domain2material[domain];
203 element.matmap = nMaterials - 1;
208 for (
auto& element : allElements) {
209 if (ElementInRange(element, allNodes)) {
210 for (
int j = 0; j < 10; j++) {
211 nodeIndices.push_back(element.emap[j]);
219 std::vector<int> nodeMap(nNodes, -1);
221 std::sort(nodeIndices.begin(), nodeIndices.end());
222 nodeIndices.erase(std::unique(nodeIndices.begin(), nodeIndices.end()),
225 for (
int i : nodeIndices) {
226 m_nodes.push_back(allNodes[i]);
228 nodeMap[i] =
m_nodes.size() - 1;
233 for (
int j = 0; j < 10; ++j) {
234 element.emap[j] = nodeMap[element.emap[j]];
235 if (element.emap[j] == -1)
return false;
240 std::ifstream ffield(field);
246 const std::string hdr1 =
250 const std::string hdr2 =
253 if (!std::getline(ffield, line)) {
255 <<
" Error parsing " << field <<
".\n";
259 }
while (line.find(hdr1) == std::string::npos &&
260 line.find(hdr2) == std::string::npos);
261 std::istringstream sline(line);
269 std::vector<std::string> wfields;
270 while (sline >> token) {
272 <<
" Reading data for weighting field " << token <<
".\n";
273 wfields.push_back(token);
274 m_wpot.emplace(token, std::vector<double>(
m_nodes.size(), 0.));
277 const size_t nWeightingFields = wfields.size();
279 const unsigned int nPrint =
280 std::pow(10,
static_cast<unsigned int>(
281 std::max(std::floor(std::log10(nNodes)) - 1, 1.)));
282 std::cout <<
m_className <<
"::Initialise: Reading potentials.\n";
285 std::vector<std::vector<double> > points;
286 for (
const auto &node :
m_nodes) {
287 std::vector<double> point = {node.x, node.y, node.z};
288 points.push_back(std::move(point));
292 const int usedSize = m_range.set ?
m_nodes.size() : nNodes;
293 std::vector<bool> used(usedSize,
false);
294 for (
int i = 0; i < nNodes; ++i) {
296 ffield >> x >> y >> z >> v;
300 std::vector<double> w;
301 for (
size_t j = 0; j < nWeightingFields; ++j) {
306 if (!CheckInRange(x, y, z))
continue;
307 std::vector<KDTreeResult> res;
311 <<
" Could not find a matching mesh node for point ("
312 << x <<
", " << y <<
", " << z <<
")\n.";
316 if (res[0].dis > MaxNodeDistance)
continue;
317 const size_t k = res[0].idx;
320 for (
size_t j = 0; j < nWeightingFields; ++j) {
321 m_wpot[wfields[j]][k] = w[j];
323 if ((i + 1) % nPrint == 0) PrintProgress(
double(i + 1) / nNodes);
327 auto nMissing = std::count(used.begin(), used.end(),
false);
328 if (m_range.set) nMissing = nMissing -
m_nodes.size() + nInRange;
331 <<
" Missing potentials for " << nMissing <<
" nodes.\n";
337 std::cout << std::endl <<
m_className <<
"::Initialise: Done.\n";
433 const std::string &label) {
435 std::cerr <<
m_className <<
"::SetDynamicWeightingPotential:\n"
436 <<
" No valid field map is present.\n"
437 <<
" Weighting fields cannot be added.\n";
441 if (!m_timeset && !GetTimeInterval(field))
return false;
444 std::cerr <<
m_className <<
"::SetDynamicWeightingPotential:\n"
445 <<
" No valid times slices of potential set.\n"
446 <<
" Please add the time slices.\n";
453 std::ifstream ffield(field);
460 if (
m_wpot.count(label) > 0) {
461 std::cout <<
m_className <<
"::SetDynamicWeightingPotential:\n"
462 <<
" Replacing existing weighting field " << label <<
".\n";
465 if (
m_dwpot.count(label) > 0) {
469 std::vector<double> pot(
m_nodes.size(), 0.);
470 std::vector<std::vector<double> > dpot(
m_nodes.size());
473 std::vector<std::vector<double> > points;
474 for (
const auto &node :
m_nodes) {
475 std::vector<double> point = {node.x, node.y, node.z};
476 points.push_back(std::move(point));
482 const int nNodes =
m_nodes.size();
483 const unsigned int nPrint =
484 std::pow(10,
static_cast<unsigned int>(
485 std::max(std::floor(std::log10(nNodes)) - 1, 1.)));
486 std::cout <<
m_className <<
"::SetDynamicWeightingPotential:\n"
487 <<
" Reading weighting potentials for " << label <<
".\n";
490 while (std::getline(ffield, line)) {
492 if (line.empty())
continue;
494 if (isComment(line))
continue;
496 std::istringstream data(line);
497 double x = 0., y = 0., z = 0.;
502 if (!CheckInRange(x, y, z))
continue;
503 std::vector<KDTreeResult> res;
506 std::cerr <<
m_className <<
"::SetDynamicWeightingPotential:\n"
507 <<
" Could not find a matching mesh node for point ("
508 << x <<
", " << y <<
", " << z <<
")\n.";
512 if (res[0].dis > MaxNodeDistance)
continue;
516 std::vector<double> pvect;
517 for (
int i = 0; i < T; i++) {
520 pvect.push_back(p - p0);
522 const size_t k = res[0].idx;
526 if ((nLines + 1) % nPrint == 0) {
527 PrintProgress(
double(nLines + 1) / nNodes);
533 std::cout << std::endl
534 <<
m_className <<
"::SetDynamicWeightingPotential: Done.\n";
536 m_wpot[label] = std::move(pot);
537 m_dwpot[label] = std::move(dpot);