| 1059 | using namespace ngcomp; |
| 1060 | |
| 1061 | void ExportReadAnsys (py::module & m) |
| 1062 | { |
| 1063 | m.def("ReadAnsysInp", [](const string & filename, double scale) -> py::dict |
| 1064 | { |
| 1065 | AnsysModel model = ParseAbaqusInp(filename); |
| 1066 | |
| 1067 | map<string,vector<int>> vol_regions, bnd_regions, bbnd_regions, mat_cells, element_sets; |
| 1068 | vector<int> id2vertex; |
| 1069 | auto ngmesh = BuildAnsysMesh(model, scale, vol_regions, bnd_regions, |
| 1070 | bbnd_regions, mat_cells, element_sets, id2vertex); |
| 1071 | |
| 1072 | auto ma = make_shared<MeshAccess>(ngmesh); |
| 1073 | ngmesh->updateSignal.Connect(ma.get(), [p=ma.get()] { p->UpdateBuffers(); }); |
| 1074 | |
| 1075 | const int nvol = ma->GetNRegions(VOL); |
| 1076 | const int nbnd = ma->GetNRegions(BND); |
| 1077 | const int nbbnd = ma->GetNRegions(BBND); |
| 1078 | |
| 1079 | auto MakeRegion = [&](VorB vb, const vector<int> & nrs, int nregions) |
| 1080 | { |
| 1081 | BitArray ba(nregions); |
| 1082 | ba.Clear(); |
| 1083 | for (int r : nrs) if (r >= 0 && r < nregions) ba.SetBit(r); |
| 1084 | return Region(ma, vb, ba); |
| 1085 | }; |
| 1086 | |
| 1087 | py::dict res; |
| 1088 | res["mesh"] = py::cast(ma); |
| 1089 | |
| 1090 | // material property data |
| 1091 | py::dict mats; |
| 1092 | for (auto & [name, mat] : model.materials) |
| 1093 | { |
| 1094 | py::dict d; |
| 1095 | if (mat.hasE) d["E"] = mat.E; |
| 1096 | if (mat.hasNu) d["nu"] = mat.nu; |
| 1097 | if (mat.hasRho) d["rho"] = mat.rho; |
| 1098 | mats[py::str(name)] = d; |
| 1099 | } |
| 1100 | res["materials"] = mats; |
| 1101 | |
| 1102 | // "true" domains: one Region(VOL) per body/part (overlap-safe) |
| 1103 | py::dict domains; |
| 1104 | for (auto & [name, nrs] : vol_regions) |
| 1105 | domains[py::str(name)] = py::cast(MakeRegion(VOL, nrs, nvol)); |
| 1106 | res["domains"] = domains; |
| 1107 | |
| 1108 | py::dict material_regions; |
| 1109 | for (auto & [name, nrs] : mat_cells) |
| 1110 | material_regions[py::str(name)] = py::cast(MakeRegion(VOL, nrs, nvol)); |
| 1111 | res["material_regions"] = material_regions; |
| 1112 | |
| 1113 | // standalone *ELSET named selections (not bodies): element-number lists, |
| 1114 | // kept out of the domain partition so it stays clean |
| 1115 | py::dict elsets; |
| 1116 | for (auto & [name, els] : element_sets) |
| 1117 | { |
| 1118 | py::list l; |
no test coverage detected