Browse Source

Merge branch 'dev'

multiple_top
cflin 2 years ago
parent
commit
61a071c61c
  1. 2
      examples/top-mech-regular-model-test/config.json
  2. 18
      examples/top-thermoelastic-regular-model/config.json
  3. 15
      src/ThermoelasticTop3d.cpp
  4. 8
      src/ThermoelasticTop3d.h
  5. 51
      src/Top3d.cpp
  6. 1
      src/Top3d.h

2
examples/top-mech-regular-model-test/config.json

@ -6,7 +6,7 @@
"topology": { "topology": {
"max_loop": 100, "max_loop": 100,
"volfrac": 0.5, "volfrac": 0.5,
"penal": 3.0, "penal": 1.0,
"r_min": 1.5 "r_min": 1.5
}, },
"model": { "model": {

18
examples/top-thermoelastic-regular-model/config.json

@ -2,23 +2,23 @@
"material": { "material": {
"E": 1.0, "E": 1.0,
"poisson_ratio": 0.3, "poisson_ratio": 0.3,
"thermal_conductivity":1e11, "unit": "W/K", "thermal_conductivity":0.004, "unit": "W/K",
"thermal_expansion_coefficient": 1e-15, "unit": "1/K" "thermal_expansion_coefficient": 1e-6, "unit": "1/K"
}, },
"topology": { "topology": {
"max_loop": 100, "max_loop": 100,
"volfrac": 0.5, "volfrac": 0.5,
"r_min": 1.5, "r_min": 1.5,
"T_ref": 295, "T_ref": 295,
"T_limit": 3250, "T_limit": 325,
"R_E": 8, "R_E": 0,
"R_lambda": 0, "R_lambda": 0,
"R_beta": 0 "R_beta": 0
}, },
"model": { "model": {
"regular_model": { "regular_model": {
"lx": 1, "lx": 2,
"ly": 40, "ly": 20,
"lz": 30 "lz": 30
}, },
"visual_model":"2-box-refined.obj" "visual_model":"2-box-refined.obj"
@ -28,7 +28,7 @@
{ {
"min": [0, 1, 0], "min": [0, 1, 0],
"max": [1, 1, 0], "max": [1, 1, 0],
"val": [0.0, 0.0, -500.0] "val": [0.0, 0.0, -1.0]
} }
], ],
@ -45,12 +45,12 @@
{ {
"min": [0, 0.25, 0.5], "min": [0, 0.25, 0.5],
"max": [1, 0.25, 0.5], "max": [1, 0.25, 0.5],
"heat_flux": 0.06, "unit": "W" "heat_flux": 1e-15, "unit": "W"
}, },
{ {
"min": [0, 0.75, 0.5], "min": [0, 0.75, 0.5],
"max": [1, 0.75, 0.5], "max": [1, 0.75, 0.5],
"heat_flux": 0.06, "unit": "W" "heat_flux": 1e-15, "unit": "W"
} }
], ],

15
src/ThermoelasticTop3d.cpp

@ -75,7 +75,7 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() {
spdlog::warn("using Eigen built-in direct solver!"); spdlog::warn("using Eigen built-in direct solver!");
#endif #endif
// start iteration // start iteration
while (change > sp_para_->tol_x * 1 && loop < sp_para_->max_loop) { while (change > sp_para_->tol_x && loop < sp_para_->max_loop) {
++loop; ++loop;
// filter // filter
xPhys_col = sp_mech_top3d_->H_ * (xPhys_col.array() / sp_mech_top3d_->Hs_.array()).matrix().eval(); xPhys_col = sp_mech_top3d_->H_ * (xPhys_col.array() / sp_mech_top3d_->Hs_.array()).matrix().eval();
@ -151,6 +151,7 @@ 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::VectorXd F = Eigen::VectorXd(sp_mech_top3d_->F_) + F_th; Eigen::VectorXd F = Eigen::VectorXd(sp_mech_top3d_->F_) + F_th;
sp_mech_top3d_->IntroduceFixedDofs(sp_mech_top3d_->K_, F); sp_mech_top3d_->IntroduceFixedDofs(sp_mech_top3d_->K_, F);
#ifdef USE_SUITESPARSE #ifdef USE_SUITESPARSE
Eigen::CholmodSupernodalLLT<Eigen::SparseMatrix<double>> solver; Eigen::CholmodSupernodalLLT<Eigen::SparseMatrix<double>> solver;
@ -170,11 +171,13 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() {
} }
double c = double c =
ce.transpose() * CalE_Vec(xPhys_col); 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 // sensitivity
// lambda_m // lambda_m
Eigen::VectorXd lambda_m = -sp_mech_top3d_->U_; Eigen::VectorXd lambda_m = -sp_mech_top3d_->U_;
// dFth_drho // dFth_drho
Eigen::SparseMatrix<double> dFth_drho(sp_mech_top3d_->sp_mesh_->GetNumEles(), Eigen::SparseMatrix<double> dFth_drho(sp_mech_top3d_->sp_mesh_->GetNumEles(),
sp_mech_top3d_->sp_mesh_->GetNumDofs()); sp_mech_top3d_->sp_mesh_->GetNumDofs());
@ -193,6 +196,7 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() {
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());
// dFth_dT // dFth_dT
Eigen::SparseMatrix<double> dFth_dT(sp_thermal_top3d_->sp_mesh_->GetNumDofs(), Eigen::SparseMatrix<double> dFth_dT(sp_thermal_top3d_->sp_mesh_->GetNumDofs(),
sp_mech_top3d_->sp_mesh_->GetNumDofs()); sp_mech_top3d_->sp_mesh_->GetNumDofs());
@ -259,6 +263,7 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() {
dT_drho(ele_id, limited.idx_of_load_dof) = ele_dT_drho(limited.idx_in_ele); dT_drho(ele_id, limited.idx_of_load_dof) = ele_dT_drho(limited.idx_in_ele);
} }
} }
// for (int i = 0; i < sp_thermal_top3d_->sp_mesh_->GetNumEles(); ++i) { // 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 dKe_th_Mul_T = // Eigen::VectorXd dKe_th_Mul_T =
@ -279,13 +284,15 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() {
// } // }
// dc_dx // dc_dx
Eigen::VectorXd dc_dx = drho_dx_ * dc_drho; Eigen::VectorXd dc_dx = sp_mech_top3d_->drho_dx_ * dc_drho;
// dT_dx // dT_dx
Eigen::MatrixXd dT_dx = drho_dx_ * dT_drho; Eigen::MatrixXd dT_dx = sp_mech_top3d_->drho_dx_ * dT_drho;
// mma solver // mma solver
size_t num_constraints = size_t num_constraints =
1 + dT_dx.cols();// volume and temperature constraints 1 + dT_dx.cols();// volume and temperature constraints
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); 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;
@ -299,6 +306,8 @@ da::sha::top::Tensor3d da::sha::top::ThermoelasticTop3d::TopOptMainLoop() {
// 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 / sp_para_->T_limit * dT_dx).finished().transpose(); << 1.0 / num_variables * dv, 1.0 / sp_para_->T_limit * dT_dx).finished().transpose();
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); static Eigen::VectorXd up_bounds = Eigen::VectorXd::Ones(num_variables);

8
src/ThermoelasticTop3d.h

@ -43,13 +43,6 @@ namespace da::sha::top {
D0_ = sp_mech_top3d_->sp_fea_->computeD(1.0); D0_ = sp_mech_top3d_->sp_fea_->computeD(1.0);
const Eigen::MatrixXd Be = sp_mech_top3d_->sp_fea_->computeBe(); const Eigen::MatrixXd Be = sp_mech_top3d_->sp_fea_->computeBe();
Inted_ = Be.transpose() * D0_ * (Eigen::VectorXd(6) << 1, 1, 1, 0, 0, 0).finished(); Inted_ = Be.transpose() * D0_ * (Eigen::VectorXd(6) << 1, 1, 1, 0, 0, 0).finished();
Eigen::VectorXi i_Hs = Eigen::VectorXi::LinSpaced(sp_mech_top3d_->Hs_.size(), 0,
sp_mech_top3d_->Hs_.size());
Eigen::SparseMatrix<double> sp_Hs(i_Hs.size(), i_Hs.size());
auto v_tri = Vec2Triplet(i_Hs, i_Hs, sp_mech_top3d_->Hs_);
sp_Hs.setFromTriplets(v_tri.begin(), v_tri.end());
drho_dx_ = sp_Hs * sp_mech_top3d_->H_;
} }
@ -60,7 +53,6 @@ namespace da::sha::top {
Eigen::VectorXi i_dFth_drho_, j_dFth_drho_; Eigen::VectorXi i_dFth_drho_, j_dFth_drho_;
Eigen::VectorXd Inted_; Eigen::VectorXd Inted_;
Eigen::MatrixXd D0_; Eigen::MatrixXd D0_;
Eigen::SparseMatrix<double> drho_dx_;
}; };
} }

51
src/Top3d.cpp

@ -7,9 +7,10 @@
#include <cassert> #include <cassert>
#include "Eigen/src/Core/Matrix.h" #include "Eigen/src/Core/Matrix.h"
#include "Util.h" #include "Util.h"
namespace da::sha { namespace da::sha {
namespace top { namespace top {
Tensor3d Top3d::TopOptMainLoop() { Tensor3d Top3d::TopOptMainLoop() {
Eigen::VectorXd xPhys_col(sp_mesh_->GetNumEles()); Eigen::VectorXd xPhys_col(sp_mesh_->GetNumEles());
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;
@ -47,6 +48,8 @@ Tensor3d Top3d::TopOptMainLoop() {
// start iteration // start iteration
while (change > sp_para_->tol_x && loop < sp_para_->max_loop) { while (change > sp_para_->tol_x && loop < sp_para_->max_loop) {
++loop; ++loop;
// filter
xPhys_col = H_ * (xPhys_col.array() / Hs_.array()).matrix().eval();
Eigen::VectorXd sK = Eigen::VectorXd sK =
(sKe_ * (Emin + xPhys_col.array().pow(sp_para_->penal) * (E0 - Emin)).matrix().transpose()) (sKe_ * (Emin + xPhys_col.array().pow(sp_para_->penal) * (E0 - Emin)).matrix().transpose())
.reshaped(); .reshaped();
@ -71,8 +74,10 @@ Tensor3d Top3d::TopOptMainLoop() {
ce.transpose() * (Emin + xPhys_col.array().pow(sp_para_->penal) * (E0 - Emin)).matrix(); ce.transpose() * (Emin + xPhys_col.array().pow(sp_para_->penal) * (E0 - Emin)).matrix();
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();
Eigen::VectorXd dc = // sensitivity
Eigen::VectorXd dc_drho =
-sp_para_->penal * (E0 - Emin) * xPhys_col.array().pow(sp_para_->penal - 1.0) * ce.array(); -sp_para_->penal * (E0 - Emin) * xPhys_col.array().pow(sp_para_->penal - 1.0) * ce.array();
Eigen::VectorXd dc_dx = drho_dx_ * dc_drho;
// mma solver // mma solver
size_t num_constrants = 1; size_t num_constrants = 1;
@ -81,8 +86,8 @@ Tensor3d Top3d::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(chosen_ele_id).eval() / dc(chosen_ele_id).cwiseAbs().maxCoeff() ? dc_dx(chosen_ele_id).eval() / dc_dx(chosen_ele_id).cwiseAbs().maxCoeff()
: dc / dc.cwiseAbs().maxCoeff(); : dc_dx / dc_dx.cwiseAbs().maxCoeff();
double fval = v - num_variables * sp_para_->volfrac; double fval = v - num_variables * sp_para_->volfrac;
Eigen::VectorXd dfdx = flg_chosen ? dv(chosen_ele_id) : dv; Eigen::VectorXd dfdx = flg_chosen ? dv(chosen_ele_id) : dv;
static Eigen::VectorXd low_bounds = Eigen::VectorXd::Zero(num_variables); static Eigen::VectorXd low_bounds = Eigen::VectorXd::Zero(num_variables);
@ -120,7 +125,7 @@ Tensor3d Top3d::TopOptMainLoop() {
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() - 1);
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(pixel_idx) = xPhys_col;
@ -146,15 +151,15 @@ Tensor3d Top3d::TopOptMainLoop() {
} }
return rho_field_zero_filled_; return rho_field_zero_filled_;
} }
std::vector<Tensor3d> Top3d::GetTensorOfStress(const Eigen::VectorXd &which_col_of_stress) { std::vector<Tensor3d> Top3d::GetTensorOfStress(const Eigen::VectorXd &which_col_of_stress) {
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 pixel_idx = sp_mesh_->GetPixelIdx();
// stress // stress
Eigen::MatrixXd mat_stress(sp_mesh_->GetNumEles(), 6); Eigen::MatrixXd mat_stress(sp_mesh_->GetNumEles(), 6);
Eigen::MatrixXd B=sp_fea_->computeBe({0, 0, 0}); Eigen::MatrixXd B = sp_fea_->computeBe({0, 0, 0});
for (int i = 0; i < sp_mesh_->GetNumEles(); ++i) { for (int i = 0; i < sp_mesh_->GetNumEles(); ++i) {
Eigen::VectorXi dofs_in_ele_i = sp_mesh_->MapEleId2Dofs(i); Eigen::VectorXi dofs_in_ele_i = sp_mesh_->MapEleId2Dofs(i);
Eigen::VectorXd Ue = U_(dofs_in_ele_i); Eigen::VectorXd Ue = U_(dofs_in_ele_i);
@ -167,9 +172,9 @@ std::vector<Tensor3d> Top3d::GetTensorOfStress(const Eigen::VectorXd &which_col_
vt.push_back(GetTensorFromCol(ele_to_write)); vt.push_back(GetTensorFromCol(ele_to_write));
} }
return vt; return vt;
} }
Tensor3d Top3d::GetTensorFromCol(const Eigen::VectorXd &proprty_col) { Tensor3d Top3d::GetTensorFromCol(const Eigen::VectorXd &proprty_col) {
Tensor3d ten_prop_to_write(sp_mesh_->GetLx() * sp_mesh_->GetLy() * sp_mesh_->GetLz(), 1, 1); Tensor3d ten_prop_to_write(sp_mesh_->GetLx() * sp_mesh_->GetLy() * sp_mesh_->GetLz(), 1, 1);
assert(proprty_col.size() == ten_prop_to_write.size()); assert(proprty_col.size() == ten_prop_to_write.size());
for (int i = 0; i < proprty_col.size(); ++i) { for (int i = 0; i < proprty_col.size(); ++i) {
@ -178,9 +183,9 @@ Tensor3d Top3d::GetTensorFromCol(const Eigen::VectorXd &proprty_col) {
ten_prop_to_write = ten_prop_to_write.reshape( 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; return ten_prop_to_write;
} }
void Top3d::Precompute() { void Top3d::Precompute() {
Eigen::MatrixXi mat_ele2dofs = sp_mesh_->GetEleId2DofsMap(); Eigen::MatrixXi mat_ele2dofs = sp_mesh_->GetEleId2DofsMap();
int dofs_each_ele = sp_mesh_->Get_NUM_NODES_EACH_ELE() * int dofs_each_ele = sp_mesh_->Get_NUM_NODES_EACH_ELE() *
sp_mesh_->Get_DOFS_EACH_NODE(); // 24 for mathe; 8 for heat sp_mesh_->Get_DOFS_EACH_NODE(); // 24 for mathe; 8 for heat
@ -190,7 +195,7 @@ void Top3d::Precompute() {
jK_ = Eigen::KroneckerProduct(mat_ele2dofs, Eigen::RowVectorXi::Ones(dofs_each_ele)) jK_ = Eigen::KroneckerProduct(mat_ele2dofs, Eigen::RowVectorXi::Ones(dofs_each_ele))
.transpose() .transpose()
.reshaped(); .reshaped();
Ke_=sp_fea_->computeKe(1.0); Ke_ = sp_fea_->computeKe(1.0);
sKe_ = Ke_.reshaped(); sKe_ = Ke_.reshaped();
// precompute filter // precompute filter
@ -217,14 +222,16 @@ void Top3d::Precompute() {
for (int i2 = std::max(i - delta, 0); i2 <= std::min(i + delta, sp_mesh_->GetLx() - 1); for (int i2 = std::max(i - delta, 0); i2 <= std::min(i + delta, sp_mesh_->GetLx() - 1);
++i2) { ++i2) {
int ele_id1 = int ele_id1 =
sp_mesh_->MapEleCoord2Id((Eigen::MatrixXi(1, 3) << i2, j2, k2).finished())(0); sp_mesh_->MapEleCoord2Id((Eigen::MatrixXi(1, 3) << i2, j2, k2).finished())(
0);
if (ele_id1 == -1) { if (ele_id1 == -1) {
continue; continue;
} }
iH(cnt) = ele_id0; iH(cnt) = ele_id0;
jH(cnt) = ele_id1; jH(cnt) = ele_id1;
sH(cnt) = sH(cnt) =
std::max(0.0, sp_para_->r_min - Eigen::Vector3d(i - i2, j - j2, k - k2).norm()); std::max(0.0,
sp_para_->r_min - Eigen::Vector3d(i - i2, j - j2, k - k2).norm());
Hs_(ele_id0) += sH(cnt); Hs_(ele_id0) += sH(cnt);
++cnt; ++cnt;
} }
@ -236,6 +243,14 @@ void Top3d::Precompute() {
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_ = SpMat(sp_mesh_->GetNumEles(), sp_mesh_->GetNumEles());
H_.setFromTriplets(v_tri.begin(), v_tri.end()); H_.setFromTriplets(v_tri.begin(), v_tri.end());
}
} // namespace top Eigen::VectorXi i_Hs = Eigen::VectorXi::LinSpaced(Hs_.size(), 0,
Hs_.size());
Eigen::SparseMatrix<double> sp_inv_Hs(i_Hs.size(), i_Hs.size());
auto v_inv_Hs_tri = Vec2Triplet(i_Hs, i_Hs, Eigen::VectorXd(1.0 / Hs_.array()));
sp_inv_Hs.setFromTriplets(v_inv_Hs_tri.begin(), v_inv_Hs_tri.end());
drho_dx_ = sp_inv_Hs * H_;
}
} // namespace top
} // namespace da::sha } // namespace da::sha

1
src/Top3d.h

@ -188,6 +188,7 @@ namespace da::sha {
SpMat H_; SpMat H_;
Eigen::VectorXd Hs_; Eigen::VectorXd Hs_;
Eigen::SparseMatrix<double> drho_dx_;
// result // result
Eigen::VectorXd U_; Eigen::VectorXd U_;
Eigen::VectorXd rho_; Eigen::VectorXd rho_;

Loading…
Cancel
Save