Amsterwolf 1 year ago
parent
commit
05ab793f71
  1. 8
      CMakeLists.txt
  2. 47
      README.md
  3. 2
      assets/top/config_Lshape.json
  4. 26
      examples/clamped_model_writer/main.cpp
  5. 13
      examples/defined_model_writer/main.cpp
  6. 16
      examples/sim_mechanical/CMakeLists.txt
  7. 55
      examples/sim_mechanical/main.cpp
  8. 85
      examples/sim_thermoelastic/main.cpp
  9. 17
      examples/top_mechanical/main.cpp
  10. 67
      examples/top_summary/config_Lshape.json
  11. 67
      examples/top_summary/config_beam.json
  12. 4
      examples/top_summary/main.cpp
  13. 19
      examples/top_thermoelastic/main.cpp
  14. 43
      src/ConfigMechanicalInterface.h
  15. 32
      src/ConfigThermalInterface.h
  16. 17
      src/Util.cpp
  17. 28
      src/Util.h

8
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)

47
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)
<b> (Optional) temperature limits, optimization of voxel mesh. </b>
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<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;
}
}
}
}
//...
}
```
3. Output see `output/txt/${example_name}/${example_name}_*` and `output/vtk/${example_name}/${example_name}_*`.
---

2
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": {

26
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());
}

13
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());
}

16
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 ()

55
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<ConfigMechanicalInterface> sp_mech_inter = std::make_shared<ConfigMechanicalInterface>(
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());
}
}

85
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<ConfigMechanicalInterface> sp_mech_inter = std::make_shared<ConfigMechanicalInterface>(
config_file.string());
config_file, tr_model);
std::shared_ptr<ConfigThermalInterface> sp_ther_inter = std::make_shared<ConfigThermalInterface>(
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<ThermoelasticTop3d>(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());
}
}

17
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<ConfigMechanicalInterface> sp_mech_inter = std::make_shared<ConfigMechanicalInterface>(
config_file.string());
config_file,tr_model);
std::string ex_name = sp_mech_inter->ex_name_;
spdlog::critical("Mechanical TO example: {}", ex_name);

67
examples/top_summary/config_Lshape.json

@ -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"
}
]
}
}

67
examples/top_summary/config_beam.json

@ -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"
}
]
}
}

4
examples/top_summary/main.cpp

@ -68,7 +68,7 @@ int main() {
// 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") {
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;
}
}

19
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<ConfigMechanicalInterface> sp_mech_inter = std::make_shared<ConfigMechanicalInterface>(
config_file.string());
config_file,tr_model);
std::shared_ptr<ConfigThermalInterface> sp_ther_inter = std::make_shared<ConfigThermalInterface>(
config_file.string());
config_file,tr_model);
std::string ex_name = sp_mech_inter->ex_name_;
spdlog::critical("Thermoelastic TO example: {}", ex_name);

43
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<typename PT>
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<Top3d> CreatTop() {
auto sp_para = CreatePara();
auto sp_mech_fea = CreateFea();
@ -54,7 +59,7 @@ protected:
return para;
}
virtual std::shared_ptr<FEA> CreateFea() {
virtual std::shared_ptr<FEA> CreateFea() {
double E = config_json_["material"]["E"];
double Poisson_ratio = config_json_["material"]["poisson_ratio"];
auto material = std::make_shared<top::Material>(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<Mesh>(tr.dimension(0), tr.dimension(1), tr.dimension(2), tr);
return sp_mesh;
std::shared_ptr<Mesh> sp_mesh;
if (model_.size() != 0) {
sp_mesh = std::make_shared<Mesh>(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<Mesh>(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<Mesh>(lx, ly, lz);
return sp_mesh;
model_ = Tensor3d(lx, ly, lz);
model_.setConstant(1);
sp_mesh = std::make_shared<Mesh>(lx, ly, lz);
} else {
throw std::runtime_error("model not found in config file");
}
return sp_mesh;
}
virtual std::shared_ptr<Mesh> 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<Mesh> sp_mesh_;
Tensor3d model_;
};

32
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<Top3d> 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<HeatMesh>(tr.dimension(0),
tr.dimension(1),
tr.dimension(2), tr);
return sp_mesh;
std::shared_ptr<Mesh> sp_mesh;
if (model_.size() != 0) {
sp_mesh = std::make_shared<HeatMesh>(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<HeatMesh>(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<HeatMesh>(lx, ly, lz);
return sp_mesh;
model_ = Tensor3d(lx, ly, lz);
model_.setConstant(1);
sp_mesh = std::make_shared<HeatMesh>(lx, ly, lz);
} else {
throw std::runtime_error("model not found in config file");
}
return sp_mesh;
}
void AddBoundaryCondition(

17
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<Mesh> 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<Mesh> 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<Mesh> sp_mesh) {
CreateParentFolder(file_path);
@ -232,7 +232,7 @@ namespace da::sha {
std::pair<MatMesh3, Eigen::VectorXd>
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<Mesh>(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<Mesh>(tr.dimension(0),tr.dimension(1),tr.dimension(2),tr);
WriteNodeToVtk(file_path,node_data,sp_mesh);
}
} // namespace top
} // namespace da::sha

28
src/Util.h

@ -21,14 +21,13 @@
#include <iostream>
#include <iterator>
#include <memory>
#include <boost/filesystem/path.hpp>
#include <unsupported/Eigen/CXX11/Tensor>
#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<double, 3>;
using Tensor3i = TensorWrapper<int, 3>;
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<typename PT>
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<typename TP>
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<Mesh> sp_mesh);
void
WriteUToVtk(const boost::filesystem::path &file_path,
WriteUToVtk(const std::filesystem::path &file_path,
const Eigen::VectorXd &U,
std::shared_ptr<Mesh> 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,

Loading…
Cancel
Save