9#ifndef model_DDFieldWidget_cpp_
10#define model_DDFieldWidget_cpp_
23#include <vtkProperty.h>
24#include <vtkTriangle.h>
25#include <vtkCellData.h>
26#include <vtkFloatArray.h>
38template <
typename FloatType>
41 std::ostringstream os;
42 os << std::scientific<<std::setprecision(n)<<
x;
50,
displacement(defectiveCrystal.microstructures().size(),
Eigen::Matrix<double,3,1>::Zero())
51,
stress(defectiveCrystal.microstructures().size(),
Eigen::Matrix<double,3,3>::Zero())
61 for(
const auto& mStruct : defectiveCrystal.microstructures())
64 stress[mID]=mStruct->stress(
P,
nullptr,
ele,
nullptr);
79 if(microstructuresCheck[
k]->isChecked())
93 if(microstructuresCheck[
k]->isChecked())
102 Eigen::Matrix<double,3,3>
temp(Eigen::Matrix<double,3,3>::Zero());
105 if(microstructuresCheck[
k]->isChecked())
114 Eigen::Matrix<double,3,3>
temp(Eigen::Matrix<double,3,3>::Zero());
117 if(microstructuresCheck[
k]->isChecked())
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);
129 else if(valID>7+3 && valID<=7+3+
mSize)
134 if(microstructuresCheck[
k]->isChecked())
146 if(microstructuresCheck[
k]->isChecked())
160 vtkRenderer*
const renderer_in,
163,
boxLabel(new QLabel(tr(
"# of planes")))
179,
lut(vtkSmartPointer<vtkLookupTable>::New())
180,
scalarBar(vtkSmartPointer<vtkScalarBarActor>::New())
186 QVBoxLayout* groupBoxLayout =
new QVBoxLayout();
187 groupBox->setLayout(groupBoxLayout);
189 QVBoxLayout* linesGroupBoxLayout =
new QVBoxLayout();
193 QGridLayout* autoscaleLayout =
new QGridLayout();
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.");
212 fieldComboBox->insertItem(
k,QString::fromStdString(
"displacement_"+std::to_string(
k+1)));
218 fieldComboBox->insertItem(
k+3,QString::fromStdString(
"stress_"+std::to_string(
i+1)+std::to_string(
j+1)));
224 const auto& mobileSpecies=
defectiveCrystal.ddBase.clusterDynamics().msVector;
225 for(Eigen::Index
k=0;
k<mobileSpecies.size();++
k)
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;
243 connect(
spinBox,SIGNAL(valueChanged(
int)),
this, SLOT(resetPlanes()));
244 connect(
linesSpinBox,SIGNAL(valueChanged(
int)),
this, SLOT(resetLines()));
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()));
253 connect(
customScaleBox,SIGNAL(toggled(
bool)),
this, SLOT(plotField()));
254 connect(
scaleBarBox,SIGNAL(toggled(
bool)),
this, SLOT(plotField()));
258 auto *samplingBox =
controls::box(
"Sampling",
this,
"Choose how many sampling planes and lines to configure.");
260 "Number of field-sampling planes. Changing this resets the plane definitions.");
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.");
265 "Field component to plot: displacement, stress or concentration in simulation units.");
267 computeButton->setToolTip(
"Evaluate fields on all configured sampling planes and lines, then refresh their plots.");
269 controls::box(
"Physics",
this,
"Choose which microstructure contributions are summed for the displayed field.");
274 "Include this physics contribution in the plotted field. This changes the sum of already computed values.");
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.");
291 lut->SetHueRange(0.66667, 0.0);
296 scalarBar->GetLabelTextProperty()->SetColor(0,0,0);
312 QLayoutItem *item =
groupBox->layout()->itemAt(
k);
313 QWidget* widget = item->widget();
316 auto* ddPlaneField =
dynamic_cast<DDPlaneField*
>(widget);
333 QWidget* widget = item->widget();
336 auto* ddLineField =
dynamic_cast<DDLineField*
>(widget);
350void DDFieldWidget::plotField()
363 double minValue=std::numeric_limits<double>::max();
364 double maxValue=-std::numeric_limits<double>::max();
369 QLayoutItem *item =
groupBox->layout()->itemAt(
k);
370 QWidget* widget = item->widget();
373 auto* ddPlaneField =
dynamic_cast<DDPlaneField*
>(widget);
376 if(ddPlaneField->groupBox->isChecked())
378 for(
const auto& vtx : ddPlaneField->dataPnts())
382 minValue=std::min(minValue,value);
383 maxValue=std::max(maxValue,value);
396 QWidget* widget = item->widget();
399 auto* ddLineField =
dynamic_cast<DDLineField*
>(widget);
402 if(ddLineField->groupBox->isChecked())
404 for(
const auto& vtx : ddLineField->dataPnts())
407 minValue=std::min(minValue,value);
408 maxValue=std::max(maxValue,value);
416 if(minValue > maxValue)
428 double lutMin(std::stod(
minScale->text().toStdString().c_str()));
432 double lutMax(std::stod(
maxScale->text().toStdString().c_str()));
434 lut->SetTableRange(lutMin, lutMax);
438 QLayoutItem *item =
groupBox->layout()->itemAt(
k);
439 QWidget* widget = item->widget();
442 auto* ddPlaneField =
dynamic_cast<DDPlaneField*
>(widget);
445 if(ddPlaneField->groupBox->isChecked())
456 QWidget* widget = item->widget();
459 auto* ddLineField =
dynamic_cast<DDLineField*
>(widget);
462 if(ddLineField->groupBox->isChecked())
471 if(
renWin->GetReadyForRendering())
476 catch (
const std::exception&
e)
481 catch (
const std::exception&
e)
490 std::cout<<
"DDPlaneField computing "<<
dataPnts().size()<<
" points..."<<std::flush;
491 const auto t0= std::chrono::system_clock::now();
493 std::exception_ptr failure;
495#pragma omp parallel for
497 for(
size_t vtkID=0;vtkID<
dataPnts().size();++vtkID)
506#pragma omp critical(ddqtFieldFailure)
511 failure = std::current_exception();
518 std::rethrow_exception(failure);
523void DDFieldWidget::clearLayout(QLayout *layout)
527 while(layout->count() > 0)
529 QLayoutItem *item = layout->takeAt(0);
530 QWidget* widget = item->widget();
540void DDFieldWidget::resetPlanes()
543 std::cout<<
"Resetting "<<
spinBox->value()<<
" planes"<<std::endl;
547 planeField->resetPlane();
548 groupBox->layout()->addWidget(planeField);
553void DDFieldWidget::resetLines()
556 std::cout<<
"Resetting "<<
linesSpinBox->value()<<
" lines"<<std::endl;
560 lineField->resetLine();
566void DDPlaneField::plotField(
const int& valID,
const std::vector<QCheckBox*>& microstructuresCheck,
const vtkSmartPointer<vtkLookupTable>& lut)
568 vtkSmartPointer<vtkUnsignedCharArray> fieldColors(vtkSmartPointer<vtkUnsignedCharArray>::New());
569 fieldColors->SetNumberOfComponents(3);
572 const double value(vtx.value(valID,microstructuresCheck));
574 lut->GetColor(value, dclr);
575 unsigned char cclr[3];
576 for(
unsigned int j = 0;
j < 3;
j++)
578 cclr[
j] =
static_cast<unsigned char>(255.0 * dclr[
j]);
580 fieldColors->InsertNextTypedTuple(cclr);
588 vtkRenderer*
const renderer_in,
592,
posEdit(new QLineEdit(
"0 0 0"))
596,
meshMapper(vtkSmartPointer<vtkPolyDataMapper>::New())
597,
meshActor(vtkSmartPointer<vtkActor>::New())
604 posEdit->setText(QString::fromStdString(std::to_string(
c(0))+
" "+std::to_string(
c(1))+
" "+std::to_string(
c(2))));
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))));
609 QGridLayout* groupBoxLayout =
new QGridLayout();
611 "Global x y z of a point on the sampling plane, in b. Press Enter to rebuild the plane.");
613 "Global nx ny nz of the sampling-plane normal. Enter a nonzero vector and press Enter.");
615 "Maximum triangle area of the sampling mesh in b squared. Smaller values sample more points. Press "
616 "Enter to rebuild.");
618 groupBox->setLayout(groupBoxLayout);
620 groupBox->setToolTip(
"Show or hide this field-sampling geometry and its plot.");
633 meshActor->GetProperty()->SetOpacity(0.8);
662 std::stringstream ssM(
meshSizeEdit->text().toStdString());
663 if((ssM >> meshSize) && std::isfinite(meshSize) && meshSize>0.0)
668 std::stringstream ssP(
posEdit->text().toStdString());
669 if(ssP >> P(0) && ssP >> P(1) && ssP >> P(2))
671 posEdit->setStyleSheet(
"background-color: white");
674 std::stringstream ssN(
normalEdit->text().toStdString());
675 if(ssN >>
N(0) && ssN >>
N(1) && ssN >>
N(2))
677 normalEdit->setStyleSheet(
"background-color: white");
678 const double nNorm(
N.norm());
679 if(P.allFinite() &&
N.allFinite() && nNorm>FLT_EPSILON)
683 const auto newPlane=std::make_shared<Plane<3>>(P,
N);
685 std::deque<FieldDataPnt> newData;
686 vtkSmartPointer<vtkPoints> meshPts(vtkSmartPointer<vtkPoints>::New());
687 for(
const auto& point2d : newMesh.vertices())
689 const auto point3d(newPlane->globalPosition(point2d));
690 meshPts->InsertNextPoint(point3d(0),point3d(1),point3d(2));
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())
708 vtkSmartPointer<vtkTriangle>
triangle = vtkSmartPointer<vtkTriangle>::New();
712 meshTriangles->InsertNextCell (
triangle );
713 const auto triColor(Eigen::Matrix<int,1,3>::Random()*255);
714 meshColors->InsertNextTuple3(triColor(0),triColor(1),triColor(2));
726 if(
renWin->GetReadyForRendering())
731 catch(
const std::exception& error)
733 QMessageBox::warning(
this,tr(
"Field plane"),QString::fromUtf8(error.what()));
738 normalEdit->setStyleSheet(
"background-color: red");
743 normalEdit->setStyleSheet(
"background-color: red");
748 posEdit->setStyleSheet(
"background-color: red");
759 vtkRenderer*
const renderer_in,
763,
posEdit(new QLineEdit(
"0 0 0"))
772,
chart(vtkSmartPointer<vtkChartXY>::New())
773,
chartScene(vtkSmartPointer<vtkContextScene>::New())
774,
chartActor(vtkSmartPointer<vtkContextActor>::New())
775,
table(vtkSmartPointer<vtkTable>::New())
776,
colors(vtkSmartPointer<vtkNamedColors>::New())
778,
lineSource(vtkSmartPointer<vtkLineSource>::New())
779,
lineMapper(vtkSmartPointer<vtkPolyDataMapper>::New())
780,
lineActor(vtkSmartPointer<vtkActor>::New())
784 posEdit->setText(QString::fromStdString(std::to_string(
c(0))+
" "+std::to_string(
c(1))+
" "+std::to_string(
c(2))));
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))));
789 QGridLayout* groupBoxLayout =
new QGridLayout();
791 "Global x y z of a point on the sampling line, in b. Press Enter to rebuild the line.");
793 "Global dx dy dz direction of the sampling line. Enter a nonzero vector and press Enter.");
795 "Number of samples along the line within the simulation box. Enter an integer and press Enter.");
798 groupBox->setLayout(groupBoxLayout);
800 groupBox->setToolTip(
"Show or hide this field-sampling geometry and its plot.");
810 vtkColor3d color3d1 =
colors->GetColor3d(
"Peacock");
811 points->SetColorF(color3d1.GetRed(), color3d1.GetGreen(), color3d1.GetBlue());
814 chart->GetAxis(0)->SetNumberOfTicks(10);
815 chart->GetAxis(1)->SetNumberOfTicks(10);
816 chart->GetAxis(0)->SetGridVisible(
false);
817 chart->GetAxis(1)->SetGridVisible(
false);
827 lineActor->GetProperty()->SetLineWidth(4);
828 lineActor->GetProperty()->SetColor(
colors->GetColor3d(
"Peacock").GetData());
869 std::stringstream ssM(
numPoinEdit->text().toStdString());
874 numPoinEdit->setStyleSheet(
"background-color: white");
877 std::stringstream ssP(
posEdit->text().toStdString());
878 if(ssP >> P(0) && ssP >> P(1) && ssP >> P(2))
880 posEdit->setStyleSheet(
"background-color: white");
885 if(ssN >>
N(0) && ssN >>
N(1) && ssN >>
N(2))
889 const double nNorm(
N.norm());
890 if(nNorm>FLT_EPSILON)
900 for(
int k=0;
k<numPoints;++
k)
913 abscissa().emplace_back((point3d-P).dot(unitDir));
970 posEdit->setStyleSheet(
"background-color: red");
975 numPoinEdit->setStyleSheet(
"background-color: red");
980 numPoinEdit->setStyleSheet(
"background-color: red");
989 std::cout<<
"DDLineField computing "<<
dataPnts().size()<<
" points..."<<std::flush;
990 const auto t0= std::chrono::system_clock::now();
991 std::exception_ptr failure;
993#pragma omp parallel for
995 for(
size_t vtkID=0;vtkID<
dataPnts().size();++vtkID)
1004#pragma omp critical(ddqtFieldFailure)
1009 failure = std::current_exception();
1016 std::rethrow_exception(failure);
1021void DDLineField::plotField(
const int& valID,
const std::vector<QCheckBox*>& microstructuresCheck,
const QComboBox*
const fieldComboBox)
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);
1036 const auto row=
table->InsertNextBlankRow(2);
1038 table->SetValue(row, 1,
dataPnts()[
k].value(valID,microstructuresCheck));
1048 chart->RecalculateBounds();
1051 chart->GetAxis(0)->SetTitle(fieldComboBox->itemText(valID).toStdString());
1060 chart->GetAxis(0)->GetLabelProperties()->SetFontSize(16);
1061 chart->GetAxis(1)->GetLabelProperties()->SetFontSize(16);
1063 chart->GetAxis(0)->GetTitleProperties()->SetFontSize(16);
1064 chart->GetAxis(1)->GetTitleProperties()->SetFontSize(16);
std::deque< Eigen::Vector2d > & vertices()
std::deque< Eigen::Vector3i > & triangles()
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
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 * > µstructuresCheck, const QComboBox *const fieldComboBox)
const std::deque< double > & abscissa() const
vtkSmartPointer< vtkNamedColors > colors
std::shared_ptr< MeshLine< 3 > > line
vtkSmartPointer< vtkPolyDataMapper > lineMapper
DDLineField(vtkGenericOpenGLRenderWindow *const renWin_in, vtkRenderer *const renderer_in, const DefectiveCrystal< 3 > &defectiveCrystal_in)
const DefectiveCrystal< 3 > & defectiveCrystal
vtkRenderer *const renderer
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 * > µstructuresCheck, const vtkSmartPointer< vtkLookupTable > &lut)
const std::deque< FieldDataPnt > & dataPnts() const
std::shared_ptr< Plane< 3 > > plane
DDPlaneField(vtkGenericOpenGLRenderWindow *const renWin_in, vtkRenderer *const renderer_in, const DefectiveCrystal< 3 > &defectiveCrystal_in)
MicrostructureBase< 3 >::ElementType ElementType
const DefectiveCrystal< 3 > & defectiveCrystal
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 * > µstructuresCheck) 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