Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
DDFieldWidget.cpp
Go to the documentation of this file.
1/* This file is part of MODEL, the Mechanics Of Defect Evolution Library.
2 *
3 * Copyright (C) 2011 by Giacomo Po <gpo@ucla.edu>.
4 *
5 * model is distributed without any warranty under the
6 * GNU General Public License (GPL) v2 <http://www.gnu.org/licenses/>.
7 */
8
9#ifndef model_DDFieldWidget_cpp_
10#define model_DDFieldWidget_cpp_
11
12#include <sstream> // std::ostringstream
13#include <string>
14#include <iostream>
15#include <iomanip>
16#include <exception>
17
18#ifdef _OPENMP
19#include <omp.h>
20#endif
21
22#include <QVBoxLayout>
23#include <vtkProperty.h>
24#include <vtkTriangle.h>
25#include <vtkCellData.h>
26#include <vtkFloatArray.h>
27#include <vtkAxis.h>
28#include <DDFieldWidget.h>
30
31#include <DDqtControls.h>
32#include <PlaneSectionMesh.h>
33#include <QMessageBox>
34
35namespace model
36{
37
38template <typename FloatType>
39std::string to_string_exact(const FloatType& x, const int& n)
40{
41 std::ostringstream os;
42 os << std::scientific<<std::setprecision(n)<< x;
43 return os.str();
44}
45
46FieldDataPnt::FieldDataPnt(const DefectiveCrystal<3>& defectiveCrystal,const Eigen::Matrix<double,3,1>& Pin,const ElementType* const ele_in):
47/* init */ voigtTraits(defectiveCrystal.ddBase.voigtTraits)
48/* init */,P(Pin)
49/* init */,ele(ele_in)
50/* init */,displacement(defectiveCrystal.microstructures().size(),Eigen::Matrix<double,3,1>::Zero())
51/* init */,stress(defectiveCrystal.microstructures().size(),Eigen::Matrix<double,3,3>::Zero())
52/* init */,mobileConcentration(defectiveCrystal.microstructures().size(),Eigen::Matrix<double,ClusterDynamicsParameters<3>::mSize,1>::Zero())
53/* init */,immobileClusters(defectiveCrystal.microstructures().size(),Eigen::Matrix<double,ClusterDynamicsParameters<3>::iSize,1>::Zero())
54{
55
56}
57
58void FieldDataPnt::compute(const DefectiveCrystal<3>& defectiveCrystal)
59{
60 int mID(0);
61 for(const auto& mStruct : defectiveCrystal.microstructures())
62 {
63 displacement[mID]=mStruct->displacement(P,nullptr,ele,nullptr);
64 stress[mID]=mStruct->stress(P,nullptr,ele,nullptr);
65 mobileConcentration[mID]=mStruct->mobileConcentration(P,nullptr,ele,nullptr);
66 mID++;
67 }
68}
69
70
71double FieldDataPnt::value(const int& valID,const std::vector<QCheckBox*>& microstructuresCheck) const
72{
73 // std::cout<<valID<<std::endl;
74 if(valID<3)
75 {
76 double temp(0.0);
77 for(size_t k=0;k<displacement.size();++k)
78 {
79 if(microstructuresCheck[k]->isChecked())
80 {
81 temp+=displacement[k](valID);
82 }
83 }
84 return temp;
85 }
86 else if(valID<6+3)
87 {
88 const int i(voigtTraits.tensorIndex(valID-3,0));
89 const int j(voigtTraits.tensorIndex(valID-3,1));
90 double temp(0.0);
91 for(size_t k=0;k<stress.size();++k)
92 {
93 if(microstructuresCheck[k]->isChecked())
94 {
95 temp+=stress[k](i,j);
96 }
97 }
98 return temp;
99 }
100 else if(valID==6+3)
101 {
102 Eigen::Matrix<double,3,3> temp(Eigen::Matrix<double,3,3>::Zero());
103 for(size_t k=0;k<stress.size();++k)
104 {
105 if(microstructuresCheck[k]->isChecked())
106 {
107 temp+=stress[k];
108 }
109 }
110 return temp.trace();
111 }
112 else if(valID==7+3)
113 {
114 Eigen::Matrix<double,3,3> temp(Eigen::Matrix<double,3,3>::Zero());
115 for(size_t k=0;k<stress.size();++k)
116 {
117 if(microstructuresCheck[k]->isChecked())
118 {
119 temp+=stress[k];
120 }
121 }
122 const Eigen::Matrix<double,3,3> tempDev(temp-temp.trace()/3.0*Eigen::Matrix<double,3,3>::Identity());
123 return std::sqrt((tempDev*tempDev).trace()*1.5);
124 }
125// else if(valID==8+3)
126// {
127// return solidAngle*useDD;
128// }
129 else if(valID>7+3 && valID<=7+3+mSize)
130 {
131 double temp(0.0);
132 for(size_t k=0;k<stress.size();++k)
133 {
134 if(microstructuresCheck[k]->isChecked())
135 {
136 temp+=mobileConcentration[k](valID-8-3);
137 }
138 }
139 return temp;
140 }
141 else if(valID>7+3+mSize && valID<=7+3+mSize+iSize)
142 {
143 double temp(0.0);
144 for(size_t k=0;k<stress.size();++k)
145 {
146 if(microstructuresCheck[k]->isChecked())
147 {
148 temp+=immobileClusters[k](valID-8-3-mSize);
149 }
150 }
151 return temp;
152 }
153 else
154 {
155 return 0.0;
156 }
157}
158
159DDFieldWidget::DDFieldWidget(vtkGenericOpenGLRenderWindow* const renWin_in,
160 vtkRenderer* const renderer_in,
161 const DefectiveCrystal<3>& defectiveCrystal_in):
162/* init */ mainLayout(new QGridLayout(this))
163/* init */,boxLabel(new QLabel(tr("# of planes")))
164/* init */,spinBox(new QSpinBox(this))
165/* init */,groupBox(new controls::GroupBox(tr("&Planes")))
166/* init */,linesBoxLabel(new QLabel(tr("# of lines")))
167/* init */,linesSpinBox(new QSpinBox(this))
168/* init */,linesGroupBox(new controls::GroupBox(tr("&Lines")))
169/* init */,computeButton(new QPushButton(tr("Compute")))
170/* init */,fieldComboBox(new QComboBox(this))
175/* init */,customScaleBox(new controls::GroupBox(tr("&Custom scale")))
176/* init */,minScale(new QLineEdit(tr("0")))
177/* init */,maxScale(new QLineEdit(tr("1")))
178/* init */,scaleBarBox(new controls::GroupBox(tr("&ScaleBar")))
179/* init */,lut(vtkSmartPointer<vtkLookupTable>::New())
180/* init */,scalarBar(vtkSmartPointer<vtkScalarBarActor>::New())
181/* init */,renWin(renWin_in)
182/* init */,renderer(renderer_in)
183/* init */,defectiveCrystal(defectiveCrystal_in)
184{
185
186 QVBoxLayout* groupBoxLayout = new QVBoxLayout();
187 groupBox->setLayout(groupBoxLayout);
188
189 QVBoxLayout* linesGroupBoxLayout = new QVBoxLayout();
190 linesGroupBox->setLayout(linesGroupBoxLayout);
191
192
193 QGridLayout* autoscaleLayout = new QGridLayout();
194 customScaleBox->setCheckable(true);
195 customScaleBox->setChecked(false);
196
198 autoscaleLayout, 0, "Minimum", minScale,
199 "Lower field color-scale bound. Press Enter to apply; disable Custom scale to use automatic bounds.");
200 controls::field(autoscaleLayout, 1, "Maximum", maxScale, "Upper field color-scale bound. Press Enter to apply.");
201
202 customScaleBox->setLayout(autoscaleLayout);
203
204 scaleBarBox->setCheckable(true);
205 scaleBarBox->setChecked(false);
206
207
208
209
210 for(int k=0;k<3;++k)
211 {
212 fieldComboBox->insertItem(k,QString::fromStdString("displacement_"+std::to_string(k+1)));
213 }
214 for(int k=0;k<defectiveCrystal.ddBase.voigtTraits.tensorIndex.rows();++k)
215 {
216 const int& i(defectiveCrystal.ddBase.voigtTraits.tensorIndex(k,0));
217 const int& j(defectiveCrystal.ddBase.voigtTraits.tensorIndex(k,1));
218 fieldComboBox->insertItem(k+3,QString::fromStdString("stress_"+std::to_string(i+1)+std::to_string(j+1)));
219 }
220 fieldComboBox->insertItem(6+3,"tr(stress)");
221 fieldComboBox->insertItem(7+3,"stress_VM");
222 if(defectiveCrystal.ddBase.clusterDynamicsBase)
223 {
224 const auto& mobileSpecies=defectiveCrystal.ddBase.clusterDynamics().msVector;
225 for(Eigen::Index k=0;k<mobileSpecies.size();++k)
226 {
227 const int species=static_cast<int>(mobileSpecies(k));
228 const int size=std::abs(species);
229 const QString defect=species<0 ? "v" : "i";
230 const QString label=species==-1 ? "c_v" :
231 "c_"+(size==1 ? QString() : QString::number(size))+defect;
232 fieldComboBox->insertItem(11+static_cast<int>(k),label);
233 }
234 }
235
236 for(const auto& mstruct : defectiveCrystal.microstructures())
237 {
238 microstructuresCheck.emplace_back(new QCheckBox(QString::fromStdString(mstruct->tag),this));
239 microstructuresCheck.back()->setChecked(true);
240 connect(microstructuresCheck.back(),SIGNAL(stateChanged(int)), this, SLOT(plotField()));
241 }
242
243 connect(spinBox,SIGNAL(valueChanged(int)), this, SLOT(resetPlanes()));
244 connect(linesSpinBox,SIGNAL(valueChanged(int)), this, SLOT(resetLines()));
245 connect(computeButton,SIGNAL(released()), this, SLOT(compute()));
246 connect(fieldComboBox,SIGNAL(currentIndexChanged(int)), this, SLOT(plotField()));
247 connect(minScale,SIGNAL(returnPressed()), this, SLOT(plotField()));
248 connect(maxScale,SIGNAL(returnPressed()), this, SLOT(plotField()));
249// connect(dislocationsCheck,SIGNAL(stateChanged(int)), this, SLOT(plotField()));
250// connect(inclusionsCheck,SIGNAL(stateChanged(int)), this, SLOT(plotField()));
251// connect(cdCheck,SIGNAL(stateChanged(int)), this, SLOT(plotField()));
252// connect(edCheck,SIGNAL(stateChanged(int)), this, SLOT(plotField()));
253 connect(customScaleBox,SIGNAL(toggled(bool)), this, SLOT(plotField()));
254 connect(scaleBarBox,SIGNAL(toggled(bool)), this, SLOT(plotField()));
255
256 boxLabel->hide();
257 linesBoxLabel->hide();
258 auto *samplingBox = controls::box("Sampling", this, "Choose how many sampling planes and lines to configure.");
259 controls::field(controls::grid(samplingBox), 0, "Planes", spinBox,
260 "Number of field-sampling planes. Changing this resets the plane definitions.");
261 controls::field(controls::grid(samplingBox), 1, "Lines", linesSpinBox,
262 "Number of line profiles. Changing this resets the line definitions.");
263 auto *displayBox = controls::box("Field display", this, "Compute and display the selected field component.");
264 controls::field(controls::grid(displayBox), 0, "Quantity", fieldComboBox,
265 "Field component to plot: displacement, stress or concentration in simulation units.");
266 controls::grid(displayBox)->addWidget(computeButton, 1, 0, 1, 2);
267 computeButton->setToolTip("Evaluate fields on all configured sampling planes and lines, then refresh their plots.");
268 auto *physicsBox =
269 controls::box("Physics", this, "Choose which microstructure contributions are summed for the displayed field.");
270 for(size_t k=0;k<microstructuresCheck.size();++k)
271 {
272 controls::grid(physicsBox)->addWidget(microstructuresCheck[k], static_cast<int>(k), 0, 1, 2);
273 microstructuresCheck[k]->setToolTip(
274 "Include this physics contribution in the plotted field. This changes the sum of already computed values.");
275 }
276 customScaleBox->setToolTip("Use the entered limits instead of the automatic field color scale.");
277 scaleBarBox->setToolTip("Show or hide the field color legend in the viewer.");
278 groupBox->setToolTip("Configure individual sampling planes; each plane checkbox controls its visibility.");
279 linesGroupBox->setToolTip("Configure individual line profiles; each line checkbox controls its visibility.");
280 mainLayout->addWidget(samplingBox, 0, 0);
281 mainLayout->addWidget(groupBox, 1, 0);
282 mainLayout->addWidget(linesGroupBox, 2, 0);
283 mainLayout->addWidget(displayBox, 3, 0);
284 mainLayout->addWidget(physicsBox, 4, 0);
285 mainLayout->addWidget(customScaleBox, 5, 0);
286 mainLayout->addWidget(scaleBarBox, 6, 0);
287 mainLayout->setRowStretch(7, 1);
288 this->setLayout(mainLayout);
289
290
291 lut->SetHueRange(0.66667, 0.0);
292 lut->Build();
293
294 scalarBar->VisibilityOff();
295 scalarBar->SetNumberOfLabels(4);
296 scalarBar->GetLabelTextProperty()->SetColor(0,0,0);
297 scalarBar->SetLookupTable( lut );
298
299 //renderer->AddActor2D(scalarBar);
300 renderer->AddViewProp(scalarBar);
301
302}
303
305{
306 if(groupBox)
307 {
308 if(groupBox->layout())
309 {
310 for(int k=0;k<groupBox->layout()->count();++k)
311 {
312 QLayoutItem *item = groupBox->layout()->itemAt(k);
313 QWidget* widget = item->widget();
314 if(widget)
315 {
316 auto* ddPlaneField = dynamic_cast<DDPlaneField*>(widget);
317 if (ddPlaneField)
318 {
319 ddPlaneField->compute(defectiveCrystal);
320 }
321 }
322 }
323 }
324 }
325
326 if(linesGroupBox)
327 {
328 if(linesGroupBox->layout())
329 {
330 for(int k=0;k<linesGroupBox->layout()->count();++k)
331 {
332 QLayoutItem *item = linesGroupBox->layout()->itemAt(k);
333 QWidget* widget = item->widget();
334 if(widget)
335 {
336 auto* ddLineField = dynamic_cast<DDLineField*>(widget);
337 if (ddLineField)
338 {
339 ddLineField->compute(defectiveCrystal);
340 }
341 }
342 }
343 }
344 }
345
346 plotField();
347
348}
349
350void DDFieldWidget::plotField()
351{
352
353// std::vector<bool> checkedMicrostructs;
354// for(const auto& mStruct : microstructuresCheck)
355// {
356// checkedMicrostructs.push_back(mStruct->isChecked());
357// }
358 const int valID(fieldComboBox->currentIndex());
359
360 // Compute lut range if customScaleBox is off
361 if(!customScaleBox->isChecked())
362 {// compute range
363 double minValue=std::numeric_limits<double>::max();
364 double maxValue=-std::numeric_limits<double>::max();
365 if(groupBox->layout())
366 {
367 for(int k=0;k<groupBox->layout()->count();++k)
368 {
369 QLayoutItem *item = groupBox->layout()->itemAt(k);
370 QWidget* widget = item->widget();
371 if(widget)
372 {
373 auto* ddPlaneField = dynamic_cast<DDPlaneField*>(widget);
374 if (ddPlaneField)
375 {
376 if(ddPlaneField->groupBox->isChecked())
377 {
378 for(const auto& vtx : ddPlaneField->dataPnts())
379 {
380 // const double value(vtx.value(valID,dislocationsCheck->isChecked(),inclusionsCheck->isChecked(),cdCheck->isChecked(),edCheck->isChecked()));
381 const double value(vtx.value(valID,microstructuresCheck));
382 minValue=std::min(minValue,value);
383 maxValue=std::max(maxValue,value);
384 }
385 }
386 }
387 }
388 }
389 }
390
391 if(linesGroupBox->layout())
392 {
393 for(int k=0;k<linesGroupBox->layout()->count();++k)
394 {
395 QLayoutItem *item = linesGroupBox->layout()->itemAt(k);
396 QWidget* widget = item->widget();
397 if(widget)
398 {
399 auto* ddLineField = dynamic_cast<DDLineField*>(widget);
400 if (ddLineField)
401 {
402 if(ddLineField->groupBox->isChecked())
403 {
404 for(const auto& vtx : ddLineField->dataPnts())
405 {
406 const double value(vtx.value(valID,microstructuresCheck));
407 minValue=std::min(minValue,value);
408 maxValue=std::max(maxValue,value);
409 }
410 }
411 }
412 }
413 }
414 }
415
416 if(minValue > maxValue)
417 {
418 scalarBar->SetVisibility(false);
419 return;
420 }
421 minScale->setText(QString::fromStdString(to_string_exact(minValue,7)));
422 maxScale->setText(QString::fromStdString(to_string_exact(maxValue,7)));
423 }
424
425 // Set lut range
426 try
427 {
428 double lutMin(std::stod(minScale->text().toStdString().c_str()));
429 // minScale->setStyleSheet("color: black");
430 try
431 {
432 double lutMax(std::stod(maxScale->text().toStdString().c_str()));
433 // maxScale->setStyleSheet("color: black");
434 lut->SetTableRange(lutMin, lutMax);
435
436 for(int k=0;k<groupBox->layout()->count();++k)
437 {
438 QLayoutItem *item = groupBox->layout()->itemAt(k);
439 QWidget* widget = item->widget();
440 if(widget)
441 {
442 auto* ddPlaneField = dynamic_cast<DDPlaneField*>(widget);
443 if (ddPlaneField)
444 {
445 if(ddPlaneField->groupBox->isChecked())
446 {
447 ddPlaneField->plotField(valID,microstructuresCheck,lut);
448 }
449 }
450 }
451 }
452
453 for(int k=0;k<linesGroupBox->layout()->count();++k)
454 {
455 QLayoutItem *item = linesGroupBox->layout()->itemAt(k);
456 QWidget* widget = item->widget();
457 if(widget)
458 {
459 auto* ddLineField = dynamic_cast<DDLineField*>(widget);
460 if (ddLineField)
461 {
462 if(ddLineField->groupBox->isChecked())
463 {
464 ddLineField->plotField(valID,microstructuresCheck,fieldComboBox);
465 }
466 }
467 }
468 }
469
470 scalarBar->SetVisibility(scaleBarBox->isChecked());
471 if(renWin->GetReadyForRendering())
472 {
473 renWin->Render();
474 }
475 }
476 catch (const std::exception& e)
477 {
478 // maxScale->setStyleSheet("color: red");
479 }
480 }
481 catch (const std::exception& e)
482 {
483 // minScale->setStyleSheet("color: red");
484 }
485
486}
487
489{
490 std::cout<<"DDPlaneField computing "<<dataPnts().size()<<" points..."<<std::flush;
491 const auto t0= std::chrono::system_clock::now();
492// const Simplex<3,3>* gessSimplex(&defectiveCrystal.ddBase.mesh.simplices().begin()->second);
493 std::exception_ptr failure;
494#ifdef _OPENMP
495#pragma omp parallel for
496#endif
497 for(size_t vtkID=0;vtkID<dataPnts().size();++vtkID)
498 {
499 try
500 {
501 dataPnts()[vtkID].compute(defectiveCrystal);
502 }
503 catch(...)
504 {
505#ifdef _OPENMP
506#pragma omp critical(ddqtFieldFailure)
507#endif
508 {
509 if(!failure)
510 {
511 failure = std::current_exception();
512 }
513 }
514 }
515 }
516 if(failure)
517 {
518 std::rethrow_exception(failure);
519 }
520 std::cout<<magentaColor<<"["<<(std::chrono::duration<double>(std::chrono::system_clock::now()-t0)).count()<<" sec]"<<defaultColor<<std::endl;
521}
522
523void DDFieldWidget::clearLayout(QLayout *layout)
524{
525 if(layout)
526 {
527 while(layout->count() > 0)
528 {
529 QLayoutItem *item = layout->takeAt(0);
530 QWidget* widget = item->widget();
531 if(widget)
532 {
533 delete widget;
534 }
535 delete item;
536 }
537 }
538}
539
540void DDFieldWidget::resetPlanes()
541{
542 clearLayout(groupBox->layout());
543 std::cout<<"Resetting "<<spinBox->value()<<" planes"<<std::endl;
544 for(int k=0;k<spinBox->value();++k)
545 {
546 DDPlaneField* planeField(new DDPlaneField(renWin,renderer,defectiveCrystal));
547 planeField->resetPlane();
548 groupBox->layout()->addWidget(planeField);
549 }
550 renWin->Render();
551}
552
553void DDFieldWidget::resetLines()
554{
555 clearLayout(linesGroupBox->layout());
556 std::cout<<"Resetting "<<linesSpinBox->value()<<" lines"<<std::endl;
557 for(int k=0;k<linesSpinBox->value();++k)
558 {
559 DDLineField* lineField(new DDLineField(renWin,renderer,defectiveCrystal));
560 lineField->resetLine();
561 linesGroupBox->layout()->addWidget(lineField);
562 }
563 renWin->Render();
564}
565
566void DDPlaneField::plotField(const int& valID,const std::vector<QCheckBox*>& microstructuresCheck,const vtkSmartPointer<vtkLookupTable>& lut)
567{
568 vtkSmartPointer<vtkUnsignedCharArray> fieldColors(vtkSmartPointer<vtkUnsignedCharArray>::New());
569 fieldColors->SetNumberOfComponents(3);
570 for(auto& vtx : dataPnts())
571 {
572 const double value(vtx.value(valID,microstructuresCheck));
573 double dclr[3];
574 lut->GetColor(value, dclr);
575 unsigned char cclr[3];
576 for(unsigned int j = 0; j < 3; j++)
577 {
578 cclr[j] = static_cast<unsigned char>(255.0 * dclr[j]);
579 }
580 fieldColors->InsertNextTypedTuple(cclr);
581 }
582 meshPolydata->GetPointData()->SetScalars(fieldColors);
583 meshPolydata->Modified();
584 meshMapper->SetScalarModeToUsePointData();
585}
586
587DDPlaneField::DDPlaneField(vtkGenericOpenGLRenderWindow* const renWin_in,
588 vtkRenderer* const renderer_in,
589 const DefectiveCrystal<3>& defectiveCrystal_in):
590/* init */ mainLayout(new QGridLayout(this))
591/* init */,groupBox(new controls::GroupBox(tr("&Plane")))
592/* init */,posEdit(new QLineEdit("0 0 0"))
593/* init */,normalEdit(new QLineEdit("1 1 1"))
594/* init */,meshSizeEdit(new QLineEdit("1000"))
595/* init */,meshPolydata(vtkSmartPointer<vtkPolyData>::New())
596/* init */,meshMapper(vtkSmartPointer<vtkPolyDataMapper>::New())
597/* init */,meshActor(vtkSmartPointer<vtkActor>::New())
598/* init */,renWin(renWin_in)
599/* init */,renderer(renderer_in)
600/* init */,defectiveCrystal(defectiveCrystal_in)
602{
603 const VectorDim c(0.5*(defectiveCrystal.ddBase.mesh.xMax()+defectiveCrystal.ddBase.mesh.xMin()));
604 posEdit->setText(QString::fromStdString(std::to_string(c(0))+" "+std::to_string(c(1))+" "+std::to_string(c(2))));
605
606 const VectorDim n(Eigen::Matrix<double,3,1>::Random());
607 normalEdit->setText(QString::fromStdString(std::to_string(n(0))+" "+std::to_string(n(1))+" "+std::to_string(n(2))));
608
609 QGridLayout* groupBoxLayout = new QGridLayout();
610 controls::field(groupBoxLayout, 0, "Center (b)", posEdit,
611 "Global x y z of a point on the sampling plane, in b. Press Enter to rebuild the plane.");
612 controls::field(groupBoxLayout, 1, "Normal", normalEdit,
613 "Global nx ny nz of the sampling-plane normal. Enter a nonzero vector and press Enter.");
614 controls::field(groupBoxLayout, 2, "Mesh area (b²)", meshSizeEdit,
615 "Maximum triangle area of the sampling mesh in b squared. Smaller values sample more points. Press "
616 "Enter to rebuild.");
617
618 groupBox->setLayout(groupBoxLayout);
619
620 groupBox->setToolTip("Show or hide this field-sampling geometry and its plot.");
621 groupBox->setCheckable(true);
622 mainLayout->addWidget(groupBox,0,0,1,1);
623 this->setLayout(mainLayout);
624
625 connect(posEdit,SIGNAL(returnPressed()), this, SLOT(resetPlane()));
626 connect(normalEdit,SIGNAL(returnPressed()), this, SLOT(resetPlane()));
627 connect(meshSizeEdit,SIGNAL(returnPressed()), this, SLOT(resetPlane()));
628 connect(groupBox,SIGNAL(toggled(bool)), this, SLOT(modify()));
629
630 meshPolydata->Allocate();
631 meshMapper->SetInputData(meshPolydata);
632 meshActor->SetMapper ( meshMapper );
633 meshActor->GetProperty()->SetOpacity(0.8); //Make the mesh have some transparency.
634 renderer->AddActor(meshActor);
635}
636
638{
639 renderer->RemoveActor(meshActor);
640}
641
642const std::deque<FieldDataPnt>& DDPlaneField::dataPnts() const
643{
644 return *this;
645}
646
647std::deque<FieldDataPnt>& DDPlaneField::dataPnts()
648{
649 return *this;
650}
651
653{
654 meshActor->SetVisibility(groupBox->isChecked());
655 renWin->Render();
656}
657
659{
660
661 double meshSize;
662 std::stringstream ssM(meshSizeEdit->text().toStdString());
663 if((ssM >> meshSize) && std::isfinite(meshSize) && meshSize>0.0)
664 {
665 meshSizeEdit->setStyleSheet("background-color: white");
666
667 VectorDim P;
668 std::stringstream ssP(posEdit->text().toStdString());
669 if(ssP >> P(0) && ssP >> P(1) && ssP >> P(2))
670 {
671 posEdit->setStyleSheet("background-color: white");
672
673 VectorDim N;
674 std::stringstream ssN(normalEdit->text().toStdString());
675 if(ssN >> N(0) && ssN >> N(1) && ssN >> N(2))
676 {
677 normalEdit->setStyleSheet("background-color: white");
678 const double nNorm(N.norm());
679 if(P.allFinite() && N.allFinite() && nNorm>FLT_EPSILON)
680 {
681 try
682 {
683 const auto newPlane=std::make_shared<Plane<3>>(P,N);
684 const auto newMesh=planeSectionMesh(defectiveCrystal.ddBase.mesh,*newPlane,meshSize);
685 std::deque<FieldDataPnt> newData;
686 vtkSmartPointer<vtkPoints> meshPts(vtkSmartPointer<vtkPoints>::New());
687 for(const auto& point2d : newMesh.vertices())
688 {
689 const auto point3d(newPlane->globalPosition(point2d));
690 meshPts->InsertNextPoint(point3d(0),point3d(1),point3d(2));
691 const ElementType* ele(nullptr);
692 if(defectiveCrystal.ddBase.fe)
693 {
694 const auto searchPair(defectiveCrystal.ddBase.mesh.search(point3d));
695 if(searchPair.first)
696 {
697 ele=&defectiveCrystal.ddBase.fe->elements().at(searchPair.second->xID);
698 }
699 }
700 newData.emplace_back(defectiveCrystal,point3d,ele);
701 }
702
703 vtkSmartPointer<vtkCellArray> meshTriangles(vtkSmartPointer<vtkCellArray>::New());
704 vtkSmartPointer<vtkUnsignedCharArray> meshColors(vtkSmartPointer<vtkUnsignedCharArray>::New());
705 meshColors->SetNumberOfComponents(3);
706 for(const auto& tri : newMesh.triangles())
707 {
708 vtkSmartPointer<vtkTriangle> triangle = vtkSmartPointer<vtkTriangle>::New();
709 triangle->GetPointIds()->SetId (0,tri(0));
710 triangle->GetPointIds()->SetId (1,tri(1));
711 triangle->GetPointIds()->SetId (2,tri(2));
712 meshTriangles->InsertNextCell ( triangle );
713 const auto triColor(Eigen::Matrix<int,1,3>::Random()*255);
714 meshColors->InsertNextTuple3(triColor(0),triColor(1),triColor(2)); // use this to assig color to each vertex
715 }
716
717 plane=newPlane;
718 vertices()=newMesh.vertices();
719 triangles()=newMesh.triangles();
720 dataPnts().swap(newData);
721 meshPolydata->SetPoints ( meshPts );
722 meshPolydata->SetPolys ( meshTriangles );
723 meshPolydata->GetCellData()->SetScalars(meshColors);
724 meshPolydata->Modified();
725 meshMapper->SetScalarModeToUseCellData();
726 if(renWin->GetReadyForRendering())
727 {
728 renWin->Render();
729 }
730 }
731 catch(const std::exception& error)
732 {
733 QMessageBox::warning(this,tr("Field plane"),QString::fromUtf8(error.what()));
734 }
735 }
736 else
737 {
738 normalEdit->setStyleSheet("background-color: red");
739 }
740 }
741 else
742 {
743 normalEdit->setStyleSheet("background-color: red");
744 }
745 }
746 else
747 {
748 posEdit->setStyleSheet("background-color: red");
749 }
750 }
751 else
752 {
753 meshSizeEdit->setStyleSheet("background-color: red");
754 }
755}
756
757
758DDLineField::DDLineField(vtkGenericOpenGLRenderWindow* const renWin_in,
759 vtkRenderer* const renderer_in,
760 const DefectiveCrystal<3>& defectiveCrystal_in):
761/* init */ mainLayout(new QGridLayout(this))
762/* init */,groupBox(new controls::GroupBox(tr("&Line")))
763/* init */,posEdit(new QLineEdit("0 0 0"))
764/* init */,directionEdit(new QLineEdit("1 0 0"))
765/* init */,numPoinEdit(new QLineEdit("1000"))
770/* init */,renWin(renWin_in)
771/* init */,renderer(renderer_in)
772/* init */,chart(vtkSmartPointer<vtkChartXY>::New())
773/* init */,chartScene(vtkSmartPointer<vtkContextScene>::New())
774/* init */,chartActor(vtkSmartPointer<vtkContextActor>::New())
775/* init */,table(vtkSmartPointer<vtkTable>::New())
776/* init */,colors(vtkSmartPointer<vtkNamedColors>::New())
777/* init */,points(chart->AddPlot(vtkChart::LINE))
778/* init */,lineSource(vtkSmartPointer<vtkLineSource>::New())
779/* init */,lineMapper(vtkSmartPointer<vtkPolyDataMapper>::New())
780/* init */,lineActor(vtkSmartPointer<vtkActor>::New())
781/* init */,defectiveCrystal(defectiveCrystal_in)
782{
783 const VectorDim c(0.5*(defectiveCrystal.ddBase.mesh.xMax()+defectiveCrystal.ddBase.mesh.xMin()));
784 posEdit->setText(QString::fromStdString(std::to_string(c(0))+" "+std::to_string(c(1))+" "+std::to_string(c(2))));
785
786 const VectorDim n(Eigen::Matrix<double,3,1>::Random());
787 directionEdit->setText(QString::fromStdString(std::to_string(n(0))+" "+std::to_string(n(1))+" "+std::to_string(n(2))));
788
789 QGridLayout* groupBoxLayout = new QGridLayout();
790 controls::field(groupBoxLayout, 0, "Center (b)", posEdit,
791 "Global x y z of a point on the sampling line, in b. Press Enter to rebuild the line.");
792 controls::field(groupBoxLayout, 1, "Direction", directionEdit,
793 "Global dx dy dz direction of the sampling line. Enter a nonzero vector and press Enter.");
794 controls::field(groupBoxLayout, 2, "Points", numPoinEdit,
795 "Number of samples along the line within the simulation box. Enter an integer and press Enter.");
796
797 // groupBoxLayout->addWidget(clrDialog,2,1,1,1);
798 groupBox->setLayout(groupBoxLayout);
799
800 groupBox->setToolTip("Show or hide this field-sampling geometry and its plot.");
801 groupBox->setCheckable(true);
802 mainLayout->addWidget(groupBox,0,0,1,1);
803 this->setLayout(mainLayout);
804
805 connect(posEdit,SIGNAL(returnPressed()), this, SLOT(resetLine()));
806 connect(directionEdit,SIGNAL(returnPressed()), this, SLOT(resetLine()));
807 connect(numPoinEdit,SIGNAL(returnPressed()), this, SLOT(resetLine()));
808 connect(groupBox,SIGNAL(toggled(bool)), this, SLOT(modify()));
809
810 vtkColor3d color3d1 = colors->GetColor3d("Peacock");
811 points->SetColorF(color3d1.GetRed(), color3d1.GetGreen(), color3d1.GetBlue());
812 points->SetWidth(5.0);
813
814 chart->GetAxis(0)->SetNumberOfTicks(10);
815 chart->GetAxis(1)->SetNumberOfTicks(10);
816 chart->GetAxis(0)->SetGridVisible(false);
817 chart->GetAxis(1)->SetGridVisible(false);
818
819
820 chartScene->AddItem(chart);
821 chartActor->SetScene(chartScene);
822 renderer->AddActor(chartActor);
823 chartScene->SetRenderer(renderer);
824
825 lineMapper->SetInputConnection(lineSource->GetOutputPort());
826 lineActor->SetMapper(lineMapper);
827 lineActor->GetProperty()->SetLineWidth(4);
828 lineActor->GetProperty()->SetColor(colors->GetColor3d("Peacock").GetData());
829 renderer->AddActor(lineActor);
830
831// meshPolydata->Allocate();
832// meshMapper->SetInputData(meshPolydata);
833// meshActor->SetMapper ( meshMapper );
834// meshActor->GetProperty()->SetOpacity(0.8); //Make the mesh have some transparency.
835// renderer->AddActor(meshActor);
836}
837
839{
840 renderer->RemoveActor(chartActor);
841 renderer->RemoveActor(lineActor);
842
843}
844
845const std::deque<FieldDataPnt>& DDLineField::dataPnts() const
846{
847 return *this;
848}
849
850std::deque<FieldDataPnt>& DDLineField::dataPnts()
851{
852 return *this;
853}
854
855const std::deque<double>& DDLineField::abscissa() const
856{
857 return *this;
858}
859
860std::deque<double>& DDLineField::abscissa()
861{
862 return *this;
863}
864
866{
867
868 int numPoints;
869 std::stringstream ssM(numPoinEdit->text().toStdString());
870 if(ssM >> numPoints)
871 {
872 if(numPoints>2)
873 {
874 numPoinEdit->setStyleSheet("background-color: white");
875
876 VectorDim P;
877 std::stringstream ssP(posEdit->text().toStdString());
878 if(ssP >> P(0) && ssP >> P(1) && ssP >> P(2))
879 {
880 posEdit->setStyleSheet("background-color: white");
881// std::cout<<"P="<<P.transpose()<<std::endl;
882
883 VectorDim N;
884 std::stringstream ssN(directionEdit->text().toStdString());
885 if(ssN >> N(0) && ssN >> N(1) && ssN >> N(2))
886 {
887 directionEdit->setStyleSheet("background-color: white");
888// std::cout<<"d="<<N.transpose()<<std::endl;
889 const double nNorm(N.norm());
890 if(nNorm>FLT_EPSILON)
891 {
892 const VectorDim unitDir(N/nNorm);
893 line.reset(new MeshLine<3>(defectiveCrystal.ddBase.mesh,P,unitDir));
894 lineSource->SetPoint1(line->P0.data());
895 lineSource->SetPoint2(line->P1.data());
896 dataPnts().clear();
897 abscissa().clear();
898 const VectorDim chord(line->P1-line->P0);
899 const VectorDim dP(chord/(numPoints-1));
900 for(int k=0;k<numPoints;++k)
901 {
902 const VectorDim point3d(line->P0+k*dP);
903 const ElementType* ele(nullptr);
904 if(defectiveCrystal.ddBase.fe)
905 {
906 const auto searchPair(defectiveCrystal.ddBase.mesh.search(point3d));
907 if(searchPair.first)
908 {
909 ele=&defectiveCrystal.ddBase.fe->elements().at(searchPair.second->xID);
910 }
911 }
912 dataPnts().emplace_back(defectiveCrystal,point3d,ele);
913 abscissa().emplace_back((point3d-P).dot(unitDir));
914
915 }
916
917// vtkSmartPointer<vtkPoints> meshPts(vtkSmartPointer<vtkPoints>::New());
918// for(const auto& point2d : this->vertices())
919// {
920// const auto point3d(plane->globalPosition(point2d));
921// meshPts->InsertNextPoint(point3d(0),point3d(1),point3d(2));
922// const ElementType* ele(nullptr);
923// if(defectiveCrystal.ddBase.fe)
924// {
925// const auto searchPair(defectiveCrystal.ddBase.mesh.search(point3d));
926// if(searchPair.first)
927// {
928// ele=&defectiveCrystal.ddBase.fe->elements().at(searchPair.second->xID);
929// }
930// }
931// dataPnts().emplace_back(defectiveCrystal,point3d,ele);
932// }
933
934// vtkSmartPointer<vtkCellArray> meshTriangles(vtkSmartPointer<vtkCellArray>::New());
935// vtkSmartPointer<vtkUnsignedCharArray> meshColors(vtkSmartPointer<vtkUnsignedCharArray>::New());
936// meshColors->SetNumberOfComponents(3);
937// for(const auto& tri : this->triangles())
938// {
939// vtkSmartPointer<vtkTriangle> triangle = vtkSmartPointer<vtkTriangle>::New();
940// triangle->GetPointIds()->SetId (0,tri(0));
941// triangle->GetPointIds()->SetId (1,tri(1));
942// triangle->GetPointIds()->SetId (2,tri(2));
943// meshTriangles->InsertNextCell ( triangle );
944// const auto triColor(Eigen::Matrix<int,1,3>::Random()*255);
945// meshColors->InsertNextTuple3(triColor(0),triColor(1),triColor(2)); // use this to assig color to each vertex
946// }
947//
948// meshPolydata->SetPoints ( meshPts );
949// meshPolydata->SetPolys ( meshTriangles );
950// meshPolydata->GetCellData()->SetScalars(meshColors);
951// meshPolydata->Modified();
952// meshMapper->SetScalarModeToUseCellData();
953// if(renWin->GetReadyForRendering())
954 {
955 renWin->Render();
956 }
957 }
958 else
959 {
960 directionEdit->setStyleSheet("background-color: red");
961 }
962 }
963 else
964 {
965 directionEdit->setStyleSheet("background-color: red");
966 }
967 }
968 else
969 {
970 posEdit->setStyleSheet("background-color: red");
971 }
972 }
973 else
974 {
975 numPoinEdit->setStyleSheet("background-color: red");
976 }
977 }
978 else
979 {
980 numPoinEdit->setStyleSheet("background-color: red");
981 }
982 modify();
983}
984
985
986
988{
989 std::cout<<"DDLineField computing "<<dataPnts().size()<<" points..."<<std::flush;
990 const auto t0= std::chrono::system_clock::now();
991 std::exception_ptr failure;
992#ifdef _OPENMP
993#pragma omp parallel for
994#endif
995 for(size_t vtkID=0;vtkID<dataPnts().size();++vtkID)
996 {
997 try
998 {
999 dataPnts()[vtkID].compute(defectiveCrystal);
1000 }
1001 catch(...)
1002 {
1003#ifdef _OPENMP
1004#pragma omp critical(ddqtFieldFailure)
1005#endif
1006 {
1007 if(!failure)
1008 {
1009 failure = std::current_exception();
1010 }
1011 }
1012 }
1013 }
1014 if(failure)
1015 {
1016 std::rethrow_exception(failure);
1017 }
1018 std::cout<<magentaColor<<"["<<(std::chrono::duration<double>(std::chrono::system_clock::now()-t0)).count()<<" sec]"<<defaultColor<<std::endl;
1019}
1020
1021void DDLineField::plotField(const int& valID,const std::vector<QCheckBox*>& microstructuresCheck,const QComboBox* const fieldComboBox)
1022{
1023
1024 table->Initialize();
1025 vtkNew<vtkFloatArray> xArray;
1026 xArray->SetName("x");
1027 table->AddColumn(xArray);
1028 vtkNew<vtkFloatArray> yArray;
1029 yArray->SetName(fieldComboBox->itemText(valID).toStdString().c_str());
1030 table->AddColumn(yArray);
1031
1032// std::ofstream tempFile("linePlot.txt");
1033
1034 for(size_t k=0;k<abscissa().size();++k)
1035 {
1036 const auto row=table->InsertNextBlankRow(2);
1037 table->SetValue(row, 0, abscissa()[k]);
1038 table->SetValue(row, 1, dataPnts()[k].value(valID,microstructuresCheck));
1039
1040// tempFile<<abscissa()[k]<<"\t"<<dataPnts()[k].value(valID,microstructuresCheck)<<"\n";
1041 }
1042
1043
1044
1045
1046 points->SetInputData(table, 0, 1);
1047 table->Modified();
1048 chart->RecalculateBounds();
1049
1050 // chart->GetAxis(0)->SetTitle(yComboBox->currentText().toStdString());
1051 chart->GetAxis(0)->SetTitle(fieldComboBox->itemText(valID).toStdString());
1052
1053 // chart->GetAxis(0)->SetLogScale(yAxisLog->isChecked());
1054 // chart->GetAxis(1)->SetLogScale(xAxisLog->isChecked());
1055
1056
1057// chart->GetAxis(0)->SetNumberOfTicks(10);
1058// chart->GetAxis(1)->SetNumberOfTicks(10);
1059
1060 chart->GetAxis(0)->GetLabelProperties()->SetFontSize(16);
1061 chart->GetAxis(1)->GetLabelProperties()->SetFontSize(16);
1062
1063 chart->GetAxis(0)->GetTitleProperties()->SetFontSize(16);
1064 chart->GetAxis(1)->GetTitleProperties()->SetFontSize(16);
1065
1066 chart->Modified();
1067}
1068
1070{
1071 lineActor->SetVisibility(groupBox->isChecked());
1072 chartActor->SetVisibility(groupBox->isChecked());
1073 renWin->Render();
1074
1075}
1076
1077} // namespace model
1078#endif
std::deque< Eigen::Vector2d > & vertices()
std::deque< Eigen::Vector3i > & triangles()
c
Definition int_R.m:15
x
Definition int_R.m:12
QGridLayout * grid(QGroupBox *group)
QGroupBox * box(const QString &title, QWidget *parent, const QString &description, QCheckBox *toggle=nullptr)
void field(QGridLayout *layout, int row, const QString &title, QWidget *input, const QString &description)
size_t InstanceCount< Derived >::count
static std::string magentaColor
std::string to_string_exact(const FloatType &x, const int &n)
TriangularMesh planeSectionMesh(const SimplicialMesh< 3 > &mesh, const Plane< 3 > &plane, const double maxArea)
static std::string defaultColor
const DefectiveCrystal< 3 > & defectiveCrystal
vtkSmartPointer< vtkLookupTable > lut
DDFieldWidget(vtkGenericOpenGLRenderWindow *const renWin_in, vtkRenderer *const renderer_in, const DefectiveCrystal< 3 > &defectiveCrystal_in)
vtkRenderer *const renderer
QGroupBox * linesGroupBox
std::vector< QCheckBox * > microstructuresCheck
QGridLayout * mainLayout
QComboBox * fieldComboBox
QGroupBox * customScaleBox
vtkSmartPointer< vtkScalarBarActor > scalarBar
vtkGenericOpenGLRenderWindow *const renWin
QPushButton * computeButton
vtkSmartPointer< vtkActor > lineActor
Eigen::Matrix< double, 3, 1 > VectorDim
vtkSmartPointer< vtkContextActor > chartActor
vtkGenericOpenGLRenderWindow *const renWin
void compute(const DefectiveCrystal< 3 > &)
vtkSmartPointer< vtkTable > table
MicrostructureBase< 3 >::ElementType ElementType
vtkSmartPointer< vtkContextScene > chartScene
const std::deque< FieldDataPnt > & dataPnts() const
QLineEdit * directionEdit
void plotField(const int &valID, const std::vector< QCheckBox * > &microstructuresCheck, const QComboBox *const fieldComboBox)
const std::deque< double > & abscissa() const
QGroupBox * groupBox
vtkSmartPointer< vtkNamedColors > colors
std::shared_ptr< MeshLine< 3 > > line
vtkSmartPointer< vtkPolyDataMapper > lineMapper
QLineEdit * numPoinEdit
QLineEdit * posEdit
DDLineField(vtkGenericOpenGLRenderWindow *const renWin_in, vtkRenderer *const renderer_in, const DefectiveCrystal< 3 > &defectiveCrystal_in)
const DefectiveCrystal< 3 > & defectiveCrystal
vtkRenderer *const renderer
QGridLayout * mainLayout
vtkSmartPointer< vtkLineSource > lineSource
vtkSmartPointer< vtkChartXY > chart
void compute(const DefectiveCrystal< 3 > &)
Eigen::Matrix< double, 3, 1 > VectorDim
vtkSmartPointer< vtkActor > meshActor
void plotField(const int &valID, const std::vector< QCheckBox * > &microstructuresCheck, const vtkSmartPointer< vtkLookupTable > &lut)
const std::deque< FieldDataPnt > & dataPnts() const
std::shared_ptr< Plane< 3 > > plane
QLineEdit * meshSizeEdit
DDPlaneField(vtkGenericOpenGLRenderWindow *const renWin_in, vtkRenderer *const renderer_in, const DefectiveCrystal< 3 > &defectiveCrystal_in)
MicrostructureBase< 3 >::ElementType ElementType
const DefectiveCrystal< 3 > & defectiveCrystal
QGridLayout * mainLayout
vtkRenderer *const renderer
vtkGenericOpenGLRenderWindow *const renWin
vtkSmartPointer< vtkPolyDataMapper > meshMapper
vtkSmartPointer< vtkPolyData > meshPolydata
const SymmetricVoigtTraits< 3 > & voigtTraits
std::vector< Eigen::Matrix< double, ClusterDynamicsParameters< 3 >::iSize, 1 > > immobileClusters
MicrostructureBase< 3 >::ElementType ElementType
const ElementType *const ele
const Eigen::Matrix< double, 3, 1 > P
static constexpr int mSize
std::vector< Eigen::Matrix< double, ClusterDynamicsParameters< 3 >::mSize, 1 > > mobileConcentration
double value(const int &valID, const std::vector< QCheckBox * > &microstructuresCheck) const
std::vector< Eigen::Matrix< double, 3, 3 > > stress
FieldDataPnt(const DefectiveCrystal< 3 > &defectiveCrystal, const Eigen::Matrix< double, 3, 1 > &Pin, const ElementType *const ele_in)
std::vector< Eigen::Matrix< double, 3, 1 > > displacement
void compute(const DefectiveCrystal< 3 > &defectiveCrystal)
static constexpr int iSize
newotri tri
int j
REAL ** triangle
Definition triangle.cpp:508
REAL t0
int k
int i
int e
vertex temp