|
@ -8,19 +8,18 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() { |
|
|
auto &sp_mesh_ = sp_mech_top3d_->sp_mesh_; |
|
|
auto &sp_mesh_ = sp_mech_top3d_->sp_mesh_; |
|
|
auto &sp_para_ = sp_mech_top3d_->sp_para_; |
|
|
auto &sp_para_ = sp_mech_top3d_->sp_para_; |
|
|
Eigen::VectorXd xPhys_col(sp_mesh_->GetNumEles()); |
|
|
Eigen::VectorXd xPhys_col(sp_mesh_->GetNumEles()); |
|
|
xPhys_col.setConstant(sp_para_->volfrac/sp_para_->volfrac); |
|
|
xPhys_col.setConstant(sp_para_->volfrac / sp_para_->volfrac); |
|
|
bool flg_chosen = false; |
|
|
bool flg_chosen = false; |
|
|
Eigen::VectorXi chosen_ele_id; |
|
|
Eigen::VectorXi chosen_ele_id(sp_mesh_->GetChosenEleIdx()); |
|
|
// Eigen::VectorXi chosen_ele_id(sp_mesh_->GetChosenEleIdx());
|
|
|
// bool flg_chosen = chosen_ele_id.size() != 0;
|
|
|
// bool flg_chosen = chosen_ele_id.size() != 0;
|
|
|
// if (!flg_chosen) {
|
|
|
// if (!flg_chosen) {
|
|
|
// // no part chosen
|
|
|
// // no part chosen
|
|
|
// xPhys_col.setConstant(sp_para_->volfrac);
|
|
|
// xPhys_col.setConstant(sp_para_->volfrac);
|
|
|
// } else {
|
|
|
// } else {
|
|
|
// // pick chosen part to sim
|
|
|
// // pick chosen part to sim
|
|
|
// xPhys_col = sp_mesh_->GetInitEleRho();
|
|
|
// xPhys_col = sp_mesh_->GetInitEleRho();
|
|
|
// xPhys_col(chosen_ele_id).setConstant(sp_para_->volfrac);
|
|
|
// xPhys_col(chosen_ele_id).setConstant(sp_para_->volfrac);
|
|
|
// }
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
int loop = 0; |
|
|
int loop = 0; |
|
|
double change = 1.0; |
|
|
double change = 1.0; |
|
@ -38,7 +37,7 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() { |
|
|
|
|
|
|
|
|
Eigen::VectorXd ele_to_write = |
|
|
Eigen::VectorXd ele_to_write = |
|
|
Eigen::VectorXd::Zero(sp_mesh_->GetLx() * sp_mesh_->GetLy() * sp_mesh_->GetLz()); |
|
|
Eigen::VectorXd::Zero(sp_mesh_->GetLx() * sp_mesh_->GetLy() * sp_mesh_->GetLz()); |
|
|
Eigen::VectorXi pixel_idx = sp_mesh_->GetPixelIdx(); |
|
|
Eigen::VectorXi global_idx_of_ele_in_use = sp_mesh_->GetGlobalIdxOfEleInUse(); |
|
|
|
|
|
|
|
|
// dofs of limited T
|
|
|
// dofs of limited T
|
|
|
struct LimitedDof { |
|
|
struct LimitedDof { |
|
@ -46,8 +45,10 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() { |
|
|
int idx_of_load_dof; |
|
|
int idx_of_load_dof; |
|
|
int idx_in_ele; |
|
|
int idx_in_ele; |
|
|
|
|
|
|
|
|
LimitedDof(int dof, int idx_of_load_dof, int idx_in_ele) : dof(dof), idx_of_load_dof(idx_of_load_dof), |
|
|
LimitedDof(int dof, int idx_of_load_dof, int idx_in_ele) |
|
|
idx_in_ele(idx_in_ele) {} |
|
|
: |
|
|
|
|
|
dof(dof), idx_of_load_dof(idx_of_load_dof), |
|
|
|
|
|
idx_in_ele(idx_in_ele) {} |
|
|
}; |
|
|
}; |
|
|
std::map<int, std::vector<LimitedDof>> map_ele2Limit; |
|
|
std::map<int, std::vector<LimitedDof>> map_ele2Limit; |
|
|
std::vector<int> v_dof(sp_thermal_top3d_->set_dofs_to_load.begin(), |
|
|
std::vector<int> v_dof(sp_thermal_top3d_->set_dofs_to_load.begin(), |
|
@ -102,7 +103,8 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() { |
|
|
return CalDRDrho_Vec(vec_rho, sp_para_->R_E) * (E0_m - E_min); |
|
|
return CalDRDrho_Vec(vec_rho, sp_para_->R_E) * (E0_m - E_min); |
|
|
}; |
|
|
}; |
|
|
auto CalLambda_Vec = [&](const Eigen::VectorXd &vec_rho) -> Eigen::VectorXd { |
|
|
auto CalLambda_Vec = [&](const Eigen::VectorXd &vec_rho) -> Eigen::VectorXd { |
|
|
return lambda_min + CalR_Vec(vec_rho, sp_para_->R_lambda).array() * (lambda0 - lambda_min); |
|
|
return lambda_min + |
|
|
|
|
|
CalR_Vec(vec_rho, sp_para_->R_lambda).array() * (lambda0 - lambda_min); |
|
|
}; |
|
|
}; |
|
|
auto CalDlambdaDrho = [&](double rho) { |
|
|
auto CalDlambdaDrho = [&](double rho) { |
|
|
return CalDRDrho(rho, sp_para_->R_lambda) * (lambda0 - lambda_min); |
|
|
return CalDRDrho(rho, sp_para_->R_lambda) * (lambda0 - lambda_min); |
|
@ -202,9 +204,11 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() { |
|
|
// double beta_rho = CalBeta(xPhys_col(i));
|
|
|
// double beta_rho = CalBeta(xPhys_col(i));
|
|
|
// F_th(dofs_m) += beta_rho * (Te - sp_mech_top3d_->sp_para_->T_ref) * Inted_;
|
|
|
// F_th(dofs_m) += beta_rho * (Te - sp_mech_top3d_->sp_para_->T_ref) * Inted_;
|
|
|
Eigen::VectorXd ele_dFth_drho = |
|
|
Eigen::VectorXd ele_dFth_drho = |
|
|
CalDBetaDrho(xPhys_col(i)) * (Te - sp_mech_top3d_->sp_para_->T_ref) * Inted_;// 24x1
|
|
|
CalDBetaDrho(xPhys_col(i)) * (Te - sp_mech_top3d_->sp_para_->T_ref) * |
|
|
|
|
|
Inted_;// 24x1
|
|
|
assert(ele_dFth_drho.size() == 24); |
|
|
assert(ele_dFth_drho.size() == 24); |
|
|
v_dFth_drho(Eigen::seqN(i * ele_dFth_drho.size(), ele_dFth_drho.size())) = ele_dFth_drho; |
|
|
v_dFth_drho( |
|
|
|
|
|
Eigen::seqN(i * ele_dFth_drho.size(), ele_dFth_drho.size())) = ele_dFth_drho; |
|
|
} |
|
|
} |
|
|
auto v_dFth_drho_tri = Vec2Triplet(i_dFth_drho_, j_dFth_drho_, v_dFth_drho); |
|
|
auto v_dFth_drho_tri = Vec2Triplet(i_dFth_drho_, j_dFth_drho_, v_dFth_drho); |
|
|
dFth_drho.setFromTriplets(v_dFth_drho_tri.begin(), v_dFth_drho_tri.end()); |
|
|
dFth_drho.setFromTriplets(v_dFth_drho_tri.begin(), v_dFth_drho_tri.end()); |
|
@ -221,9 +225,11 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() { |
|
|
// F_th(dofs_m) += beta_rho * (Te - sp_mech_top3d_->sp_para_->T_ref) * Inted_;
|
|
|
// F_th(dofs_m) += beta_rho * (Te - sp_mech_top3d_->sp_para_->T_ref) * Inted_;
|
|
|
Eigen::MatrixXd ele_dFth_dT = |
|
|
Eigen::MatrixXd ele_dFth_dT = |
|
|
Eigen::VectorXd::Ones(sp_thermal_top3d_->sp_mesh_->Get_DOFS_EACH_ELE()) * 1.0 / |
|
|
Eigen::VectorXd::Ones(sp_thermal_top3d_->sp_mesh_->Get_DOFS_EACH_ELE()) * 1.0 / |
|
|
sp_thermal_top3d_->sp_mesh_->Get_DOFS_EACH_ELE() * beta_rho * Inted_.transpose(); |
|
|
sp_thermal_top3d_->sp_mesh_->Get_DOFS_EACH_ELE() * beta_rho * |
|
|
|
|
|
Inted_.transpose(); |
|
|
assert(ele_dFth_dT.rows() == 8 && ele_dFth_dT.cols() == 24); |
|
|
assert(ele_dFth_dT.rows() == 8 && ele_dFth_dT.cols() == 24); |
|
|
v_dFth_dT(Eigen::seqN(i * ele_dFth_dT.size(), ele_dFth_dT.size())) = ele_dFth_dT.reshaped(); |
|
|
v_dFth_dT(Eigen::seqN(i * ele_dFth_dT.size(), |
|
|
|
|
|
ele_dFth_dT.size())) = ele_dFth_dT.reshaped(); |
|
|
} |
|
|
} |
|
|
auto v_dFth_dT_tri = Vec2Triplet(i_dFth_dT_, j_dFth_dT_, v_dFth_dT); |
|
|
auto v_dFth_dT_tri = Vec2Triplet(i_dFth_dT_, j_dFth_dT_, v_dFth_dT); |
|
|
dFth_dT.setFromTriplets(v_dFth_dT_tri.begin(), v_dFth_dT_tri.end()); |
|
|
dFth_dT.setFromTriplets(v_dFth_dT_tri.begin(), v_dFth_dT_tri.end()); |
|
@ -248,7 +254,8 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() { |
|
|
Eigen::VectorXd lambda_t_e = lambda_t(dofs_in_ele_i); |
|
|
Eigen::VectorXd lambda_t_e = lambda_t(dofs_in_ele_i); |
|
|
ce_th(i) = lambda_t_e.transpose() * sp_thermal_top3d_->Ke_ * Te; |
|
|
ce_th(i) = lambda_t_e.transpose() * sp_thermal_top3d_->Ke_ * Te; |
|
|
} |
|
|
} |
|
|
Eigen::VectorXd lambda_t_Mul_dKt_drho_Mul_T = CalDlambdaDrho_Vec(xPhys_col).array() * ce_th.array(); |
|
|
Eigen::VectorXd lambda_t_Mul_dKt_drho_Mul_T = |
|
|
|
|
|
CalDlambdaDrho_Vec(xPhys_col).array() * ce_th.array(); |
|
|
// dc_drho
|
|
|
// dc_drho
|
|
|
// Eigen::VectorXd dc_drho = lambda_t_Mul_dKt_drho_Mul_T +
|
|
|
// Eigen::VectorXd dc_drho = lambda_t_Mul_dKt_drho_Mul_T +
|
|
|
// lambda_m_Mul_dKm_drho_Mul_U +
|
|
|
// lambda_m_Mul_dKm_drho_Mul_U +
|
|
@ -279,7 +286,8 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() { |
|
|
} |
|
|
} |
|
|
return sp_dKth_Mul_T; |
|
|
return sp_dKth_Mul_T; |
|
|
}; |
|
|
}; |
|
|
auto CalDTi_Drhoj = [&](int Tdof, const Eigen::SparseVector<double> &sp_dKth_Mul_T) -> double { |
|
|
auto CalDTi_Drhoj = [&](int Tdof, |
|
|
|
|
|
const Eigen::SparseVector<double> &sp_dKth_Mul_T) -> double { |
|
|
Eigen::VectorXd Li = Eigen::VectorXd::Zero(sp_dKth_Mul_T.rows()); |
|
|
Eigen::VectorXd Li = Eigen::VectorXd::Zero(sp_dKth_Mul_T.rows()); |
|
|
Li(Tdof) = -1; |
|
|
Li(Tdof) = -1; |
|
|
for (auto dof_value: sp_thermal_top3d_->v_dofs_to_set) { |
|
|
for (auto dof_value: sp_thermal_top3d_->v_dofs_to_set) { |
|
@ -320,16 +328,18 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() { |
|
|
Eigen::VectorXd variables_tmp = flg_chosen ? xPhys_col(chosen_ele_id) : xPhys_col; |
|
|
Eigen::VectorXd variables_tmp = flg_chosen ? xPhys_col(chosen_ele_id) : xPhys_col; |
|
|
double f0val = c; |
|
|
double f0val = c; |
|
|
Eigen::VectorXd df0dx = flg_chosen |
|
|
Eigen::VectorXd df0dx = flg_chosen |
|
|
? dc_dx(chosen_ele_id).eval() / dc_dx(chosen_ele_id).cwiseAbs().maxCoeff() * |
|
|
? dc_dx(chosen_ele_id).eval() / |
|
|
|
|
|
dc_dx(chosen_ele_id).cwiseAbs().maxCoeff() * |
|
|
SENSITIVITY_SCALE_COEF |
|
|
SENSITIVITY_SCALE_COEF |
|
|
: dc_dx / dc_dx.cwiseAbs().maxCoeff() * SENSITIVITY_SCALE_COEF; |
|
|
: dc_dx / dc_dx.cwiseAbs().maxCoeff() * SENSITIVITY_SCALE_COEF; |
|
|
// double fval = v - num_variables * sp_para_->volfrac;
|
|
|
// double fval = v - num_variables * sp_para_->volfrac;
|
|
|
|
|
|
|
|
|
Eigen::VectorXd fval = (Eigen::VectorXd(num_constraints) << (v / num_variables - sp_para_->volfrac) |
|
|
Eigen::VectorXd fval = |
|
|
|
|
|
(Eigen::VectorXd(num_constraints) << (v / num_variables - sp_para_->volfrac) |
|
|
#ifndef MECH_ONLY |
|
|
#ifndef MECH_ONLY |
|
|
, T(v_dof).array() / sp_para_->T_limit - 1 |
|
|
, T(v_dof).array() / sp_para_->T_limit - 1 |
|
|
#endif |
|
|
#endif |
|
|
).finished() * SENSITIVITY_SCALE_COEF; |
|
|
).finished() * SENSITIVITY_SCALE_COEF; |
|
|
// Eigen::VectorXd dfdx = flg_chosen ? dv(chosen_ele_id) : dv;
|
|
|
// Eigen::VectorXd dfdx = flg_chosen ? dv(chosen_ele_id) : dv;
|
|
|
Eigen::MatrixXd dfdx = (Eigen::MatrixXd(num_variables, num_constraints) |
|
|
Eigen::MatrixXd dfdx = (Eigen::MatrixXd(num_variables, num_constraints) |
|
|
<< 1.0 / num_variables * dv |
|
|
<< 1.0 / num_variables * dv |
|
@ -354,11 +364,12 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() { |
|
|
xPhys_col = variables_tmp; |
|
|
xPhys_col = variables_tmp; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
spdlog::critical("Iter: {:3d}, Comp: {:.3e}, Vol: {:.2f}, Change: {:f}", loop, c, v, change); |
|
|
spdlog::critical("Iter: {:3d}, Comp: {:.3e}, Vol: {:.2f}, Change: {:f}", loop, c, v, |
|
|
|
|
|
change); |
|
|
std::cout << fval.transpose() << std::endl; |
|
|
std::cout << fval.transpose() << std::endl; |
|
|
#ifdef WRITE_TENSOR_IN_LOOP |
|
|
#ifdef WRITE_TENSOR_IN_LOOP |
|
|
// extract vtk
|
|
|
// extract vtk
|
|
|
ele_to_write(pixel_idx) = xPhys_col; |
|
|
ele_to_write(idx_of_ele_in_use) = xPhys_col; |
|
|
Tensor3d ten_xPhys_to_write(sp_mesh_->GetLx() * sp_mesh_->GetLy() * sp_mesh_->GetLz(), 1, 1); |
|
|
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) { |
|
|
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(i, 0, 0) = ele_to_write(i); |
|
@ -375,12 +386,14 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() { |
|
|
// set 0 to rho of unchosen part
|
|
|
// set 0 to rho of unchosen part
|
|
|
assert(xPhys_col.size()); |
|
|
assert(xPhys_col.size()); |
|
|
Eigen::VectorXi continue_idx = |
|
|
Eigen::VectorXi continue_idx = |
|
|
Eigen::VectorXi::LinSpaced(xPhys_col.size(), 0, xPhys_col.size() - 1); |
|
|
Eigen::VectorXi::LinSpaced(xPhys_col.size(), 0, xPhys_col.size()); |
|
|
Eigen::VectorXi unchosen_idx = flg_chosen ? SetDifference(continue_idx, chosen_ele_id) : Eigen::VectorXi(); |
|
|
Eigen::VectorXi unchosen_idx = flg_chosen ? SetDifference(continue_idx, chosen_ele_id) |
|
|
|
|
|
: Eigen::VectorXi(); |
|
|
{ |
|
|
{ |
|
|
xPhys_col(unchosen_idx).setZero(); |
|
|
xPhys_col(unchosen_idx).setZero(); |
|
|
ele_to_write(pixel_idx) = xPhys_col; |
|
|
ele_to_write(global_idx_of_ele_in_use) = xPhys_col; |
|
|
Tensor3d ten_xPhys_to_write(sp_mesh_->GetLx() * sp_mesh_->GetLy() * sp_mesh_->GetLz(), 1, 1); |
|
|
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) { |
|
|
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(i, 0, 0) = ele_to_write(i); |
|
|
} |
|
|
} |
|
@ -391,8 +404,9 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() { |
|
|
|
|
|
|
|
|
{ |
|
|
{ |
|
|
xPhys_col(unchosen_idx).setOnes(); |
|
|
xPhys_col(unchosen_idx).setOnes(); |
|
|
ele_to_write(pixel_idx) = xPhys_col; |
|
|
ele_to_write(global_idx_of_ele_in_use) = xPhys_col; |
|
|
Tensor3d ten_xPhys_to_write(sp_mesh_->GetLx() * sp_mesh_->GetLy() * sp_mesh_->GetLz(), 1, 1); |
|
|
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) { |
|
|
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(i, 0, 0) = ele_to_write(i); |
|
|
} |
|
|
} |
|
|