You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

151 lines
7.1 KiB

//
// Created by cflin on 6/9/23.
//
#include <memory>
#include <nlohmann/json.hpp>
#include "Boundary.h"
#include "Mesh/IrregularMesh.h"
#include "Top3d.h"
#include "Util.h"
int main() {
// using namespace da;
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(CONFIG_FILE);
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("asserts 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);
// 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->penal = j_config["topology"]["penal"];
para->r_min = j_config["topology"]["r_min"];
// set material parameters
double E = j_config["material"]["E"];
double Poisson_ratio = j_config["material"]["poisson_ratio"];
auto material = std::make_shared<top::Material>();
material->E=E;
material->poisson_ratio=Poisson_ratio;
// set fea
auto sp_fea=std::make_shared<top::MechanicalLinearFEA>(material);
// 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"];
auto mesh = std::make_shared<top::Mesh>(len_x, len_y, len_z);
// initialize Top3d
top::Top3d top3d(para, sp_fea, mesh);
// auxiliary class(Boundary) help to get boundary coordinates
// see the comments in Boundary.h for more information
top::Boundary bdr(mesh);
// add Dirichlet boundary, see the comments in Top3d::AddDBC for more information
assert(j_config.count("DBC"));
int DBCNum = j_config["DBC"].size();
for (int _i = 0; _i < DBCNum; ++_i) {
const auto &DBCI = j_config["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);
top3d.AddDBC(bdr.GetChosenCoordsByRelativeAlignedBox(t_dir.box), t_dir.dir);
}
// add Neumann boundary, see the comments in Top3d::AddNBC for more information
assert(j_config.count("NBC"));
int NBCNum = j_config["NBC"].size();
for (int _i = 0; _i < NBCNum; ++_i) {
const auto &NBCI = j_config["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);
top3d.AddNBC(bdr.GetChosenCoordsByRelativeAlignedBox(t_neu.box), t_neu.val);
}
// process topology optimization
top::Tensor3d ten_rho = top3d.TopOptMainLoop();
// extract txt or vtk
write_tensor3d( output_dir / "txt" /"top_mach_regular_field_matrix.txt", ten_rho, mesh->GetOrigin(),
mesh->GetOrigin() + mesh->GetLenBox());
WriteTensorToVtk(output_dir /"vtk" / "top_mach_regular_field_matrix.vtk", ten_rho, mesh);
// extract stress field
// auto v_tenosr = top3d.GetTensorOfStress(Eigen::Vector3d{0, 1, 2});
// write_tensor3d(output_dir / "stressX_field_matrix.txt", v_tenosr[0],
// mesh->GetOrigin(), mesh->GetOrigin() + mesh->GetLenBox());
// write_tensor3d(output_dir /"stressY_field_matrix.txt", v_tenosr[1],
// mesh->GetOrigin(), mesh->GetOrigin() + mesh->GetLenBox());
// write_tensor3d(output_dir /"stressZ_field_matrix.txt", v_tenosr[2],
// mesh->GetOrigin(), mesh->GetOrigin() + mesh->GetLenBox());
// WriteTensorToVtk(output_dir / "stressX_field_matrix.vtk", v_tenosr[0], mesh);
// WriteTensorToVtk(output_dir / "stressY_field_matrix.vtk", v_tenosr[1], mesh);
// WriteTensorToVtk(output_dir / "stressZ_field_matrix.vtk", v_tenosr[2], mesh);
// if ( 0 && !j_config["model"].count("visual_model")) {
// // visual model with tensor
// // rho
// {
// auto [mesh_obj, vertex_propty] = top::GetMeshVertexPropty(assets_dir / j_config["model"]["visual_model"],
// top3d.GetRhoFieldOneFilled(), bdr, true);
// std::string vtk_path = (output_dir / "regular_with_rho.vtk").string();
// top::WriteTriVTK(vtk_path, mesh_obj.mat_coordinates, mesh_obj.mat_faces, {},
// std::vector<double>(vertex_propty.data(), vertex_propty.data() + vertex_propty.size()));
// spdlog::info("write vtk with rho to: {}", vtk_path);
// top::WriteVectorXd((output_dir / "regular_rho.txt").string(), vertex_propty);
// }
// // stressX
// {
// auto [mesh_obj, vertex_propty] = top::GetMeshVertexPropty(
// assets_dir / j_config["model"]["visual_model"], v_tenosr[0], bdr, true);
// std::string vtk_path = (output_dir / "regular_with_stressX.vtk").string();
// top::WriteTriVTK(vtk_path, mesh_obj.mat_coordinates, mesh_obj.mat_faces, {},
// std::vector<double>(vertex_propty.data(), vertex_propty.data() + vertex_propty.size()));
// spdlog::info("write vtk with stressX to: {}", vtk_path);
// top::WriteVectorXd((output_dir / "regular_stressX.txt").string(), vertex_propty);
// }
// // stressY
// {
// auto [mesh_obj, vertex_propty] = top::GetMeshVertexPropty(
// assets_dir / j_config["model"]["visual_model"], v_tenosr[1], bdr, true);
// std::string vtk_path = (output_dir / "regular_with_stressY.vtk").string();
// top::WriteTriVTK(vtk_path, mesh_obj.mat_coordinates, mesh_obj.mat_faces, {},
// std::vector<double>(vertex_propty.data(), vertex_propty.data() + vertex_propty.size()));
// spdlog::info("write vtk with stressY to: {}", vtk_path);
// top::WriteVectorXd((output_dir / "regular_stressY.txt").string(), vertex_propty);
// }
// // stressZ
// {
// auto [mesh_obj, vertex_propty] = top::GetMeshVertexPropty(
// assets_dir / j_config["model"]["visual_model"], v_tenosr[2], bdr, true);
// std::string vtk_path = (output_dir / "regular_with_stressZ.vtk").string();
// top::WriteTriVTK(vtk_path, mesh_obj.mat_coordinates, mesh_obj.mat_faces, {},
// std::vector<double>(vertex_propty.data(), vertex_propty.data() + vertex_propty.size()));
// spdlog::info("write vtk with stressZ to: {}", vtk_path);
// top::WriteVectorXd((output_dir / "regular_stressZ.txt").string(), vertex_propty);
// }
// }
}