|
|
@ -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,51 +163,15 @@ 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> |
|
|
@ -208,7 +207,8 @@ 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); |
|
|
|
static const Eigen::MatrixXd delta_coord = (Eigen::MatrixXd(8, 3) << |
|
|
@ -235,9 +235,11 @@ 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
|
|
|
|
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) { |
|
|
@ -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()); |
|
|
|
|
|
|
|