|
|
@ -4,7 +4,10 @@ |
|
|
|
|
|
|
|
#include "ThermoelasticTop3d.h" |
|
|
|
#include "LinearSolver/Amgcl.h" |
|
|
|
|
|
|
|
#ifdef USE_AMGCL_CUDA |
|
|
|
#include "LinearSolver/AmgclCuda.h" |
|
|
|
#endif |
|
|
|
|
|
|
|
da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() { |
|
|
|
auto &sp_mesh_ = sp_mech_top3d_->sp_mesh_; |
|
|
@ -38,7 +41,8 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() { |
|
|
|
dv = (sp_mech_top3d_->H_ * dv).array() / sp_mech_top3d_->Hs_.array(); |
|
|
|
|
|
|
|
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 global_idx_of_ele_in_use = sp_mesh_->GetGlobalIdxOfEleInUse(); |
|
|
|
|
|
|
|
// dofs of limited T
|
|
|
@ -65,7 +69,8 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() { |
|
|
|
if (map_ele2Limit.find(i) == map_ele2Limit.end()) { |
|
|
|
map_ele2Limit[i] = {LimitedDof(v_dof[k], k, j)}; |
|
|
|
} else { |
|
|
|
map_ele2Limit[i].push_back(LimitedDof(v_dof[k], k, j)); |
|
|
|
map_ele2Limit[i].push_back( |
|
|
|
LimitedDof(v_dof[k], k, j)); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -80,36 +85,45 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() { |
|
|
|
while (change > sp_para_->tol_x && loop < sp_para_->max_loop) { |
|
|
|
++loop; |
|
|
|
// filter
|
|
|
|
xPhys_col = (sp_mech_top3d_->H_ * xPhys_col).array() / sp_mech_top3d_->Hs_.array(); |
|
|
|
xPhys_col = (sp_mech_top3d_->H_ * xPhys_col).array() / |
|
|
|
sp_mech_top3d_->Hs_.array(); |
|
|
|
auto CalR = [](double rho, double R) { |
|
|
|
return rho / (1.0 + R * (1.0 - rho)); |
|
|
|
}; |
|
|
|
auto CalR_Vec = [](const Eigen::VectorXd &vec_rho, double R) -> Eigen::VectorXd { |
|
|
|
auto CalR_Vec = [](const Eigen::VectorXd &vec_rho, |
|
|
|
double R) -> Eigen::VectorXd { |
|
|
|
return vec_rho.array() / (1.0 + R * (1.0 - vec_rho.array())); |
|
|
|
}; |
|
|
|
auto CalDRDrho = [](double rho, double R) { |
|
|
|
double down = 1 + R * (1 - rho); |
|
|
|
return (1 + R) / (down * down); |
|
|
|
}; |
|
|
|
auto CalDRDrho_Vec = [](const Eigen::VectorXd &vec_rho, double R) -> Eigen::VectorXd { |
|
|
|
auto CalDRDrho_Vec = [](const Eigen::VectorXd &vec_rho, |
|
|
|
double R) -> Eigen::VectorXd { |
|
|
|
auto down = 1 + R * (1 - vec_rho.array()); |
|
|
|
return (1 + R) / (down * down); |
|
|
|
}; |
|
|
|
auto CalE_Vec = [&](const Eigen::VectorXd &vec_rho) -> Eigen::VectorXd { |
|
|
|
return E_min + CalR_Vec(vec_rho, sp_para_->R_E).array() * (E0_m - E_min); |
|
|
|
return E_min + |
|
|
|
CalR_Vec(vec_rho, sp_para_->R_E).array() * (E0_m - E_min); |
|
|
|
}; |
|
|
|
auto CalDEDrho_Vec = [&](const Eigen::VectorXd &vec_rho) -> Eigen::VectorXd { |
|
|
|
auto CalDEDrho_Vec = [&]( |
|
|
|
const Eigen::VectorXd &vec_rho) -> Eigen::VectorXd { |
|
|
|
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); |
|
|
|
CalR_Vec(vec_rho, sp_para_->R_lambda).array() * |
|
|
|
(lambda0 - lambda_min); |
|
|
|
}; |
|
|
|
auto CalDlambdaDrho = [&](double rho) { |
|
|
|
return CalDRDrho(rho, sp_para_->R_lambda) * (lambda0 - lambda_min); |
|
|
|
}; |
|
|
|
auto CalDlambdaDrho_Vec = [&](const Eigen::VectorXd &vec_rho) -> Eigen::VectorXd { |
|
|
|
return CalDRDrho_Vec(vec_rho, sp_para_->R_lambda) * (lambda0 - lambda_min); |
|
|
|
auto CalDlambdaDrho_Vec = [&]( |
|
|
|
const Eigen::VectorXd &vec_rho) -> Eigen::VectorXd { |
|
|
|
return CalDRDrho_Vec(vec_rho, sp_para_->R_lambda) * |
|
|
|
(lambda0 - lambda_min); |
|
|
|
}; |
|
|
|
|
|
|
|
auto CalBeta = [&](double rho) { |
|
|
@ -125,10 +139,12 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() { |
|
|
|
Eigen::VectorXd sK_th = |
|
|
|
(sp_thermal_top3d_->sKe_ * CalLambda_Vec(xPhys_col).transpose()) |
|
|
|
.reshaped(); |
|
|
|
auto v_tri_th = Vec2Triplet(sp_thermal_top3d_->iK_, sp_thermal_top3d_->jK_, sK_th); |
|
|
|
auto v_tri_th = Vec2Triplet(sp_thermal_top3d_->iK_, |
|
|
|
sp_thermal_top3d_->jK_, sK_th); |
|
|
|
sp_thermal_top3d_->K_.setFromTriplets(v_tri_th.begin(), v_tri_th.end()); |
|
|
|
sp_thermal_top3d_->IntroduceFixedDofs(sp_thermal_top3d_->K_, sp_thermal_top3d_->F_); |
|
|
|
INIT_SOLVER(solver_th,sp_thermal_top3d_->K_); |
|
|
|
sp_thermal_top3d_->IntroduceFixedDofs(sp_thermal_top3d_->K_, |
|
|
|
sp_thermal_top3d_->F_); |
|
|
|
INIT_SOLVER(solver_th, sp_thermal_top3d_->K_); |
|
|
|
sp_thermal_top3d_->U_ = solver_th.solve(sp_thermal_top3d_->F_); |
|
|
|
#endif |
|
|
|
|
|
|
@ -137,22 +153,27 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() { |
|
|
|
Eigen::VectorXd sK_m = |
|
|
|
(sp_mech_top3d_->sKe_ * CalE_Vec(xPhys_col).transpose()) |
|
|
|
.reshaped(); |
|
|
|
auto v_tri_m = Vec2Triplet(sp_mech_top3d_->iK_, sp_mech_top3d_->jK_, sK_m); |
|
|
|
auto v_tri_m = Vec2Triplet(sp_mech_top3d_->iK_, sp_mech_top3d_->jK_, |
|
|
|
sK_m); |
|
|
|
sp_mech_top3d_->K_.setFromTriplets(v_tri_m.begin(), v_tri_m.end()); |
|
|
|
#ifndef MECH_ONLY |
|
|
|
// F_th
|
|
|
|
Eigen::VectorXd &T = sp_thermal_top3d_->U_; |
|
|
|
Eigen::VectorXd F_th = Eigen::VectorXd::Zero(sp_mech_top3d_->sp_mesh_->GetNumDofs()); |
|
|
|
Eigen::VectorXd F_th = Eigen::VectorXd::Zero( |
|
|
|
sp_mech_top3d_->sp_mesh_->GetNumDofs()); |
|
|
|
|
|
|
|
for (int i = 0; i < sp_thermal_top3d_->sp_mesh_->GetNumEles(); ++i) { |
|
|
|
Eigen::VectorXi dofs_th = sp_thermal_top3d_->sp_mesh_->MapEleId2Dofs(i); |
|
|
|
Eigen::VectorXi dofs_th = sp_thermal_top3d_->sp_mesh_->MapEleId2Dofs( |
|
|
|
i); |
|
|
|
Eigen::VectorXi dofs_m = sp_mech_top3d_->sp_mesh_->MapEleId2Dofs(i); |
|
|
|
double Te = T(dofs_th).mean(); |
|
|
|
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_; |
|
|
|
} |
|
|
|
if (loop == 1 || loop == sp_para_->max_loop) |
|
|
|
spdlog::info("||Fth|| / ||Fm||: {}", F_th.norm() / sp_mech_top3d_->F_.norm()); |
|
|
|
spdlog::info("||Fth|| / ||Fm||: {}", |
|
|
|
F_th.norm() / sp_mech_top3d_->F_.norm()); |
|
|
|
#endif |
|
|
|
Eigen::VectorXd F = Eigen::VectorXd(sp_mech_top3d_->F_) |
|
|
|
#ifndef MECH_ONLY |
|
|
@ -163,7 +184,7 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() { |
|
|
|
|
|
|
|
sp_mech_top3d_->IntroduceFixedDofs(sp_mech_top3d_->K_, F); |
|
|
|
// Timer::tic();
|
|
|
|
INIT_SOLVER(solver,sp_mech_top3d_->K_); |
|
|
|
INIT_SOLVER(solver, sp_mech_top3d_->K_); |
|
|
|
sp_mech_top3d_->U_ = solver.solve(F); |
|
|
|
// Timer::toc();
|
|
|
|
|
|
|
@ -171,43 +192,52 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() { |
|
|
|
// compliance
|
|
|
|
Eigen::VectorXd ce(sp_mech_top3d_->sp_mesh_->GetNumEles()); |
|
|
|
for (int i = 0; i < sp_mech_top3d_->sp_mesh_->GetNumEles(); ++i) { |
|
|
|
Eigen::VectorXi dofs_in_ele_i = sp_mech_top3d_->sp_mesh_->MapEleId2Dofs(i); |
|
|
|
Eigen::VectorXi dofs_in_ele_i = sp_mech_top3d_->sp_mesh_->MapEleId2Dofs( |
|
|
|
i); |
|
|
|
Eigen::VectorXd Ue = sp_mech_top3d_->U_(dofs_in_ele_i); |
|
|
|
ce(i) = Ue.transpose() * sp_mech_top3d_->Ke_ * Ue; |
|
|
|
} |
|
|
|
double c = |
|
|
|
ce.transpose() * CalE_Vec(xPhys_col); |
|
|
|
|
|
|
|
double v = flg_chosen ? xPhys_col(chosen_ele_id).sum() : xPhys_col.sum(); |
|
|
|
double v = flg_chosen ? xPhys_col(chosen_ele_id).sum() |
|
|
|
: xPhys_col.sum(); |
|
|
|
|
|
|
|
// sensitivity
|
|
|
|
// lambda_m
|
|
|
|
Eigen::VectorXd lambda_m = -sp_mech_top3d_->U_; |
|
|
|
#ifndef MECH_ONLY |
|
|
|
// dFth_drho
|
|
|
|
Eigen::SparseMatrix<double> dFth_drho(sp_mech_top3d_->sp_mesh_->GetNumEles(), |
|
|
|
sp_mech_top3d_->sp_mesh_->GetNumDofs()); |
|
|
|
Eigen::SparseMatrix<double> dFth_drho( |
|
|
|
sp_mech_top3d_->sp_mesh_->GetNumEles(), |
|
|
|
sp_mech_top3d_->sp_mesh_->GetNumDofs()); |
|
|
|
Eigen::VectorXd v_dFth_drho(i_dFth_drho_.size()); |
|
|
|
for (int i = 0; i < sp_thermal_top3d_->sp_mesh_->GetNumEles(); ++i) { |
|
|
|
Eigen::VectorXi dofs_th = sp_thermal_top3d_->sp_mesh_->MapEleId2Dofs(i); |
|
|
|
Eigen::VectorXi dofs_th = sp_thermal_top3d_->sp_mesh_->MapEleId2Dofs( |
|
|
|
i); |
|
|
|
// Eigen::VectorXi dofs_m = sp_mech_top3d_->sp_mesh_->MapEleId2Dofs(i);
|
|
|
|
double Te = T(dofs_th).mean(); |
|
|
|
// double beta_rho = CalBeta(xPhys_col(i));
|
|
|
|
// F_th(dofs_m) += beta_rho * (Te - sp_mech_top3d_->sp_para_->T_ref) * Inted_;
|
|
|
|
Eigen::VectorXd ele_dFth_drho = |
|
|
|
CalDBetaDrho(xPhys_col(i)) * (Te - sp_mech_top3d_->sp_para_->T_ref) * |
|
|
|
CalDBetaDrho(xPhys_col(i)) * |
|
|
|
(Te - sp_mech_top3d_->sp_para_->T_ref) * |
|
|
|
Inted_;// 24x1
|
|
|
|
assert(ele_dFth_drho.size() == 24); |
|
|
|
v_dFth_drho( |
|
|
|
Eigen::seqN(i * ele_dFth_drho.size(), ele_dFth_drho.size())) = ele_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); |
|
|
|
dFth_drho.setFromTriplets(v_dFth_drho_tri.begin(), v_dFth_drho_tri.end()); |
|
|
|
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_dT
|
|
|
|
Eigen::SparseMatrix<double> dFth_dT(sp_thermal_top3d_->sp_mesh_->GetNumDofs(), |
|
|
|
sp_mech_top3d_->sp_mesh_->GetNumDofs()); |
|
|
|
Eigen::SparseMatrix<double> dFth_dT( |
|
|
|
sp_thermal_top3d_->sp_mesh_->GetNumDofs(), |
|
|
|
sp_mech_top3d_->sp_mesh_->GetNumDofs()); |
|
|
|
Eigen::VectorXd v_dFth_dT(i_dFth_dT_.size()); |
|
|
|
for (int i = 0; i < sp_thermal_top3d_->sp_mesh_->GetNumEles(); ++i) { |
|
|
|
// Eigen::VectorXi dofs_th = sp_thermal_top3d_->sp_mesh_->MapEleId2Dofs(i);
|
|
|
@ -215,8 +245,11 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() { |
|
|
|
double beta_rho = CalBeta(xPhys_col(i)); |
|
|
|
// F_th(dofs_m) += beta_rho * (Te - sp_mech_top3d_->sp_para_->T_ref) * Inted_;
|
|
|
|
Eigen::MatrixXd ele_dFth_dT = |
|
|
|
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 * |
|
|
|
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(); |
|
|
|
assert(ele_dFth_dT.rows() == 8 && ele_dFth_dT.cols() == 24); |
|
|
|
v_dFth_dT(Eigen::seqN(i * ele_dFth_dT.size(), |
|
|
@ -240,7 +273,8 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() { |
|
|
|
// lambda_t_Mul_dKt_drho_Mul_T
|
|
|
|
Eigen::VectorXd ce_th(sp_thermal_top3d_->sp_mesh_->GetNumEles()); |
|
|
|
for (int i = 0; i < sp_thermal_top3d_->sp_mesh_->GetNumEles(); ++i) { |
|
|
|
Eigen::VectorXi dofs_in_ele_i = sp_thermal_top3d_->sp_mesh_->MapEleId2Dofs(i); |
|
|
|
Eigen::VectorXi dofs_in_ele_i = sp_thermal_top3d_->sp_mesh_->MapEleId2Dofs( |
|
|
|
i); |
|
|
|
Eigen::VectorXd Te = sp_thermal_top3d_->U_(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; |
|
|
@ -261,13 +295,18 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() { |
|
|
|
2 * Eigen::VectorXd(dFth_drho * sp_mech_top3d_->U_); |
|
|
|
#endif |
|
|
|
#ifndef MECH_ONLY |
|
|
|
#ifdef WITH_T_LIMIT |
|
|
|
// dT_drho
|
|
|
|
auto CalDKth_Mul_T__For_DTi_Drhoj = [&](int rho_i) -> Eigen::SparseVector<double> { |
|
|
|
Eigen::VectorXi dofs_in_ele = sp_thermal_top3d_->sp_mesh_->MapEleId2Dofs(rho_i); |
|
|
|
auto CalDKth_Mul_T__For_DTi_Drhoj = [&]( |
|
|
|
int rho_i) -> Eigen::SparseVector<double> { |
|
|
|
Eigen::VectorXi dofs_in_ele = sp_thermal_top3d_->sp_mesh_->MapEleId2Dofs( |
|
|
|
rho_i); |
|
|
|
Eigen::VectorXd ele_T = sp_thermal_top3d_->U_(dofs_in_ele); |
|
|
|
Eigen::SparseVector<double> sp_dKth_Mul_T(sp_thermal_top3d_->sp_mesh_->GetNumDofs()); |
|
|
|
Eigen::SparseVector<double> sp_dKth_Mul_T( |
|
|
|
sp_thermal_top3d_->sp_mesh_->GetNumDofs()); |
|
|
|
Eigen::VectorXd dKe_th_Mul_T = |
|
|
|
CalDlambdaDrho(xPhys_col(rho_i)) * sp_thermal_top3d_->Ke_ * ele_T; |
|
|
|
CalDlambdaDrho(xPhys_col(rho_i)) * sp_thermal_top3d_->Ke_ * |
|
|
|
ele_T; |
|
|
|
for (int i = 0; i < dofs_in_ele.size(); ++i) { |
|
|
|
sp_dKth_Mul_T.coeffRef(dofs_in_ele(i)) = dKe_th_Mul_T(i); |
|
|
|
} |
|
|
@ -284,18 +323,21 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() { |
|
|
|
Eigen::VectorXd lambda_i = solver_th.solve(Li); |
|
|
|
return lambda_i.transpose() * sp_dKth_Mul_T; |
|
|
|
}; |
|
|
|
Eigen::MatrixXd dT_drho = Eigen::MatrixXd::Zero(sp_thermal_top3d_->sp_mesh_->GetNumEles(), |
|
|
|
sp_thermal_top3d_->set_dofs_to_load.size()); |
|
|
|
Eigen::MatrixXd dT_drho = Eigen::MatrixXd::Zero( |
|
|
|
sp_thermal_top3d_->sp_mesh_->GetNumEles(), |
|
|
|
sp_thermal_top3d_->set_dofs_to_load.size()); |
|
|
|
for (auto it = map_ele2Limit.begin(); it != map_ele2Limit.end(); ++it) { |
|
|
|
auto [ele_id, v_limited] = *it; |
|
|
|
auto sp_dKth_Mul_T = CalDKth_Mul_T__For_DTi_Drhoj(ele_id); |
|
|
|
for (auto &limited: v_limited) { |
|
|
|
dT_drho(ele_id, limited.idx_of_load_dof) = CalDTi_Drhoj(limited.dof, sp_dKth_Mul_T); |
|
|
|
dT_drho(ele_id, limited.idx_of_load_dof) = CalDTi_Drhoj( |
|
|
|
limited.dof, sp_dKth_Mul_T); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// dT_dx
|
|
|
|
Eigen::MatrixXd dT_dx = sp_mech_top3d_->drho_dx_ * dT_drho; |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
// dc_dx
|
|
|
|
Eigen::VectorXd dc_dx = sp_mech_top3d_->drho_dx_ * dc_drho; |
|
|
@ -305,68 +347,68 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() { |
|
|
|
size_t num_constraints = |
|
|
|
1 |
|
|
|
#ifndef MECH_ONLY |
|
|
|
#ifdef WITH_T_LIMIT |
|
|
|
+ dT_dx.cols()// volume and temperature constraints
|
|
|
|
#endif |
|
|
|
#endif |
|
|
|
; |
|
|
|
|
|
|
|
|
|
|
|
size_t num_variables = flg_chosen ? chosen_ele_id.size() : sp_mesh_->GetNumEles(); |
|
|
|
size_t num_variables = flg_chosen ? chosen_ele_id.size() |
|
|
|
: sp_mesh_->GetNumEles(); |
|
|
|
auto mma = std::make_shared<MMASolver>(num_variables, num_constraints); |
|
|
|
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; |
|
|
|
Eigen::VectorXd df0dx = flg_chosen |
|
|
|
? dc_dx(chosen_ele_id).eval() / |
|
|
|
dc_dx(chosen_ele_id).cwiseAbs().maxCoeff() * |
|
|
|
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;
|
|
|
|
|
|
|
|
Eigen::VectorXd fval = |
|
|
|
(Eigen::VectorXd(num_constraints) << (v / num_variables - sp_para_->volfrac) |
|
|
|
(Eigen::VectorXd(num_constraints) |
|
|
|
<< (v / num_variables - sp_para_->volfrac) |
|
|
|
#ifndef MECH_ONLY |
|
|
|
#ifdef WITH_T_LIMIT |
|
|
|
, T(v_dof).array() / sp_para_->T_limit - 1 |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
).finished() * SENSITIVITY_SCALE_COEF; |
|
|
|
// Eigen::VectorXd dfdx = flg_chosen ? dv(chosen_ele_id) : dv;
|
|
|
|
Eigen::MatrixXd dfdx = (Eigen::MatrixXd(num_variables, num_constraints) |
|
|
|
<< 1.0 / num_variables * dv |
|
|
|
#ifndef MECH_ONLY |
|
|
|
#ifdef WITH_T_LIMIT |
|
|
|
, 1.0 / sp_para_->T_limit * dT_dx |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
).finished().transpose() * |
|
|
|
SENSITIVITY_SCALE_COEF; |
|
|
|
|
|
|
|
|
|
|
|
static Eigen::VectorXd low_bounds = Eigen::VectorXd::Zero(num_variables); |
|
|
|
static Eigen::VectorXd low_bounds = Eigen::VectorXd::Zero( |
|
|
|
num_variables); |
|
|
|
static Eigen::VectorXd up_bounds = Eigen::VectorXd::Ones(num_variables); |
|
|
|
|
|
|
|
// spdlog::info("mma update");
|
|
|
|
mma->Update(variables_tmp.data(), df0dx.data(), fval.data(), dfdx.data(), low_bounds.data(), |
|
|
|
mma->Update(variables_tmp.data(), df0dx.data(), fval.data(), |
|
|
|
dfdx.data(), low_bounds.data(), |
|
|
|
up_bounds.data()); |
|
|
|
if (flg_chosen) { |
|
|
|
change = (variables_tmp - xPhys_col(chosen_ele_id)).cwiseAbs().maxCoeff(); |
|
|
|
change = (variables_tmp - |
|
|
|
xPhys_col(chosen_ele_id)).cwiseAbs().maxCoeff(); |
|
|
|
xPhys_col(chosen_ele_id) = variables_tmp; |
|
|
|
} else { |
|
|
|
change = (variables_tmp - xPhys_col).cwiseAbs().maxCoeff(); |
|
|
|
xPhys_col = variables_tmp; |
|
|
|
} |
|
|
|
|
|
|
|
spdlog::critical("Iter: {:3d}, Comp: {:.3e}, Vol: {:.2f}, Change: {:f}", loop, c, v, |
|
|
|
spdlog::critical("Iter: {:3d}, Comp: {:.3e}, Vol: {:.2f}, Change: {:f}", |
|
|
|
loop, c, v, |
|
|
|
change); |
|
|
|
// std::cout << fval.transpose() << std::endl;
|
|
|
|
#ifdef WRITE_TENSOR_IN_LOOP |
|
|
|
// extract vtk
|
|
|
|
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); |
|
|
|
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()}); |
|
|
|
top::WriteTensorToVtk( |
|
|
|
da::WorkingResultDirectoryPath() / ("field_matrix" + std::to_string(loop) + ".vtk"), |
|
|
|
ten_xPhys_to_write, sp_mesh_); |
|
|
|
#endif |
|
|
|
} |
|
|
|
// result
|
|
|
|
sp_mech_top3d_->rho_ = xPhys_col; |
|
|
@ -374,31 +416,38 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() { |
|
|
|
assert(xPhys_col.size()); |
|
|
|
Eigen::VectorXi continue_idx = |
|
|
|
Eigen::VectorXi::LinSpaced(xPhys_col.size(), 0, xPhys_col.size()); |
|
|
|
Eigen::VectorXi unchosen_idx = flg_chosen ? SetDifference(continue_idx, chosen_ele_id) |
|
|
|
Eigen::VectorXi unchosen_idx = flg_chosen ? SetDifference(continue_idx, |
|
|
|
chosen_ele_id) |
|
|
|
: Eigen::VectorXi(); |
|
|
|
{ |
|
|
|
xPhys_col(unchosen_idx).setZero(); |
|
|
|
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) { |
|
|
|
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()}); |
|
|
|
ten_xPhys_to_write = ten_xPhys_to_write.reshape( |
|
|
|
Eigen::array<Eigen::DenseIndex, 3>{ |
|
|
|
sp_mesh_->GetLx(), sp_mesh_->GetLy(), |
|
|
|
sp_mesh_->GetLz()}); |
|
|
|
sp_mech_top3d_->rho_field_zero_filled_ = ten_xPhys_to_write; |
|
|
|
} |
|
|
|
|
|
|
|
{ |
|
|
|
xPhys_col(unchosen_idx).setOnes(); |
|
|
|
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) { |
|
|
|
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()}); |
|
|
|
ten_xPhys_to_write = ten_xPhys_to_write.reshape( |
|
|
|
Eigen::array<Eigen::DenseIndex, 3>{ |
|
|
|
sp_mesh_->GetLx(), sp_mesh_->GetLy(), |
|
|
|
sp_mesh_->GetLz()}); |
|
|
|
sp_mech_top3d_->rho_field_one_filled_ = ten_xPhys_to_write; |
|
|
|
} |
|
|
|
|
|
|
|