From 05ab793f71c6b631a41c2c37036af861195f9079 Mon Sep 17 00:00:00 2001 From: Amsterwolf <2497695115@qq.com> Date: Tue, 2 Apr 2024 20:15:43 +0800 Subject: [PATCH] restruct --- CMakeLists.txt | 8 +-- README.md | 47 ++++---------- assets/top/config_Lshape.json | 2 +- examples/clamped_model_writer/main.cpp | 26 +++++--- examples/defined_model_writer/main.cpp | 13 ++-- examples/sim_mechanical/CMakeLists.txt | 16 +++++ examples/sim_mechanical/main.cpp | 55 ++++++++++++++++ examples/sim_thermoelastic/main.cpp | 85 +++++++++++++++---------- examples/top_mechanical/main.cpp | 17 +++-- examples/top_summary/config_Lshape.json | 67 ------------------- examples/top_summary/config_beam.json | 67 ------------------- examples/top_summary/main.cpp | 4 +- examples/top_thermoelastic/main.cpp | 19 ++++-- src/ConfigMechanicalInterface.h | 43 +++++++++---- src/ConfigThermalInterface.h | 32 ++++++---- src/Util.cpp | 17 +++-- src/Util.h | 28 ++++---- 17 files changed, 271 insertions(+), 275 deletions(-) create mode 100644 examples/sim_mechanical/CMakeLists.txt create mode 100644 examples/sim_mechanical/main.cpp delete mode 100644 examples/top_summary/config_Lshape.json delete mode 100644 examples/top_summary/config_beam.json diff --git a/CMakeLists.txt b/CMakeLists.txt index 2abc6f3..640b72f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ project(top3d LANGUAGES CUDA CXX) option(VERBOSE "Show more infos" ON) # choose linear solver option(ENABLE_AMGCL "Use AMGCL" ON) -option(ENABLE_AMGCL_CUDA "use Cuda to speed up AMGCL" OFF) +option(ENABLE_AMGCL_CUDA "use Cuda to speed up AMGCL" ON) option(ENABLE_SUITESPARSE "Use SuiteSparse" OFF) set(CMAKE_CXX_STANDARD 17) @@ -57,9 +57,9 @@ target_link_libraries(${PROJECT_NAME}_lib PUBLIC nlohmann_json::nlohmann_json) add_subdirectory(${LIBIGL_DIR} 3rd/libigl) target_link_libraries(${PROJECT_NAME}_lib PUBLIC igl::core) -# boost -find_package(Boost REQUIRED COMPONENTS filesystem) -target_link_libraries(${PROJECT_NAME}_lib PUBLIC Boost::filesystem) +## boost +#find_package(Boost REQUIRED COMPONENTS filesystem) +#target_link_libraries(${PROJECT_NAME}_lib PUBLIC Boost::filesystem) # MMA add_subdirectory(3rd/mma) diff --git a/README.md b/README.md index 61a8838..01e4820 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,33 @@ -# Thermo-elastic Topology Optimization +# Thermo-elastic/Mechanical Topology Optimization/Simuation ![Screenshot from 2023-07-02 13-57-29.png](docs%2Fimgs%2FScreenshot%20from%202023-07-02%2013-57-29.png) (Optional) temperature limits, optimization of voxel mesh. This is the implementation of the paper [Thermo-elastic topology optimization with stress and temperature constraints.](ref%2FThermo-elastic%20topology%20optimization%20with%20stress%0Aand%20temperature%20constraints.pdf) +By the way, this procedure realized the thermo-elastic TO(topology optimization)([Thermo-elastic topology optimization with stress +and temperature constraints.](ref%2FThermo-elastic%20topology%20optimization%20with%20stress%0Aand%20temperature%20constraints), mechanical TO([top3d.pdf](ref%2Ftop3d.pdf)) and corresponding simulations. ## Files * `3rd/`: third-party library * `assets/`: user-defined assets * `examples/`: several teaching examples + - `defined_model_writer`: User defined voxel mesh/model as TO/simulation input. + - `clamped_model_writer`: Clamped to 0 or 1 of the optimized density. + - `sim_mechanical`: Mechanical simulation. + - `sim_thermoelastic`: Thermo-elastic simulation. + - `top_mechanical`: Mechanical TO. + - `top_thermoelastic`: Thermoelastic TO. * `output/`: output directory * `ref/`: reference material * `src/`: source code * `cmake/`: CMake files ## Dependencies -**A inside library**: +**Inside libraries**: * [mma](3rd%2Fmma): constrained optimization algorithm * [Eigen](https://eigen.tuxfamily.org/): linear algebra * [libigl](https://github.com/libigl/libigl): basic geometry functions +* [AMGCL](https://github.com/ddemidov/amgcl): Linear solver. Optional. * **The following dependencies require user installation**: * [json](https://github.com/nlohmann/json): parsing input JSON scenes @@ -28,9 +37,7 @@ and temperature constraints.](ref%2FThermo-elastic%20topology%20optimization%20w sudo apt install libomp-dev ``` * [SuiteSparse](https://github.com/DrTimothyAldenDavis/SuiteSparse): Linear solver. Optional, NOTE: Use of the Intel MKL BLAS is strongly recommended. -* [boost](https://github.com/boostorg/boost): Use filesystem -* [AMGCL](https://github.com/ddemidov/amgcl): Linear solver. Optional. -* [CUDA Toolkit](https://developer.nvidia.com/cuda-toolkit): CUDA support. Optional. +* [CUDA Toolkit](https://developer.nvidia.com/cuda-toolkit): CUDA support. Optional (Suggested). **Select a Linear solver** @@ -65,7 +72,6 @@ make -j 16 ## Usage ### 3/28 update -0. Git switch to multiple_top branch. 1. Use `example/top-thermolastic-compare-3d` to run mechanical(Me)/mechanical thermal(MeTh) topology optimization(Top) and simulation(Sim). The procedure run in following order: 1. Me Top & MeTh Top -> density(*_MeTop_rho.vtk & *_MethTop_rho.vtk) and compliance/volume each iteration(*_MeTop_compliance.txt *_MeTop_volume.txt & ...) @@ -73,35 +79,8 @@ The procedure run in following order: 3. MeTh Sim -> temperature(*_T.vtk), displacement(*_U.vtk), Von Mise Stress(*_von_stress.vtk). Note: open .vtk via Paraview software. 2. Input - 1. Set parameters in *.json. see comments in `example/top-thermoelastic-*.json`(see comments in `examples/top-thermoelastic-BiclampedStructure/config.json` and ref paper for MeTh parameters; see comments in `examples/top-thermoelastic-compare-3d/config_beam.json`) + 1. Set parameters in *.json. see comments in `assets/top-thermoelastic-*.json`(see comments in `assets/config_biclamed.json` and ref paper for MeTh parameters; see comments in `assets/top/config_Lshape.json`) 2. Redirect in `main.cpp` or `main.cu` if ENABLE_AMGCL_CUDA is ON: - ```c++ - top::fs_path config_file( - CMAKE_SOURCE_DIR "/examples/top-thermoelastic-compare-3d/${your_config_file}.json"); - ``` - 3. For irregular voxel model(e.g. Lshape), you can define the initial density in `main.cpp` or `main.cu`: - ```c++ - // NOTE: USER DEFINE GRID HERE!!! - std::shared_ptr sp_mech_mesh; - std::shared_ptr 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; - } - } - } - } - //... - } - ``` 3. Output see `output/txt/${example_name}/${example_name}_*` and `output/vtk/${example_name}/${example_name}_*`. --- diff --git a/assets/top/config_Lshape.json b/assets/top/config_Lshape.json index 7401b7a..4921faf 100644 --- a/assets/top/config_Lshape.json +++ b/assets/top/config_Lshape.json @@ -22,7 +22,7 @@ }, "model": { "defined_model": { - "path": "/home/cflin/Documents/CppField/source/topology-optimization-3d/output/txt/L_shape_model.txt" + "path": "path/to/user_defined_model.txt", "//": "used only when the model is not passed to the interface!" } }, "mechanical_boundary_condition": { diff --git a/examples/clamped_model_writer/main.cpp b/examples/clamped_model_writer/main.cpp index 611411b..bb922de 100644 --- a/examples/clamped_model_writer/main.cpp +++ b/examples/clamped_model_writer/main.cpp @@ -3,8 +3,12 @@ int main() { using namespace da::sha::top; - std::string rho_path = OUTPUT_DIR "/txt/Lshape/Lshape_MeTop_rho.txt"; - spdlog::info("Algo read density(0~1) model from '{}'", rho_path); + std::string ex_name = "Lshape"; + std::filesystem::path out_dir(OUTPUT_DIR); + std::filesystem::path assets_dir(ASSETS_DIR); + std::filesystem::path rho_path = + out_dir / "txt" / ex_name / (ex_name + "_MeTop_rho.txt"); + spdlog::info("Algo read density(0~1) model from '{}'", rho_path.string()); Tensor3d tr_rho = ReadTensor3d(rho_path); // USER DEFINED THRESHOLD HERE double threshold = 0.35; @@ -17,14 +21,16 @@ int main() { } } } - std::string txt_path = - ASSETS_DIR "/voxel_model/Clamped_Lshape_model" + str_thresh + - ".txt"; + std::filesystem::path txt_path = + assets_dir / "voxel_model" / + ("Clamped_" + ex_name + "_model" + str_thresh + + ".txt"); WriteTensor3d(txt_path, tr_rho); - spdlog::info("Write user defined grid to file: {}", txt_path); - std::string vtk_path = - ASSETS_DIR "/voxel_model/Clamped_Lshape_model" + str_thresh + - ".vtk"; + spdlog::info("Write user defined grid to file: {}", txt_path.string()); + std::filesystem::path vtk_path = + assets_dir / "voxel_model" / + ("Clamped_" + ex_name + "_model" + str_thresh + + ".vtk"); WriteTensorToVtk(vtk_path, tr_rho); - spdlog::info("visualize user defined grid to file: {}", vtk_path); + spdlog::info("visualize user defined grid to file: {}", vtk_path.string()); } diff --git a/examples/defined_model_writer/main.cpp b/examples/defined_model_writer/main.cpp index fb8764c..cfe2e59 100644 --- a/examples/defined_model_writer/main.cpp +++ b/examples/defined_model_writer/main.cpp @@ -3,6 +3,9 @@ int main() { using namespace da::sha::top; + std::string ex_name = "Lshape"; + std::filesystem::path out_dir(OUTPUT_DIR); + std::filesystem::path assets_dir(ASSETS_DIR); int len_x = 2; int len_y = 30; int len_z = 20; @@ -20,12 +23,14 @@ int main() { } } } - std::string txt_path = ASSETS_DIR "/voxel_model/Lshape_model.txt"; + std::filesystem::path txt_path = + assets_dir / "voxel_model" / (ex_name + "_model.txt"); WriteTensor3d(txt_path, L_shape_grid); - spdlog::info("Write user defined grid to file: {}", txt_path); + spdlog::info("Write user defined grid to file: {}", txt_path.string()); // vtk - std::string vtk_path = ASSETS_DIR "/voxel_model/Lshape_model.vtk"; + std::filesystem::path vtk_path = + assets_dir / "voxel_model" / (ex_name + "_model.vtk"); WriteTensorToVtk(vtk_path, L_shape_grid); - spdlog::info("Visualize user defined grid to file: {}", vtk_path); + spdlog::info("Visualize user defined grid to file: {}", vtk_path.string()); } diff --git a/examples/sim_mechanical/CMakeLists.txt b/examples/sim_mechanical/CMakeLists.txt new file mode 100644 index 0000000..5de8cb9 --- /dev/null +++ b/examples/sim_mechanical/CMakeLists.txt @@ -0,0 +1,16 @@ +set(SUB_PROJECT_NAME sim_mechanical) +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 () diff --git a/examples/sim_mechanical/main.cpp b/examples/sim_mechanical/main.cpp new file mode 100644 index 0000000..6b0a02b --- /dev/null +++ b/examples/sim_mechanical/main.cpp @@ -0,0 +1,55 @@ +#include "ConfigMechanicalInterface.h" +#include "ConfigThermalInterface.h" + +int main() { + // INPUT ARGS + fs_path config_file(ASSETS_DIR "/top/config_Lshape.json"); + fs_path model_file( + ASSETS_DIR "/voxel_model/Clamped_Lshape_model_thresh35.txt"); + // END INPUT + + std::string model_name = model_file.filename().replace_extension(); + Tensor3d tr_model = ReadTensor3d(model_file); + fs_path output_dir(OUTPUT_DIR); + spdlog::info("Read config from '{}'", config_file.string()); + spdlog::info("Read model from '{}'", model_file.string()); + spdlog::info("Output to '{}'", output_dir.string()); + + // Config interface + std::shared_ptr sp_mech_inter = std::make_shared( + config_file, tr_model); + std::string ex_name = sp_mech_inter->ex_name_; + spdlog::critical("Mechancial SIM example: {}, model: {}", ex_name,model_name); + + // initialize Top3d + auto sp_mech_top3d = sp_mech_inter->CreatTop(); + + spdlog::critical("start to mechanical simulation ..."); + // loop + sp_mech_top3d->TopOptMainLoop(true); + // postprocess + { + // extract displacement (vtk) + fs_path U_vtk_path = + output_dir / "vtk" / ex_name / model_name / + "Me_displacement.vtk"; + WriteNodeToVtk(U_vtk_path, sp_mech_top3d->GetNormedDisplacement(), + tr_model); + spdlog::info("write displacement norm vtk to: {}", U_vtk_path.string()); + + // extract stress field (vtk) + fs_path von_stress_vtk_path = + output_dir / "vtk" / ex_name / model_name / + "Me_Von_Mises_stress.vtk"; + WriteNodeToVtk(von_stress_vtk_path, sp_mech_top3d->GetVonStress(), + tr_model); + spdlog::info("write von stress vtk to: {}", + von_stress_vtk_path.string()); + + // extract compliance of the model (txt) + fs_path compliance_path = + output_dir / "txt" / ex_name / model_name / "Me_compliance.txt"; + WriteStdVector(compliance_path, sp_mech_top3d->v_compliance_); + spdlog::info("write compliance txt to: {}", compliance_path.string()); + } +} \ No newline at end of file diff --git a/examples/sim_thermoelastic/main.cpp b/examples/sim_thermoelastic/main.cpp index 647be78..64f4595 100644 --- a/examples/sim_thermoelastic/main.cpp +++ b/examples/sim_thermoelastic/main.cpp @@ -2,49 +2,68 @@ #include "ConfigThermalInterface.h" int main() { + // INPUT ARGS + fs_path config_file(ASSETS_DIR "/top/config_Lshape.json"); + fs_path model_file( + ASSETS_DIR "/voxel_model/Clamped_Lshape_model_thresh35.txt"); + // END INPUT + + std::string model_name = model_file.filename().replace_extension(); + Tensor3d tr_model = ReadTensor3d(model_file); fs_path output_dir(OUTPUT_DIR); - fs_path config_file( - ASSETS_DIR "/top/config_Lshape.json"); - spdlog::info("Algo read from '{}'", config_file.string()); - spdlog::info("Algo output to '{}'", output_dir.string()); + spdlog::info("Read config from '{}'", config_file.string()); + spdlog::info("Read model from '{}'", model_file.string()); + spdlog::info("Output to '{}'", output_dir.string()); + // Config interface std::shared_ptr sp_mech_inter = std::make_shared( - config_file.string()); + config_file, tr_model); + std::shared_ptr sp_ther_inter = std::make_shared( + config_file, tr_model); std::string ex_name = sp_mech_inter->ex_name_; - spdlog::critical("Mechanical SIM example: {}", ex_name); + spdlog::critical("Thermoelastic SIM example: {}, model: {}", ex_name,model_name); // initialize Top3d auto sp_mech_top3d = sp_mech_inter->CreatTop(); + auto sp_ther_top3d = sp_ther_inter->CreatTop(); + + spdlog::critical("start to thermoelastic simulation ..."); + // init thermoelastic top3d + auto sp_MeTh_top3d = std::make_shared(sp_mech_top3d, + sp_ther_top3d); // loop - spdlog::critical("start to mechanical top opt ..."); - Tensor3d t_me_rho = sp_mech_top3d->TopOptMainLoop(); + sp_MeTh_top3d->TopOptMainLoop(true); // postprocess { - spdlog::critical("extract compliance and volume each iteration ..."); - // extract compliance and volume each iteration + // extract temperature (vtk) + fs_path T_vtk_path = + output_dir / "vtk" / ex_name / model_name / + "MeTh_temperature.vtk"; + WriteNodeToVtk(T_vtk_path, sp_MeTh_top3d->GetTemperature(), + tr_model); + spdlog::info("write temperature vtk to: {}", T_vtk_path.string()); + + // extract displacement (vtk) + fs_path U_vtk_path = + output_dir / "vtk" / ex_name / model_name / + "MeTh_displacement.vtk"; + WriteNodeToVtk(U_vtk_path, sp_MeTh_top3d->GetNormedDisplacement(), + tr_model); + spdlog::info("write displacement norm vtk to: {}", U_vtk_path.string()); + + // extract stress field (vtk) + fs_path von_stress_vtk_path = + output_dir / "vtk" / ex_name / model_name / + "MeTh_Von_Mises_stress.vtk"; + WriteNodeToVtk(von_stress_vtk_path, sp_MeTh_top3d->GetVonStress(), + tr_model); + spdlog::info("write von stress vtk to: {}", + von_stress_vtk_path.string()); + + // extract compliance of the model (txt) 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"); - WriteTensor3d(rho_txt_path, t_me_rho); - 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_inter->sp_mesh_); - spdlog::info("write density vtk to: {}", rho_vtk_path.c_str()); + output_dir / "txt" / ex_name / model_name / "MeTh_compliance.txt"; + WriteStdVector(compliance_path, sp_MeTh_top3d->v_compliance_); + spdlog::info("write compliance txt to: {}", compliance_path.string()); } } \ No newline at end of file diff --git a/examples/top_mechanical/main.cpp b/examples/top_mechanical/main.cpp index d5372a9..e9e54e9 100644 --- a/examples/top_mechanical/main.cpp +++ b/examples/top_mechanical/main.cpp @@ -2,14 +2,21 @@ #include "ConfigThermalInterface.h" int main() { + // INPUT ARGS + fs_path config_file(ASSETS_DIR "/top/config_Lshape.json"); + fs_path model_file( + ASSETS_DIR "/voxel_model/Lshape_model.txt"); + // END INPUT + + std::string model_name = model_file.filename().replace_extension(); + Tensor3d tr_model = ReadTensor3d(model_file); fs_path output_dir(OUTPUT_DIR); - fs_path config_file( - ASSETS_DIR "/top/config_Lshape.json"); - spdlog::info("Algo read from '{}'", config_file.string()); - spdlog::info("Algo output to '{}'", output_dir.string()); + spdlog::info("Read config from '{}'", config_file.string()); + spdlog::info("Read model from '{}'", model_file.string()); + spdlog::info("Output to '{}'", output_dir.string()); std::shared_ptr sp_mech_inter = std::make_shared( - config_file.string()); + config_file,tr_model); std::string ex_name = sp_mech_inter->ex_name_; spdlog::critical("Mechanical TO example: {}", ex_name); diff --git a/examples/top_summary/config_Lshape.json b/examples/top_summary/config_Lshape.json deleted file mode 100644 index e17cca2..0000000 --- a/examples/top_summary/config_Lshape.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "TopologyOptimizationExample": "Lshape","//": "user defined project name", - "material": { - "E": 2.1e11, - "poisson_ratio": 0.3, - "thermal_conductivity":43, "//unit": "W/(m*K)", - "thermal_expansion_coefficient": 1.21e-5, "//unit": "1/K" - }, - "topology": { - "max_loop": 100, - "volfrac": 0.5, - "penal": 3.0, - "r_min": 1.05, - "T_ref": 312, - "T_limit": 3996.52, - "R_E": 28, - "R_lambda": 28, - "R_beta":0 - }, - "model": { - "regular_model": { - "lx":1, - "ly": 30, - "lz": 20 - } - }, - "mechanical_boundary_condition":{ - "NBC": [ - { - "min": [0, 1, 0], - "max": [1, 1, 0], - "val": [0.0,0.0 , -1e8] - } - - ], - "DBC": [ - { - "min": [0, 0, 1], - "max": [1, 0.5, 1], - "dir": [1, 1, 1] - } - - ] - }, - "thermal_boundary_condition": { - "NBC": [ - { - "min": [0.5, 0.2, 0.2], - "max": [0.5, 0.2, 0.2], - "heat_flux": 3.5, "//unit": "W" - }, - { - "min": [0.5, 0.8, 0.2], - "max": [0.5, 0.8, 0.2], - "heat_flux": 3.5, "//unit": "W" - } - - ], - "DBC": [ - { - "min": [0, 0, 1], - "max": [1, 0.5, 1], - "temperature": 312, "//unit": "K" - } - ] - } -} \ No newline at end of file diff --git a/examples/top_summary/config_beam.json b/examples/top_summary/config_beam.json deleted file mode 100644 index b49914c..0000000 --- a/examples/top_summary/config_beam.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "TopologyOptimizationExample": "beam","//": "user defined project name", - "material": { - "E": 2.1e11, - "poisson_ratio": 0.3, - "thermal_conductivity":43, "//unit": "W/(m*K)", - "thermal_expansion_coefficient": 1.21e-5, "//unit": "1/K" - }, - "topology": { - "max_loop":20, - "volfrac": 0.5, - "penal": 3.0, "//": "1-6, only work for Mechanical Top Opt, the higher the value, the density tends to be 0/1", - "r_min": 1.2, - "T_ref": 312, - "T_limit": 3996.52, - "R_E": 28, - "R_lambda": 28, - "R_beta":0 - }, - "model": { - "regular_model": { - "lx": 1, - "ly": 30, - "lz": 10 - } - }, - "mechanical_boundary_condition":{ - "DBC": [ - { - "min": [0, 0, 0], - "max": [1, 0, 1], - "dir": [1, 1, 1] - } - - ], - "NBC": [ - { - "min": [0, 1, 0], - "max": [1, 1, 0], - "val": [0.0,0.0 , -1e8] - } - - ] - }, - "thermal_boundary_condition": { - "NBC": [ - { - "min": [0.5, 0.2, 0.2], - "max": [0.5, 0.2, 0.2], - "heat_flux": 3.5, "//unit": "W" - }, - { - "min": [0.5, 0.8, 0.2], - "max": [0.5, 0.8, 0.2], - "heat_flux": 3.5, "//unit": "W" - } - - ], - "DBC": [ - { - "min": [0, 0, 1], - "max": [1, 0.5, 1], - "temperature": 312, "//unit": "K" - } - ] - } -} \ No newline at end of file diff --git a/examples/top_summary/main.cpp b/examples/top_summary/main.cpp index b419474..c9a5ed9 100644 --- a/examples/top_summary/main.cpp +++ b/examples/top_summary/main.cpp @@ -68,7 +68,7 @@ int main() { // NOTE: USER DEFINE GRID HERE!!! std::shared_ptr sp_mech_mesh; std::shared_ptr sp_thermal_mesh; - if (ex_name=="Lshape") { + if (ex_name == "Lshape") { // L-shape condition spdlog::critical("Using User Defined density!"); top::Tensor3d L_shape_model(len_x, len_y, len_z); @@ -77,7 +77,7 @@ int main() { 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) { + if (j > len_y * 0.6 & k > len_z * 0.5) { L_shape_model(i, j, k) = 0; } } diff --git a/examples/top_thermoelastic/main.cpp b/examples/top_thermoelastic/main.cpp index 1574adf..95ae9cd 100644 --- a/examples/top_thermoelastic/main.cpp +++ b/examples/top_thermoelastic/main.cpp @@ -2,16 +2,23 @@ #include "ConfigThermalInterface.h" int main() { + // INPUT ARGS + fs_path config_file(ASSETS_DIR "/top/config_Lshape.json"); + fs_path model_file( + ASSETS_DIR "/voxel_model/Lshape_model.txt"); + // END INPUT + + std::string model_name = model_file.filename().replace_extension(); + Tensor3d tr_model = ReadTensor3d(model_file); fs_path output_dir(OUTPUT_DIR); - fs_path config_file( - ASSETS_DIR "/top/config_Lshape.json"); - spdlog::info("Algo read from '{}'", config_file.string()); - spdlog::info("Algo output to '{}'", output_dir.string()); + spdlog::info("Read config from '{}'", config_file.string()); + spdlog::info("Read model from '{}'", model_file.string()); + spdlog::info("Output to '{}'", output_dir.string()); std::shared_ptr sp_mech_inter = std::make_shared( - config_file.string()); + config_file,tr_model); std::shared_ptr sp_ther_inter = std::make_shared( - config_file.string()); + config_file,tr_model); std::string ex_name = sp_mech_inter->ex_name_; spdlog::critical("Thermoelastic TO example: {}", ex_name); diff --git a/src/ConfigMechanicalInterface.h b/src/ConfigMechanicalInterface.h index e0c343e..9b4a678 100644 --- a/src/ConfigMechanicalInterface.h +++ b/src/ConfigMechanicalInterface.h @@ -22,18 +22,23 @@ using std::string; class ConfigMechanicalInterface { public: - ConfigMechanicalInterface(const std::string &config_path) : config_path_( - config_path) { - std::ifstream f(config_path_); + template + ConfigMechanicalInterface(const PT &config_path, + const Tensor3d &tr_model = Tensor3d()) + :model_(tr_model) { + std::ifstream f(config_path); if (!f.is_open()) { - throw std::runtime_error( - "Cannot open config file: " + config_path_); + throw std::runtime_error("Cannot open config file"); } config_json_ = nlohmann::json::parse(f); // read title ex_name_ = config_json_["TopologyOptimizationExample"]; } + void LoadModel(const Tensor3d &tr_model) { + model_ = tr_model; + } + std::shared_ptr CreatTop() { auto sp_para = CreatePara(); auto sp_mech_fea = CreateFea(); @@ -54,7 +59,7 @@ protected: return para; } - virtual std::shared_ptr CreateFea() { + virtual std::shared_ptr CreateFea() { double E = config_json_["material"]["E"]; double Poisson_ratio = config_json_["material"]["poisson_ratio"]; auto material = std::make_shared(E, Poisson_ratio); @@ -67,20 +72,32 @@ protected: if (!config_json_.count("model")) { throw std::runtime_error("model not found in config file"); } - if (config_json_["model"].count("defined_model")) { - Tensor3d tr=ReadTensor3d(config_json_["model"]["defined_model"]["path"]); - auto sp_mesh = std::make_shared(tr.dimension(0), tr.dimension(1), tr.dimension(2), tr); - return sp_mesh; + + std::shared_ptr sp_mesh; + if (model_.size() != 0) { + sp_mesh = std::make_shared(model_.dimension(0), + model_.dimension(1), + model_.dimension(2), + model_); + } else if (config_json_["model"].count("defined_model")) { + std::filesystem::path tr_path = config_json_["model"]["defined_model"]["path"]; + model_ = ReadTensor3d(tr_path); + sp_mesh = std::make_shared(model_.dimension(0), + model_.dimension(1), + model_.dimension(2), + model_); } else if (config_json_["model"].count("regular_model")) { // set mesh(regular) int lx = config_json_["model"]["regular_model"]["lx"]; int ly = config_json_["model"]["regular_model"]["ly"]; int lz = config_json_["model"]["regular_model"]["lz"]; - auto sp_mesh = std::make_shared(lx, ly, lz); - return sp_mesh; + model_ = Tensor3d(lx, ly, lz); + model_.setConstant(1); + sp_mesh = std::make_shared(lx, ly, lz); } else { throw std::runtime_error("model not found in config file"); } + return sp_mesh; } virtual std::shared_ptr CreateMesh(const Tensor3d &tr) { @@ -149,10 +166,10 @@ protected: }; public: - std::string config_path_; nlohmann::json config_json_; std::string ex_name_; std::shared_ptr sp_mesh_; + Tensor3d model_; }; diff --git a/src/ConfigThermalInterface.h b/src/ConfigThermalInterface.h index fb66800..910fd83 100644 --- a/src/ConfigThermalInterface.h +++ b/src/ConfigThermalInterface.h @@ -9,8 +9,9 @@ class ConfigThermalInterface : public ConfigMechanicalInterface { public: - ConfigThermalInterface(const std::string &config_path) - : ConfigMechanicalInterface(config_path) {} + ConfigThermalInterface(const std::string &config_path, + const Tensor3d &tr_model = Tensor3d()) + : ConfigMechanicalInterface(config_path, tr_model) {} std::shared_ptr CreatTop() { auto sp_para = CreatePara(); @@ -53,23 +54,32 @@ protected: if (!config_json_.count("model")) { throw std::runtime_error("model not found in config file"); } - if (config_json_["model"].count("defined_model")) { - Tensor3d tr = ReadTensor3d( - config_json_["model"]["defined_model"]["path"]); - auto sp_mesh = std::make_shared(tr.dimension(0), - tr.dimension(1), - tr.dimension(2), tr); - return sp_mesh; + + std::shared_ptr sp_mesh; + if (model_.size() != 0) { + sp_mesh = std::make_shared(model_.dimension(0), + model_.dimension(1), + model_.dimension(2), + model_); + } else if (config_json_["model"].count("defined_model")) { + std::filesystem::path tr_path = config_json_["model"]["defined_model"]["path"]; + model_ = ReadTensor3d(tr_path); + sp_mesh = std::make_shared(model_.dimension(0), + model_.dimension(1), + model_.dimension(2), + model_); } else if (config_json_["model"].count("regular_model")) { // set mesh(regular) int lx = config_json_["model"]["regular_model"]["lx"]; int ly = config_json_["model"]["regular_model"]["ly"]; int lz = config_json_["model"]["regular_model"]["lz"]; - auto sp_mesh = std::make_shared(lx, ly, lz); - return sp_mesh; + model_ = Tensor3d(lx, ly, lz); + model_.setConstant(1); + sp_mesh = std::make_shared(lx, ly, lz); } else { throw std::runtime_error("model not found in config file"); } + return sp_mesh; } void AddBoundaryCondition( diff --git a/src/Util.cpp b/src/Util.cpp index e4eea3f..80eaeee 100644 --- a/src/Util.cpp +++ b/src/Util.cpp @@ -137,7 +137,7 @@ namespace da::sha { } void - WriteTensorToVtk(const boost::filesystem::path &file_path, + WriteTensorToVtk(const std::filesystem::path &file_path, const Tensor3d &t3, std::shared_ptr sp_mesh, double threshold) { CreateParentFolder(file_path); @@ -174,7 +174,7 @@ namespace da::sha { } void - WriteNodeToVtk(const boost::filesystem::path &file_path, + WriteNodeToVtk(const std::filesystem::path &file_path, const Eigen::VectorXd &node_data, std::shared_ptr sp_mesh) { CreateParentFolder(file_path); @@ -204,7 +204,7 @@ namespace da::sha { } void - WriteUToVtk(const boost::filesystem::path &file_path, + WriteUToVtk(const std::filesystem::path &file_path, const Eigen::VectorXd &U, std::shared_ptr sp_mesh) { CreateParentFolder(file_path); @@ -232,7 +232,7 @@ namespace da::sha { std::pair - GetMeshVertexPropty(const boost::filesystem::path &fs_obj, + GetMeshVertexPropty(const std::filesystem::path &fs_obj, const Tensor3d &ten_rho_field, Boundary &r_bdr, bool offset_flg) { MatMesh3 obj_mesh; @@ -312,7 +312,7 @@ namespace da::sha { return {obj_mesh, rho_each_vertex}; } - void WriteTensorToVtk(const boost::filesystem::path &file_path, + void WriteTensorToVtk(const std::filesystem::path &file_path, const Tensor3d &t3) { auto sp_mesh = std::make_shared(t3.dimension(0), t3.dimension(1), @@ -320,5 +320,12 @@ namespace da::sha { WriteTensorToVtk(file_path, t3, sp_mesh, -1); } + void WriteNodeToVtk(const std::filesystem::path &file_path, + const Eigen::VectorXd &node_data, + const Tensor3d &tr) { + auto sp_mesh=std::make_shared(tr.dimension(0),tr.dimension(1),tr.dimension(2),tr); + WriteNodeToVtk(file_path,node_data,sp_mesh); + } + } // namespace top } // namespace da::sha \ No newline at end of file diff --git a/src/Util.h b/src/Util.h index 98cb831..7ad10e3 100644 --- a/src/Util.h +++ b/src/Util.h @@ -21,14 +21,13 @@ #include #include #include -#include #include #include "TensorWrapper.h" #include "Timer.h" namespace da::sha { namespace top { - using fs_path = boost::filesystem::path; + using fs_path = std::filesystem::path; using Tensor3d = TensorWrapper; using Tensor3i = TensorWrapper; using Eigen::all; @@ -152,21 +151,17 @@ namespace da::sha { } } - inline void CreateParentFolder(const fs_path &save_path) { - std::filesystem::path s_path(save_path.string()); - CreateParentFolder(std::filesystem::path(save_path.string())); - } - inline void CreateParentFolder(const std::string &save_path) { CreateParentFolder(std::filesystem::path(save_path)); } + template inline void - WriteTensor3d(const std::string &save_path, const Tensor3d &t3) { + WriteTensor3d(const PT &save_path, const Tensor3d &t3) { // if folder not exist, create it CreateParentFolder(save_path); - std::ofstream of(save_path.c_str()); + std::ofstream of(save_path); of << t3.dimension(0) << '\t' << t3.dimension(1) << '\t' << t3.dimension(2) << std::endl; @@ -182,8 +177,9 @@ namespace da::sha { of.close(); } + template inline Tensor3d - ReadTensor3d(const std::string &read_path) { + ReadTensor3d(const TP &read_path) { std::ifstream iif(read_path); int lx, ly, lz; iif >> lx >> ly >> lz; @@ -203,6 +199,11 @@ namespace da::sha { WriteTensor3d(save_path.string(), t3); } + /// Discard + /// \param save_path + /// \param t3 + /// \param bd_min + /// \param bd_max inline void write_tensor3d(const fs_path &save_path, const Tensor3d &t3, const Eigen::Vector3d &bd_min, const Eigen::Vector3d &bd_max) { @@ -271,17 +272,18 @@ namespace da::sha { class Mesh; + void WriteNodeToVtk(const std::filesystem::path &file_path,const Eigen::VectorXd&node_data,const Tensor3d& tr); void - WriteNodeToVtk(const boost::filesystem::path &file_path, + WriteNodeToVtk(const std::filesystem::path &file_path, const Eigen::VectorXd &node_data, std::shared_ptr sp_mesh); void - WriteUToVtk(const boost::filesystem::path &file_path, + WriteUToVtk(const std::filesystem::path &file_path, const Eigen::VectorXd &U, std::shared_ptr sp_mesh); - void WriteTensorToVtk(const boost::filesystem::path &file_path, + void WriteTensorToVtk(const std::filesystem::path &file_path, const Tensor3d &t3); void WriteTensorToVtk(const fs_path &file_path, const Tensor3d &t3,