LCOV - code coverage report
Current view: top level - algs - CopyMesh.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 123 142 86.6 %
Date: 2020-07-01 15:24:36 Functions: 11 14 78.6 %
Branches: 152 308 49.4 %

           Branch data     Line data    Source code
       1                 :            : #include "meshkit/CopyMesh.hpp"
       2                 :            : #include "meshkit/MKCore.hpp"
       3                 :            : #include "meshkit/ModelEnt.hpp"
       4                 :            : #include "meshkit/SizingFunction.hpp"
       5                 :            : #include "meshkit/RegisterMeshOp.hpp"
       6                 :            : #include "meshkit/LocalSet.hpp"
       7                 :            : 
       8                 :            : #include "iMesh_extensions.h"
       9                 :            : #include "MBCN.h"
      10                 :            : 
      11                 :            : #define CHKERR(err) do {                        \
      12                 :            :     if ((err) != iBase_SUCCESS)                   \
      13                 :            :     return iBase_ErrorType(err);                \
      14                 :            :     } while(false)
      15                 :            : 
      16                 :            : 
      17                 :            : namespace MeshKit
      18                 :            : {
      19                 :            : 
      20                 :            : // static registration of this  mesh scheme
      21                 :            : moab::EntityType CopyMesh_tps[] = { moab::MBVERTEX,
      22                 :            :                                     moab::MBEDGE,
      23                 :            :                                     moab::MBTRI,
      24                 :            :                                     moab::MBHEX,
      25                 :            :                                     moab::MBMAXTYPE};
      26                 :         40 : const moab::EntityType* CopyMesh::output_types()
      27                 :         40 : { return CopyMesh_tps; }
      28                 :            : 
      29                 :          4 : CopyMesh::CopyMesh(MKCore *mkcore, const MEntVector &me_vec)
      30                 :            :     : MeshScheme(mkcore, me_vec),
      31         [ +  - ]:          4 :       mesh(mkcore->imesh_instance()),
      32                 :            :       copyTag(mkcore, "__CopyMeshTag"),
      33                 :          0 :       transform(new Copy::Identity()),
      34                 :            :       copySets(mkcore),
      35 [ +  - ][ +  - ]:          8 :       expandSets(mkcore)
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
      36                 :            : {
      37                 :          4 :   flag_process_ce_set = false;
      38                 :          4 : }
      39                 :            : 
      40                 :         12 : CopyMesh::~CopyMesh()
      41                 :            : {
      42         [ +  - ]:          4 :     delete transform;
      43         [ -  + ]:          8 : }
      44                 :            : 
      45                 :            : 
      46                 :          0 : bool CopyMesh::add_modelent(ModelEnt *model_ent)
      47                 :            : {
      48                 :          0 :     return MeshOp::add_modelent(model_ent);
      49                 :            : }
      50                 :            : 
      51                 :          4 : void CopyMesh::setup_this()
      52                 :            : {
      53                 :          4 : }
      54                 :            : 
      55                 :          4 : void CopyMesh::execute_this()
      56                 :            : {
      57                 :          4 :     iBase_EntitySetHandle t = NULL;
      58   [ +  -  +  - ]:         16 :     for (MEntSelection::iterator mit = mentSelection.begin();
                 [ +  + ]
      59                 :          8 :          mit != mentSelection.end(); mit++) {
      60         [ +  - ]:          4 :         ModelEnt *me = mit->first;
      61                 :            :         //orig_ents[i++] = reinterpret_cast<iBase_EntityHandle> (me->mesh_handle());
      62         [ +  - ]:          4 :         t = reinterpret_cast<iBase_EntitySetHandle> (me->mesh_handle());
      63                 :            :     }
      64                 :            : 
      65 [ +  - ][ +  - ]:          4 :     LocalSet set(this->mk_core());
      66         [ +  - ]:          8 :     std::vector<iBase_EntityHandle> original;
      67                 :          4 :     original.clear();
      68                 :            :     iBase_EntityType type_t;
      69 [ +  - ][ +  - ]:          4 :     IBERRCHK(mesh->getEntType((iBase_EntityHandle)t, type_t), *mesh);
      70                 :            :     // check if this is a set(4)
      71         [ -  + ]:          4 :     if((int) type_t !=4){
      72 [ #  # ][ #  # ]:          0 :         std::cout << "Invalid model ent set, bailing out.." << std::endl;
      73                 :          0 :         exit(0);
      74                 :            :     }
      75                 :            : 
      76 [ +  - ][ +  - ]:          4 :     IBERRCHK(mesh->getEntities(t, iBase_ALL_TYPES, iMesh_ALL_TOPOLOGIES, original), *mesh);
      77 [ +  - ][ +  - ]:          4 :     IBERRCHK(mesh->addEntArrToSet(&original[0], original.size(), set), *mesh);
         [ +  - ][ +  - ]
      78 [ +  - ][ +  - ]:          8 :     do_copy(set);
      79                 :          4 : }
      80                 :            : 
      81                 :          4 : int CopyMesh::getStructure(iMesh_Instance instance,
      82                 :            :                            iBase_EntitySetHandle set,
      83                 :            :                            std::vector<iBase_EntityHandle> &ents,
      84                 :            :                            std::vector<iBase_EntityHandle> &unique_adj,
      85                 :            :                            std::vector<int> &indices,
      86                 :            :                            std::vector<int> &offsets)
      87                 :            : {
      88                 :            :     // 1) Get source entities, making sure verts are first
      89                 :            :     int num;
      90                 :            :     int err;
      91         [ +  - ]:          4 :     iMesh_getNumOfTypeRec(instance, set, iBase_ALL_TYPES, true, &num, &err);
      92         [ -  + ]:          4 :     CHKERR(err);
      93                 :            : 
      94         [ +  - ]:          4 :     ents.resize(num);
      95         [ +  - ]:          4 :     offsets.resize(num+1);
      96                 :            : 
      97         [ +  - ]:          4 :     iBase_EntityHandle *block = &ents[0];
      98                 :          4 :     int block_alloc = ents.size(), block_size, num_verts = 0;
      99 [ +  - ][ +  + ]:         33 :     for (int t = iMesh_POINT; t < iMesh_ALL_TOPOLOGIES && block_alloc; ++t) {
     100                 :            :         iMesh_getEntitiesRec(instance, set, iBase_ALL_TYPES, t, true,
     101         [ +  - ]:         29 :                              &block, &block_alloc, &block_size, &err);
     102         [ -  + ]:         29 :         CHKERR(err);
     103                 :            : 
     104                 :         29 :         block_alloc -= block_size;
     105                 :         29 :         block += block_size;
     106         [ +  + ]:         29 :         if (t == iMesh_POINT)
     107                 :          4 :             num_verts = block_size;
     108                 :            :     }
     109                 :            : 
     110                 :            :     // 2) Get verts adjacent to all source entitites (verts are adj to themselves)
     111 [ +  - ][ +  - ]:          4 :     std::vector<iBase_EntityHandle> all_adj(ents.begin(), ents.begin()+num_verts);
     112                 :            : 
     113                 :            :     // first, fill the vertex-vertex adjacencies
     114         [ +  + ]:         85 :     for (int i = 0; i < num_verts; ++i)
     115         [ +  - ]:         81 :         offsets[i] = i;
     116                 :            : 
     117                 :          4 :     iBase_EntityHandle *tmp_adj = NULL;
     118                 :          4 :     int tmp_adj_alloc = 0, tmp_adj_size;
     119         [ +  - ]:          4 :     int *tmp_off = &offsets[num_verts];
     120                 :          4 :     int tmp_off_alloc = offsets.size() - num_verts, tmp_off_size;
     121         [ +  - ]:          4 :     iMesh_getEntArrAdj(instance, &ents[num_verts], ents.size()-num_verts,
     122                 :            :                        iBase_VERTEX, &tmp_adj, &tmp_adj_alloc, &tmp_adj_size,
     123         [ +  - ]:          4 :                        &tmp_off, &tmp_off_alloc, &tmp_off_size, &err);
     124         [ -  + ]:          4 :     CHKERR(err);
     125                 :            : 
     126                 :            :     // shift all the offsets to account for vertices
     127         [ +  + ]:         45 :     for(unsigned int i = num_verts; i < offsets.size(); ++i)
     128         [ +  - ]:         41 :         offsets[i] += num_verts;
     129                 :            : 
     130         [ +  - ]:          4 :     all_adj.reserve(all_adj.size() + tmp_adj_size);
     131         [ +  - ]:          4 :     all_adj.insert(all_adj.end(), tmp_adj, tmp_adj+tmp_adj_size);
     132                 :          4 :     free(tmp_adj);
     133                 :            : 
     134                 :            :     // 3) Get unique adjacent vertices and offsets
     135         [ +  - ]:          4 :     unique_adj.resize(all_adj.size());
     136         [ +  - ]:          4 :     indices.resize(all_adj.size());
     137         [ +  - ]:          4 :     std::copy(all_adj.begin(), all_adj.end(), unique_adj.begin());
     138         [ +  - ]:          4 :     std::sort(unique_adj.begin(), unique_adj.end());
     139                 :            : 
     140                 :            :     size_t unique_size;
     141 [ +  - ][ +  - ]:          4 :     unique_size = std::unique(unique_adj.begin(), unique_adj.end()) -
     142                 :          4 :             unique_adj.begin();
     143         [ +  - ]:          4 :     unique_adj.resize(unique_size);
     144                 :            : 
     145         [ +  + ]:        329 :     for (size_t i = 0; i < all_adj.size(); ++i) {
     146         [ +  - ]:        325 :         indices[i] = std::lower_bound(unique_adj.begin(), unique_adj.end(),
     147 [ +  - ][ +  - ]:        325 :                                       all_adj[i]) - unique_adj.begin();
                 [ +  - ]
     148                 :            :     }
     149                 :            : 
     150                 :          4 :     return 0;
     151                 :            : }
     152                 :            : 
     153                 :          4 : void CopyMesh::do_copy(iMesh::EntitySetHandle set_handle)
     154                 :            : {
     155         [ -  + ]:          4 :     assert(transform);
     156                 :            : 
     157 [ +  - ][ +  - ]:          4 :     LocalTag local_tag(this->mk_core());
     158                 :            : 
     159         [ +  - ]:          8 :     std::vector<iBase_EntityHandle> ents;
     160         [ +  - ]:          8 :     std::vector<iBase_EntityHandle> verts;
     161         [ +  - ]:          8 :     std::vector<int> indices;
     162         [ +  - ]:          8 :     std::vector<int> offsets;
     163                 :            :     //    IBERRCHK(iMesh_getStructure(mesh->instance(), set_handle, ents, verts,
     164                 :            :     //                                indices, offsets), *mesh);
     165                 :            :     getStructure(mesh->instance(), set_handle, ents, verts,
     166 [ +  - ][ +  - ]:          4 :                  indices, offsets);
     167                 :            :     // copy the vertices
     168         [ +  - ]:          8 :     std::vector<iBase_EntityHandle> new_verts;
     169         [ +  - ]:          4 :     transform->transform(mesh, verts, new_verts);
     170         [ -  + ]:          4 :     assert(new_verts.size() == verts.size());
     171                 :            : 
     172                 :            :     // set the local copy tags on vertices
     173                 :            :     // XXX: Should this really happen? Doing so adds more entities to copy sets
     174                 :            :     // than explicitly passed into this function. This may be a domain-specific
     175                 :            :     // question.
     176 [ +  - ][ +  - ]:          4 :     IBERRCHK(mesh->setEHArrData(&verts[0], verts.size(), local_tag,
         [ +  - ][ +  - ]
     177         [ +  - ]:          4 :              &new_verts[0]), *mesh);
     178                 :            : 
     179                 :            :     // now connect the new vertices to make the higher-dimension entities
     180 [ +  - ][ +  - ]:          4 :     connect_the_dots(mesh, local_tag, ents, indices, offsets, new_verts);
     181                 :            : 
     182                 :            :     // take care of copy/expand sets
     183         [ +  - ]:          4 :     update_sets();
     184                 :            : 
     185 [ +  - ][ +  - ]:          4 :     link_expand_sets(expandSets, local_tag);
     186                 :            : 
     187         [ +  + ]:          4 :     if(flag_process_ce_set == true)
     188 [ +  - ][ +  - ]:          1 :       process_ce_sets(mesh, copySets.sets(), local_tag);
                 [ +  - ]
     189 [ +  - ][ +  - ]:          4 :     process_ce_sets(mesh, expandSets.sets(), local_tag);
                 [ +  - ]
     190                 :            : 
     191 [ +  - ][ +  - ]:          8 :     tag_copy_sets(copySets, local_tag, copyTag);
                 [ +  - ]
     192                 :          4 : }
     193                 :            : 
     194                 :          4 : void CopyMesh::update_sets()
     195                 :            : {
     196                 :          4 :     copySets.update_tagged_sets();
     197                 :          4 :     expandSets.update_tagged_sets();
     198                 :          4 : }
     199                 :            : 
     200                 :          0 : void CopyMesh::tag_copied_sets(const char **tag_names, const char **tag_vals,
     201                 :            :                                const int num_tags)
     202                 :            : {
     203         [ #  # ]:          0 :     for (int t = 0; t < num_tags; t++) {
     204                 :            :         iMesh::TagHandle tag;
     205 [ #  # ][ #  # ]:          0 :         IBERRCHK(mesh->getTagHandle(tag_names[t], tag), *mesh);
     206                 :            : 
     207         [ #  # ]:          0 :         tag_copy_sets(mesh, copyTag, copySets.sets(), tag,
     208 [ #  # ][ #  # ]:          0 :                       tag_vals ? tag_vals[t] : NULL);
                 [ #  # ]
     209                 :            :     }
     210                 :          0 : }
     211                 :            : 
     212                 :          0 : void CopyMesh::tag_copied_sets(iMesh::TagHandle *tags, const char **tag_vals,
     213                 :            :                                const int num_tags)
     214                 :            : {
     215         [ #  # ]:          0 :     for (int t = 0; t < num_tags; t++)
     216                 :          0 :         tag_copy_sets(mesh, copyTag, copySets.sets(), tags[t],
     217         [ #  # ]:          0 :                       tag_vals ? tag_vals[t] : NULL);
     218                 :          0 : }
     219                 :            : 
     220                 :          7 : void connect_the_dots(iMesh *mesh, iBase_TagHandle local_tag,
     221                 :            :                       const std::vector<iBase_EntityHandle> &ents,
     222                 :            :                       const std::vector<int> &indices,
     223                 :            :                       const std::vector<int> &offsets,
     224                 :            :                       const std::vector<iBase_EntityHandle> &verts)
     225                 :            : {
     226         [ +  - ]:          7 :     std::vector<iMesh_EntityTopology> topos(ents.size());
     227 [ +  - ][ +  - ]:          7 :     IBERRCHK(mesh->getEntArrTopo(&ents[0], ents.size(), &topos[0]), *mesh);
         [ +  - ][ +  - ]
     228                 :            : 
     229                 :            :     // scan forward to first non-vertex
     230                 :          7 :     size_t pos = 0;
     231 [ +  - ][ +  - ]:         88 :     while (pos < topos.size() && iMesh_POINT == topos[pos])
         [ +  + ][ +  + ]
     232                 :         81 :         pos++;
     233         [ -  + ]:         14 :     if (pos == topos.size()) return;
     234                 :            : 
     235                 :            :     // for each run of same size & type
     236 [ +  - ][ +  - ]:         14 :     std::vector<iBase_EntityHandle> connect, new_ents;
                 [ +  - ]
     237                 :          7 :     size_t begin, end = pos;
     238         [ +  + ]:         17 :     while (end < ents.size()) {
     239                 :            :         // get next run; end points to start of *next* element,
     240                 :            :         // or ents_size if no elems left
     241                 :         10 :         begin = end++;
     242                 :            : 
     243         [ +  - ]:         10 :         iMesh_EntityTopology topo = topos[begin];
     244 [ +  - ][ +  - ]:         10 :         int vtx_per_ent = offsets[end] - offsets[begin];
     245 [ +  + ][ +  + ]:        116 :         while (end < ents.size() &&
     246 [ +  + ][ +  - ]:         75 :                topos[end] == topo &&
                 [ +  - ]
     247 [ +  - ][ +  - ]:         31 :                offsets[end+1] - offsets[end] == vtx_per_ent)
     248                 :         31 :             end++;
     249                 :         10 :         size_t num_ents = end - begin;
     250                 :            : 
     251                 :            :         int mbcn_type;
     252                 :            :         int num_corner_verts;
     253         [ +  - ]:         10 :         iMesh_MBCNType(topo, &mbcn_type);
     254         [ +  - ]:         10 :         MBCN_VerticesPerEntity(mbcn_type, &num_corner_verts);
     255                 :            : 
     256                 :            :         // build vector of vtx handles
     257         [ +  - ]:         10 :         connect.resize(vtx_per_ent * num_ents);
     258         [ +  + ]:        269 :         for (size_t i = 0; i < connect.size(); i++)
     259 [ +  - ][ +  - ]:        259 :             connect[i] = verts[indices[offsets[begin] + i]];
         [ +  - ][ +  - ]
     260                 :            : 
     261                 :            :         // create entities
     262         [ +  - ]:         10 :         new_ents.resize(num_ents);
     263                 :            : 
     264         [ +  - ]:         10 :         if (num_corner_verts == vtx_per_ent) {
     265 [ +  - ][ +  - ]:         10 :             IBERRCHK(mesh->createEntArr(topo, &connect[0], connect.size(),
                 [ +  - ]
     266         [ +  - ]:         10 :                      &new_ents[0]), *mesh);
     267                 :            :         }
     268                 :            :         else {
     269                 :            :             // use single-entity function in this case, entity might have higher-
     270                 :            :             // order nodes (imesh fcn doesn't have argument for # entities)
     271         [ #  # ]:          0 :             for (size_t i = 0; i < num_ents; i++) {
     272 [ #  # ][ #  # ]:          0 :                 IBERRCHK(mesh->createEnt(topo, &connect[i*vtx_per_ent],
                 [ #  # ]
     273         [ #  # ]:          0 :                          vtx_per_ent, new_ents[i]), *mesh);
     274                 :            :             }
     275                 :            :         }
     276                 :            : 
     277                 :            :         // set the local copy tags
     278 [ +  - ][ +  - ]:         10 :         IBERRCHK(mesh->setEHArrData(&ents[begin], num_ents, local_tag,
                 [ +  - ]
     279         [ +  - ]:         10 :                                     &new_ents[0]), *mesh);
     280                 :          7 :     }
     281                 :            : }
     282                 :            : 
     283 [ +  - ][ +  - ]:        156 : } // namespace MeshKit

Generated by: LCOV version 1.11