68 std::set<int> unique_numbers;
69 for (
const auto& sublist : connections)
73 unique_numbers.insert(sublist.front());
74 unique_numbers.insert(sublist.back());
77 std::vector<int> sorted_numbers(unique_numbers.begin(), unique_numbers.end());
78 for (
size_t i = 1;
i < sorted_numbers.size(); ++
i)
80 if (sorted_numbers[
i] != sorted_numbers[
i - 1] + 1)
82 int diff = sorted_numbers[
i] - (sorted_numbers[
i - 1] + 1);
83 for (
size_t j =
i;
j < sorted_numbers.size(); ++
j)
85 sorted_numbers[
j] -= diff;
89 std::map<int, int> adjust_map;
90 for (
size_t i = 0;
i < sorted_numbers.size(); ++
i)
92 adjust_map[*next(unique_numbers.begin(),
i)] = sorted_numbers[
i];
94 for (
auto& sublist : connections)
96 for (
auto&
num : sublist)
98 if (adjust_map.find(
num) != adjust_map.end())
186 std::set<size_t> removedIndices;
187 for (
const auto& pair : removedNodeIDmap)
189 removedIndices.insert(pair.second);
191 Eigen::MatrixXd updatedNodePythonVelocity = Eigen::MatrixXd::Zero(nodePythonVelocity.rows() + removedIndices.size(), this->NdofXnode);
195 for (newRow = 0; oldRow < nodePythonVelocity.rows(); ++newRow)
197 if (removedIndices.find(newRow) != removedIndices.end())
199 updatedNodePythonVelocity.row(newRow) = Eigen::RowVectorXd::Zero(this->NdofXnode);
203 updatedNodePythonVelocity.row(newRow) = nodePythonVelocity.row(oldRow);
207 return updatedNodePythonVelocity;
214 const auto t0= std::chrono::system_clock::now();
215 std::cout<<
"PyGlideSolver solving " <<
"\n" << std::flush;
219 std::ofstream f_file;
220 std::ofstream F_labels;
221 this->
DN.output(configIO,auxIO,f_file,F_labels);
224 for(
const auto& entry : this->
DN.networkLinks())
226 for(
const auto& point : entry.second.lock()->quadraturePoints())
231 const auto Temperature(this->
DN.ddBase.poly.T);
233 const auto segmentMap(configIO.segments());
235 std::map<size_t, DislocationNodeIO<3>> nodeMap;
237 for (
const auto &node : configIO.nodes())
239 nodeMap.emplace(node.sID, node);
243 std::map<std::pair<size_t, size_t>, std::map<size_t, DislocationQuadraturePointIO<3>>> qPointsMap;
244 std::set<std::pair<size_t, size_t>> segmentConnetions;
248 const std::pair<size_t, size_t> outerKey(std::make_pair(qp.sourceID, qp.sinkID));
249 const size_t innerKey(qp.qID);
250 qPointsMap[outerKey].emplace(innerKey, qp);
251 segmentConnetions.insert(outerKey);
254 int segmentsSize(segmentConnetions.size());
256 std::map<size_t, size_t> nodesToRemove;
258 for (
const auto& node : nodeMap)
261 for (
const auto& qp : qPointsMap)
263 if (qp.first.first == node.first || qp.first.second == node.first)
271 nodesToRemove.emplace(node.first,
j);
275 for (
const auto& nodeKey : nodesToRemove)
277 nodeMap.erase(nodeKey.first);
279 int nodeSize(nodeMap.size());
282 Eigen::MatrixXd nodalPositions(Eigen::MatrixXd::Zero(nodeSize+qpSize,this->
DN.NdofXnode));
283 int positionsCount(0);
284 for (
const auto &node : nodeMap)
286 nodalPositions.row(positionsCount) << node.second.P.transpose()*this->
DN.ddBase.poly.b_SI*1.0e10;
289 for (
const auto &outerPair : qPointsMap)
291 for (
const auto &innerPair : outerPair.second)
293 const auto &qp(innerPair.second);
294 nodalPositions.row(positionsCount) << qp.r.transpose()*this->
DN.ddBase.poly.b_SI*1.0e10;
300 Eigen::MatrixXd nodalStresses(Eigen::MatrixXd::Zero(nodeSize+qpSize,this->
DN.NdofXnode*this->DN.NdofXnode));
301 int stressesCount(nodeMap.size());
302 for (
const auto &outerPair : qPointsMap)
304 for (
const auto &innerPair : outerPair.second)
306 const auto &qp(innerPair.second);
307 Eigen::Matrix<double, 3, 3> tempStress(Eigen::Matrix<double,3,3>::Zero());
308 tempStress << qp.stress*this->
DN.ddBase.poly.mu_SI*1
e-9;
309 nodalStresses.row(stressesCount) << tempStress.reshaped<Eigen::RowMajor>().transpose();
315 Eigen::MatrixXd nodalBurgersVector(Eigen::MatrixXd::Zero(segmentsSize,this->
DN.NdofXnode));
316 int burgersVectorCount(0);
317 for (
const auto &outerPair : qPointsMap)
319 nodalBurgersVector.row(burgersVectorCount) << segmentMap.at(outerPair.first).b.transpose()*this->
DN.ddBase.poly.b_SI*1.0e10;
320 burgersVectorCount+=1;
324 std::list<std::list<int>> segmentConnections;
325 std::list<int> singleConnection;
326 size_t qPointsCounter(1);
327 for (
const auto &outerPair : qPointsMap)
329 const auto &sourceNodeID(outerPair.first.first);
330 const auto &sinkNodeID(outerPair.first.second);
331 singleConnection.push_back(sourceNodeID);
332 for (
size_t k = 0;
k < outerPair.second.size(); ++
k)
334 singleConnection.push_back(qPointsCounter +
k + nodeMap.rbegin()->first);
336 qPointsCounter += outerPair.second.size();
337 singleConnection.push_back(sinkNodeID);
338 segmentConnections.push_back(singleConnection);
339 singleConnection.erase(singleConnection.begin(),singleConnection.end());
347 Eigen::MatrixXd nodePythonVelocity;
350 std::cout<<
"Computing Nodal Velocities from ML..." << std::endl;
351 nodePythonVelocity =
pyModule.attr(
"PIGNN")().attr(
"MLmobility")(nodalPositions,nodalStresses,nodalBurgersVector,segmentConnections,Temperature).
template cast<Eigen::MatrixXd>();
355 std::cout<<
"There are No Remaining Dislocations..." << std::endl;
356 nodePythonVelocity = Eigen::MatrixXd::Zero(nodeMap.size(), 3);
360 if(nodePythonVelocity.rows()!=nodeSize || nodePythonVelocity.cols()!=dim || !nodePythonVelocity.allFinite())
362 throw std::runtime_error(
"Python glide model returned invalid nodal velocities.");
365 Eigen::MatrixXd updatedVelocity = updatedVelo;
366 updatedVelocity /= 3.228757859764734e01;
388 std::cout<<
magentaColor<<std::setprecision(3)<<std::scientific<<
" ["<<(std::chrono::duration<double>(std::chrono::system_clock::now()-
t0)).
count()<<
" sec]."<<
defaultColor<<std::endl;