4 changed files with 30 additions and 468 deletions
@ -1,3 +1,16 @@ |
|||||
set(SUB_PROJECT_NAME clamped_model_writer) |
set(SUB_PROJECT_NAME clamped_model_writer) |
||||
add_executable(${SUB_PROJECT_NAME} main.cpp) |
if (ENABLE_AMGCL_CUDA) |
||||
target_link_libraries(${SUB_PROJECT_NAME} ${PROJECT_NAME}_lib) |
# cp main.cpp to main.cu |
||||
|
configure_file( |
||||
|
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp |
||||
|
${CMAKE_CURRENT_SOURCE_DIR}/main.cu |
||||
|
COPYONLY |
||||
|
) |
||||
|
add_executable(${SUB_PROJECT_NAME} main.cu) |
||||
|
# # OpenMP Required! |
||||
|
target_compile_options(${SUB_PROJECT_NAME} PRIVATE -Xcompiler -fopenmp) |
||||
|
target_link_libraries(${SUB_PROJECT_NAME} PUBLIC ${PROJECT_NAME}_cuda_lib) |
||||
|
else () |
||||
|
add_executable(${SUB_PROJECT_NAME} main.cpp) |
||||
|
target_link_libraries(${SUB_PROJECT_NAME} ${PROJECT_NAME}_lib) |
||||
|
endif () |
@ -1,3 +1,16 @@ |
|||||
set(SUB_PROJECT_NAME defined_model_writer) |
set(SUB_PROJECT_NAME defined_model_writer) |
||||
add_executable(${SUB_PROJECT_NAME} main.cpp) |
if (ENABLE_AMGCL_CUDA) |
||||
target_link_libraries(${SUB_PROJECT_NAME} ${PROJECT_NAME}_lib) |
# cp main.cpp to main.cu |
||||
|
configure_file( |
||||
|
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp |
||||
|
${CMAKE_CURRENT_SOURCE_DIR}/main.cu |
||||
|
COPYONLY |
||||
|
) |
||||
|
add_executable(${SUB_PROJECT_NAME} main.cu) |
||||
|
# # OpenMP Required! |
||||
|
target_compile_options(${SUB_PROJECT_NAME} PRIVATE -Xcompiler -fopenmp) |
||||
|
target_link_libraries(${SUB_PROJECT_NAME} PUBLIC ${PROJECT_NAME}_cuda_lib) |
||||
|
else () |
||||
|
add_executable(${SUB_PROJECT_NAME} main.cpp) |
||||
|
target_link_libraries(${SUB_PROJECT_NAME} ${PROJECT_NAME}_lib) |
||||
|
endif () |
@ -1,17 +0,0 @@ |
|||||
set(SUB_PROJECT_NAME top_summary) |
|
||||
if (ENABLE_AMGCL_CUDA) |
|
||||
# cp main.cpp to main.cu |
|
||||
configure_file( |
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp |
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cu |
|
||||
COPYONLY |
|
||||
) |
|
||||
add_executable(${SUB_PROJECT_NAME} main.cu) |
|
||||
# # OpenMP Required! |
|
||||
target_compile_options(${SUB_PROJECT_NAME} PRIVATE -Xcompiler -fopenmp) |
|
||||
target_link_libraries(${SUB_PROJECT_NAME} PUBLIC ${PROJECT_NAME}_cuda_lib) |
|
||||
else () |
|
||||
add_executable(${SUB_PROJECT_NAME} main.cpp) |
|
||||
target_link_libraries(${SUB_PROJECT_NAME} ${PROJECT_NAME}_lib) |
|
||||
endif () |
|
||||
#target_compile_definitions(${SUB_PROJECT_NAME} PUBLIC CONFIG_FILE= "${CMAKE_CURRENT_SOURCE_DIR}/config.json") |
|
@ -1,447 +0,0 @@ |
|||||
//
|
|
||||
// Created by cflin on 6/9/23.
|
|
||||
//
|
|
||||
#include <memory> |
|
||||
#include <nlohmann/json.hpp> |
|
||||
#include "Boundary.h" |
|
||||
#include "Mesh/HeatMesh.h" |
|
||||
#include "Util.h" |
|
||||
#include "ThermoelasticTop3d.h" |
|
||||
#include "FEA/MechanicalLinearFEA.h" |
|
||||
#include "FEA/ThermalLinearFEA.h" |
|
||||
#include "TensorWrapper.h" |
|
||||
|
|
||||
int main() { |
|
||||
using namespace da::sha; |
|
||||
using namespace da::sha::top; |
|
||||
using top::fs_path; |
|
||||
using std::string; |
|
||||
top::fs_path output_dir(OUTPUT_DIR); |
|
||||
top::fs_path config_file( |
|
||||
CMAKE_SOURCE_DIR "/examples/top-thermoelastic-compare-3d/config_Lshape.json"); |
|
||||
top::fs_path assets_dir(ASSETS_DIR); |
|
||||
spdlog::info("Algo read from '{}'", config_file.string()); |
|
||||
spdlog::info("Algo output to '{}'", output_dir.string()); |
|
||||
spdlog::info("assets dir: '{}'", assets_dir.string()); |
|
||||
|
|
||||
// read json
|
|
||||
std::ifstream f(config_file.c_str()); |
|
||||
if (!f) { |
|
||||
spdlog::critical("f open fail!"); |
|
||||
exit(-7); |
|
||||
} |
|
||||
nlohmann::json j_config = nlohmann::json::parse(f); |
|
||||
// read title
|
|
||||
std::string ex_name = j_config["TopologyOptimizationExample"]; |
|
||||
spdlog::critical("TopologyOptimizationExample: {}", ex_name); |
|
||||
|
|
||||
// set topology parameters
|
|
||||
auto para = std::make_shared<top::CtrlPara>(); |
|
||||
para->max_loop = j_config["topology"]["max_loop"]; |
|
||||
para->volfrac = j_config["topology"]["volfrac"]; |
|
||||
para->r_min = j_config["topology"]["r_min"]; |
|
||||
para->penal = j_config["topology"]["penal"]; |
|
||||
para->T_ref = j_config["topology"]["T_ref"]; |
|
||||
para->T_limit = j_config["topology"]["T_limit"]; |
|
||||
para->R_E = j_config["topology"]["R_E"]; |
|
||||
para->R_lambda = j_config["topology"]["R_lambda"]; |
|
||||
para->R_beta = j_config["topology"]["R_beta"]; |
|
||||
|
|
||||
// set material parameters
|
|
||||
double E = j_config["material"]["E"]; |
|
||||
double Poisson_ratio = j_config["material"]["poisson_ratio"]; |
|
||||
double thermal_conductivity = j_config["material"]["thermal_conductivity"]; |
|
||||
double thermal_expansion_coefficient = j_config["material"]["thermal_expansion_coefficient"]; |
|
||||
auto material = std::make_shared<top::Material>(E, Poisson_ratio, |
|
||||
thermal_conductivity, |
|
||||
thermal_expansion_coefficient); |
|
||||
// set fea
|
|
||||
auto sp_mech_fea = std::make_shared<top::MechanicalLinearFEA>( |
|
||||
material);// for mechanical
|
|
||||
auto sp_thermal_fea = std::make_shared<top::ThermalLinearFEA>( |
|
||||
material);// for thermal
|
|
||||
|
|
||||
// set mesh(regular)
|
|
||||
int len_x = j_config["model"]["regular_model"]["lx"]; |
|
||||
int len_y = j_config["model"]["regular_model"]["ly"]; |
|
||||
int len_z = j_config["model"]["regular_model"]["lz"]; |
|
||||
// NOTE: USER DEFINE GRID HERE!!!
|
|
||||
std::shared_ptr<top::Mesh> sp_mech_mesh; |
|
||||
std::shared_ptr<top::HeatMesh> sp_thermal_mesh; |
|
||||
if (ex_name == "Lshape") { |
|
||||
// L-shape condition
|
|
||||
spdlog::critical("Using User Defined density!"); |
|
||||
top::Tensor3d L_shape_model(len_x, len_y, len_z); |
|
||||
L_shape_model.setConstant(1); |
|
||||
// set the initial voxel model
|
|
||||
for (int k = 0; k < len_z; ++k) { |
|
||||
for (int j = 0; j < len_y; ++j) { |
|
||||
for (int i = 0; i < len_x; ++i) { |
|
||||
if (j > len_y * 0.6 & k > len_z * 0.5) { |
|
||||
L_shape_model(i, j, k) = 0; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
auto &model = L_shape_model; |
|
||||
sp_mech_mesh = std::make_shared<top::Mesh>(len_x, len_y, len_z, model); |
|
||||
sp_thermal_mesh = std::make_shared<top::HeatMesh>(len_x, len_y, len_z, |
|
||||
model); |
|
||||
} else { |
|
||||
sp_mech_mesh = std::make_shared<top::Mesh>(len_x, len_y, len_z); |
|
||||
sp_thermal_mesh = std::make_shared<top::HeatMesh>(len_x, len_y, len_z); |
|
||||
} |
|
||||
// initialize Top3d
|
|
||||
auto sp_mech_top3d = std::make_shared<top::Top3d>(para, sp_mech_fea, |
|
||||
sp_mech_mesh); |
|
||||
auto sp_ther_top3d = std::make_shared<top::Top3d>(para, sp_thermal_fea, |
|
||||
sp_thermal_mesh); |
|
||||
|
|
||||
// auxiliary class(Boundary) help to get boundary coordinates
|
|
||||
// see the comments in Boundary.h for more information
|
|
||||
auto AddBoundaryMechanicalCondition = [&j_config]( |
|
||||
std::shared_ptr<top::Top3d> sp_mech_top3d, |
|
||||
std::shared_ptr<top::Mesh> sp_mech_mesh) { |
|
||||
top::Boundary mech_bdr(sp_mech_mesh); |
|
||||
|
|
||||
{ |
|
||||
// add Dirichlet boundary, see the comments in Top3d::AddDBC for more information
|
|
||||
assert(j_config.count("mechanical_boundary_condition")); |
|
||||
assert(j_config["mechanical_boundary_condition"].count("DBC")); |
|
||||
assert(j_config["mechanical_boundary_condition"].count("NBC")); |
|
||||
int DBCNum = j_config["mechanical_boundary_condition"]["DBC"].size(); |
|
||||
for (int _i = 0; _i < DBCNum; ++_i) { |
|
||||
const auto &DBCI = j_config["mechanical_boundary_condition"]["DBC"][_i]; |
|
||||
Eigen::Vector3d minBBox(DBCI["min"][0], DBCI["min"][1], |
|
||||
DBCI["min"][2]); |
|
||||
Eigen::Vector3d maxBBox(DBCI["max"][0], DBCI["max"][1], |
|
||||
DBCI["max"][2]); |
|
||||
Eigen::Vector3i dir(DBCI["dir"][0], DBCI["dir"][1], |
|
||||
DBCI["dir"][2]); |
|
||||
top::Dir t_dir(minBBox, maxBBox, dir); |
|
||||
|
|
||||
sp_mech_top3d->AddDBC( |
|
||||
mech_bdr.GetChosenCoordsByRelativeAlignedBox(t_dir.box), |
|
||||
t_dir.dir); |
|
||||
} |
|
||||
|
|
||||
// add Neumann boundary, see the comments in Top3d::AddNBC for more information
|
|
||||
int NBCNum = j_config["mechanical_boundary_condition"]["NBC"].size(); |
|
||||
for (int _i = 0; _i < NBCNum; ++_i) { |
|
||||
const auto &NBCI = j_config["mechanical_boundary_condition"]["NBC"][_i]; |
|
||||
Eigen::Vector3d minBBox(NBCI["min"][0], NBCI["min"][1], |
|
||||
NBCI["min"][2]); |
|
||||
Eigen::Vector3d maxBBox(NBCI["max"][0], NBCI["max"][1], |
|
||||
NBCI["max"][2]); |
|
||||
Eigen::Vector3d val(NBCI["val"][0], NBCI["val"][1], |
|
||||
NBCI["val"][2]); |
|
||||
top::Neu t_neu(minBBox, maxBBox, val); |
|
||||
|
|
||||
Eigen::MatrixXi coords = mech_bdr.GetChosenCoordsByRelativeAlignedBox( |
|
||||
t_neu.box); |
|
||||
sp_mech_top3d->AddNBC(coords, t_neu.val / coords.rows()); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
}; |
|
||||
auto AddBoundaryThermalCondition = [&j_config]( |
|
||||
std::shared_ptr<top::Top3d> sp_ther_top3d, |
|
||||
std::shared_ptr<top::HeatMesh> sp_ther_mesh) { |
|
||||
top::Boundary thermal_bdr(sp_ther_mesh); |
|
||||
{ |
|
||||
// add Dirichlet boundary, see the comments in Top3d::AddDBC for more information
|
|
||||
assert(j_config.count("thermal_boundary_condition")); |
|
||||
assert(j_config["thermal_boundary_condition"].count("DBC")); |
|
||||
assert(j_config["thermal_boundary_condition"].count("NBC")); |
|
||||
int DBCNum = j_config["thermal_boundary_condition"]["DBC"].size(); |
|
||||
for (int _i = 0; _i < DBCNum; ++_i) { |
|
||||
const auto &DBCI = j_config["thermal_boundary_condition"]["DBC"][_i]; |
|
||||
Eigen::Vector3d minBBox(DBCI["min"][0], DBCI["min"][1], |
|
||||
DBCI["min"][2]); |
|
||||
Eigen::Vector3d maxBBox(DBCI["max"][0], DBCI["max"][1], |
|
||||
DBCI["max"][2]); |
|
||||
top::Dir t_dir(minBBox, maxBBox, Eigen::Vector3i(1, 0, 0)); |
|
||||
|
|
||||
sp_ther_top3d->AddDBC( |
|
||||
thermal_bdr.GetChosenCoordsByRelativeAlignedBox( |
|
||||
t_dir.box), |
|
||||
t_dir.dir, DBCI["temperature"]); |
|
||||
} |
|
||||
|
|
||||
// add Neumann boundary, see the comments in Top3d::AddNBC for more information
|
|
||||
int NBCNum = j_config["thermal_boundary_condition"]["NBC"].size(); |
|
||||
for (int _i = 0; _i < NBCNum; ++_i) { |
|
||||
const auto &NBCI = j_config["thermal_boundary_condition"]["NBC"][_i]; |
|
||||
Eigen::Vector3d minBBox(NBCI["min"][0], NBCI["min"][1], |
|
||||
NBCI["min"][2]); |
|
||||
Eigen::Vector3d maxBBox(NBCI["max"][0], NBCI["max"][1], |
|
||||
NBCI["max"][2]); |
|
||||
Eigen::Vector3d val(NBCI["heat_flux"], 0, 0); |
|
||||
top::Neu t_neu(minBBox, maxBBox, val); |
|
||||
|
|
||||
Eigen::MatrixXi coords = thermal_bdr.GetChosenCoordsByRelativeAlignedBox( |
|
||||
t_neu.box); |
|
||||
sp_ther_top3d->AddNBC(coords, t_neu.val / coords.rows()); |
|
||||
} |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
AddBoundaryMechanicalCondition(sp_mech_top3d, sp_mech_mesh); |
|
||||
AddBoundaryThermalCondition(sp_ther_top3d, sp_thermal_mesh); |
|
||||
|
|
||||
// process topology optimization
|
|
||||
spdlog::critical("start to mechanical top opt ..."); |
|
||||
top::Tensor3d t_me_rho = sp_mech_top3d->TopOptMainLoop(); |
|
||||
{ |
|
||||
spdlog::critical("extract compliance and volume each iteration ..."); |
|
||||
// extract compliance and volume each iteration
|
|
||||
fs_path compliance_path = |
|
||||
output_dir / "txt" / ex_name / |
|
||||
(ex_name + "_MeTop" + "_compliance.txt"); |
|
||||
WriteStdVector(compliance_path, sp_mech_top3d->v_compliance_); |
|
||||
spdlog::info("write compliance txt to: {}", compliance_path.c_str()); |
|
||||
|
|
||||
fs_path volume_path = |
|
||||
output_dir / "txt" / ex_name / |
|
||||
(ex_name + "_MeTop" + "_volume.txt"); |
|
||||
WriteStdVector(volume_path, sp_mech_top3d->v_volume_); |
|
||||
spdlog::info("write volume txt to: {}", volume_path.c_str()); |
|
||||
|
|
||||
// extract rho (txt and vtk)
|
|
||||
fs_path rho_txt_path = |
|
||||
output_dir / "txt" / ex_name / |
|
||||
(ex_name + "_MeTop" + "_rho.txt"); |
|
||||
write_tensor3d(rho_txt_path, t_me_rho, sp_mech_mesh->GetOrigin(), |
|
||||
sp_mech_mesh->GetOrigin() + sp_mech_mesh->GetLenBox()); |
|
||||
spdlog::info("write density txt to: {}", rho_txt_path.c_str()); |
|
||||
|
|
||||
fs_path rho_vtk_path = |
|
||||
output_dir / "vtk" / ex_name / |
|
||||
(ex_name + "_MeTop" + "_rho.vtk"); |
|
||||
WriteTensorToVtk(rho_vtk_path, t_me_rho, sp_mech_mesh); |
|
||||
spdlog::info("write density vtk to: {}", rho_vtk_path.c_str()); |
|
||||
} |
|
||||
|
|
||||
spdlog::critical("start to mechanical thermal top opt ..."); |
|
||||
// init thermoelastic top3d
|
|
||||
top::ThermoelasticTop3d mech_ther_top3d(sp_mech_top3d, sp_ther_top3d); |
|
||||
top::Tensor3d t_meth_rho = mech_ther_top3d.TopOptMainLoop(); |
|
||||
{ |
|
||||
spdlog::critical("extract compliance and volume each iteration ..."); |
|
||||
// extract compliance and volume each iteration
|
|
||||
fs_path compliance_path = |
|
||||
output_dir / "txt" / ex_name / |
|
||||
(ex_name + "_MeThTop" + "_compliance.txt"); |
|
||||
WriteStdVector(compliance_path, mech_ther_top3d.v_compliance_); |
|
||||
spdlog::info("write compliance txt to: {}", compliance_path.c_str()); |
|
||||
|
|
||||
fs_path volume_path = |
|
||||
output_dir / "txt" / ex_name / |
|
||||
(ex_name + "_MeThTop" + "_volume.txt"); |
|
||||
WriteStdVector(volume_path, mech_ther_top3d.v_volume_); |
|
||||
spdlog::info("write volume txt to: {}", volume_path.c_str()); |
|
||||
|
|
||||
// extract rho (txt and vtk)
|
|
||||
fs_path rho_txt_path = |
|
||||
output_dir / "txt" / ex_name / |
|
||||
(ex_name + "_MeThTop" + "_rho.txt"); |
|
||||
write_tensor3d(rho_txt_path, t_meth_rho, sp_mech_mesh->GetOrigin(), |
|
||||
sp_mech_mesh->GetOrigin() + sp_mech_mesh->GetLenBox()); |
|
||||
spdlog::info("write density txt to: {}", rho_txt_path.c_str()); |
|
||||
|
|
||||
fs_path rho_vtk_path = |
|
||||
output_dir / "vtk" / ex_name / |
|
||||
(ex_name + "_MeThTop" + "_rho.vtk"); |
|
||||
WriteTensorToVtk(rho_vtk_path, t_meth_rho, sp_mech_mesh); |
|
||||
spdlog::info("write density vtk to: {}", rho_vtk_path.c_str()); |
|
||||
} |
|
||||
|
|
||||
// // extract rho (txt and vtk)
|
|
||||
// fs_path rho_txt_path = output_dir / "txt" / (ex_name + "_rho.txt");
|
|
||||
// write_tensor3d(rho_txt_path, ten_rho, sp_mech_mesh->GetOrigin(),
|
|
||||
// sp_mech_mesh->GetOrigin() + sp_mech_mesh->GetLenBox());
|
|
||||
// spdlog::info("write density txt to: {}", rho_txt_path.c_str());
|
|
||||
//
|
|
||||
// fs_path rho_vtk_path = output_dir / "vtk" / (ex_name + "_rho.vtk");
|
|
||||
// WriteTensorToVtk(rho_vtk_path, ten_rho, sp_mech_mesh);
|
|
||||
// spdlog::info("write density vtk to: {}", rho_vtk_path.c_str());
|
|
||||
|
|
||||
// // extract temperature(vtk)
|
|
||||
// fs_path T_vtk_path = output_dir / "vtk" / (ex_name + "_T.vtk");
|
|
||||
// WriteUToVtk(T_vtk_path, ther_top3d.GetTemperature(), sp_thermal_mesh);
|
|
||||
// spdlog::info("write temperature vtk to: {}", T_vtk_path.c_str());
|
|
||||
//
|
|
||||
// // extract displacement(vtk)
|
|
||||
// fs_path U_vtk_path = output_dir / "vtk" / (ex_name + "_U.vtk");
|
|
||||
// WriteUToVtk(U_vtk_path, ther_top3d.GetNormedDisplacement(), sp_mech_mesh);
|
|
||||
// spdlog::info("write displacement norm vtk to: {}", U_vtk_path.c_str());
|
|
||||
//
|
|
||||
// // extract stress field(txt or vtk)
|
|
||||
// auto t_von_stress = ther_top3d.GetVonStress();
|
|
||||
// fs_path von_stress_txt_path =
|
|
||||
// output_dir / "txt" / (ex_name + "_von_stress.txt");
|
|
||||
// write_tensor3d(von_stress_txt_path, t_von_stress, sp_mech_mesh->GetOrigin(),
|
|
||||
// sp_mech_mesh->GetOrigin() + sp_mech_mesh->GetLenBox());
|
|
||||
// spdlog::info("write von stress txt to: {}", von_stress_txt_path.c_str());
|
|
||||
//
|
|
||||
// fs_path von_stress_vtk_path =
|
|
||||
// output_dir / "vtk" / (ex_name + "_von_stress.vtk");
|
|
||||
// WriteTensorToVtk(von_stress_vtk_path, t_von_stress, sp_mech_mesh);
|
|
||||
// spdlog::info("write von stress vtk to: {}", von_stress_vtk_path.c_str());
|
|
||||
|
|
||||
|
|
||||
// postprocess--------------------------------------------------------------
|
|
||||
auto MechanicalSimulation = [&](const top::Tensor3d &t_rho, |
|
||||
const string &suffix) { |
|
||||
sp_mech_mesh = std::make_shared<top::Mesh>(t_rho.dimension(0), |
|
||||
t_rho.dimension(1), |
|
||||
t_rho.dimension(2), t_rho); |
|
||||
// postprocess: simulation
|
|
||||
// MeSim
|
|
||||
{ |
|
||||
auto sp_mech_top3d_sim = std::make_shared<top::Top3d>(para, |
|
||||
sp_mech_fea, |
|
||||
sp_mech_mesh); |
|
||||
sp_mech_top3d_sim->TopOptMainLoop(true); |
|
||||
|
|
||||
// extract displacement(vtk)
|
|
||||
fs_path U_vtk_path = output_dir / "vtk" / |
|
||||
(ex_name + "_MeSim" + "_U" + suffix + |
|
||||
".vtk"); |
|
||||
WriteUToVtk(U_vtk_path, sp_mech_top3d_sim->GetNormedDisplacement(), |
|
||||
sp_mech_mesh); |
|
||||
spdlog::info("write displacement norm vtk to: {}", |
|
||||
U_vtk_path.c_str()); |
|
||||
|
|
||||
// extract stress field(txt and vtk)
|
|
||||
auto t_von_stress = sp_mech_top3d_sim->GetVonStress(); |
|
||||
fs_path von_stress_vtk_path = |
|
||||
output_dir / "vtk" / |
|
||||
(ex_name + "_MeSim" + "_von_stress" + suffix + ".vtk"); |
|
||||
WriteNodeToVtk(von_stress_vtk_path, t_von_stress, sp_mech_mesh); |
|
||||
spdlog::info("write von stress vtk to: {}", |
|
||||
von_stress_vtk_path.c_str()); |
|
||||
|
|
||||
// extract compliance
|
|
||||
fs_path compliance_path = |
|
||||
output_dir / "txt" / |
|
||||
(ex_name + "_MeSim" + "_compliance" + suffix + ".txt"); |
|
||||
WriteStdVector(compliance_path, mech_ther_top3d.v_compliance_); |
|
||||
spdlog::info("write compliance txt to: {}", |
|
||||
compliance_path.c_str()); |
|
||||
|
|
||||
} |
|
||||
}; |
|
||||
auto MechanicalThermalSimulation = [&output_dir, &ex_name, ¶, &sp_mech_fea, &sp_thermal_fea, &AddBoundaryThermalCondition, &AddBoundaryMechanicalCondition]( |
|
||||
const top::Tensor3d &t_rho, |
|
||||
const string &suffix) { |
|
||||
auto sp_mech_mesh_sim = std::make_shared<top::Mesh>(t_rho.dimension(0), |
|
||||
t_rho.dimension(1), |
|
||||
t_rho.dimension(2), |
|
||||
t_rho); |
|
||||
auto sp_thermal_mesh_sim = std::make_shared<top::HeatMesh>( |
|
||||
t_rho.dimension(0), |
|
||||
t_rho.dimension(1), |
|
||||
t_rho.dimension(2), |
|
||||
t_rho); |
|
||||
auto sp_mech_top3d_sim = std::make_shared<top::Top3d>(para, sp_mech_fea, |
|
||||
sp_mech_mesh_sim); |
|
||||
auto sp_thermal_top3d_sim = std::make_shared<top::Top3d>(para, |
|
||||
sp_thermal_fea, |
|
||||
sp_thermal_mesh_sim); |
|
||||
AddBoundaryMechanicalCondition(sp_mech_top3d_sim, sp_mech_mesh_sim); |
|
||||
AddBoundaryThermalCondition(sp_thermal_top3d_sim, sp_thermal_mesh_sim); |
|
||||
top::ThermoelasticTop3d ther_top3d_sim(sp_mech_top3d_sim, |
|
||||
sp_thermal_top3d_sim); |
|
||||
ther_top3d_sim.TopOptMainLoop(true); |
|
||||
{ |
|
||||
// extract clamped rho (vtk)
|
|
||||
fs_path rho_vtk_path = output_dir / "vtk" / ex_name / |
|
||||
(ex_name + suffix + "_rho" + |
|
||||
".vtk"); |
|
||||
auto t_temp = t_rho; |
|
||||
t_temp.SetConst(1); |
|
||||
WriteTensorToVtk(rho_vtk_path, t_temp, sp_mech_mesh_sim); |
|
||||
spdlog::info("write clamped density vtk to: {}", |
|
||||
rho_vtk_path.c_str()); |
|
||||
|
|
||||
// extract temperature (vtk)
|
|
||||
fs_path T_vtk_path = output_dir / "vtk" / ex_name / |
|
||||
(ex_name + suffix + "_T" + |
|
||||
".vtk"); |
|
||||
WriteNodeToVtk(T_vtk_path, ther_top3d_sim.GetTemperature(), |
|
||||
sp_thermal_mesh_sim); |
|
||||
spdlog::info("write temperature vtk to: {}", T_vtk_path.c_str()); |
|
||||
|
|
||||
// extract displacement (vtk)
|
|
||||
fs_path U_vtk_path = output_dir / "vtk" / ex_name / |
|
||||
(ex_name + suffix + "_U" + |
|
||||
".vtk"); |
|
||||
WriteNodeToVtk(U_vtk_path, ther_top3d_sim.GetNormedDisplacement(), |
|
||||
sp_mech_mesh_sim); |
|
||||
spdlog::info("write displacement norm vtk to: {}", |
|
||||
U_vtk_path.c_str()); |
|
||||
|
|
||||
// extract stress field(txt or vtk)
|
|
||||
auto t_von_stress = ther_top3d_sim.GetVonStress(); |
|
||||
fs_path von_stress_vtk_path = |
|
||||
output_dir / "vtk" / ex_name / |
|
||||
(ex_name + suffix + "_von_stress" + |
|
||||
".vtk"); |
|
||||
WriteNodeToVtk(von_stress_vtk_path, t_von_stress, sp_mech_mesh_sim); |
|
||||
spdlog::info("write von stress vtk to: {}", |
|
||||
von_stress_vtk_path.c_str()); |
|
||||
|
|
||||
// extract compliance
|
|
||||
fs_path compliance_path = |
|
||||
output_dir / "txt" / ex_name / |
|
||||
(ex_name + suffix + "_compliance" + ".txt"); |
|
||||
WriteStdVector(compliance_path, ther_top3d_sim.v_compliance_); |
|
||||
spdlog::info("write compliance txt to: {}", |
|
||||
compliance_path.c_str()); |
|
||||
} |
|
||||
}; |
|
||||
auto ClampAndSimulation = [&](const top::Tensor3d &res_rho, |
|
||||
const std::string &suffix) { |
|
||||
// clamp density to 0 or 1
|
|
||||
// set different thresholds to pick a suitable density result
|
|
||||
for (double threshold = 0.2; |
|
||||
threshold < 0.5 + 0.0001; threshold += 0.05) { |
|
||||
std::string str_thresh = |
|
||||
"_thresh" + std::to_string((int) (threshold * 100)); |
|
||||
top::Tensor3d t_rho = res_rho; |
|
||||
for (int k = 0; k < t_rho.dimension(2); ++k) { |
|
||||
for (int j = 0; j < t_rho.dimension(1); ++j) { |
|
||||
for (int i = 0; i < t_rho.dimension(0); ++i) { |
|
||||
t_rho(i, j, k) = t_rho(i, j, k) >= threshold ? 1 : 0; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
try { |
|
||||
// mech ther sim
|
|
||||
MechanicalThermalSimulation(t_rho, suffix + str_thresh); |
|
||||
} catch (std::exception &e) { |
|
||||
spdlog::error(e.what() + std::string(" skip") + str_thresh); |
|
||||
} |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
{ |
|
||||
spdlog::critical("postprocess: mechanical result simulation ..."); |
|
||||
// SIM: Mechanical result -> clamped -> MeThSim
|
|
||||
ClampAndSimulation(t_me_rho, "_MeSim"); |
|
||||
} |
|
||||
|
|
||||
{ |
|
||||
spdlog::critical( |
|
||||
"postprocess: mechanical thermal result simulation ..."); |
|
||||
// SIM: Mechanical thermal result -> clamped -> MeThSim
|
|
||||
ClampAndSimulation(t_meth_rho, "_MeThSim"); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
Loading…
Reference in new issue