|
|
@ -14,7 +14,8 @@ |
|
|
|
#endif |
|
|
|
namespace da::sha { |
|
|
|
namespace top { |
|
|
|
Tensor3d Top3d::TopOptMainLoop(bool only_simulation) { |
|
|
|
Tensor3d |
|
|
|
Top3d::TopOptMainLoop(bool only_simulation, bool save_internal_rho) { |
|
|
|
Eigen::VectorXd xPhys_col(sp_mesh_->GetNumEles()); |
|
|
|
Eigen::VectorXi chosen_ele_id(sp_mesh_->GetChosenEleIdx()); |
|
|
|
bool flg_chosen = chosen_ele_id.size() != 0; |
|
|
@ -49,6 +50,40 @@ namespace da::sha { |
|
|
|
|
|
|
|
LOG_SOLVER |
|
|
|
|
|
|
|
// set 0 to rho of unchosen part
|
|
|
|
assert(xPhys_col.size()); |
|
|
|
Eigen::VectorXi continue_idx = |
|
|
|
Eigen::VectorXi::LinSpaced(xPhys_col.size(), 0, |
|
|
|
xPhys_col.size() - 1); |
|
|
|
Eigen::VectorXi unchosen_idx = flg_chosen ? SetDifference( |
|
|
|
continue_idx, chosen_ele_id) |
|
|
|
: Eigen::VectorXi(); |
|
|
|
|
|
|
|
auto RhoVec2Ten = [&](Eigen::VectorXd rho) -> Tensor3d { |
|
|
|
rho(unchosen_idx).setZero(); |
|
|
|
Eigen::VectorXd ele_to_write = |
|
|
|
Eigen::VectorXd::Zero( |
|
|
|
sp_mesh_->GetLx() * sp_mesh_->GetLy() * |
|
|
|
sp_mesh_->GetLz()); |
|
|
|
ele_to_write(pixel_idx) = rho; |
|
|
|
Tensor3d ten_xPhys_to_write( |
|
|
|
sp_mesh_->GetLx() * sp_mesh_->GetLy() * |
|
|
|
sp_mesh_->GetLz(), 1, |
|
|
|
1); |
|
|
|
for (int i = 0; i < ele_to_write.size(); ++i) { |
|
|
|
ten_xPhys_to_write(i, 0, 0) = ele_to_write(i); |
|
|
|
} |
|
|
|
ten_xPhys_to_write = ten_xPhys_to_write.reshape( |
|
|
|
Eigen::array < Eigen::DenseIndex, 3 > { |
|
|
|
sp_mesh_->GetLx(), sp_mesh_->GetLy(), |
|
|
|
sp_mesh_->GetLz()}); |
|
|
|
return ten_xPhys_to_write; |
|
|
|
}; |
|
|
|
|
|
|
|
if (save_internal_rho) { |
|
|
|
v_ten_rho_.emplace_back(RhoVec2Ten(xPhys_col)); |
|
|
|
} |
|
|
|
|
|
|
|
// start iteration
|
|
|
|
while (change > sp_para_->tol_x && loop < sp_para_->max_loop) { |
|
|
|
++loop; |
|
|
@ -128,54 +163,18 @@ namespace da::sha { |
|
|
|
if (only_simulation) { |
|
|
|
break; |
|
|
|
} |
|
|
|
if (save_internal_rho) { |
|
|
|
v_ten_rho_.emplace_back(RhoVec2Ten(xPhys_col)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// result
|
|
|
|
rho_ = only_simulation ? sp_mesh_->GetInitEleRho() : xPhys_col; |
|
|
|
// set 0 to rho of unchosen part
|
|
|
|
assert(xPhys_col.size()); |
|
|
|
Eigen::VectorXi continue_idx = |
|
|
|
Eigen::VectorXi::LinSpaced(xPhys_col.size(), 0, |
|
|
|
xPhys_col.size() - 1); |
|
|
|
Eigen::VectorXi unchosen_idx = flg_chosen ? SetDifference( |
|
|
|
continue_idx, chosen_ele_id) |
|
|
|
: Eigen::VectorXi(); |
|
|
|
{ |
|
|
|
xPhys_col(unchosen_idx).setZero(); |
|
|
|
ele_to_write(pixel_idx) = xPhys_col; |
|
|
|
Tensor3d ten_xPhys_to_write( |
|
|
|
sp_mesh_->GetLx() * sp_mesh_->GetLy() * |
|
|
|
sp_mesh_->GetLz(), 1, 1); |
|
|
|
for (int i = 0; i < ele_to_write.size(); ++i) { |
|
|
|
ten_xPhys_to_write(i, 0, 0) = ele_to_write(i); |
|
|
|
} |
|
|
|
ten_xPhys_to_write = ten_xPhys_to_write.reshape( |
|
|
|
Eigen::array<Eigen::DenseIndex, 3>{ |
|
|
|
sp_mesh_->GetLx(), sp_mesh_->GetLy(), |
|
|
|
sp_mesh_->GetLz()}); |
|
|
|
rho_field_zero_filled_ = ten_xPhys_to_write; |
|
|
|
} |
|
|
|
|
|
|
|
{ |
|
|
|
xPhys_col(unchosen_idx).setOnes(); |
|
|
|
ele_to_write(pixel_idx) = xPhys_col; |
|
|
|
Tensor3d ten_xPhys_to_write( |
|
|
|
sp_mesh_->GetLx() * sp_mesh_->GetLy() * |
|
|
|
sp_mesh_->GetLz(), 1, 1); |
|
|
|
for (int i = 0; i < ele_to_write.size(); ++i) { |
|
|
|
ten_xPhys_to_write(i, 0, 0) = ele_to_write(i); |
|
|
|
} |
|
|
|
ten_xPhys_to_write = ten_xPhys_to_write.reshape( |
|
|
|
Eigen::array<Eigen::DenseIndex, 3>{ |
|
|
|
sp_mesh_->GetLx(), sp_mesh_->GetLy(), |
|
|
|
sp_mesh_->GetLz()}); |
|
|
|
rho_field_one_filled_ = ten_xPhys_to_write; |
|
|
|
} |
|
|
|
|
|
|
|
return rho_field_zero_filled_; |
|
|
|
return RhoVec2Ten(rho_); |
|
|
|
} |
|
|
|
|
|
|
|
std::vector<Tensor3d> |
|
|
|
std::vector <Tensor3d> |
|
|
|
Top3d::GetTensorOfStress(const Eigen::VectorXd &which_col_of_stress) { |
|
|
|
Eigen::VectorXd ele_to_write = |
|
|
|
Eigen::VectorXd::Zero( |
|
|
@ -191,7 +190,7 @@ namespace da::sha { |
|
|
|
mat_stress.row(i) = rho_(i) * sp_fea_->computeD() * B * Ue; |
|
|
|
} |
|
|
|
// fill
|
|
|
|
std::vector<Tensor3d> vt; |
|
|
|
std::vector <Tensor3d> vt; |
|
|
|
for (int i = 0; i < which_col_of_stress.size(); ++i) { |
|
|
|
ele_to_write(pixel_idx) = mat_stress.col( |
|
|
|
which_col_of_stress(i)); |
|
|
@ -208,9 +207,10 @@ namespace da::sha { |
|
|
|
sp_mesh_->GetLz()); |
|
|
|
Eigen::VectorXi pixel_idx = sp_mesh_->GetGlobalIdxOfEleInUse(); |
|
|
|
// stress
|
|
|
|
Eigen::VectorXd node_to_write=Eigen::VectorXd::Zero(sp_mesh_->GetNumNodes()); |
|
|
|
Eigen::VectorXd node_to_write = Eigen::VectorXd::Zero( |
|
|
|
sp_mesh_->GetNumNodes()); |
|
|
|
|
|
|
|
std::vector<Eigen::MatrixXd> v_B(8); |
|
|
|
std::vector <Eigen::MatrixXd> v_B(8); |
|
|
|
static const Eigen::MatrixXd delta_coord = (Eigen::MatrixXd(8, 3) << |
|
|
|
0, 0, 0, |
|
|
|
1, 0, 0, |
|
|
@ -221,8 +221,8 @@ namespace da::sha { |
|
|
|
1, 1, 1, |
|
|
|
0, 1, 1 |
|
|
|
).finished(); |
|
|
|
for(int i=0;i<delta_coord.rows();++i){ |
|
|
|
v_B[i]=sp_fea_->computeBe(delta_coord.row(i).array()-0.5); |
|
|
|
for (int i = 0; i < delta_coord.rows(); ++i) { |
|
|
|
v_B[i] = sp_fea_->computeBe(delta_coord.row(i).array() - 0.5); |
|
|
|
} |
|
|
|
auto computeVonStress = [&](Eigen::VectorXd stress) -> double { |
|
|
|
double x = stress(0); |
|
|
@ -235,17 +235,19 @@ namespace da::sha { |
|
|
|
3 * (xy * xy + yz * yz + zx * zx)); |
|
|
|
}; |
|
|
|
for (int i = 0; i < sp_mesh_->GetNumEles(); ++i) { |
|
|
|
Eigen::VectorXi dofs_in_ele_i = sp_mesh_->MapEleId2Dofs(i);// 1x 24
|
|
|
|
Eigen::VectorXi dofs_in_ele_i = sp_mesh_->MapEleId2Dofs( |
|
|
|
i);// 1x 24
|
|
|
|
Eigen::VectorXd Ue = U_(dofs_in_ele_i); |
|
|
|
Eigen::VectorXi node_id_in_ele_i = sp_mesh_->MapEleId2NodeIds(i);// 1x8
|
|
|
|
for(int j=0;j<node_id_in_ele_i.size();++j){ |
|
|
|
int i_node=node_id_in_ele_i(j); |
|
|
|
if(node_to_write(i_node)!=0){ |
|
|
|
Eigen::VectorXi node_id_in_ele_i = sp_mesh_->MapEleId2NodeIds( |
|
|
|
i);// 1x8
|
|
|
|
for (int j = 0; j < node_id_in_ele_i.size(); ++j) { |
|
|
|
int i_node = node_id_in_ele_i(j); |
|
|
|
if (node_to_write(i_node) != 0) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
Eigen::MatrixXd B=v_B[j]; |
|
|
|
Eigen::VectorXd s6=rho_(i) * sp_fea_->computeD() * B * Ue; |
|
|
|
node_to_write(i_node)=computeVonStress(s6); |
|
|
|
Eigen::MatrixXd B = v_B[j]; |
|
|
|
Eigen::VectorXd s6 = rho_(i) * sp_fea_->computeD() * B * Ue; |
|
|
|
node_to_write(i_node) = computeVonStress(s6); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -262,9 +264,9 @@ namespace da::sha { |
|
|
|
ten_prop_to_write(i, 0, 0) = proprty_col(i); |
|
|
|
} |
|
|
|
ten_prop_to_write = ten_prop_to_write.reshape( |
|
|
|
Eigen::array<Eigen::DenseIndex, 3>{sp_mesh_->GetLx(), |
|
|
|
sp_mesh_->GetLy(), |
|
|
|
sp_mesh_->GetLz()}); |
|
|
|
Eigen::array < Eigen::DenseIndex, 3 > {sp_mesh_->GetLx(), |
|
|
|
sp_mesh_->GetLy(), |
|
|
|
sp_mesh_->GetLz()}); |
|
|
|
return ten_prop_to_write; |
|
|
|
} |
|
|
|
|
|
|
@ -339,7 +341,8 @@ namespace da::sha { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
std::vector<Eigen::Triplet<double>> v_tri = Vec2Triplet(iH, jH, sH); |
|
|
|
std::vector <Eigen::Triplet<double>> v_tri = Vec2Triplet(iH, jH, |
|
|
|
sH); |
|
|
|
H_ = SpMat(sp_mesh_->GetNumEles(), sp_mesh_->GetNumEles()); |
|
|
|
H_.setFromTriplets(v_tri.begin(), v_tri.end()); |
|
|
|
|
|
|
|