LCOV - code coverage report
Current view: top level - extern/netgen - NGTetMesher.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 84 84 100.0 %
Date: 2020-07-01 15:24:36 Functions: 7 7 100.0 %
Branches: 106 230 46.1 %

           Branch data     Line data    Source code
       1                 :            : #include "meshkit/NGTetMesher.hpp"
       2                 :            : #include "meshkit/MeshScheme.hpp"
       3                 :            : #include "meshkit/ModelEnt.hpp"
       4                 :            : #include "moab/Interface.hpp"
       5                 :            : #include "moab/ReadUtilIface.hpp"
       6                 :            : #include "moab/Range.hpp"
       7                 :            : #include "meshkit/RegisterMeshOp.hpp"
       8                 :            : namespace nglib 
       9                 :            : {
      10                 :            : #include "nglib.h"
      11                 :            : }
      12                 :            : 
      13                 :            : #include <vector>
      14                 :            : 
      15                 :            : namespace MeshKit
      16                 :            : {
      17                 :            : 
      18                 :            : moab::EntityType NGTetMesher::meshTps[] = {moab::MBVERTEX, moab::MBTET, moab::MBMAXTYPE};
      19                 :            : 
      20                 :          2 : NGTetMesher::NGTetMesher(MKCore *mk_core, const MEntVector &me_vec)
      21                 :          2 :         : MeshScheme(mk_core, me_vec)
      22                 :            : {
      23                 :          2 : }
      24                 :            : 
      25                 :          6 : NGTetMesher::~NGTetMesher()
      26                 :            : {
      27         [ -  + ]:          4 : }
      28                 :            : 
      29                 :          2 : MeshOp *NGTetMesher::get_tri_mesher() 
      30                 :            : {
      31         [ +  - ]:          2 :   std::vector<MeshOpProxy *> proxies;
      32 [ +  - ][ +  - ]:          2 :   mk_core()->meshop_by_mesh_type(moab::MBTRI, proxies);
      33 [ -  + ][ #  # ]:          2 :   if (proxies.empty()) throw Error(MK_FAILURE, "Couldn't find a MeshOp capable of producing triangles.");
      34 [ +  - ][ +  - ]:          2 :   return mk_core()->construct_meshop("AF2DfltTriangleMeshOp");
         [ +  - ][ +  - ]
      35                 :            : }
      36                 :            : 
      37                 :          2 : void NGTetMesher::setup_this()
      38                 :            : {
      39                 :          2 :   MeshOp *tri_mesher = NULL;
      40         [ +  - ]:          2 :   MEntVector surfs;
      41                 :            :   
      42 [ +  - ][ +  - ]:          4 :   for (MEntSelection::iterator sit = mentSelection.begin(); sit != mentSelection.end(); sit++) {
                 [ +  + ]
      43         [ +  - ]:          2 :     ModelEnt *me = (*sit).first;
      44 [ +  - ][ -  + ]:          2 :     if (me->dimension() != 3) throw Error(MK_BAD_INPUT, "Tet mesher assigned to an entity with dimension != 3.");
                 [ #  # ]
      45                 :            :     
      46                 :            :       // get the bounding faces
      47                 :          2 :     surfs.clear();
      48         [ +  - ]:          2 :     me->get_adjacencies(2, surfs);
      49                 :            :     
      50                 :            :       // check the mesh scheme on each one; if there is one, verify it can generate tris; if there
      51                 :            :       // isn't one, make one
      52                 :          2 :     bool inserted = false;
      53                 :            :     
      54 [ +  - ][ +  - ]:         24 :     for (MEntVector::iterator vit = surfs.begin(); vit != surfs.end(); vit++) {
                 [ +  + ]
      55 [ +  - ][ +  - ]:         22 :       if ((*vit)->is_meshops_list_empty()) {
                 [ +  - ]
      56                 :            :           // get a tri mesher if we haven't already
      57 [ +  + ][ +  - ]:         22 :         if (!tri_mesher) tri_mesher = get_tri_mesher();
      58                 :            :         
      59                 :            :           // add this surface to it, and if first for the volume, make sure it's added upstream
      60 [ +  - ][ +  - ]:         22 :         tri_mesher->add_modelent(*vit);
      61         [ +  + ]:         22 :         if (!inserted) {
      62 [ +  - ][ +  - ]:          2 :           mk_core()->insert_node(tri_mesher, this);
      63                 :          2 :           inserted = true;
      64                 :            :         }
      65                 :            :       } // if no meshops
      66                 :            :     } // over surfs
      67                 :          2 :   } // over vols
      68                 :          2 : }
      69                 :            : 
      70                 :          2 : void NGTetMesher::execute_this()
      71                 :            : {
      72                 :          2 :   nglib::Ng_Init();
      73                 :            : 
      74 [ +  - ][ +  - ]:          4 :   for (MEntSelection::iterator sit = mentSelection.begin(); sit != mentSelection.end(); sit++) {
                 [ +  + ]
      75                 :            :       // make a me, for convenience
      76         [ +  - ]:          2 :     ModelEnt *me = (*sit).first;
      77                 :            : 
      78                 :            :     // assemble bounding mesh
      79         [ +  - ]:          2 :     std::vector<moab::EntityHandle> bdy;
      80 [ +  - ][ +  - ]:          4 :     std::vector<int> group_sizes, senses, bdy_ids;
                 [ +  - ]
      81         [ +  - ]:          2 :     me->boundary(2, bdy, &senses, &group_sizes);
      82                 :            :     
      83                 :            :       // get connectivity 
      84                 :            : 
      85                 :            :       // convert the handles to integers for input to CMLTetMesher
      86         [ +  - ]:          4 :     moab::Range bdy_vrange;
      87         [ +  - ]:          4 :     std::vector<double> coords;
      88         [ +  - ]:          2 :     me->get_indexed_connect_coords(bdy, &senses, NULL, bdy_ids, coords, &bdy_vrange, 1);
      89                 :            : 
      90         [ +  - ]:          2 :     nglib::Ng_Mesh *ngmesh = nglib::Ng_NewMesh();
      91         [ +  - ]:          2 :     unsigned int numvs = bdy_vrange.size();
      92                 :            :     
      93                 :            :       // add the points
      94         [ +  + ]:       2264 :     for (unsigned int i = 0; i < numvs; i++)
      95 [ +  - ][ +  - ]:       2262 :       nglib::Ng_AddPoint(ngmesh, &coords[3*i]);
      96                 :            : 
      97                 :            :       // add the tris
      98                 :          2 :     unsigned int numtris = bdy.size();
      99         [ +  + ]:       4538 :     for (unsigned int i = 0; i < numtris; i++)
     100 [ +  - ][ +  - ]:       4536 :       nglib::Ng_AddSurfaceElement(ngmesh, nglib::NG_TRIG, &bdy_ids[3*i]);
     101                 :            :     
     102         [ +  - ]:          2 :     double my_size = me->mesh_interval_size();
     103         [ -  + ]:          2 :     if (0 > my_size) my_size = 1.0;
     104         [ +  - ]:          2 :     nglib::Ng_RestrictMeshSizeGlobal(ngmesh, my_size);
     105                 :            : 
     106         [ +  - ]:          2 :     nglib::Ng_Meshing_Parameters ngp;
     107                 :          2 :     ngp.maxh = my_size;
     108                 :          2 :     ngp.fineness = 0.5;
     109                 :            :     
     110                 :            :     // Use variable name second_order if using newer version of NetGen
     111                 :            :     //ngp.secondorder = 0;
     112                 :          2 :         ngp.second_order = 0;
     113                 :            :     //    nglib.h Rev. 663 http://netgen-mesher.svn.sourceforge.net/viewvc/netgen-mesher/netgen/nglib/nglib.h?revision=663&view=markup
     114                 :            :     //uses: second_order instead of secondorder(4.9.13) 
     115                 :            : 
     116                 :            :     
     117         [ +  - ]:          2 :     nglib::Ng_Result result = nglib::Ng_GenerateVolumeMesh(ngmesh, &ngp);
     118 [ -  + ][ #  # ]:          2 :     if (nglib::NG_OK != result) ECERRCHK(MK_FAILURE, "Netgen mesher returned !ok.");
                 [ #  # ]
     119                 :            :     
     120                 :            :     moab::ErrorCode rval;
     121         [ +  - ]:          4 :     moab::Range new_ents;
     122         [ +  - ]:          2 :     int num_pts = nglib::Ng_GetNP(ngmesh);
     123         [ -  + ]:          2 :     assert(num_pts >= (int)numvs);
     124         [ +  - ]:          2 :     if (num_pts > (int)numvs) {
     125         [ +  - ]:          2 :       coords.resize(3*(num_pts-numvs));
     126                 :            :       
     127         [ +  + ]:       1373 :       for (unsigned int i = (unsigned int) numvs; i < (unsigned int) num_pts; i++)
     128 [ +  - ][ +  - ]:       1371 :         nglib::Ng_GetPoint(ngmesh, i, &coords[3*(i-numvs)]);
     129                 :            :       
     130                 :            :         // create the new vertices' entities 
     131 [ +  - ][ +  - ]:          2 :       rval = mk_core()->moab_instance()->create_vertices(&coords[0], num_pts-numvs, new_ents);
         [ +  - ][ +  - ]
     132 [ -  + ][ #  # ]:          2 :       MBERRCHK(rval, mk_core()->moab_instance());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     133                 :            :     }
     134                 :            : 
     135                 :            :       // for tets, pre-allocate connectivity
     136                 :            :     moab::ReadUtilIface *iface;
     137 [ +  - ][ +  - ]:          2 :     rval = mk_core()-> moab_instance() -> query_interface(iface);
                 [ +  - ]
     138 [ -  + ][ #  # ]:          2 :     MBERRCHK(rval, mk_core()->moab_instance());              
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     139                 :            : 
     140                 :            :       //create the tris, get a direct ptr to connectivity
     141         [ +  - ]:          2 :     int num_tets = (int) nglib::Ng_GetNE(ngmesh);
     142                 :            :     moab::EntityHandle starth, *connect;
     143         [ +  - ]:          2 :     rval = iface->get_element_connect(num_tets, 4, moab::MBTET, 1, starth, connect);
     144 [ -  + ][ #  # ]:          2 :     MBERRCHK(rval, mk_core()->moab_instance());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     145                 :            : 
     146                 :            :       // read connectivity directly into that array, as int's
     147                 :          2 :     int *connecti = (int*) connect;
     148         [ +  + ]:      14465 :     for (unsigned int i = 0; i < (unsigned int) num_tets; i++)
     149         [ +  - ]:      14463 :       nglib::Ng_GetVolumeElement(ngmesh, i+1, connecti+4*i);
     150                 :            : 
     151                 :            :       // put vertex handles into an indexible array
     152         [ +  - ]:          4 :     std::vector<moab::EntityHandle> bdy_vvec;
     153 [ +  - ][ +  - ]:          2 :     std::copy(bdy_vrange.begin(), bdy_vrange.end(), std::back_inserter(bdy_vvec));
         [ +  - ][ +  - ]
     154 [ +  - ][ +  - ]:          2 :     std::copy(new_ents.begin(), new_ents.end(), std::back_inserter(bdy_vvec));
         [ +  - ][ +  - ]
     155                 :            :     
     156                 :            :       // now convert vertex indices into handles in-place, working from the back
     157         [ +  + ]:      57854 :     for (int i = 4*num_tets-1; i >= 0; i--) {
     158 [ +  - ][ -  + ]:      57852 :       assert(connecti[i] > 0 && connecti[i] <= (int)bdy_vvec.size());
     159         [ +  - ]:      57852 :       connect[i] = bdy_vvec[connecti[i]-1];
     160                 :            :     }
     161                 :            :     
     162                 :            :       // put new tris into new entity range, then commit the mesh
     163         [ +  - ]:          2 :     new_ents.insert(starth, starth+num_tets-1);
     164         [ +  - ]:          2 :     me->commit_mesh(new_ents, COMPLETE_MESH);
     165                 :            : 
     166         [ +  - ]:          2 :     nglib::Ng_DeleteMesh(ngmesh);
     167                 :          2 :   }
     168                 :            : 
     169                 :          2 :   nglib::Ng_Exit();
     170                 :          2 : }
     171                 :            : 
     172 [ +  - ][ +  - ]:        156 : } // namespace MeshKit

Generated by: LCOV version 1.11