LCOV - code coverage report
Current view: top level - algs - EBMesher.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 600 1232 48.7 %
Date: 2020-07-01 15:24:36 Functions: 31 44 70.5 %
Branches: 605 2520 24.0 %

           Branch data     Line data    Source code
       1                 :            : #include "meshkit/EBMesher.hpp"
       2                 :            : #include "meshkit/SCDMesh.hpp"
       3                 :            : #include "meshkit/MKCore.hpp"
       4                 :            : #include "meshkit/ModelEnt.hpp"
       5                 :            : #include "meshkit/SizingFunction.hpp"
       6                 :            : #include "moab/ReadUtilIface.hpp"
       7                 :            : #include "meshkit/iGeom.hpp"
       8                 :            : #include "meshkit/RegisterMeshOp.hpp"
       9                 :            : 
      10                 :            : #include "moab/Core.hpp"
      11                 :            : #include "moab/Range.hpp"
      12                 :            : #include "moab/CartVect.hpp"
      13                 :            : #include "moab/EntityType.hpp"
      14                 :            : #include "moab/HomXform.hpp"
      15                 :            : #include "moab/GeomTopoTool.hpp"
      16                 :            : 
      17                 :            : #include <time.h>
      18                 :            : 
      19                 :            : #ifdef HAVE_CGM
      20                 :            : #include "CubitDefines.h"
      21                 :            : #include "GeometryQueryTool.hpp"
      22                 :            : #include "RefFace.hpp"
      23                 :            : #endif
      24                 :            : 
      25                 :            : #define PI 3.14159265
      26                 :            : #define ERRORRF(a) {if (iBase_SUCCESS != err) {std::cerr << a << std::endl; return false;}}
      27                 :            : 
      28                 :            : double rayDir[3][3] = {{1., 0., 0.}, {0., 1., 0.}, {0., 0., 1.}};
      29                 :            : 
      30                 :            : const bool debug_ebmesh = false;
      31                 :        729 : inline bool less_intersect(const IntersectDist d1, const IntersectDist d2) {
      32                 :        729 :   return d1.distance < d2.distance;
      33                 :            : }
      34                 :            : 
      35                 :            : inline bool equal_intersect(const IntersectDist d1, const IntersectDist d2) {
      36                 :            :   return std::abs(d1.distance - d2.distance) < 10e-7;
      37                 :            : }
      38                 :            : 
      39                 :            : namespace MeshKit 
      40                 :            : {
      41                 :            : // static registration of this  mesh scheme
      42                 :            : moab::EntityType EBMesher_tps[] = {moab::MBVERTEX, moab::MBHEX, moab::MBMAXTYPE};
      43                 :         40 : const moab::EntityType* EBMesher::output_types()
      44                 :         40 :   { return EBMesher_tps; }
      45                 :            : 
      46                 :          1 : EBMesher::EBMesher(MKCore *mkcore, const MEntVector &me_vec,
      47                 :            :                    double size, bool use_geom, int add_layer)
      48 [ +  - ][ +  - ]:          4 :   : MeshScheme(mkcore, me_vec), m_nAddLayer(add_layer),  m_dInputSize(size), m_bUseGeom(use_geom)
         [ +  - ][ +  - ]
         [ +  - ][ +  + ]
         [ +  - ][ +  - ]
         [ +  - ][ +  -  
          #  #  #  #  #  
                      # ]
      49                 :            : {
      50 [ +  - ][ +  - ]:          1 :   m_mesh = mkcore->imesh_instance()->instance();
      51 [ +  - ][ +  - ]:          1 :   m_hRootSet = mkcore->imesh_instance()->getRootSet();
      52                 :          1 :   m_nStatus = OUTSIDE;
      53                 :          1 :   m_iStartHex = 0;
      54                 :          1 :   m_hObbTree = NULL;
      55                 :          1 :   m_hTreeRoot = 0;
      56                 :            : 
      57                 :            :   // create tags with MOAB for dense tags
      58                 :          1 :   int outside = 1;
      59                 :          1 :   const void *out = &outside;
      60                 :            :   m_elemStatusTag = get_tag("ELEM_STATUS_TAG", 1,
      61         [ +  - ]:          1 :                             moab::MB_TAG_DENSE, moab::MB_TYPE_INTEGER, out);
      62                 :            :   
      63                 :          1 :   int length = 1;
      64                 :          1 :   const void *leng = &length;
      65                 :            :   m_edgeCutFracLengthTag = get_tag("EDGE_CUT_FRAC_LENGTH_TAG", // # of fractions
      66                 :            :                                    3,
      67                 :            :                                    //moab::MB_TAG_SPARSE, // using dense for hdf5 exporting performance
      68                 :            :                                    moab::MB_TAG_DENSE,
      69         [ +  - ]:          1 :                                    moab::MB_TYPE_INTEGER, leng);
      70                 :            : 
      71                 :            :   m_edgeCutFracTag = get_various_length_tag("EDGE_CUT_FRAC_TAG",
      72                 :            :                                             //moab::MB_TAG_SPARSE,
      73                 :            :                                             moab::MB_TAG_DENSE,
      74         [ +  - ]:          1 :                                             moab::MB_TYPE_DOUBLE);
      75                 :            : 
      76                 :          1 :   int m_id = 1;
      77                 :          1 :   const void *id = &m_id;
      78                 :            :   m_volFracLengthTag = get_tag("VOL_FRAC_LENGTH_TAG", 1,
      79         [ +  - ]:          1 :                                moab::MB_TAG_SPARSE, moab::MB_TYPE_INTEGER, id);
      80                 :            :   
      81                 :            :   m_volFracHandleTag = get_various_length_tag("VOL_FRAC_HANDLE_TAG",
      82         [ +  - ]:          1 :                                           moab::MB_TAG_SPARSE, moab::MB_TYPE_INTEGER);
      83                 :            : 
      84                 :            :   m_volFracTag = get_various_length_tag("VOL_FRAC_TAG",
      85         [ +  - ]:          1 :                                         moab::MB_TAG_SPARSE, moab::MB_TYPE_DOUBLE);
      86                 :            :   
      87                 :            :   // set bounding box size tag
      88                 :          1 :   double bb_default[6] = { 0., 0., 0., 0., 0., 0. };
      89                 :            :   m_bbTag = get_tag("BOUNDING_BOX_SIZE", 6,
      90         [ +  - ]:          1 :                     moab::MB_TAG_SPARSE, moab::MB_TYPE_DOUBLE, bb_default);
      91                 :            :   
      92 [ +  - ][ +  - ]:          1 :   m_GeomTopoTool = new moab::GeomTopoTool( moab_instance() );
                 [ +  - ]
      93         [ #  # ]:          1 : }
      94                 :            : 
      95 [ +  - ][ +  + ]:          6 : EBMesher::~EBMesher()
      96                 :            : {
      97         [ +  - ]:          1 :   delete m_GeomTopoTool;
      98         [ -  + ]:          2 : }
      99                 :            : 
     100                 :          0 : bool EBMesher::can_mesh(ModelEnt *me) 
     101                 :            : {
     102         [ #  # ]:          0 :   if (me->dimension() == 3) return true;
     103                 :          0 :   else return false;
     104                 :            : }
     105                 :            :     
     106                 :          0 : bool EBMesher::add_modelent(ModelEnt *model_ent) 
     107                 :            : {
     108                 :            :     // make sure this represents geometric volumes
     109         [ #  # ]:          0 :   if (3 != model_ent->dimension()) 
     110         [ #  # ]:          0 :     throw Error(MK_WRONG_DIMENSION, "Wrong dimension entity added to EBMesher.");
     111                 :            : 
     112                 :          0 :   return MeshOp::add_modelent(model_ent);
     113                 :            : }
     114                 :            : 
     115                 :          1 : MeshOp *EBMesher::get_scd_mesher()
     116                 :            : {
     117                 :          1 :   MeshOpProxy* proxy = NULL;
     118                 :          1 :   proxy = MKCore::meshop_proxy("SCDMesh");
     119 [ -  + ][ #  # ]:          1 :   if (proxy == NULL) throw Error(MK_FAILURE, "Couldn't find a MeshOp capable of producing the given mesh type.");
     120 [ +  - ][ +  - ]:          1 :   return mk_core()->construct_meshop(proxy);
     121                 :            : }
     122                 :            : 
     123                 :          1 : void EBMesher::setup_this()
     124                 :            : {
     125                 :          1 :   MeshOp *scd_mesher = NULL;
     126         [ +  - ]:          1 :   std::vector<MeshOp*> meshops;
     127                 :          1 :   bool inserted = false;
     128                 :            : 
     129 [ #  # ][ +  - ]:          1 :   for (MEntSelection::iterator sit = mentSelection.begin(); sit != mentSelection.end(); sit++) {
                 [ +  - ]
     130         [ +  - ]:          1 :     ModelEnt *me = (*sit).first;
     131                 :          1 :     bool found = false;
     132 [ +  - ][ +  - ]:          1 :     if (!scd_mesher) scd_mesher = get_scd_mesher();
     133                 :          1 :     meshops.clear();
     134         [ +  - ]:          1 :     me->get_meshops(meshops);
     135                 :          1 :     int n_meshops = meshops.size();
     136                 :            : 
     137         [ -  + ]:          1 :     if (n_meshops > 0) {
     138         [ #  # ]:          0 :       for (int i = 0; i < n_meshops; i++) {
     139 [ #  # ][ #  # ]:          0 :         if (meshops[i] == scd_mesher) {
     140                 :          0 :           found = true;
     141                 :          0 :           break;
     142                 :            :         }
     143                 :            :       }
     144                 :            :     }
     145                 :            : 
     146         [ +  - ]:          1 :     if (!found) { // if no scd meshop
     147                 :            :       // add this entity to it, and if first, make sure it's added upstream
     148         [ +  - ]:          1 :       scd_mesher->add_modelent(me);
     149         [ +  - ]:          1 :       if (!inserted) {
     150 [ +  - ][ +  - ]:          1 :         mk_core()->insert_node(scd_mesher, this);
     151                 :          1 :         inserted = true;
     152                 :            :       }
     153                 :            :     }
     154                 :            : 
     155                 :            :     // no need to traverse all geometry for using whole geometry
     156         [ +  - ]:          1 :     if (m_bUseWholeGeom) break;
     157                 :            :   }
     158                 :            : 
     159                 :          1 :   SCDMesh *sm = (SCDMesh*) scd_mesher;
     160         [ +  - ]:          1 :   sm->set_interface_scheme(SCDMesh::full);
     161         [ +  - ]:          1 :   sm->set_grid_scheme(SCDMesh::cfMesh);
     162                 :            :   
     163         [ +  - ]:          1 :   sm->set_axis_scheme(SCDMesh::cartesian);
     164         [ +  - ]:          1 :   sm->set_box_increase_ratio(m_boxIncrease); // add some extra layer to box
     165                 :            : 
     166 [ +  - ][ +  - ]:          1 :   if (m_bUseWholeGeom) sm->set_geometry_scheme(SCDMesh::all);
     167         [ #  # ]:          0 :   else sm->set_geometry_scheme(SCDMesh::individual);
     168                 :            : 
     169                 :            :   // use mesh based geometry in SCDMesh and make tree to get box dimension
     170         [ -  + ]:          1 :   if (m_bUseMeshGeom) {
     171         [ #  # ]:          0 :     sm->use_mesh_geometry(true);
     172         [ #  # ]:          0 :     sm->set_cart_box_min_max(m_minCoord, m_maxCoord, m_boxIncrease);
     173                 :            :   }
     174                 :            : 
     175                 :            :   // set # of intervals for 3 directions
     176         [ +  - ]:          2 :   std::vector<int> fine_i (m_nDiv[0], 1);
     177         [ +  - ]:          1 :   sm->set_coarse_i_grid(m_nDiv[0]);
     178 [ +  - ][ +  - ]:          1 :   sm->set_fine_i_grid(fine_i);
     179         [ +  - ]:          2 :   std::vector<int> fine_j (m_nDiv[1], 1);
     180         [ +  - ]:          1 :   sm->set_coarse_j_grid(m_nDiv[1]);
     181 [ +  - ][ +  - ]:          1 :   sm->set_fine_j_grid(fine_j);
     182         [ +  - ]:          2 :   std::vector<int> fine_k (m_nDiv[2], 1);
     183         [ +  - ]:          1 :   sm->set_coarse_k_grid(m_nDiv[2]);
     184 [ +  - ][ +  - ]:          2 :   sm->set_fine_k_grid(fine_k);
     185                 :          1 : }
     186                 :            : 
     187                 :          1 : void EBMesher::execute_this() 
     188                 :            : {
     189                 :            :   iBase_ErrorType  err;
     190 [ +  - ][ +  - ]:          1 :   GraphNode *scd_node = other_node(in_arcs());
     191                 :            : 
     192                 :          1 :   double obb_time = .0;
     193                 :          1 :   double intersection_time = .0;
     194                 :          1 :   double set_info_time = .0;
     195                 :            :   time_t time1, time2, time3, time4;
     196                 :            :   unsigned long long mem1, mem3, mem4;
     197 [ +  - ][ +  - ]:          1 :   moab_instance()->estimated_memory_use(0, 0, 0, &mem1);
     198                 :            :   moab::ErrorCode rval;
     199                 :            : 
     200                 :            :   if (debug_ebmesh) {
     201                 :            :     rval = mk_core()->moab_instance()->write_mesh("input.vtk");
     202                 :            :     MBERRCHK(rval, mk_core()->moab_instance());
     203                 :            :   }
     204                 :            : 
     205                 :          1 :   time(&time1);
     206 [ +  - ][ +  - ]:          1 :   if (m_bUseGeom && !m_bUseMeshGeom) { // construct obb tree for geometry surfaces and volumes by GeomTopoTool
     207         [ +  - ]:          1 :     rval = m_GeomTopoTool->construct_obb_trees(m_bUseWholeGeom);
     208 [ -  + ][ #  # ]:          1 :     MBERRCHK(rval, mk_core()->moab_instance());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     209                 :            :   }
     210                 :          1 :   time(&time2);
     211                 :          1 :   obb_time += difftime(time2, time1);
     212                 :            : 
     213 [ #  # ][ +  - ]:          1 :   for (MEntSelection::iterator sit = mentSelection.begin(); sit != mentSelection.end(); sit++) {
                 [ +  - ]
     214                 :            :     // 1. set division
     215                 :            :     double box_min_max[6];
     216         [ +  - ]:          1 :     if (m_bUseWholeGeom) {
     217         [ +  - ]:          1 :       static_cast<SCDMesh*> (scd_node)->get_box_dimension(box_min_max, &box_min_max[3]);
     218                 :            :     }
     219                 :            :     else {
     220 [ #  # ][ #  # ]:          0 :       err = mk_core()->imesh_instance()->getData(reinterpret_cast< iBase_EntityHandle >
     221 [ #  # ][ #  # ]:          0 :                                                  (sit ->first->mesh_handle()), m_bbTag, &box_min_max[0]);
                 [ #  # ]
     222         [ #  # ]:          0 :       IBERRCHK(err, "Failed to get hexes.\n");
     223                 :            :     }
     224         [ +  - ]:          1 :     set_division(box_min_max, &box_min_max[3]);
     225                 :            : 
     226                 :            :     // 2. set or construct obb tree
     227                 :          1 :     time(&time1);
     228 [ +  - ][ +  - ]:          1 :     set_tree_root(sit->first);
     229                 :          1 :     time(&time2);
     230                 :          1 :     obb_time += difftime(time2, time1);
     231                 :            : 
     232                 :            :     // 3. find intersected geometry surfaces by rays
     233         [ +  - ]:          1 :     find_intersections();
     234                 :          1 :     time(&time3);
     235                 :          1 :     intersection_time += difftime(time3, time2);
     236 [ +  - ][ +  - ]:          1 :     moab_instance()->estimated_memory_use(0, 0, 0, &mem3);
     237                 :            :     
     238                 :            :     // 4. set hex status and boundary hex cut fraction info
     239         [ +  - ]:          1 :     set_tag_info();
     240                 :          1 :     time(&time4);
     241                 :          1 :     set_info_time += difftime(time4, time3);
     242 [ +  - ][ +  - ]:          1 :     moab_instance()->estimated_memory_use(0, 0, 0, &mem4);
     243                 :            : 
     244         [ +  - ]:          1 :     if (m_bUseWholeGeom) break;
     245                 :            :   }
     246                 :            :   if (debug_ebmesh) {
     247                 :            :     std::cout << "OBB_tree_construct_time: " << obb_time
     248                 :            :               << ", intersection_time: " << intersection_time
     249                 :            :               << ", set_info_time: " << set_info_time << std::endl;
     250                 :            :     std::cout << "start_memory: " << mem1
     251                 :            :               //<< ", OBB_tree_construct_moemory: " << mem2
     252                 :            :               << ", intersection_memory: " << mem3
     253                 :            :               << ", set_info_memory: " << mem4
     254                 :            :               << std::endl;
     255                 :            :   }
     256                 :          1 : }
     257                 :            : 
     258                 :          1 : void EBMesher::set_num_interval(int* n_interval)
     259                 :            : {
     260         [ +  + ]:          4 :   for (int i = 0; i < 3; i++) {
     261                 :          3 :     m_nDiv[i] = n_interval[i];
     262                 :            :   }
     263                 :          1 : }
     264                 :            : 
     265                 :          1 : void EBMesher::set_tree_root(ModelEnt* me)
     266                 :            : {
     267                 :            :   moab::ErrorCode rval;
     268         [ +  - ]:          1 :   if (m_bUseGeom) {
     269         [ +  - ]:          1 :     if (m_hObbTree == NULL) {
     270                 :          1 :       m_hObbTree = m_GeomTopoTool->obb_tree();
     271                 :            :     }
     272         [ +  - ]:          1 :     if (m_bUseWholeGeom) {
     273         [ +  - ]:          1 :       if (!m_bUseMeshGeom) m_hTreeRoot = m_GeomTopoTool->get_one_vol_root();
     274                 :            :     }
     275                 :            :     else {
     276                 :          0 :       rval = m_GeomTopoTool->get_root(me->mesh_handle(), m_hTreeRoot);
     277 [ #  # ][ #  # ]:          1 :       MBERRCHK(rval, mk_core()->moab_instance());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     278                 :            :     }
     279                 :            :   }
     280                 :            :   else { // facet data input case
     281                 :            :     moab::EntityHandle meshset;
     282         [ #  # ]:          0 :     if (m_bUseWholeGeom) meshset = 0;
     283         [ #  # ]:          0 :     else meshset = me->mesh_handle();
     284                 :            : 
     285                 :            :     // get triangles
     286         [ #  # ]:          0 :     moab::Range tris;
     287 [ #  # ][ #  # ]:          0 :     rval = moab_instance()->get_entities_by_dimension(meshset, 2, tris);
     288 [ #  # ][ #  # ]:          0 :     MBERRCHK(rval, mk_core()->moab_instance());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     289                 :            :     
     290                 :            :     // make tree
     291         [ #  # ]:          0 :     if (m_hObbTree == NULL) {
     292 [ #  # ][ #  # ]:          0 :       m_hObbTree = new moab::OrientedBoxTreeTool( moab_instance() );
                 [ #  # ]
     293                 :            :     }
     294         [ #  # ]:          0 :     rval = m_hObbTree->build(tris, m_hTreeRoot);
     295 [ #  # ][ #  # ]:          0 :     MBERRCHK(rval, mk_core()->moab_instance());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     296                 :            :   }
     297                 :          1 : }
     298                 :            : 
     299                 :          1 : void EBMesher::find_intersections()
     300                 :            : {
     301                 :          1 :   std::cout << "starting to find intersections." << std::endl;
     302                 :            :   int i;
     303                 :            :   //m_vnHexStatus.resize(m_nHex, 1); // initialize all hex as outside
     304         [ +  - ]:          1 :   m_vnHexStatus.resize(m_nHex, 0); // initialize all hex as inside
     305                 :            : 
     306                 :            :   // fire rays to 3 directions
     307         [ +  + ]:          4 :   for (i = 0; i < 3; i++) {
     308                 :            :     //m_vnEdgeStatus[i].resize(m_nDiv[i]*m_nDiv[(i + 1)%3]*m_nDiv[(i + 2)%3], OUTSIDE);
     309         [ +  - ]:          3 :     m_vnEdgeStatus[i].resize(m_nDiv[i]*m_nDiv[(i + 1)%3]*m_nDiv[(i + 2)%3], INSIDE);
     310                 :          3 :     fire_rays(i);
     311                 :            :   }
     312                 :          1 :   std::cout << "finished to find intersections." << std::endl;
     313                 :          1 : }
     314                 :            : 
     315                 :          1 : void EBMesher::export_mesh(const char* file_name, bool separate)
     316                 :            : { 
     317                 :            :   // get all hexes
     318                 :            :   time_t time1, time2, time3;
     319                 :          1 :   time(&time1);
     320                 :            :   int i;
     321                 :            :   iBase_ErrorType err;
     322         [ +  - ]:          1 :   std::vector<iBase_EntityHandle> hex_handles;
     323                 :            :   err = mk_core()->imesh_instance()->getEntities(m_hRootSet, iBase_REGION,
     324 [ +  - ][ +  - ]:          1 :                                                  iMesh_HEXAHEDRON, hex_handles);
                 [ +  - ]
     325         [ +  - ]:          1 :   IBERRCHK(err, "Failed to get hexes.\n");
     326                 :            :   /*
     327                 :            :   int hex_size = hex_handles.size();
     328                 :            :   int* hex_status = new int[hex_size];
     329                 :            :   int* hex_status = NULL;
     330                 :            :   std::vector<int> hex_status(hex_size);
     331                 :            :   err = mk_core()->imesh_instance()->getIntArrData(&hex_handles[0], hex_size,
     332                 :            :   m_elemStatusTag, &hex_status[0]);*/
     333                 :            : 
     334                 :            :   int error;
     335                 :          1 :   int hex_size = hex_handles.size();
     336 [ +  - ][ +  - ]:          1 :   int* hex_status = new int[hex_size];
     337                 :          1 :   int hex_status_alloc = sizeof(int)*hex_size;
     338                 :          1 :   int hex_status_size = 0;
     339         [ +  - ]:          1 :   iMesh_getIntArrData(m_mesh, &hex_handles[0],
     340                 :            :                       hex_size, m_elemStatusTag,
     341                 :            :                       &hex_status, &hex_status_alloc,
     342         [ +  - ]:          1 :                       &hex_status_size, &error);
     343         [ +  - ]:          1 :   IBERRCHK(error, "Failed to get hex status.\n");
     344                 :          1 :   time(&time2);
     345                 :            : 
     346         [ -  + ]:          1 :   if (separate) {
     347                 :          0 :     int n_inside_hex = 0;
     348                 :          0 :     int n_outside_hex = 0;
     349                 :          0 :     int n_boundary_hex = 0;
     350                 :            :     int hex_stat;
     351                 :            :     (void) hex_stat;
     352 [ #  # ][ #  # ]:          0 :     std::vector<iBase_EntityHandle> insideHex, outsideHex, bndrHex;
                 [ #  # ]
     353         [ #  # ]:          0 :     for (i = 0; i < hex_size; i++) {
     354         [ #  # ]:          0 :       if (hex_status[i] == 0) {
     355                 :          0 :         n_inside_hex++;
     356                 :          0 :         hex_stat = 0;
     357 [ #  # ][ #  # ]:          0 :         insideHex.push_back(hex_handles[i]);
     358                 :            :       }
     359         [ #  # ]:          0 :       else if (hex_status[i] == 1) {
     360                 :          0 :         n_outside_hex++;
     361                 :          0 :         hex_stat = 1;
     362 [ #  # ][ #  # ]:          0 :         outsideHex.push_back(hex_handles[i]);
     363                 :            :       }
     364         [ #  # ]:          0 :       else if (hex_status[i] == 2) {
     365                 :          0 :         n_boundary_hex++;
     366                 :          0 :         hex_stat = 2;
     367 [ #  # ][ #  # ]:          0 :         bndrHex.push_back(hex_handles[i]);
     368                 :            :       }
     369                 :            :       else {
     370         [ #  # ]:          0 :         throw Error(MK_FAILURE, "Hex element status should be inside/outside/boundary.");
     371                 :            :       }
     372                 :            :     }
     373                 :            :     
     374 [ #  # ][ #  # ]:          0 :     std::cout << "# of exported inside hex:" << n_inside_hex
     375 [ #  # ][ #  # ]:          0 :               << ", # of exported outside hex:" << n_outside_hex
     376 [ #  # ][ #  # ]:          0 :               << ", # of exported boundary hex:" << n_boundary_hex
     377         [ #  # ]:          0 :               << ", geom vol:"
     378         [ #  # ]:          0 :               << n_inside_hex*m_dIntervalSize[0]*m_dIntervalSize[1]*m_dIntervalSize[2]
     379 [ #  # ][ #  # ]:          0 :               << ", vox vol:" << hex_size*m_dIntervalSize[0]*m_dIntervalSize[1]*m_dIntervalSize[2]
     380         [ #  # ]:          0 :               << std::endl;
     381                 :          0 :     time(&time3);
     382                 :            : 
     383                 :            :     // save inside/outside/boundary elements separately
     384         [ #  # ]:          0 :     if (n_inside_hex > 0) {
     385 [ #  # ][ #  # ]:          0 :       write_mesh(file_name, 0, &insideHex[0], n_inside_hex);
     386                 :            :     }
     387         [ #  # ]:          0 :     if (n_boundary_hex > 0) {
     388 [ #  # ][ #  # ]:          0 :       write_mesh(file_name, 2, &bndrHex[0], n_boundary_hex);
     389                 :            :     }
     390         [ #  # ]:          0 :     if (n_outside_hex > 0) {
     391 [ #  # ][ #  # ]:          0 :       write_mesh(file_name, 1, &outsideHex[0], n_outside_hex);
     392                 :            :     }
     393                 :            : 
     394                 :            :     if (debug_ebmesh) {
     395                 :            :       std::cout << "hex_handle_get_time: "
     396                 :            :                 << difftime(time2, time1)
     397                 :            :                 << ", separate_write_time: "
     398                 :            :                 << difftime(time3, time2)
     399                 :            :                 << std::endl;
     400                 :          0 :     }
     401                 :            :   }
     402                 :            :   else {
     403 [ +  - ][ +  - ]:          1 :     write_mesh(file_name, 3, &hex_handles[0], hex_size);
     404                 :          1 :     time3 = clock();
     405                 :            :     if (debug_ebmesh) {
     406                 :            :       std::cout << "hex_handle_get_time: "
     407                 :            :                 << difftime(time2, time1)
     408                 :            :                 << ", actual_write_time: "
     409                 :            :                 << difftime(time3, time2)
     410                 :            :                 << std::endl;
     411                 :            :     }
     412                 :            :   }
     413         [ +  - ]:          1 :   delete [] hex_status;
     414                 :          1 : }
     415                 :            : 
     416                 :          1 : void EBMesher::write_mesh(const char* file_name, int type,
     417                 :            :                           iBase_EntityHandle* handles, int& n_elem)
     418                 :            : {
     419                 :            :   time_t time1, time2, time3;
     420                 :          1 :   time(&time1);
     421                 :          1 :   int is_list = 1;
     422                 :            :   moab::ErrorCode rval;
     423                 :            :   iBase_EntitySetHandle set;
     424                 :            :   iBase_ErrorType err;
     425                 :            : 
     426 [ +  - ][ +  - ]:          1 :   err = mk_core()->imesh_instance()->createEntSet(is_list, set);
                 [ +  - ]
     427         [ +  - ]:          1 :   IBERRCHK(err, "Couldn't create set.");
     428                 :            : 
     429 [ +  - ][ +  - ]:          1 :   err = mk_core()->imesh_instance()->addEntArrToSet(handles, n_elem, set);
                 [ +  - ]
     430         [ +  - ]:          1 :   IBERRCHK(err, "Couldn't add hexes to set.");
     431                 :          1 :   time(&time2);
     432                 :            : 
     433         [ +  - ]:          1 :   std::string out_name;
     434 [ +  - ][ +  - ]:          2 :   std::stringstream ss;
     435 [ -  + ][ #  # ]:          1 :   if (type == 0) ss << "inside_";
     436 [ -  + ][ #  # ]:          1 :   else if (type == 1) ss << "outside_";
     437 [ -  + ][ #  # ]:          1 :   else if (type == 2) ss << "boundary_";
     438         [ +  - ]:          1 :   ss << file_name;
     439         [ +  - ]:          1 :   ss >> out_name;
     440                 :            :   
     441         [ +  - ]:          1 :   rval = moab_instance()->write_mesh(out_name.c_str(),
     442         [ +  - ]:          1 :                                      (const moab::EntityHandle*) &set, 1);
     443 [ -  + ][ #  # ]:          1 :   MBERRCHK(rval, mk_core()->moab_instance());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     444                 :            :   
     445 [ +  - ][ +  - ]:          1 :   std::cout << "Elements are exported." << std::endl;
     446                 :          1 :   time(&time3);
     447                 :            : 
     448                 :            :   if (debug_ebmesh) {
     449                 :            :     std::cout << "set_creation_time: "
     450                 :            :               << difftime(time2, time1)
     451                 :            :               << ", write_time: "
     452                 :            :               << difftime(time3, time2)
     453                 :            :               << std::endl;
     454                 :          1 :   }
     455                 :          1 : }
     456                 :            : 
     457                 :        573 : EdgeStatus EBMesher::get_edge_status(const double dP, int& iSkip)
     458                 :            : {
     459         [ +  + ]:        573 :   if (m_nStatus == INSIDE) { // previous inside
     460         [ -  + ]:        207 :     if (dP < m_dSecondP) {
     461                 :          0 :       m_nMove = 0;
     462                 :          0 :       iSkip = m_iSecondP;
     463                 :          0 :       return INSIDE;
     464                 :            :     }
     465                 :            :     else {
     466         [ -  + ]:        207 :       if (is_shared_overlapped_surf(m_iInter - 1)) m_nMove = 1;
     467                 :        207 :       else m_nMove = 2;
     468                 :            :         
     469                 :            :       // skip shared and overlapped interesections
     470         [ -  + ]:        414 :       while (m_vIntersection[m_iInter].distance -
     471   [ +  +  -  + ]:        300 :              m_vIntersection[m_iInter - 1].distance < 1e-7 &&
     472                 :         93 :              (unsigned int) (m_iInter + 1) < m_vIntersection.size()) m_iInter++;        
     473                 :            :       
     474                 :        207 :       return BOUNDARY;
     475                 :            :     }
     476                 :            :   }
     477         [ +  + ]:        366 :   else if (m_nStatus == OUTSIDE) { // previous outside
     478         [ -  + ]:        159 :     if (dP < m_dFirstP) {
     479                 :          0 :       m_nMove = 0;
     480                 :          0 :       return OUTSIDE;
     481                 :            :     }
     482                 :            :     else {
     483         [ +  - ]:        159 :       if (dP < m_dSecondP) m_nMove = 0;
     484         [ #  # ]:          0 :       else if (is_shared_overlapped_surf(m_iInter - 1)) m_nMove = 1;
     485                 :          0 :       else m_nMove = 2;
     486                 :            : 
     487                 :            :       // skip shared and overlapped interesections
     488         [ -  + ]:        318 :       while (m_vIntersection[m_iInter].distance -
     489   [ +  +  -  + ]:        218 :              m_vIntersection[m_iInter - 1].distance < 1e-7 &&
     490                 :         59 :              (unsigned int) (m_iInter + 1) < m_vIntersection.size()) m_iInter++;
     491                 :            : 
     492                 :        159 :       return BOUNDARY;
     493                 :            :     }
     494                 :            :   }
     495         [ +  - ]:        207 :   else if (m_nStatus == BOUNDARY) { // previous boundary
     496         [ -  + ]:        207 :     if (dP < m_dFirstP) {
     497                 :          0 :       m_nMove = 0;
     498                 :          0 :       iSkip = m_iFirstP;
     499                 :          0 :       return OUTSIDE;
     500                 :            :     }
     501                 :            :     else {
     502         [ +  - ]:        207 :       if (dP < m_dSecondP) {
     503                 :        207 :         m_nMove = 0;
     504         [ -  + ]:        207 :         if (m_prevPnt < m_dFirstP) return BOUNDARY;
     505                 :            :         else {
     506                 :        207 :           iSkip = m_iSecondP;
     507                 :        207 :           return INSIDE;
     508                 :            :         }
     509                 :            :       }
     510                 :            :       else {
     511         [ #  # ]:          0 :         if (is_shared_overlapped_surf(m_iInter - 1)) m_nMove = 1;
     512                 :          0 :         else m_nMove = 2;
     513                 :            : 
     514                 :            :         // skip shared and overlapped interesections
     515         [ #  # ]:          0 :         while (m_vIntersection[m_iInter].distance -
     516   [ #  #  #  # ]:          0 :                m_vIntersection[m_iInter - 1].distance < 1e-7 &&
     517                 :          0 :                (unsigned int) (m_iInter + 1) < m_vIntersection.size()) m_iInter++;
     518                 :            : 
     519         [ #  # ]:          0 :         if (m_prevPnt < m_dSecondP) return BOUNDARY;
     520                 :          0 :         else return OUTSIDE;
     521                 :            :       }
     522                 :            :     }
     523                 :            :   }
     524                 :            :   else {
     525                 :          0 :     std::cerr << "Couldn't get edge status." << std::endl;
     526                 :          0 :     return INSIDE;
     527                 :            :   }
     528                 :            : }
     529                 :            : 
     530                 :       1413 : bool EBMesher::set_neighbor_hex_status(int dir, int i, int j, int k)
     531                 :            : {
     532                 :            :   int iElem;
     533                 :       1413 :   int otherDir1 = (dir + 1)%3;
     534                 :       1413 :   int otherDir2 = (dir + 2)%3;
     535                 :            : 
     536         [ +  + ]:       1413 :   if (dir == 0) { // x coordinate ray
     537                 :        471 :     m_iElem = j*m_nDiv[0]*m_nDiv[1] + i*m_nDiv[0] + k;
     538         [ -  + ]:        471 :     if (!set_hex_status(m_iElem, m_nStatus, dir)) return false;
     539                 :        471 :     iElem = m_iElem - m_nDiv[dir];
     540         [ -  + ]:        471 :     if (!set_hex_status(iElem, m_nStatus, dir)) return false;
     541                 :        471 :     iElem -= m_nDiv[dir]*m_nDiv[otherDir1];
     542         [ -  + ]:        471 :     if (!set_hex_status(iElem, m_nStatus, dir)) return false;
     543                 :        471 :     iElem += m_nDiv[dir];
     544         [ -  + ]:        471 :     if (!set_hex_status(iElem, m_nStatus, dir)) return false;
     545                 :            :   }
     546         [ +  + ]:        942 :   else if (dir == 1) { // y coordinate ray
     547                 :        471 :     m_iElem = i*m_nDiv[1]*m_nDiv[0] + k*m_nDiv[0] + j;
     548         [ -  + ]:        471 :     if (!set_hex_status(m_iElem, m_nStatus, dir)) return false;
     549                 :        471 :     iElem = m_iElem - 1;
     550         [ -  + ]:        471 :     if (!set_hex_status(iElem, m_nStatus, dir)) return false;
     551                 :        471 :     iElem -= m_nDiv[dir]*m_nDiv[otherDir2];
     552         [ -  + ]:        471 :     if (!set_hex_status(iElem++, m_nStatus, dir)) return false;
     553         [ -  + ]:        471 :     if (!set_hex_status(iElem, m_nStatus, dir)) return false;
     554                 :            :   }
     555         [ +  - ]:        471 :   else if (dir == 2) { // z coordinate ray
     556                 :        471 :     m_iElem = k*m_nDiv[0]*m_nDiv[1] + j*m_nDiv[0] + i;
     557         [ -  + ]:        471 :     if (!set_hex_status(m_iElem, m_nStatus, dir)) return false;
     558                 :        471 :     iElem = m_iElem - 1;
     559         [ -  + ]:        471 :     if (!set_hex_status(iElem, m_nStatus, dir)) return false;
     560                 :        471 :     iElem -= m_nDiv[otherDir1];
     561         [ -  + ]:        471 :     if (!set_hex_status(iElem++, m_nStatus, dir)) return false;
     562         [ -  + ]:        471 :     if (!set_hex_status(iElem, m_nStatus, dir)) return false;
     563                 :            :   }
     564                 :            : 
     565                 :       1413 :   return true;
     566                 :            : }
     567                 :            : 
     568                 :       5652 : bool EBMesher::set_hex_status(int index, EdgeStatus value, int dir)
     569                 :            : {
     570 [ +  - ][ -  + ]:       5652 :   if (index < 0 || index > m_nHex - 1) {
     571                 :          0 :     return false;
     572                 :            :   }
     573                 :            : 
     574         [ +  + ]:       5652 :   if (m_vnHexStatus[index] != 2) {
     575         [ +  + ]:       3249 :     if (value == INSIDE) {
     576                 :        457 :       m_vnHexStatus[index] = 0;
     577                 :            :     }
     578         [ +  + ]:       2792 :     else if (value == OUTSIDE) {
     579                 :       2400 :       m_vnHexStatus[index] = 1;
     580                 :            :     }
     581         [ +  - ]:        392 :     else if (value == BOUNDARY) {
     582                 :        392 :       m_vnHexStatus[index] = 2;
     583                 :            :     }
     584                 :            :   }
     585                 :            : 
     586                 :       5652 :   return true;
     587                 :            : }
     588                 :            : 
     589                 :        366 : bool EBMesher::set_edge_status(int dir)
     590                 :            : {
     591                 :            :   // set boundary cut information to edge
     592         [ +  - ]:        366 :   std::vector<double> vdCutFraction;
     593 [ +  + ][ +  - ]:        366 :   if (m_nMove == 0) vdCutFraction.push_back((m_curPnt - m_dFirstP)/m_dIntervalSize[dir] - 1.);
     594 [ +  - ][ +  - ]:        207 :   else if (m_nMove == 1) vdCutFraction.push_back(1. - (m_curPnt - m_dSecondP)/m_dIntervalSize[dir]);
     595         [ #  # ]:          0 :   else if (m_nMove == 2) {
     596         [ #  # ]:          0 :     vdCutFraction.push_back(1. - (m_curPnt - m_dSecondP)/m_dIntervalSize[dir]);
     597         [ #  # ]:          0 :     if (m_dFirstP < m_curPnt) {
     598         [ #  # ]:          0 :       vdCutFraction.push_back((m_curPnt - m_dFirstP)/m_dIntervalSize[dir] - 1.);
     599                 :            :     }
     600                 :            :   }
     601                 :            : 
     602         [ +  - ]:        366 :   std::map<int, CutFraction>::iterator iter = m_mdCutFraction.find(m_iElem);
     603 [ +  - ][ +  + ]:        366 :   if (iter == m_mdCutFraction.end()) { // not exist
     604         [ +  - ]:        268 :     CutFraction cFraction(dir, vdCutFraction);
     605 [ +  - ][ +  - ]:        268 :     m_mdCutFraction[m_iElem] = cFraction;
     606                 :            :   }
     607                 :            :   else { // exist
     608 [ +  - ][ +  - ]:         98 :     iter->second.add(dir, vdCutFraction);
     609                 :            :   }
     610                 :            : 
     611                 :            :   //m_nFraction += vdCutFraction.size();
     612                 :            : 
     613                 :        366 :   return true;
     614                 :            : }
     615                 :            : 
     616                 :          0 : void EBMesher::set_division()
     617                 :            : {
     618                 :            :   int i, j;
     619 [ #  # ][ #  # ]:          0 :   moab::CartVect box_center, box_axis1, box_axis2, box_axis3,
         [ #  # ][ #  # ]
     620         [ #  # ]:          0 :     min_cart_box(HUGE_VAL, HUGE_VAL, HUGE_VAL),
     621         [ #  # ]:          0 :     max_cart_box(0., 0., 0.);
     622                 :            :   
     623                 :            :   moab::ErrorCode rval = m_hObbTree->box(m_hTreeRoot, box_center.array(),
     624                 :            :                                      box_axis1.array(), box_axis2.array(),
     625 [ #  # ][ #  # ]:          0 :                                      box_axis3.array());
         [ #  # ][ #  # ]
                 [ #  # ]
     626 [ #  # ][ #  # ]:          0 :   MBERRCHK(rval, mk_core()->moab_instance());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     627                 :            : 
     628                 :            :   // cartesian box corners
     629 [ #  # ][ #  # ]:          0 :   moab::CartVect corners[8] = {box_center + box_axis1 + box_axis2 + box_axis3,
     630 [ #  # ][ #  # ]:          0 :                                box_center + box_axis1 + box_axis2 - box_axis3,
     631 [ #  # ][ #  # ]:          0 :                                box_center + box_axis1 - box_axis2 + box_axis3,
     632 [ #  # ][ #  # ]:          0 :                                box_center + box_axis1 - box_axis2 - box_axis3,
     633 [ #  # ][ #  # ]:          0 :                                box_center - box_axis1 + box_axis2 + box_axis3,
     634 [ #  # ][ #  # ]:          0 :                                box_center - box_axis1 + box_axis2 - box_axis3,
     635 [ #  # ][ #  # ]:          0 :                                box_center - box_axis1 - box_axis2 + box_axis3,
     636 [ #  # ][ #  # ]:          0 :                                box_center - box_axis1 - box_axis2 - box_axis3};
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     637                 :            : 
     638                 :            :   // get the max, min cartesian box corners
     639         [ #  # ]:          0 :   for (i = 0; i < 8; i++) {
     640         [ #  # ]:          0 :     for (j = 0; j < 3; j++) {
     641 [ #  # ][ #  # ]:          0 :       if (corners[i][j] < min_cart_box[j]) min_cart_box[j] = corners[i][j];
         [ #  # ][ #  # ]
                 [ #  # ]
     642 [ #  # ][ #  # ]:          0 :       if (corners[i][j] > max_cart_box[j]) max_cart_box[j] = corners[i][j];
         [ #  # ][ #  # ]
                 [ #  # ]
     643                 :            :     }
     644                 :            :   }
     645         [ #  # ]:          0 :   moab::CartVect length = max_cart_box - min_cart_box;
     646                 :            :   
     647                 :            :   // default value is adjusted to large geometry file
     648                 :            :   // interval_size_estimate : 2*L*sqrt(2*PI*sqrt(2)/# of tris)
     649         [ #  # ]:          0 :   if (m_dInputSize < 0.) {
     650                 :            :     int n_tri;
     651         [ #  # ]:          0 :     rval = moab_instance()->
     652                 :            :       get_number_entities_by_dimension(reinterpret_cast<moab::EntityHandle>(m_hRootSet),
     653         [ #  # ]:          0 :                                        2, n_tri);
     654 [ #  # ][ #  # ]:          0 :     MBERRCHK(rval, mk_core()->moab_instance());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     655                 :            :     
     656 [ #  # ][ #  # ]:          0 :     double box_length_ave = (length[0] + length[1] + length[2])/3.;
                 [ #  # ]
     657                 :          0 :     m_dInputSize = 2.*box_length_ave*sqrt(8.886/n_tri);
     658                 :            :   }
     659                 :            : 
     660         [ #  # ]:          0 :   for (i = 0; i < 3; i++) {
     661         [ #  # ]:          0 :     m_nDiv[i] = length[i]/m_dInputSize;
     662         [ #  # ]:          0 :     if (m_nDiv[i] < m_nAddLayer) m_nDiv[i] = m_nAddLayer; // make "m_nAddLayer" elements larger than bounding box
     663                 :          0 :     m_dIntervalSize[i] = m_dInputSize;
     664                 :            :     //if (m_nDiv[i]*.07 > m_nAddLayer) m_nDiv[i] += m_nDiv[i]*.07;
     665                 :            :     //else m_nDiv[i] += m_nAddLayer;
     666                 :          0 :     m_nDiv[i] += m_nAddLayer;
     667                 :          0 :     m_nNode[i] = m_nDiv[i] + 1;
     668         [ #  # ]:          0 :     m_origin_coords[i] = box_center[i] - .5*m_nDiv[i]*m_dIntervalSize[i];
     669                 :            :   }
     670                 :            : 
     671                 :          0 :   m_nHex = m_nDiv[0]*m_nDiv[1]*m_nDiv[2];
     672                 :            : 
     673 [ #  # ][ #  # ]:          0 :   std::cout << "# of hex: " << m_nHex << ", interval size: "
                 [ #  # ]
     674 [ #  # ][ #  # ]:          0 :             << m_dInputSize << std::endl;
     675                 :            : 
     676 [ #  # ][ #  # ]:          0 :   std::cout << "# of division: " << m_nDiv[0] << ","
                 [ #  # ]
     677 [ #  # ][ #  # ]:          0 :             << m_nDiv[1] << "," << m_nDiv[2] << std::endl;
         [ #  # ][ #  # ]
     678                 :          0 : }
     679                 :            : 
     680                 :          1 : int EBMesher::set_division(double* min, double* max)
     681                 :            : {
     682         [ +  + ]:          4 :   for (int i = 0; i < 3; i++) {
     683                 :          3 :     m_dIntervalSize[i] = (max[i] - min[i])/m_nDiv[i];
     684                 :          3 :     m_nNode[i] = m_nDiv[i] + 1;
     685                 :          3 :     m_origin_coords[i] = min[i];
     686                 :            :   }
     687                 :            : 
     688                 :          1 :   m_nHex = m_nDiv[0]*m_nDiv[1]*m_nDiv[2];
     689                 :            : 
     690                 :          1 :   std::cout << "# of hex: " << m_nHex << ", interval_size: "
     691                 :          1 :             << m_dIntervalSize[0] << ", " << m_dIntervalSize[1] << ", "
     692                 :          1 :             << m_dIntervalSize[2] << std::endl;
     693                 :            : 
     694                 :          1 :   std::cout << "# of division: " << m_nDiv[0] << ","
     695                 :          1 :             << m_nDiv[1] << "," << m_nDiv[2] << std::endl;
     696                 :            : 
     697                 :          1 :   return iBase_SUCCESS;
     698                 :            : }
     699                 :            : 
     700                 :          0 : int EBMesher::make_scd_hexes()
     701                 :            : {
     702                 :            :   // create vertex and hex sequences
     703                 :            :   int i;
     704                 :            :   double max_coords[3];
     705                 :            :   (void) max_coords;
     706         [ #  # ]:          0 :   for (i = 0; i < 3; i++) {
     707                 :          0 :     max_coords[i] = m_origin_coords[i] + m_nDiv[i]*m_dIntervalSize[i];
     708                 :            :   }
     709                 :            : 
     710         [ #  # ]:          0 :   moab::HomCoord coord_min(0, 0, 0);
     711         [ #  # ]:          0 :   moab::HomCoord coord_max(m_nDiv[0], m_nDiv[1], m_nDiv[2]);
     712                 :          0 :   moab::EntitySequence* vertex_seq = NULL;
     713                 :          0 :   moab::EntitySequence* cell_seq = NULL;
     714                 :            :   moab::EntityHandle vs, cs;
     715 [ #  # ][ #  # ]:          0 :   moab::Core *mbcore = dynamic_cast<moab::Core*>(moab_instance());
     716                 :            : 
     717         [ #  # ]:          0 :   moab::ErrorCode rval = mbcore->create_scd_sequence(coord_min, coord_max, moab::MBVERTEX, 1, vs, vertex_seq);
     718 [ #  # ][ #  # ]:          0 :   MBERRCHK(rval, mk_core()->moab_instance());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     719                 :            :   
     720         [ #  # ]:          0 :   mbcore->create_scd_sequence(coord_min, coord_max, moab::MBHEX, 1, cs, cell_seq);
     721 [ #  # ][ #  # ]:          0 :   MBERRCHK(rval, mk_core()->moab_instance());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     722                 :            : 
     723 [ #  # ][ #  # ]:          0 :   moab::HomCoord p2(coord_max.i(), coord_min.j(), coord_min.k());
         [ #  # ][ #  # ]
     724 [ #  # ][ #  # ]:          0 :   moab::HomCoord p3(coord_min.i(), coord_max.j(), coord_min.k()); 
         [ #  # ][ #  # ]
     725                 :            :   
     726                 :            :   rval = mbcore->add_vsequence(vertex_seq, cell_seq, coord_min, coord_min,
     727         [ #  # ]:          0 :                                         p2, p2, p3, p3);
     728 [ #  # ][ #  # ]:          0 :   MBERRCHK(rval, mk_core()->moab_instance());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     729                 :            : 
     730                 :          0 :   int nTotNode = m_nNode[0]*m_nNode[1]*m_nNode[2];
     731                 :            :   int ii, jj, kk;
     732                 :            :   moab::EntityHandle handle;
     733                 :            :   double dumv[3];
     734         [ #  # ]:          0 :   for (i = 0, handle = vs; i < nTotNode; i++, handle++) {
     735                 :          0 :     ii = (i%(m_nNode[0]*m_nNode[1]))%m_nNode[0];
     736                 :          0 :     jj = (i%(m_nNode[0]*m_nNode[1]))/m_nNode[0];
     737                 :          0 :     kk = i/m_nNode[0]/m_nNode[1];
     738                 :          0 :     dumv[0] = m_origin_coords[0] + ii*m_dIntervalSize[0];
     739                 :          0 :     dumv[1] = m_origin_coords[1] + jj*m_dIntervalSize[1];
     740                 :          0 :     dumv[2] = m_origin_coords[2] + kk*m_dIntervalSize[2];
     741 [ #  # ][ #  # ]:          0 :     rval = moab_instance()->set_coords(&handle, 1, dumv);
     742 [ #  # ][ #  # ]:          0 :     MBERRCHK(rval, mk_core()->moab_instance());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     743                 :            :   }
     744                 :            : 
     745 [ #  # ][ #  # ]:          0 :   m_iStartHex = moab_instance()->id_from_handle(cs);
     746                 :            : 
     747                 :          0 :   return iBase_SUCCESS;
     748                 :            : }
     749                 :            : 
     750                 :          4 : iBase_TagHandle EBMesher::get_tag(const char* name, int size,
     751                 :            :                                      unsigned store, moab::DataType type,
     752                 :            :                                      const void* def_value,
     753                 :            :                                      bool create_if_missing) 
     754                 :            : {
     755                 :          4 :   moab::Tag retval = 0;
     756                 :            :   /*moab::ErrorCode result = moab_instance()->tag_create(name, size, store, type,
     757                 :            :                                                    retval, def_value,
     758                 :            :                                                    create_if_missing);*/
     759                 :          4 :   store = store | moab::MB_TAG_CREAT;
     760         [ -  + ]:          4 :   if(!create_if_missing)
     761                 :          0 :     store = store | moab::MB_TAG_EXCL;
     762         [ +  - ]:          4 :   moab::ErrorCode result = moab_instance()->tag_get_handle(name, size, type, retval, store,
     763         [ +  - ]:          4 :                                                       def_value);
     764 [ +  - ][ -  + ]:          4 :   if (create_if_missing && moab::MB_SUCCESS != result) {
     765 [ #  # ][ #  # ]:          0 :     std::cerr << "Couldn't find nor create tag named " << name << std::endl;
                 [ #  # ]
     766                 :            :   }
     767                 :            :   
     768                 :          4 :   return (iBase_TagHandle) retval;
     769                 :            : }
     770                 :            : 
     771                 :          3 : iBase_TagHandle EBMesher::get_various_length_tag(const char* name,
     772                 :            :                                                     unsigned store, moab::DataType type)
     773                 :            : {
     774                 :          3 :   moab::Tag retval = 0;
     775                 :          3 :   store = store | moab::MB_TAG_VARLEN | moab::MB_TAG_CREAT;
     776         [ +  - ]:          3 :   moab::ErrorCode result = moab_instance()->
     777         [ +  - ]:          3 :     tag_get_handle( name, 1, type, retval, store);
     778         [ -  + ]:          3 :   if (moab::MB_SUCCESS != result) {
     779 [ #  # ][ #  # ]:          0 :     std::cerr << "Couldn't find nor create tag named " << name << std::endl;
                 [ #  # ]
     780                 :            :   }
     781                 :            :   
     782                 :          3 :   return (iBase_TagHandle) retval;
     783                 :            : }
     784                 :            : 
     785                 :          1 : void EBMesher::set_tag_info()
     786                 :            : {
     787                 :            :   // get all hexes
     788                 :            :   int i, j, k;
     789                 :            :   iBase_ErrorType err;
     790         [ +  - ]:          1 :   std::vector<iBase_EntityHandle> hex_handles;
     791                 :            :   err = mk_core()->imesh_instance()->getEntities(m_hRootSet, iBase_REGION,
     792 [ +  - ][ +  - ]:          1 :                                                  iMesh_HEXAHEDRON, hex_handles);
                 [ +  - ]
     793         [ +  - ]:          1 :   IBERRCHK(err, "Failed to get hexes.\n");
     794                 :            : 
     795 [ +  - ][ +  - ]:          1 :   err = mk_core()->imesh_instance()->setIntArrData(&hex_handles[0], m_nHex,
                 [ +  - ]
     796                 :            :                                                    m_elemStatusTag,
     797 [ +  - ][ +  - ]:          2 :                                                    &m_vnHexStatus[0]);
     798         [ +  - ]:          1 :   IBERRCHK(err, "Failed to set hex element status data.");
     799                 :            : 
     800                 :            :   // set cut fraction info to boundary hexes
     801                 :          1 :   int nBndrHex = m_mdCutFraction.size();
     802         [ +  - ]:          2 :   std::vector<iBase_EntityHandle> hvBndrHex(nBndrHex);
     803 [ +  - ][ +  - ]:          1 :   int* frac_size = new int[nBndrHex];
     804 [ +  - ][ +  - ]:          1 :   int* frac_leng = new int[3*nBndrHex];
     805                 :          1 :   int nFracSize, nTempSize, iHex, nTolFrac = 0;
     806                 :          1 :   int nDoubleSize = sizeof(double);
     807                 :          1 :   std::map<int, CutFraction>::iterator iter = m_mdCutFraction.begin();
     808                 :          1 :   std::map<int, CutFraction>::iterator end_iter = m_mdCutFraction.end();
     809 [ +  - ][ +  - ]:        269 :   for (i = 0; iter != end_iter; iter++, i++) {
                 [ +  + ]
     810         [ +  - ]:        268 :     iHex = iter->first;
     811 [ +  - ][ +  - ]:        268 :     hvBndrHex[i] = hex_handles[iHex];
     812                 :            : 
     813                 :        268 :     nFracSize = 0;
     814         [ +  + ]:       1072 :     for (j = 0; j < 3; j++) {
     815         [ +  - ]:        804 :       nTempSize = iter->second.fraction[j].size();
     816                 :        804 :       nFracSize += nTempSize;
     817                 :        804 :       frac_leng[3*i + j] = nTempSize;
     818                 :            :     }
     819                 :        268 :     frac_size[i] = nDoubleSize*nFracSize; // sizeof(double)*
     820                 :        268 :     nTolFrac += nFracSize;
     821                 :            :   }
     822                 :            : 
     823                 :          1 :   int iFrac = 0;
     824 [ +  - ][ +  - ]:          1 :   double* fractions = new double[nTolFrac];
     825         [ +  - ]:          2 :   std::vector<const void*> frac_data_pointer(nBndrHex);
     826                 :          1 :   iter = m_mdCutFraction.begin();
     827 [ +  - ][ +  - ]:        269 :   for (i = 0; iter != end_iter; iter++, i++) {
                 [ +  + ]
     828         [ +  + ]:       1072 :     for (j = 0; j < 3; j++) {
     829         [ +  - ]:        804 :       nFracSize = iter->second.fraction[j].size();
     830         [ +  - ]:        804 :       frac_data_pointer[i] = &fractions[iFrac];
     831         [ +  + ]:       1170 :       for (k = 0; k < nFracSize; k++) {
     832 [ +  - ][ +  - ]:        366 :         fractions[iFrac++] = iter->second.fraction[j][k];
     833                 :            :       }
     834                 :            :     }
     835                 :            :   }
     836                 :            : 
     837 [ +  - ][ +  - ]:          1 :   err = mk_core()->imesh_instance()->setIntArrData(&hvBndrHex[0], nBndrHex,
                 [ +  - ]
     838                 :            :                                                    m_edgeCutFracLengthTag,
     839         [ +  - ]:          1 :                                                    frac_leng);
     840         [ +  - ]:          1 :   IBERRCHK(err, "Failed to set cut fraction sizes to hex.");
     841                 :            : 
     842         [ +  - ]:          1 :   moab::ErrorCode rval = moab_instance()->tag_set_by_ptr(reinterpret_cast<moab::Tag> (m_edgeCutFracTag),
     843         [ +  - ]:          1 :                                                    reinterpret_cast<moab::EntityHandle*> (&hvBndrHex[0]),
     844 [ +  - ][ +  - ]:          2 :                                                    nBndrHex, &frac_data_pointer[0], frac_size);
     845 [ -  + ][ #  # ]:          1 :   MBERRCHK(rval, mk_core()->moab_instance());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     846                 :            :   
     847         [ +  - ]:          1 :   delete [] frac_size;
     848         [ +  - ]:          1 :   delete [] frac_leng;
     849         [ +  - ]:          2 :   delete [] fractions;
     850                 :          1 : }
     851                 :            : 
     852                 :          3 : void EBMesher::fire_rays(int dir)
     853                 :            : {
     854                 :            :   // ray fire
     855                 :            :   int i, j, k, l, index[3];
     856                 :          3 :   double tolerance = 1e-12;
     857                 :          3 :   double rayLength = m_nDiv[dir]*m_dIntervalSize[dir];
     858                 :            :   int iNodeStart, iNodeEnd, nIntersect, nNodeSlice;
     859                 :            :   double startPnt[3], endPnt[3];
     860                 :          3 :   int otherDir1 = (dir + 1)%3;
     861                 :          3 :   int otherDir2 = (dir + 2)%3;
     862                 :            :  // harmless as this expression (does nothing) so that a compiler sees it is used.
     863                 :            :   (void) iNodeEnd;
     864                 :            :   (void) nNodeSlice;
     865                 :            : 
     866         [ +  + ]:         30 :   for (j = 1; j < m_nNode[otherDir2] - 1; j++) {
     867         [ +  + ]:        270 :     for (i = 1; i < m_nNode[otherDir1] - 1; i++) {
     868                 :            : 
     869                 :            :       // get ray start and end points
     870         [ +  + ]:        243 :       if (dir == 0) { // x coordinate ray
     871                 :         81 :         iNodeStart = j*m_nNode[dir]*m_nNode[otherDir1] + i*m_nNode[dir];
     872                 :         81 :         iNodeEnd = iNodeStart + m_nNode[dir] - 1;
     873                 :         81 :         nNodeSlice = 1;
     874                 :         81 :         index[0] = 0;
     875                 :         81 :         index[1] = i;
     876                 :         81 :         index[2] = j;
     877                 :            :       }
     878         [ +  + ]:        162 :       else if (dir == 1) { // y coordinate ray
     879                 :         81 :         iNodeStart = i*m_nNode[otherDir2]*m_nNode[dir] + j;
     880                 :         81 :         iNodeEnd = iNodeStart + m_nNode[otherDir2]*(m_nNode[dir] - 1);
     881                 :         81 :         nNodeSlice = m_nNode[otherDir2];
     882                 :         81 :         index[0] = j;
     883                 :         81 :         index[1] = 0;
     884                 :         81 :         index[2] = i;
     885                 :            :       }
     886         [ +  - ]:         81 :       else if (dir == 2) { // z coordinate ray
     887                 :         81 :         iNodeStart = j*m_nNode[otherDir1] + i;
     888                 :         81 :         iNodeEnd = iNodeStart + m_nNode[otherDir1]*m_nNode[otherDir2]*(m_nNode[dir] - 1);
     889                 :         81 :         nNodeSlice = m_nNode[otherDir1]*m_nNode[otherDir2];
     890                 :         81 :         index[0] = i;
     891                 :         81 :         index[1] = j;
     892                 :         81 :         index[2] = 0;
     893                 :            :       }
     894         [ #  # ]:          0 :       else IBERRCHK(iBase_FAILURE, "Ray direction should be 0 to 2.");
     895                 :            :       
     896         [ +  + ]:        972 :       for (l = 0; l < 3; l++) {
     897         [ +  + ]:        729 :         if (l == dir) {
     898                 :        243 :           startPnt[l] = m_origin_coords[l];
     899                 :        243 :           endPnt[l] = m_origin_coords[l] + m_nDiv[dir]*m_dIntervalSize[l];
     900                 :            :         }
     901                 :            :         else {
     902                 :        486 :           startPnt[l] = m_origin_coords[l] + index[l]*m_dIntervalSize[l];
     903                 :        486 :           endPnt[l] = startPnt[l];
     904                 :            :         }
     905                 :            :       }
     906                 :            :       
     907                 :        243 :       k = 0;
     908                 :        243 :       m_iInter = 0;
     909 [ +  - ][ -  + ]:        243 :       if (!fire_ray(nIntersect, startPnt, endPnt, tolerance, dir, rayLength)) {
     910         [ #  # ]:          0 :         IBERRCHK(iBase_FAILURE, "Couldn't fire ray.");
     911                 :            :       }
     912                 :            :       
     913         [ +  + ]:        243 :       if (nIntersect > 0) {
     914         [ +  - ]:        207 :         m_iFirstP = m_vIntersection[m_iInter].distance/m_dIntervalSize[dir];
     915         [ +  - ]:        207 :         m_dFirstP = startPnt[dir] + m_vIntersection[m_iInter++].distance;
     916         [ +  - ]:        207 :         m_iSecondP = m_vIntersection[m_iInter].distance/m_dIntervalSize[dir];
     917         [ +  - ]:        207 :         m_dSecondP = startPnt[dir] + m_vIntersection[m_iInter++].distance;
     918                 :            : 
     919                 :            :         // set outside before the first hit
     920         [ +  + ]:        447 :         for (k = 0; k < m_iFirstP; k++) {
     921                 :        240 :           m_nStatus = OUTSIDE;
     922                 :            :           
     923 [ +  - ][ -  + ]:        240 :           if (!set_neighbor_hex_status(dir, i, j, k)) {
     924         [ #  # ]:          0 :             IBERRCHK(iBase_FAILURE, "Couldn't set neighbor hex status.");
     925                 :            :           }
     926                 :            :         }
     927                 :            :         
     928         [ +  - ]:        780 :         for (; k < m_nNode[dir] - 1;) {
     929                 :        573 :           int i_skip = 0;
     930                 :        573 :           m_curPnt = startPnt[dir] + (k + 1)*m_dIntervalSize[dir];
     931                 :        573 :           EdgeStatus preStat = m_nStatus;
     932         [ +  - ]:        573 :           m_nStatus = get_edge_status(m_curPnt, i_skip);
     933         [ +  - ]:        573 :           m_vnEdgeStatus[dir][i*m_nDiv[dir] + j*m_nDiv[dir]*m_nDiv[otherDir1] + k] = m_nStatus;
     934                 :            : 
     935                 :            :           // set status of all hexes sharing the edge
     936 [ +  - ][ -  + ]:        573 :           if (!set_neighbor_hex_status(dir, i, j, k)) {
     937         [ #  # ]:          0 :             IBERRCHK(iBase_FAILURE, "Couldn't set neighbor hex status.");
     938                 :            :           }
     939                 :            : 
     940         [ +  + ]:        573 :           if (m_nMove > 0) {
     941         [ -  + ]:        207 :             if (m_iInter < nIntersect) {
     942 [ #  # ][ #  # ]:          0 :               if (!move_intersections(dir, nIntersect, startPnt)) {
     943         [ #  # ]:          0 :                 IBERRCHK(iBase_FAILURE, "Couldn't move intersections.");
     944                 :            :               }
     945                 :            :             }
     946                 :            :             else {
     947                 :        207 :               m_nMove = 1;
     948 [ +  - ][ +  - ]:        207 :               if (m_nStatus == BOUNDARY && !set_edge_status(dir)) {
         [ -  + ][ -  + ]
     949         [ #  # ]:          0 :                 IBERRCHK(iBase_FAILURE, "Couldn't set edge status.");
     950                 :            :               }
     951                 :        207 :               k++;
     952                 :        207 :               break; // rest is all outside
     953                 :            :             }
     954                 :            :           }
     955 [ +  + ][ +  - ]:        366 :           else if (m_nStatus == BOUNDARY && !set_edge_status(dir)) {
         [ -  + ][ -  + ]
     956         [ #  # ]:          0 :             IBERRCHK(iBase_FAILURE, "Couldn't set edge status.");
     957                 :            :           }
     958 [ -  + ][ #  # ]:        366 :           else if (m_nStatus == OUTSIDE && preStat == BOUNDARY) { // set outside until next hit
     959                 :          0 :             k++;
     960         [ #  # ]:          0 :             for (; k < i_skip; k++) {
     961                 :          0 :               m_nStatus = OUTSIDE;
     962 [ #  # ][ #  # ]:          0 :               if (!set_neighbor_hex_status(dir, i, j, k)) {
     963         [ #  # ]:          0 :                 IBERRCHK(iBase_FAILURE, "Couldn't set neighbor hex status.");
     964                 :            :               }
     965                 :            :             }
     966                 :            :           }
     967                 :            : 
     968                 :            :           // set cut-cell edge status
     969         [ +  + ]:        366 :           if (i_skip > 0) {
     970                 :        207 :             m_prevPnt = startPnt[dir] + i_skip*m_dIntervalSize[dir];
     971                 :        207 :             k = i_skip;
     972                 :            :           }
     973                 :            :           else {
     974                 :        159 :             m_prevPnt = m_curPnt;
     975                 :        366 :             k++;
     976                 :            :           }
     977                 :            :         }
     978                 :            :       }
     979                 :            :         
     980                 :            :       // the rest are all outside
     981         [ +  + ]:        843 :       for (; k < m_nNode[dir] - 1; k++) {
     982                 :        600 :         m_nStatus = OUTSIDE;
     983 [ +  - ][ -  + ]:        600 :         if (!set_neighbor_hex_status(dir, i, j, k)) {
     984         [ #  # ]:          0 :           IBERRCHK(iBase_FAILURE, "Couldn't set neighbor hex status.");
     985                 :            :         }
     986                 :            :       }
     987                 :            :     }
     988                 :            :   }
     989                 :          3 : }
     990                 :            : 
     991                 :        243 : bool EBMesher::fire_ray(int& nIntersect, double startPnt[3],
     992                 :            :                       double endPnt[3], double tol, int dir,
     993                 :            :                       double rayLength)
     994                 :            : {
     995                 :        243 :   m_vIntersection.clear();
     996                 :        243 :   m_vhInterSurf.clear();
     997                 :        243 :   m_vhInterFacet.clear();
     998                 :        243 :   m_mhOverlappedSurf.clear();
     999         [ +  - ]:        243 :   std::vector<double> temp_intersects;
    1000                 :            :   moab::ErrorCode rVal;
    1001         [ +  - ]:        486 :   moab::OrientedBoxTreeTool::TrvStats stats;
    1002         [ +  - ]:        243 :   if (m_bUseGeom) { // geometry input
    1003                 :            :     rVal = m_hObbTree->ray_intersect_sets(temp_intersects, m_vhInterSurf,
    1004                 :            :                                           m_vhInterFacet, m_hTreeRoot, tol,
    1005                 :            :                                           startPnt, rayDir[dir], &rayLength,
    1006         [ +  - ]:        243 :                                           &stats);
    1007                 :            :   }
    1008                 :            :   else { // facet input
    1009         [ #  # ]:          0 :     std::vector<moab::EntityHandle> dum_facets_out;
    1010                 :            :     rVal = m_hObbTree->ray_intersect_triangles(temp_intersects, dum_facets_out,
    1011                 :            :                                                m_hTreeRoot, tol,
    1012                 :            :                                                startPnt, rayDir[dir], &rayLength,
    1013         [ #  # ]:          0 :                                                &stats);
    1014                 :            :   }
    1015                 :            :   
    1016                 :        243 :   nIntersect = temp_intersects.size();
    1017         [ -  + ]:        243 :   if (moab::MB_SUCCESS != rVal) {
    1018 [ #  # ][ #  # ]:          0 :     std::cerr << "Failed : ray-triangle intersection." << std::endl;
    1019                 :          0 :     return false;
    1020                 :            :   }
    1021                 :            :   
    1022         [ +  + ]:        243 :   if (nIntersect > 0) {
    1023         [ +  - ]:        207 :     m_vIntersection.resize(nIntersect);
    1024                 :            :     
    1025         [ +  + ]:        730 :     for (int l = 0; l < nIntersect; l++) {
    1026 [ +  - ][ +  - ]:        523 :       IntersectDist temp_inter_dist(temp_intersects[l], l);
    1027         [ +  - ]:        523 :       m_vIntersection[l] = temp_inter_dist;
    1028                 :            :     }
    1029         [ +  - ]:        207 :     std::sort(m_vIntersection.begin(), m_vIntersection.end(), less_intersect);
    1030                 :            : 
    1031         [ +  - ]:        207 :     if (nIntersect > 1) {
    1032                 :            :       bool bMoveOnce;
    1033                 :        207 :       m_nIteration = 0;
    1034                 :        207 :       m_iOverlap = 0;
    1035                 :            :       
    1036         [ +  - ]:        207 :       if (m_bUseGeom) { // if there are geometry info
    1037         [ +  - ]:        207 :         remove_intersection_duplicates();
    1038                 :            :       }
    1039 [ #  # ][ #  # ]:          0 :       else if (is_ray_move_and_set_overlap_surf(bMoveOnce)) { // facet geom case
    1040 [ #  # ][ #  # ]:          0 :         if (!move_ray(nIntersect, startPnt, endPnt, tol, dir, bMoveOnce)) {
    1041 [ #  # ][ #  # ]:          0 :           std::cerr << "Number of Intersection between edges and ray should be even." << std::endl;
    1042                 :          0 :           return false;
    1043                 :            :         }
    1044                 :            :       }
    1045                 :        207 :       nIntersect = m_vIntersection.size();
    1046                 :            :     }
    1047                 :            :   }
    1048                 :            :   
    1049                 :        486 :   return true;
    1050                 :            : }
    1051                 :            : 
    1052                 :          0 : bool EBMesher::move_intersections(int n_dir, int n_inter, double start_pnt[3])
    1053                 :            : {
    1054         [ #  # ]:          0 :   if (m_nMove > 0) {
    1055         [ #  # ]:          0 :     if (m_iInter < n_inter) {
    1056         [ #  # ]:          0 :       if (m_nMove == 1) {
    1057         [ #  # ]:          0 :         do {
    1058 [ #  # ][ #  # ]:          0 :           if (m_nStatus == BOUNDARY && !set_edge_status(n_dir)) return false;
                 [ #  # ]
    1059                 :          0 :           m_iFirstP = m_iSecondP;
    1060                 :          0 :           m_dFirstP = m_dSecondP;
    1061                 :          0 :           m_iSecondP = m_vIntersection[m_iInter].distance/m_dIntervalSize[n_dir];
    1062                 :          0 :           m_dSecondP = start_pnt[n_dir] + m_vIntersection[m_iInter++].distance;
    1063                 :            :         }
    1064         [ #  # ]:          0 :         while (m_dSecondP < m_curPnt && m_iInter < n_inter);
    1065                 :            :       }
    1066         [ #  # ]:          0 :       else if (m_nMove == 2) {
    1067         [ #  # ]:          0 :         do {
    1068                 :          0 :           m_iFirstP = m_vIntersection[m_iInter].distance/m_dIntervalSize[n_dir];
    1069                 :          0 :           m_dFirstP = start_pnt[n_dir] + m_vIntersection[m_iInter++].distance;
    1070 [ #  # ][ #  # ]:          0 :           if (m_nStatus == BOUNDARY && !set_edge_status(n_dir)) return false;
                 [ #  # ]
    1071         [ #  # ]:          0 :           if (m_iInter < n_inter) {
    1072                 :          0 :             m_iSecondP = m_vIntersection[m_iInter].distance/m_dIntervalSize[n_dir];
    1073                 :          0 :             m_dSecondP = start_pnt[n_dir] + m_vIntersection[m_iInter++].distance;
    1074                 :            :           }
    1075                 :            :           else {
    1076                 :          0 :             m_iSecondP = m_iFirstP;
    1077                 :          0 :             m_dSecondP = m_dFirstP;
    1078                 :            :           }
    1079                 :            :         }
    1080         [ #  # ]:          0 :         while (m_dSecondP < m_curPnt && m_iInter < n_inter);
    1081                 :            :       }
    1082                 :            :     }
    1083                 :            :   }
    1084                 :            : 
    1085                 :          0 :   return true;
    1086                 :            : }
    1087                 :            : 
    1088                 :        207 : bool EBMesher::is_shared_overlapped_surf(int index)
    1089                 :            : {
    1090                 :            :   int nParent;
    1091                 :            :   iBase_ErrorType err;
    1092                 :            :   moab::EntityHandle hSurf;
    1093         [ +  - ]:        207 :   if (m_bUseGeom) {
    1094 [ +  - ][ +  - ]:        207 :     hSurf = m_vhInterSurf[m_vIntersection[index].index];
    1095 [ +  - ][ +  - ]:        207 :     err = mk_core()->imesh_instance()->getNumPrnt(reinterpret_cast<iBase_EntitySetHandle> (hSurf),
    1096         [ +  - ]:        207 :                                                   1, nParent);
    1097         [ +  - ]:        207 :     IBERRCHK(err, "Failed to get number of surface parents.\n");
    1098                 :            : 
    1099         [ -  + ]:        207 :     if (nParent > 1) return true;
    1100                 :            :   }
    1101         [ #  # ]:          0 :   else hSurf = m_vIntersection[index].index;
    1102                 :            : 
    1103         [ +  - ]:        207 :   return m_mhOverlappedSurf.count(hSurf) > 0;
    1104                 :            : }
    1105                 :            : 
    1106                 :          1 : void EBMesher::get_grid_and_edges_techX(double* boxMin, double* boxMax, int* nDiv,
    1107                 :            :                                       std::map< CutCellSurfEdgeKey, std::vector<double>, LessThan >& rmdCutCellSurfEdge,
    1108                 :            :                                       std::vector<int>& rvnInsideCell, bool isCornerExterior)
    1109                 :            : {
    1110                 :            :   int i, j, err, ii, jj, kk, iHex;
    1111         [ +  + ]:          4 :   for (i = 0; i < 3; i++) {
    1112                 :          3 :     boxMin[i] = m_origin_coords[i];
    1113                 :          3 :     boxMax[i] = m_origin_coords[i] + m_dIntervalSize[i]*m_nDiv[i];
    1114                 :          3 :     nDiv[i] = m_nDiv[i];
    1115                 :            :   }
    1116                 :            :   
    1117                 :            :   // get all hexes
    1118         [ +  - ]:          1 :   std::vector<iBase_EntityHandle> hex_handles;
    1119                 :            :   err = mk_core()->imesh_instance()->getEntities(m_hRootSet, iBase_REGION,
    1120 [ +  - ][ +  - ]:          1 :                                                  iMesh_HEXAHEDRON, hex_handles);
                 [ +  - ]
    1121         [ +  - ]:          1 :   IBERRCHK(err, "Failed to get hexes.\n");
    1122                 :            :   
    1123                 :            :   // get hex status
    1124                 :          1 :   int hex_size = hex_handles.size();
    1125                 :            :   /*
    1126                 :            :   //int* hex_status = new int[hex_size];
    1127                 :            :   //int* hex_status;
    1128                 :            :   //std::vector<int> hex_status(hex_size);
    1129                 :            :   int temp = 0;
    1130                 :            :   int* hex_status = &temp;
    1131                 :            :   err = mk_core()->imesh_instance()->getIntArrData(&hex_handles[0], hex_size,
    1132                 :            :                                                    m_elemStatusTag, hex_status);
    1133                 :            :   */
    1134                 :            :   int error;
    1135 [ +  - ][ +  - ]:          1 :   int* hex_status = new int[hex_size];
    1136                 :          1 :   int hex_status_alloc = sizeof(int)*hex_size;
    1137                 :          1 :   int hex_status_size = 0;
    1138         [ +  - ]:          1 :   iMesh_getIntArrData(m_mesh, &hex_handles[0],
    1139                 :            :                       hex_size, m_elemStatusTag,
    1140                 :            :                       &hex_status, &hex_status_alloc,
    1141         [ +  - ]:          1 :                       &hex_status_size, &error);
    1142         [ +  - ]:          1 :   IBERRCHK(error, "Failed to get hex status.");
    1143                 :            : 
    1144                 :            :   // get inside and boundary hexes
    1145                 :          1 :   int nInside = 0;
    1146                 :          1 :   int nOutside = 0;
    1147                 :          1 :   int nBoundary = 0;
    1148                 :          1 :   rvnInsideCell.clear();
    1149         [ +  + ]:       1001 :   for (i = 0; i < hex_size; i++) {
    1150         [ +  + ]:       1000 :     if (hex_status[i] == 0) { // if inside
    1151         [ +  - ]:        304 :       iHex = moab_instance()->id_from_handle(reinterpret_cast<moab::EntityHandle>
    1152 [ +  - ][ +  - ]:        304 :                                              (hex_handles[i])) - m_iStartHex;
    1153         [ +  - ]:        304 :       rvnInsideCell.push_back((iHex%(m_nDiv[0]*m_nDiv[1]))%m_nDiv[0]);
    1154         [ +  - ]:        304 :       rvnInsideCell.push_back((iHex%(m_nDiv[0]*m_nDiv[1]))/m_nDiv[0]);
    1155         [ +  - ]:        304 :       rvnInsideCell.push_back(iHex/m_nDiv[0]/m_nDiv[1]);
    1156                 :        304 :       nInside++;
    1157                 :            :     }
    1158         [ +  + ]:        696 :     else if (hex_status[i] == 1) nOutside++;
    1159         [ +  - ]:        392 :     else if (hex_status[i] == 2) nBoundary++;
    1160         [ #  # ]:          0 :     else IBERRCHK(err, "Element status should be one of inside/outside/boundary."); 
    1161                 :            :   }
    1162 [ +  - ][ +  - ]:          1 :   std::cout << "# of inside, outside, boundary elem: " << nInside
    1163 [ +  - ][ +  - ]:          1 :             << ", " << nOutside << ", " << nBoundary << std::endl;
         [ +  - ][ +  - ]
                 [ +  - ]
    1164         [ +  - ]:          1 :   delete [] hex_status;
    1165                 :            : 
    1166                 :            :   // get cut-cell fractions
    1167                 :            :   double dFrac[4];
    1168                 :          1 :   std::map<int, CutFraction>::iterator iter = m_mdCutFraction.begin();
    1169                 :          1 :   std::map<int, CutFraction>::iterator end_iter = m_mdCutFraction.end();
    1170                 :            :   
    1171 [ +  - ][ +  - ]:        269 :   for (; iter != end_iter; iter++) { // for each cut-cell
                 [ +  + ]
    1172                 :            :     // get i, j, k index from handle
    1173         [ +  - ]:        268 :     iHex = iter->first;
    1174                 :        268 :     ii = (iHex%(m_nDiv[0]*m_nDiv[1]))%m_nDiv[0];
    1175                 :        268 :     jj = (iHex%(m_nDiv[0]*m_nDiv[1]))/m_nDiv[0];
    1176                 :        268 :     kk = iHex/m_nDiv[0]/m_nDiv[1];
    1177                 :            : 
    1178                 :            :     // surface 1
    1179 [ +  - ][ +  - ]:        268 :     CutFraction cutFrac = iter->second;
    1180         [ +  + ]:        268 :     if (cutFrac.fraction[1].size() > 0) {
    1181         [ +  - ]:        122 :       dFrac[0] = cutFrac.fraction[1][0];
    1182         [ +  + ]:        122 :       if (dFrac[0] < 0.) dFrac[0] *= -1.;
    1183                 :            :     }
    1184                 :        146 :     else dFrac[0] = -1.;
    1185         [ +  + ]:        268 :     if (cutFrac.fraction[2].size() > 0) {
    1186         [ +  - ]:        122 :       dFrac[3] = cutFrac.fraction[2][0];
    1187         [ +  + ]:        122 :       if (dFrac[3] < 0.) dFrac[3] *= -1.;
    1188                 :            :     }
    1189                 :        146 :     else dFrac[3] = -1.;
    1190         [ +  - ]:        268 :     dFrac[1] = get_edge_fraction(iHex + m_nDiv[0], 2);
    1191         [ +  - ]:        268 :     dFrac[2] = get_edge_fraction(iHex + m_nDiv[0]*m_nDiv[1], 1);
    1192                 :            :     
    1193 [ +  + ][ +  + ]:        268 :     if (dFrac[0] > 0. || dFrac[1] > 0. || dFrac[2] > 0. || dFrac[3] > 0.) { // if surface is cut
         [ +  + ][ +  + ]
    1194         [ +  - ]:        211 :       CutCellSurfEdgeKey surfKey(ii, jj, kk, 0);
    1195         [ +  - ]:        211 :       std::vector<double> edges;
    1196 [ +  + ][ +  - ]:        211 :       if (dFrac[0] < 0.) dFrac[0] = get_uncut_edge_fraction(ii, jj, kk, 1);
    1197 [ +  + ][ +  - ]:        211 :       if (dFrac[1] < 0.) dFrac[1] = get_uncut_edge_fraction(ii, jj + 1, kk, 2);
    1198 [ +  + ][ +  - ]:        211 :       if (dFrac[2] < 0.) dFrac[2] = get_uncut_edge_fraction(ii, jj, kk + 1, 1);
    1199 [ +  + ][ +  - ]:        211 :       if (dFrac[3] < 0.) dFrac[3] = get_uncut_edge_fraction(ii, jj, kk, 2);
    1200 [ +  - ][ +  + ]:       1055 :       for (j = 0; j < 4; j++) edges.push_back(dFrac[j]);
    1201 [ +  - ][ +  - ]:        211 :       rmdCutCellSurfEdge[surfKey] = edges;
    1202                 :            :     }
    1203                 :            : 
    1204                 :            :     // surface 2
    1205 [ +  - ][ +  - ]:        268 :     cutFrac = iter->second;
    1206         [ +  + ]:        268 :     if (cutFrac.fraction[0].size() > 0) {
    1207         [ +  - ]:        122 :       dFrac[0] = cutFrac.fraction[0][0];
    1208         [ +  + ]:        122 :       if (dFrac[0] < 0.) dFrac[0] *= -1.;
    1209                 :            :     }
    1210                 :        146 :     else dFrac[0] = -1.;
    1211         [ +  + ]:        268 :     if (cutFrac.fraction[1].size() > 0) {
    1212         [ +  - ]:        122 :       dFrac[3] = cutFrac.fraction[1][0];
    1213         [ +  + ]:        122 :       if (dFrac[3] < 0.) dFrac[3] *= -1.;
    1214                 :            :     }
    1215                 :        146 :     else dFrac[3] = -1.;
    1216         [ +  - ]:        268 :     dFrac[1] = get_edge_fraction(iHex + 1, 2);
    1217         [ +  - ]:        268 :     dFrac[2] = get_edge_fraction(iHex + m_nDiv[0]*m_nDiv[1], 0);
    1218                 :            :     
    1219 [ +  + ][ +  + ]:        268 :     if (dFrac[0] > 0. || dFrac[1] > 0. || dFrac[2] > 0. || dFrac[3] > 0.) { // if surface is cut
         [ +  + ][ +  + ]
    1220         [ +  - ]:        263 :       CutCellSurfEdgeKey surfKey(ii, jj, kk, 1);
    1221         [ +  - ]:        263 :       std::vector<double> edges;
    1222 [ +  + ][ +  - ]:        263 :       if (dFrac[0] < 0.) dFrac[0] = get_uncut_edge_fraction(ii, jj, kk, 0);
    1223 [ +  + ][ +  - ]:        263 :       if (dFrac[1] < 0.) dFrac[1] = get_uncut_edge_fraction(ii + 1, jj, kk, 2);
    1224 [ +  + ][ +  - ]:        263 :       if (dFrac[2] < 0.) dFrac[2] = get_uncut_edge_fraction(ii, jj, kk + 1, 0);
    1225 [ +  + ][ +  - ]:        263 :       if (dFrac[3] < 0.) dFrac[3] = get_uncut_edge_fraction(ii, jj, kk, 2);
    1226 [ +  - ][ +  + ]:       1315 :       for (j = 0; j < 4; j++) edges.push_back(dFrac[j]);
    1227 [ +  - ][ +  - ]:        263 :       rmdCutCellSurfEdge[surfKey] = edges;
    1228                 :            :     }
    1229                 :            :     
    1230                 :            :     // surface 3
    1231 [ +  - ][ +  - ]:        268 :     cutFrac = iter->second;
    1232         [ +  + ]:        268 :     if (cutFrac.fraction[0].size() > 0) {
    1233         [ +  - ]:        122 :       dFrac[0] = cutFrac.fraction[0][0];
    1234         [ +  + ]:        122 :       if (dFrac[0] < 0.) dFrac[0] *= -1.;
    1235                 :            :     }
    1236                 :        146 :     else dFrac[0] = -1.;
    1237         [ +  + ]:        268 :     if (cutFrac.fraction[1].size() > 0) {
    1238         [ +  - ]:        122 :       dFrac[3] = cutFrac.fraction[1][0];
    1239         [ +  + ]:        122 :       if (dFrac[3] < 0.) dFrac[3] *= -1.;
    1240                 :            :     }
    1241                 :        146 :     else dFrac[3] = -1.;
    1242         [ +  - ]:        268 :     dFrac[1] = get_edge_fraction(iHex + 1, 1);
    1243         [ +  - ]:        268 :     dFrac[2] = get_edge_fraction(iHex + m_nDiv[0], 0);
    1244                 :            : 
    1245 [ +  + ][ +  + ]:        268 :     if (dFrac[0] > 0. || dFrac[1] > 0. || dFrac[2] > 0. || dFrac[3] > 0.) { // if surface is cut
         [ +  + ][ +  + ]
    1246         [ +  - ]:        211 :       CutCellSurfEdgeKey surfKey(ii, jj, kk, 2);
    1247         [ +  - ]:        211 :       std::vector<double> edges;
    1248 [ +  + ][ +  - ]:        211 :       if (dFrac[0] < 0.) dFrac[0] = get_uncut_edge_fraction(ii, jj, kk, 0);
    1249 [ +  + ][ +  - ]:        211 :       if (dFrac[1] < 0.) dFrac[1] = get_uncut_edge_fraction(ii + 1, jj, kk, 1);
    1250 [ +  + ][ +  - ]:        211 :       if (dFrac[2] < 0.) dFrac[2] = get_uncut_edge_fraction(ii, jj + 1, kk, 0);
    1251 [ +  + ][ +  - ]:        211 :       if (dFrac[3] < 0.) dFrac[3] = get_uncut_edge_fraction(ii, jj, kk, 1);
    1252 [ +  - ][ +  + ]:       1055 :       for (j = 0; j < 4; j++) edges.push_back(dFrac[j]);
    1253 [ +  - ][ +  - ]:        211 :       rmdCutCellSurfEdge[surfKey] = edges;
    1254                 :            :     }
    1255                 :        268 :   }
    1256                 :            :   
    1257                 :          1 :   if (debug_ebmesh) export_fraction_edges(rmdCutCellSurfEdge);
    1258                 :          1 : }
    1259                 :            : 
    1260                 :          1 : bool EBMesher::get_grid_and_edges(double* boxMin, double* boxMax, int* nDiv,
    1261                 :            :                                      std::map< CutCellSurfEdgeKey, std::vector<double>, LessThan >& rmdCutCellEdge,
    1262                 :            :                                      std::vector<int>& rvnInsideCell, bool isCornerExterior)
    1263                 :            : {
    1264                 :            :   int i, ii, jj, kk, iHex;
    1265         [ +  + ]:          4 :   for (i = 0; i < 3; i++) {
    1266                 :          3 :     boxMin[i] = m_origin_coords[i];
    1267                 :          3 :     boxMax[i] = m_origin_coords[i] + m_dIntervalSize[i]*m_nDiv[i];
    1268                 :          3 :     nDiv[i] = m_nDiv[i];
    1269                 :            :   }
    1270                 :            :   
    1271 [ +  - ][ -  + ]:          1 :   if (!get_inside_hex(rvnInsideCell)) return false;
    1272                 :            : 
    1273                 :            :   // get cut-cell fractions
    1274                 :          1 :   std::map<int, CutFraction>::iterator iter = m_mdCutFraction.begin();
    1275                 :          1 :   std::map<int, CutFraction>::iterator end_iter = m_mdCutFraction.end();
    1276                 :            :   
    1277 [ +  - ][ +  - ]:        269 :   for (; iter != end_iter; iter++) { // for each cut-cell
                 [ +  + ]
    1278                 :            :     // get i, j, k index from handle
    1279         [ +  - ]:        268 :     iHex = iter->first;
    1280                 :        268 :     ii = (iHex%(m_nDiv[0]*m_nDiv[1]))%m_nDiv[0];
    1281                 :        268 :     jj = (iHex%(m_nDiv[0]*m_nDiv[1]))/m_nDiv[0];
    1282                 :        268 :     kk = iHex/m_nDiv[0]/m_nDiv[1];
    1283                 :            : 
    1284         [ +  + ]:       1072 :     for (i = 0; i < 3; i++) {
    1285 [ +  - ][ +  - ]:        804 :       std::vector<double> fractions(iter->second.fraction[i]);
    1286         [ +  - ]:        804 :       CutCellSurfEdgeKey edgeKey(ii, jj, kk, i);
    1287 [ +  - ][ +  - ]:        804 :       rmdCutCellEdge[edgeKey] = fractions;
    1288                 :        804 :     }
    1289                 :            :   }
    1290                 :            : 
    1291                 :            :   if (debug_ebmesh) return export_fraction_points(rmdCutCellEdge);
    1292                 :            :  
    1293                 :          1 :   return true;
    1294                 :            : }
    1295                 :            : 
    1296                 :          1 : bool EBMesher::get_inside_hex(std::vector<int>& rvnInsideCell)
    1297                 :            : {
    1298                 :            :   int i, err, iHex;
    1299                 :            :   
    1300                 :            :   // get all hexes
    1301         [ +  - ]:          1 :   std::vector<iBase_EntityHandle> hex_handles;
    1302                 :            :   err = mk_core()->imesh_instance()->getEntities(m_hRootSet, iBase_REGION,
    1303 [ +  - ][ +  - ]:          1 :                                                  iMesh_HEXAHEDRON, hex_handles);
                 [ +  - ]
    1304         [ +  - ]:          1 :   IBERRCHK(err, "Failed to get hexes.\n");
    1305                 :            :   
    1306                 :            :   // get hex status
    1307                 :          1 :   int hex_size = hex_handles.size();
    1308                 :            :   /*
    1309                 :            :   //int* hex_status = new int[hex_size];
    1310                 :            :   //int* hex_status;
    1311                 :            :   std::vector<int> hex_status(hex_size);
    1312                 :            :   err = mk_core()->imesh_instance()->getIntArrData(&hex_handles[0], hex_size,
    1313                 :            :                                                    m_elemStatusTag, &hex_status[0]);
    1314                 :            :   */
    1315                 :            :   int error;
    1316 [ +  - ][ +  - ]:          1 :   int* hex_status = new int[hex_size];
    1317                 :          1 :   int hex_status_alloc = sizeof(int)*hex_size;
    1318                 :          1 :   int hex_status_size = 0;
    1319         [ +  - ]:          1 :   iMesh_getIntArrData(m_mesh, &hex_handles[0],
    1320                 :            :                       hex_size, m_elemStatusTag,
    1321                 :            :                       &hex_status, &hex_status_alloc,
    1322         [ +  - ]:          1 :                       &hex_status_size, &error);
    1323 [ -  + ][ #  # ]:          1 :   ERRORRF("Failed to get hex status.\n");
                 [ #  # ]
    1324                 :            : 
    1325                 :            :   // get inside and boundary hexes
    1326                 :          1 :   int nInside = 0;
    1327                 :          1 :   int nOutside = 0;
    1328                 :          1 :   int nBoundary = 0;
    1329                 :          1 :   rvnInsideCell.clear();
    1330         [ +  + ]:       1001 :   for (i = 0; i < hex_size; i++) {
    1331         [ +  + ]:       1000 :     if (hex_status[i] == 0) { // if inside
    1332         [ +  - ]:        304 :       iHex = moab_instance()->id_from_handle(reinterpret_cast<moab::EntityHandle>
    1333 [ +  - ][ +  - ]:        304 :                                              (hex_handles[i])) - m_iStartHex;
    1334         [ +  - ]:        304 :       rvnInsideCell.push_back((iHex%(m_nDiv[0]*m_nDiv[1]))%m_nDiv[0]);
    1335         [ +  - ]:        304 :       rvnInsideCell.push_back((iHex%(m_nDiv[0]*m_nDiv[1]))/m_nDiv[0]);
    1336         [ +  - ]:        304 :       rvnInsideCell.push_back(iHex/m_nDiv[0]/m_nDiv[1]);
    1337                 :        304 :       nInside++;
    1338                 :            :     }
    1339         [ +  + ]:        696 :     else if (hex_status[i] == 1) nOutside++;
    1340         [ +  - ]:        392 :     else if (hex_status[i] == 2) nBoundary++;
    1341 [ #  # ][ #  # ]:          0 :     else ERRORRF("Element status should be one of inside/outside/boundary.\n"); 
                 [ #  # ]
    1342                 :            :   }
    1343 [ +  - ][ +  - ]:          1 :   std::cout << "# of inside, outside, boundary elem: " << nInside
    1344 [ +  - ][ +  - ]:          1 :             << ", " << nOutside << ", " << nBoundary << std::endl;
         [ +  - ][ +  - ]
                 [ +  - ]
    1345                 :            : 
    1346         [ +  - ]:          1 :   delete [] hex_status;
    1347                 :          1 :   return true;
    1348                 :            : }
    1349                 :            : 
    1350                 :          0 : bool EBMesher::export_fraction_edges(std::map< CutCellSurfEdgeKey, std::vector<double>, LessThan >& mdCutCellSurfEdge)
    1351                 :            : {
    1352                 :            :   // export fractions as edge
    1353                 :            :   double curPnt[3], ePnt[6];
    1354         [ #  # ]:          0 :   std::vector<iBase_EntityHandle> edge_handles;
    1355                 :          0 :   std::map< CutCellSurfEdgeKey, std::vector<double>, LessThan >::iterator itr = mdCutCellSurfEdge.begin();
    1356                 :          0 :   std::map< CutCellSurfEdgeKey, std::vector<double>, LessThan >::iterator e_itr = mdCutCellSurfEdge.end();
    1357 [ #  # ][ #  # ]:          0 :   for (; itr != e_itr; itr++) {
                 [ #  # ]
    1358         [ #  # ]:          0 :     curPnt[0] = m_origin_coords[0] + itr->first.i*m_dIntervalSize[0];
    1359         [ #  # ]:          0 :     curPnt[1] = m_origin_coords[1] + itr->first.j*m_dIntervalSize[1];
    1360         [ #  # ]:          0 :     curPnt[2] = m_origin_coords[2] + itr->first.k*m_dIntervalSize[2];
    1361 [ #  # ][ #  # ]:          0 :     std::vector<double> edges = itr->second;
    1362                 :            :     
    1363 [ #  # ][ #  # ]:          0 :     if (itr->first.l == 0) {
    1364 [ #  # ][ #  # ]:          0 :       if (edges[0] > 0. && edges[0] < 1.) {
         [ #  # ][ #  # ]
                 [ #  # ]
    1365                 :          0 :         ePnt[0] = curPnt[0];
    1366                 :          0 :         ePnt[1] = curPnt[1];
    1367                 :          0 :         ePnt[2] = curPnt[2];
    1368                 :          0 :         ePnt[3] = ePnt[0];
    1369         [ #  # ]:          0 :         ePnt[4] = ePnt[1] + edges[0]*m_dIntervalSize[1];
    1370                 :          0 :         ePnt[5] = ePnt[2];
    1371 [ #  # ][ #  # ]:          0 :         if (!make_edge(ePnt, edge_handles)) return false;
    1372                 :            :       }
    1373 [ #  # ][ #  # ]:          0 :       if (edges[1] > 0. && edges[1] < 1.) {
         [ #  # ][ #  # ]
                 [ #  # ]
    1374                 :          0 :         ePnt[0] = curPnt[0];
    1375                 :          0 :         ePnt[1] = curPnt[1] + m_dIntervalSize[1];
    1376                 :          0 :         ePnt[2] = curPnt[2];
    1377                 :          0 :         ePnt[3] = ePnt[0];
    1378                 :          0 :         ePnt[4] = ePnt[1];
    1379         [ #  # ]:          0 :         ePnt[5] = ePnt[2] + edges[1]*m_dIntervalSize[2];
    1380 [ #  # ][ #  # ]:          0 :         if (!make_edge(ePnt, edge_handles)) return false;
    1381                 :            :       }
    1382 [ #  # ][ #  # ]:          0 :       if (edges[2] > 0. && edges[2] < 1.) {
         [ #  # ][ #  # ]
                 [ #  # ]
    1383                 :          0 :         ePnt[0] = curPnt[0];
    1384                 :          0 :         ePnt[1] = curPnt[1];
    1385                 :          0 :         ePnt[2] = curPnt[2] + m_dIntervalSize[2];
    1386                 :          0 :         ePnt[3] = ePnt[0];
    1387         [ #  # ]:          0 :         ePnt[4] = ePnt[1] + edges[2]*m_dIntervalSize[1];
    1388                 :          0 :         ePnt[5] = ePnt[2];
    1389 [ #  # ][ #  # ]:          0 :         if (!make_edge(ePnt, edge_handles)) return false;
    1390                 :            :       }
    1391 [ #  # ][ #  # ]:          0 :       if (edges[3] > 0. && edges[3] < 1.) {
         [ #  # ][ #  # ]
                 [ #  # ]
    1392                 :          0 :         ePnt[0] = curPnt[0];
    1393                 :          0 :         ePnt[1] = curPnt[1];
    1394                 :          0 :         ePnt[2] = curPnt[2];
    1395                 :          0 :         ePnt[3] = ePnt[0];
    1396                 :          0 :         ePnt[4] = ePnt[1];
    1397         [ #  # ]:          0 :         ePnt[5] = ePnt[2] + edges[3]*m_dIntervalSize[2];
    1398 [ #  # ][ #  # ]:          0 :         if (!make_edge(ePnt, edge_handles)) return false;
    1399                 :            :       }
    1400                 :            :     }
    1401 [ #  # ][ #  # ]:          0 :     if (itr->first.l == 1) {
    1402 [ #  # ][ #  # ]:          0 :       if (edges[0] > 0. && edges[0] < 1.) {
         [ #  # ][ #  # ]
                 [ #  # ]
    1403                 :          0 :         ePnt[0] = curPnt[0];
    1404                 :          0 :         ePnt[1] = curPnt[1];
    1405                 :          0 :         ePnt[2] = curPnt[2];
    1406         [ #  # ]:          0 :         ePnt[3] = ePnt[0] + edges[0]*m_dIntervalSize[0];
    1407                 :          0 :         ePnt[4] = ePnt[1];
    1408                 :          0 :         ePnt[5] = ePnt[2];
    1409 [ #  # ][ #  # ]:          0 :         if (!make_edge(ePnt, edge_handles)) return false;
    1410                 :            :       }
    1411 [ #  # ][ #  # ]:          0 :       if (edges[1] > 0. && edges[1] < 1.) {
         [ #  # ][ #  # ]
                 [ #  # ]
    1412                 :          0 :         ePnt[0] = curPnt[0] + m_dIntervalSize[0];
    1413                 :          0 :         ePnt[1] = curPnt[1];
    1414                 :          0 :         ePnt[2] = curPnt[2];
    1415                 :          0 :         ePnt[3] = ePnt[0];
    1416                 :          0 :         ePnt[4] = ePnt[1];
    1417         [ #  # ]:          0 :         ePnt[5] = ePnt[2] + edges[1]*m_dIntervalSize[2];
    1418 [ #  # ][ #  # ]:          0 :         if (!make_edge(ePnt, edge_handles)) return false;
    1419                 :            :       }
    1420 [ #  # ][ #  # ]:          0 :       if (edges[2] > 0. && edges[2] < 1.) {
         [ #  # ][ #  # ]
                 [ #  # ]
    1421                 :          0 :         ePnt[0] = curPnt[0];
    1422                 :          0 :         ePnt[1] = curPnt[1];
    1423                 :          0 :         ePnt[2] = curPnt[2] + m_dIntervalSize[2];
    1424         [ #  # ]:          0 :         ePnt[3] = ePnt[0] + edges[2]*m_dIntervalSize[0];
    1425                 :          0 :         ePnt[4] = ePnt[1];
    1426                 :          0 :         ePnt[5] = ePnt[2];
    1427 [ #  # ][ #  # ]:          0 :         if (!make_edge(ePnt, edge_handles)) return false;
    1428                 :            :       }
    1429 [ #  # ][ #  # ]:          0 :       if (edges[3] > 0. && edges[3] < 1.) {
         [ #  # ][ #  # ]
                 [ #  # ]
    1430                 :          0 :         ePnt[0] = curPnt[0];
    1431                 :          0 :         ePnt[1] = curPnt[1];
    1432                 :          0 :         ePnt[2] = curPnt[2];
    1433                 :          0 :         ePnt[3] = ePnt[0];
    1434                 :          0 :         ePnt[4] = ePnt[1];
    1435         [ #  # ]:          0 :         ePnt[5] = ePnt[2] + edges[3]*m_dIntervalSize[2];
    1436 [ #  # ][ #  # ]:          0 :         if (!make_edge(ePnt, edge_handles)) return false;
    1437                 :            :       }
    1438                 :            :     }
    1439 [ #  # ][ #  # ]:          0 :     if (itr->first.l == 2) {
    1440 [ #  # ][ #  # ]:          0 :       if (edges[0] > 0. && edges[0] < 1.) {
         [ #  # ][ #  # ]
                 [ #  # ]
    1441                 :          0 :         ePnt[0] = curPnt[0];
    1442                 :          0 :         ePnt[1] = curPnt[1];
    1443                 :          0 :         ePnt[2] = curPnt[2];
    1444         [ #  # ]:          0 :         ePnt[3] = ePnt[0] + edges[0]*m_dIntervalSize[0];
    1445                 :          0 :         ePnt[4] = ePnt[1];
    1446                 :          0 :         ePnt[5] = ePnt[2];
    1447 [ #  # ][ #  # ]:          0 :         if (!make_edge(ePnt, edge_handles)) return false;
    1448                 :            :       }
    1449 [ #  # ][ #  # ]:          0 :       if (edges[1] > 0. && edges[1] < 1.) {
         [ #  # ][ #  # ]
                 [ #  # ]
    1450                 :          0 :         ePnt[0] = curPnt[0] + m_dIntervalSize[0];
    1451                 :          0 :         ePnt[1] = curPnt[1];
    1452                 :          0 :         ePnt[2] = curPnt[2];
    1453                 :          0 :         ePnt[3] = ePnt[0];
    1454         [ #  # ]:          0 :         ePnt[4] = ePnt[1] + edges[1]*m_dIntervalSize[1];
    1455                 :          0 :         ePnt[5] = ePnt[2];
    1456 [ #  # ][ #  # ]:          0 :         if (!make_edge(ePnt, edge_handles)) return false;
    1457                 :            :       }
    1458 [ #  # ][ #  # ]:          0 :       if (edges[2] > 0. && edges[2] < 1.) {
         [ #  # ][ #  # ]
                 [ #  # ]
    1459                 :          0 :         ePnt[0] = curPnt[0];
    1460                 :          0 :         ePnt[1] = curPnt[1] + m_dIntervalSize[2];
    1461                 :          0 :         ePnt[2] = curPnt[2];
    1462         [ #  # ]:          0 :         ePnt[3] = ePnt[0] + edges[2]*m_dIntervalSize[0];
    1463                 :          0 :         ePnt[4] = ePnt[1];
    1464                 :          0 :         ePnt[5] = ePnt[2];
    1465 [ #  # ][ #  # ]:          0 :         if (!make_edge(ePnt, edge_handles)) return false;
    1466                 :            :       }
    1467 [ #  # ][ #  # ]:          0 :       if (edges[3] > 0. && edges[3] < 1.) {
         [ #  # ][ #  # ]
                 [ #  # ]
    1468                 :          0 :         ePnt[0] = curPnt[0];
    1469                 :          0 :         ePnt[1] = curPnt[1];
    1470                 :          0 :         ePnt[2] = curPnt[2];
    1471                 :          0 :         ePnt[3] = ePnt[0];
    1472         [ #  # ]:          0 :         ePnt[4] = ePnt[1] + edges[3]*m_dIntervalSize[1];
    1473                 :          0 :         ePnt[5] = ePnt[2];
    1474 [ #  # ][ #  # ]:          0 :         if (!make_edge(ePnt, edge_handles)) return false;
                 [ #  # ]
    1475                 :            :       }
    1476                 :            :     }
    1477                 :          0 :   }
    1478                 :            : 
    1479                 :          0 :   int is_list = 1;
    1480                 :            :   iBase_EntitySetHandle set;
    1481                 :            :   iBase_ErrorType err;
    1482 [ #  # ][ #  # ]:          0 :   err = mk_core()->imesh_instance()->createEntSet(is_list, set);
                 [ #  # ]
    1483         [ #  # ]:          0 :   IBERRCHK(err, "Couldn't create set.");
    1484                 :            :   
    1485 [ #  # ][ #  # ]:          0 :   err = mk_core()->imesh_instance()->addEntArrToSet(&edge_handles[0],
                 [ #  # ]
    1486         [ #  # ]:          0 :                                                     edge_handles.size(), set);
    1487         [ #  # ]:          0 :   IBERRCHK(err, "Couldn't add edges to set.");
    1488                 :            :   
    1489         [ #  # ]:          0 :   moab::ErrorCode rval = moab_instance()->write_mesh("edges.vtk",
    1490         [ #  # ]:          0 :                                                      (const moab::EntityHandle*) &set, 1);
    1491 [ #  # ][ #  # ]:          0 :   MBERRCHK(rval, mk_core()->moab_instance());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1492                 :            : 
    1493                 :          0 :   return true;
    1494                 :            : }
    1495                 :            : 
    1496                 :          0 : bool EBMesher::export_fraction_points(std::map< CutCellSurfEdgeKey, std::vector<double>, LessThan >& mdCutCellEdge)
    1497                 :            : {
    1498                 :            :   // export fractions as edge
    1499                 :            :   int i, j, dir, nFrc;
    1500                 :            :   iBase_ErrorType err;
    1501                 :            :   double curPnt[3], fracPnt[3], frac;
    1502                 :            :   iBase_EntityHandle v_handle;
    1503         [ #  # ]:          0 :   std::vector<iBase_EntityHandle> vertex_handles;
    1504                 :          0 :   std::map< CutCellSurfEdgeKey, std::vector<double>, LessThan >::iterator itr = mdCutCellEdge.begin();
    1505                 :          0 :   std::map< CutCellSurfEdgeKey, std::vector<double>, LessThan >::iterator e_itr = mdCutCellEdge.end();
    1506 [ #  # ][ #  # ]:          0 :   for (; itr != e_itr; itr++) {
                 [ #  # ]
    1507         [ #  # ]:          0 :     curPnt[0] = m_origin_coords[0] + itr->first.i*m_dIntervalSize[0];
    1508         [ #  # ]:          0 :     curPnt[1] = m_origin_coords[1] + itr->first.j*m_dIntervalSize[1];
    1509         [ #  # ]:          0 :     curPnt[2] = m_origin_coords[2] + itr->first.k*m_dIntervalSize[2];
    1510         [ #  # ]:          0 :     dir = itr->first.l;
    1511         [ #  # ]:          0 :     nFrc = itr->second.size();
    1512                 :            :     
    1513         [ #  # ]:          0 :     for (i = 0; i < nFrc; i++) {
    1514 [ #  # ][ #  # ]:          0 :       frac = itr->second[i];
    1515 [ #  # ][ #  # ]:          0 :       if (frac > 0. && frac < 1.) {
    1516         [ #  # ]:          0 :         for (j = 0; j < 3; j++) {
    1517         [ #  # ]:          0 :           if (j == dir) fracPnt[j] = curPnt[j] + frac*m_dIntervalSize[j];
    1518                 :          0 :           else fracPnt[j] = curPnt[j];
    1519                 :            :         }
    1520                 :            :         err = mk_core()->imesh_instance()->createVtx(fracPnt[0], fracPnt[1],
    1521 [ #  # ][ #  # ]:          0 :                                                      fracPnt[2], v_handle);
                 [ #  # ]
    1522         [ #  # ]:          0 :         IBERRCHK(err, "Couldn't create vertex.");
    1523         [ #  # ]:          0 :         vertex_handles.push_back(v_handle);
    1524                 :            :       }
    1525                 :            :     }
    1526                 :            :   }
    1527                 :            :     
    1528                 :          0 :   int is_list = 1;
    1529                 :            :   moab::ErrorCode result;
    1530                 :            :   iBase_EntitySetHandle set;
    1531 [ #  # ][ #  # ]:          0 :   err = mk_core()->imesh_instance()->createEntSet(is_list, set);
                 [ #  # ]
    1532         [ #  # ]:          0 :   IBERRCHK(err, "Couldn't create set.");
    1533                 :            :   
    1534 [ #  # ][ #  # ]:          0 :   err = mk_core()->imesh_instance()->addEntArrToSet(&vertex_handles[0],
                 [ #  # ]
    1535         [ #  # ]:          0 :                                                     vertex_handles.size(), set);
    1536         [ #  # ]:          0 :   IBERRCHK(err, "Couldn't add vertices to set.");
    1537                 :            :   
    1538         [ #  # ]:          0 :   result = moab_instance()->write_mesh("frac_vertices.vtk",
    1539         [ #  # ]:          0 :                                        (const moab::EntityHandle*) &set, 1);
    1540         [ #  # ]:          0 :   if (moab::MB_SUCCESS != result) {
    1541 [ #  # ][ #  # ]:          0 :     std::cerr << "Failed to write fraction vertices." << std::endl;
    1542                 :          0 :     return false;
    1543                 :            :   }
    1544                 :            : 
    1545                 :          0 :   return true;
    1546                 :            : }
    1547                 :            : 
    1548                 :          0 : bool EBMesher::make_edge(double ePnt[6], std::vector<iBase_EntityHandle>& edge_handles)
    1549                 :            : {
    1550                 :            :   iBase_ErrorType err;
    1551                 :            :   iBase_EntityHandle vertex_handle[2], edge_handle;
    1552                 :          0 :   iBase_EntityHandle* pVertexHandle = &vertex_handle[0];
    1553                 :            :   err = mk_core()->imesh_instance()->createVtxArr(2, iBase_INTERLEAVED,
    1554 [ #  # ][ #  # ]:          0 :                                                   ePnt, pVertexHandle);
                 [ #  # ]
    1555         [ #  # ]:          0 :   IBERRCHK(err, "Failed to create vertices.\n");
    1556                 :            : 
    1557                 :            :   err = mk_core()->imesh_instance()->createEnt(iMesh_LINE_SEGMENT,
    1558                 :            :                                                &vertex_handle[0], 2,
    1559 [ #  # ][ #  # ]:          0 :                                                edge_handle);
                 [ #  # ]
    1560         [ #  # ]:          0 :   IBERRCHK(err, "Failed to create edge.\n");
    1561                 :            : 
    1562         [ #  # ]:          0 :   edge_handles.push_back(edge_handle);
    1563                 :            : 
    1564                 :          0 :   return true;
    1565                 :            : }
    1566                 :            : 
    1567                 :       1608 : double EBMesher::get_edge_fraction(int idHex, int dir)
    1568                 :            : {
    1569                 :       1608 :   std::map<int, CutFraction>::iterator end_iter = m_mdCutFraction.end();
    1570         [ +  - ]:       1608 :   std::map<int, CutFraction>::iterator iter = m_mdCutFraction.find(idHex);
    1571 [ +  - ][ +  + ]:       1608 :   if (iter != end_iter && iter->second.fraction[dir].size() > 0) {
         [ +  - ][ +  + ]
                 [ +  + ]
    1572 [ +  - ][ +  - ]:        516 :     double frac = iter->second.fraction[dir][0];
    1573         [ +  + ]:        516 :     if (frac < 0.) frac *= -1.;
    1574                 :        516 :     return frac;
    1575                 :            :   }
    1576                 :       1608 :   else return -1.;
    1577                 :            : }
    1578                 :            : 
    1579                 :       1492 : double EBMesher::get_uncut_edge_fraction(int i, int j, int k, int dir)
    1580                 :            : {
    1581                 :            :   int iEdge;
    1582                 :            : 
    1583         [ +  + ]:       1492 :   if (dir == 0) {
    1584 [ +  + ][ +  + ]:        532 :     if (j == m_nDiv[1] || k == m_nDiv[2]) return 0.; // return outside
    1585                 :        476 :     iEdge = k*m_nDiv[0]*m_nDiv[1] + j*m_nDiv[0] + i;
    1586                 :            :   }
    1587         [ +  + ]:        960 :   else if (dir == 1) {
    1588 [ +  + ][ +  + ]:        428 :     if (i == m_nDiv[0] || k == m_nDiv[2]) return 0.; // return outside
    1589                 :        376 :     iEdge = i*m_nDiv[1]*m_nDiv[2] + k*m_nDiv[1] + j;
    1590                 :            :   }
    1591         [ +  - ]:        532 :   else if (dir == 2) {
    1592 [ +  + ][ +  + ]:        532 :     if (i == m_nDiv[0] || j == m_nDiv[1]) return 0.; // return outside
    1593                 :        476 :     iEdge = j*m_nDiv[0]*m_nDiv[2] + i*m_nDiv[2] + k;
    1594                 :            :   }
    1595                 :          0 :   else return -1.;
    1596                 :            : 
    1597                 :       1328 :   EdgeStatus edgeStatus = m_vnEdgeStatus[dir][iEdge];
    1598         [ +  + ]:       1328 :   if (edgeStatus == INSIDE) return 1.;
    1599         [ -  + ]:         80 :   else if (edgeStatus == OUTSIDE) return 0.;
    1600                 :         80 :   else return -1.;
    1601                 :            : }
    1602                 :            : 
    1603                 :          0 : bool EBMesher::move_ray(int& nIntersect, double* startPnt, double* endPnt,
    1604                 :            :                       double tol, int dir, bool bSpecialCase)
    1605                 :            : {
    1606                 :            :   //int i, nIteration;
    1607                 :            :   int i;
    1608                 :          0 :   bool bMove = true;
    1609                 :            : 
    1610         [ #  # ]:          0 :   if (bSpecialCase) m_iOverlap = 0;
    1611                 :            : 
    1612         [ #  # ]:          0 :   while (bMove) {
    1613         [ #  # ]:          0 :     if (m_nIteration > 10) {
    1614         [ #  # ]:          0 :       if (bSpecialCase) return true; // special case
    1615         [ #  # ]:          0 :       else if (m_bUseGeom) { // shared/overlapped, faceting case
    1616         [ #  # ]:          0 :         m_mhOverlappedSurf[m_iOverlap] = 0;
    1617         [ #  # ]:          0 :         m_mhOverlappedSurf[m_iOverlap + 1] = 0;
    1618                 :          0 :         return true;
    1619                 :            :       }
    1620                 :            :       else {
    1621                 :          0 :         return false;
    1622                 :            :       }
    1623                 :            :     }
    1624                 :            : 
    1625         [ #  # ]:          0 :     for (i = 0; i < 3; i++) {
    1626         [ #  # ]:          0 :       if (i != dir) {
    1627                 :          0 :         startPnt[i] += tol;
    1628                 :          0 :         endPnt[i] += tol;
    1629                 :            :       }
    1630                 :            :     }
    1631                 :            : 
    1632         [ #  # ]:          0 :     moab::CartVect ray(endPnt[0] - startPnt[0], endPnt[1] - startPnt[1], endPnt[2] - startPnt[2]);
    1633         [ #  # ]:          0 :     double rayLength = ray.length();
    1634                 :            :     moab::ErrorCode rVal;
    1635         [ #  # ]:          0 :     ray.normalize();
    1636                 :          0 :     m_vIntersection.clear();
    1637                 :          0 :     m_vhInterSurf.clear();
    1638                 :          0 :     m_vhInterFacet.clear();
    1639                 :            :     
    1640         [ #  # ]:          0 :     std::vector<double> temp_intersects;
    1641 [ #  # ][ #  # ]:          0 :     moab::OrientedBoxTreeTool::TrvStats stats;
    1642         [ #  # ]:          0 :     if (m_bUseGeom) {
    1643                 :            :       rVal = m_hObbTree->ray_intersect_sets(temp_intersects, m_vhInterSurf,
    1644                 :            :                                             m_vhInterFacet, m_hTreeRoot, tol,
    1645         [ #  # ]:          0 :                                             startPnt, ray.array(), &rayLength,
    1646         [ #  # ]:          0 :                                             &stats);
    1647                 :            :     }
    1648                 :            :     else { // facet input
    1649         [ #  # ]:          0 :       std::vector<moab::EntityHandle> dum_facets_out;
    1650                 :            :       rVal = m_hObbTree->ray_intersect_triangles(temp_intersects, dum_facets_out,
    1651                 :            :                                                  m_hTreeRoot, tol,
    1652         [ #  # ]:          0 :                                                  startPnt, ray.array(), &rayLength,
    1653         [ #  # ]:          0 :                                                  &stats);
    1654         [ #  # ]:          0 :       m_vhInterSurf.resize(temp_intersects.size());
    1655                 :            :     }
    1656                 :            : 
    1657         [ #  # ]:          0 :     if (moab::MB_SUCCESS != rVal) {
    1658 [ #  # ][ #  # ]:          0 :       std::cerr << "Failed : ray-triangle intersection." << std::endl;
    1659                 :          0 :       return false;
    1660                 :            :     }
    1661                 :            : 
    1662                 :          0 :     nIntersect = temp_intersects.size();
    1663         [ #  # ]:          0 :     m_vIntersection.resize(nIntersect);
    1664         [ #  # ]:          0 :     for (i = 0; i < nIntersect; i++) {
    1665 [ #  # ][ #  # ]:          0 :       IntersectDist temp_inter_dist(temp_intersects[i], i);
    1666         [ #  # ]:          0 :       m_vIntersection[i] = temp_inter_dist;
    1667                 :            :     }
    1668         [ #  # ]:          0 :     std::sort(m_vIntersection.begin(), m_vIntersection.end(), less_intersect);
    1669         [ #  # ]:          0 :     bMove = is_ray_move_and_set_overlap_surf(bSpecialCase);
    1670         [ #  # ]:          0 :     m_nIteration++;
    1671                 :          0 :   }
    1672                 :            : 
    1673                 :          0 :   std::cout << "ray is moved successfully." << std::endl;
    1674                 :            : 
    1675                 :          0 :   return true;
    1676                 :            : }
    1677                 :            : 
    1678                 :          0 : bool EBMesher::is_ray_move_and_set_overlap_surf(bool& bSpecialCase)
    1679                 :            : {
    1680                 :          0 :   int nInter = m_vIntersection.size() - 1;
    1681                 :            : 
    1682         [ #  # ]:          0 :   while (m_iOverlap < nInter) {
    1683         [ #  # ]:          0 :     if (m_vIntersection[m_iOverlap + 1].distance - m_vIntersection[m_iOverlap].distance < 1e-7) {
    1684         [ #  # ]:          0 :       if (m_bUseGeom) {
    1685 [ #  # ][ #  # ]:          0 :         moab::EntityHandle h1 = m_vhInterSurf[m_vIntersection[m_iOverlap].index];
    1686 [ #  # ][ #  # ]:          0 :         moab::EntityHandle h2 = m_vhInterSurf[m_vIntersection[m_iOverlap + 1].index];
    1687                 :            :         
    1688         [ #  # ]:          0 :         if (h1 == h2) { // remove too close case
    1689                 :          0 :           bSpecialCase = false;
    1690                 :          0 :           return true;
    1691                 :            :         }
    1692         [ #  # ]:          0 :         else if (m_nIteration < 10) { // when ray intesect shared edge by 2 triangles
    1693                 :          0 :           bSpecialCase = true;
    1694                 :          0 :           return true;
    1695                 :            :         }
    1696                 :            :         else { // overlapped surfaces
    1697         [ #  # ]:          0 :           m_mhOverlappedSurf[h1] = 0;
    1698         [ #  # ]:          0 :           m_mhOverlappedSurf[h2] = 0;
    1699                 :          0 :           m_nIteration = 0;
    1700                 :          0 :           m_iOverlap++;
    1701                 :            :         }
    1702                 :            :       }
    1703                 :            :       else {
    1704         [ #  # ]:          0 :         if (m_nIteration < 10) { // when ray intesect shared edge by 2 triangles
    1705                 :          0 :           bSpecialCase = true;
    1706                 :          0 :           return true;
    1707                 :            :         }
    1708                 :            :         else { // overlapped surfaces
    1709                 :            :           //bSpecialCase = false;
    1710                 :            :           //m_nIteration = 0;
    1711                 :            :           //m_iOverlap++;
    1712 [ #  # ][ #  # ]:          0 :           m_vIntersection.erase(m_vIntersection.begin() + m_iOverlap + 1);
                 [ #  # ]
    1713                 :          0 :           nInter = m_vIntersection.size();
    1714                 :          0 :           m_vhInterSurf.resize(nInter);
    1715                 :            :           //m_nIteration = 0;
    1716                 :            :         }
    1717                 :            :       }
    1718                 :            :     }
    1719                 :          0 :     else m_iOverlap++;
    1720                 :            :   }
    1721                 :            : 
    1722                 :          0 :   return false;
    1723                 :            : }
    1724                 :            : 
    1725                 :        207 : void EBMesher::remove_intersection_duplicates()
    1726                 :            : {
    1727                 :        207 :   int ind = 0;
    1728                 :        207 :   int nInter = m_vIntersection.size() - 1;
    1729                 :            : 
    1730         [ +  + ]:        523 :   while (ind < nInter) {
    1731         [ +  + ]:        316 :     if (m_vIntersection[ind + 1].distance - m_vIntersection[ind].distance < 1e-7) {
    1732 [ +  - ][ +  - ]:        109 :       moab::EntityHandle h1 = m_vhInterSurf[m_vIntersection[ind].index];
    1733 [ +  - ][ +  - ]:        109 :       moab::EntityHandle h2 = m_vhInterSurf[m_vIntersection[ind + 1].index];
    1734                 :            :       
    1735         [ +  + ]:        109 :       if (h1 != h2) { // overlapped/shared surfaces
    1736 [ +  - ][ +  - ]:        142 :         std::vector<iBase_EntitySetHandle> parents_out1, parents_out2;
    1737 [ +  - ][ +  - ]:         71 :         int err = mk_core()->imesh_instance()->getPrnts(reinterpret_cast<iBase_EntitySetHandle> (h1), 1, parents_out1);
                 [ +  - ]
    1738         [ +  - ]:         71 :         IBERRCHK(err, "Failed to get number of surface parents.\n");
    1739 [ +  - ][ +  - ]:         71 :         err = mk_core()->imesh_instance()->getPrnts(reinterpret_cast<iBase_EntitySetHandle> (h2), 1, parents_out2);
                 [ +  - ]
    1740         [ +  - ]:         71 :         IBERRCHK(err, "Failed to get number of surface parents.\n");
    1741 [ +  - ][ +  - ]:         71 :         if (parents_out1.size() == 1 && parents_out2.size() == 1) {
                 [ +  - ]
    1742 [ +  - ][ +  - ]:         71 :           if (parents_out1[0] != parents_out2[0]) { // parent volues are also different
                 [ -  + ]
    1743         [ #  # ]:          0 :             m_mhOverlappedSurf[h1] = 0;
    1744         [ #  # ]:          0 :             m_mhOverlappedSurf[h2] = 0;
    1745                 :            :           }
    1746                 :         71 :         }
    1747                 :            :       }
    1748 [ +  - ][ +  - ]:        109 :       m_vIntersection.erase(m_vIntersection.begin() + ind + 1);
                 [ +  - ]
    1749                 :        109 :       nInter--;
    1750                 :            :     }
    1751                 :        207 :     else ind++;
    1752                 :            :   }
    1753                 :        207 : }
    1754                 :            : 
    1755                 :          0 : bool EBMesher::get_volume_fraction(int vol_frac_div)
    1756                 :            : {
    1757 [ #  # ][ #  # ]:          0 :   std::cout << "starting get_volume_fraction." << std::endl;
    1758                 :            :   int i, j, k, l, n, iHex, dir, nIntersect, rayIndex[3], index[3],
    1759                 :            :     otherDir1, otherDir2, err, nParent;
    1760                 :            :   (void) otherDir1;
    1761                 :            :   (void) otherDir2;
    1762                 :          0 :   double tolerance = 1e-12, dDistance, elem_origin[3],
    1763                 :            :     elem_interval_size[3], startPnt[3], endPnt[3], rayMaxEnd[3];
    1764                 :            :   moab::ErrorCode rval;
    1765                 :          0 :   bool bOverlapSecond, bClosed = true;
    1766         [ #  # ]:          0 :   std::vector<iBase_EntityHandle> edge_handles;
    1767                 :            : 
    1768                 :          0 :   double dTotEdgeElem = 0.;
    1769         [ #  # ]:          0 :   for (i = 0; i < 3; i++) {
    1770                 :          0 :     rayMaxEnd[i] = m_origin_coords[i] + m_nDiv[i]*m_dIntervalSize[i];
    1771                 :          0 :     dTotEdgeElem += m_dIntervalSize[i]*(vol_frac_div + 1)*(vol_frac_div + 1);
    1772                 :            :   }
    1773                 :            : 
    1774                 :            :   // get all hexes
    1775         [ #  # ]:          0 :   std::vector<iBase_EntityHandle> hex_handles;
    1776                 :            :   err = mk_core()->imesh_instance()->getEntities(m_hRootSet, iBase_REGION,
    1777 [ #  # ][ #  # ]:          0 :                                                  iMesh_HEXAHEDRON, hex_handles);
                 [ #  # ]
    1778         [ #  # ]:          0 :   IBERRCHK(err, "Failed to get hexes.\n");
    1779                 :            : 
    1780                 :          0 :   int hex_size = hex_handles.size();
    1781                 :            :   /*
    1782                 :            :   std::vector<int> hex_status(hex_size);
    1783                 :            :   //int* hex_status = NULL;
    1784                 :            :   err = mk_core()->imesh_instance()->getIntArrData(&hex_handles[0], hex_size,
    1785                 :            :                                                    m_elemStatusTag, &hex_status[0]);
    1786                 :            :   */
    1787                 :            :   int error;
    1788         [ #  # ]:          0 :   std::vector<int> frac_length;
    1789 [ #  # ][ #  # ]:          0 :   int* hex_status = new int[hex_size];
    1790                 :          0 :   int hex_status_alloc = sizeof(int)*hex_size;
    1791                 :          0 :   int hex_status_size = 0;
    1792         [ #  # ]:          0 :   iMesh_getIntArrData(m_mesh, &hex_handles[0],
    1793                 :            :                       hex_size, m_elemStatusTag,
    1794                 :            :                       &hex_status, &hex_status_alloc,
    1795         [ #  # ]:          0 :                       &hex_status_size, &error);
    1796 [ #  # ][ #  # ]:          0 :   ERRORRF("Failed to get hex status.\n");
                 [ #  # ]
    1797                 :            : 
    1798         [ #  # ]:          0 :   for (n = 0; n < hex_size; n++) {
    1799         [ #  # ]:          0 :     if (hex_status[n] == 2) { // just boundary
    1800         [ #  # ]:          0 :       std::map<moab::EntityHandle, VolFrac> vol_fraction;
    1801         [ #  # ]:          0 :       std::map<moab::EntityHandle, VolFrac>::iterator vf_iter;
    1802         [ #  # ]:          0 :       std::map<moab::EntityHandle, VolFrac>::iterator vf_end_iter;
    1803         [ #  # ]:          0 :       iHex = moab_instance()->id_from_handle(reinterpret_cast<moab::EntityHandle>
    1804 [ #  # ][ #  # ]:          0 :                                              (hex_handles[n])) - m_iStartHex;
    1805                 :          0 :       index[0] = (iHex%(m_nDiv[0]*m_nDiv[1]))%m_nDiv[0];
    1806                 :          0 :       index[1] = (iHex%(m_nDiv[0]*m_nDiv[1]))/m_nDiv[0];
    1807                 :          0 :       index[2] = iHex/m_nDiv[0]/m_nDiv[1];
    1808                 :            :       
    1809         [ #  # ]:          0 :       for (i = 0; i < 3; i++) {
    1810                 :          0 :         elem_origin[i] = m_origin_coords[i] + index[i]*m_dIntervalSize[i];
    1811                 :          0 :         elem_interval_size[i] = m_dIntervalSize[i]/vol_frac_div;
    1812                 :            :       }
    1813                 :            :       
    1814         [ #  # ]:          0 :       for (dir = 0; dir < 3; dir++) { // x, y, z directions
    1815                 :          0 :         otherDir1 = (dir + 1)%3;
    1816                 :          0 :         otherDir2 = (dir + 2)%3;
    1817                 :            :         
    1818         [ #  # ]:          0 :         for (j = 0; j < vol_frac_div + 1; j++) {
    1819         [ #  # ]:          0 :           for (i = 0; i < vol_frac_div + 1; i++) {
    1820                 :            :             // get ray start and end points
    1821         [ #  # ]:          0 :             if (dir == 0) { // x coordinate ray
    1822                 :          0 :               rayIndex[0] = 0;
    1823                 :          0 :               rayIndex[1] = i;
    1824                 :          0 :               rayIndex[2] = j;
    1825                 :            :             }
    1826         [ #  # ]:          0 :             else if (dir == 1) { // y coordinate ray
    1827                 :          0 :               rayIndex[0] = j;
    1828                 :          0 :               rayIndex[1] = 0;
    1829                 :          0 :               rayIndex[2] = i;
    1830                 :            :             }
    1831         [ #  # ]:          0 :             else if (dir == 2) { // z coordinate ray
    1832                 :          0 :               rayIndex[0] = i;
    1833                 :          0 :               rayIndex[1] = j;
    1834                 :          0 :               rayIndex[2] = 0;
    1835                 :            :             }
    1836         [ #  # ]:          0 :             else IBERRCHK(iBase_FAILURE, "Ray direction should be from 0 to 2.");
    1837                 :            :             
    1838         [ #  # ]:          0 :             for (k = 0; k < 3; k++) {
    1839         [ #  # ]:          0 :               if (k == dir) {
    1840                 :          0 :                 startPnt[k] = elem_origin[k];
    1841                 :          0 :                 endPnt[k] = startPnt[k] + m_dIntervalSize[k];
    1842                 :            :               }
    1843                 :            :               else {
    1844                 :          0 :                 startPnt[k] = elem_origin[k] + rayIndex[k]*elem_interval_size[k];
    1845                 :          0 :                 endPnt[k] = startPnt[k];
    1846                 :            :               }
    1847                 :            :             }
    1848                 :            :             
    1849                 :            :             // ray-tracing
    1850         [ #  # ]:          0 :             if (!fire_ray(nIntersect, startPnt, endPnt,
    1851         [ #  # ]:          0 :                           tolerance, dir, m_dIntervalSize[dir])) return iBase_FAILURE;
    1852                 :            :             
    1853         [ #  # ]:          0 :             if (nIntersect > 0) { // ray is intersected
    1854                 :          0 :               bOverlapSecond = false;
    1855                 :          0 :               bClosed = true;
    1856         [ #  # ]:          0 :               for (k = 0; k < nIntersect; k++) {
    1857         [ #  # ]:          0 :                 std::vector<moab::EntityHandle> parents;
    1858                 :            :                 //moab::Range parents;
    1859 [ #  # ][ #  # ]:          0 :                 rval = moab_instance()->get_parent_meshsets(m_vhInterSurf[m_vIntersection[k].index],
                 [ #  # ]
    1860         [ #  # ]:          0 :                                                             parents);
    1861         [ #  # ]:          0 :                 if (rval != moab::MB_SUCCESS) {
    1862 [ #  # ][ #  # ]:          0 :                   std::cerr << "Couldn't get parents." << std::endl;
    1863                 :          0 :                   return false;
    1864                 :            :                 }
    1865                 :            : 
    1866                 :          0 :                 nParent = parents.size();
    1867         [ #  # ]:          0 :                 dDistance = m_vIntersection[k].distance;
    1868                 :            :                 
    1869 [ #  # ][ #  # ]:          0 :                 if (is_shared_overlapped_surf(k)) {
    1870         [ #  # ]:          0 :                   if (nParent == 2) { // shared surface
    1871         [ #  # ]:          0 :                     for (l = 0; l < 2; l++) {
    1872         [ #  # ]:          0 :                       if (l == 1) {
    1873                 :          0 :                         dDistance *= -1.;
    1874                 :          0 :                         bClosed = false;
    1875                 :            :                       }
    1876                 :          0 :                       else bClosed = true;
    1877                 :            : 
    1878 [ #  # ][ #  # ]:          0 :                       vf_iter = vol_fraction.find(parents[l]);
    1879 [ #  # ][ #  # ]:          0 :                       if (vf_iter == vol_fraction.end()) {
    1880         [ #  # ]:          0 :                         VolFrac temp_vf(dDistance, bClosed);
    1881 [ #  # ][ #  # ]:          0 :                         vol_fraction[parents[l]] = temp_vf;
    1882                 :            :                         //std::cout << "iHex=" << iHex << ", vh="
    1883                 :            :                         //        << parents[l] << ", dir=" << dir << ", dDistance1="
    1884                 :            :                         //        << dDistance << ", vol="
    1885                 :            :                         //        << temp_vf.vol << std::endl;
    1886                 :            :                       }
    1887                 :            :                       else {
    1888         [ #  # ]:          0 :                         vf_iter->second.vol += dDistance;
    1889         [ #  # ]:          0 :                         vf_iter->second.closed = bClosed;
    1890                 :            :                         //std::cout << "iHex=" << iHex << ", vh="
    1891                 :            :                         //        << vf_iter->first << ", dir=" << dir << ", dDistance1="
    1892                 :            :                         //                         << dDistance << ", vol="
    1893                 :            :                         //        << vf_iter->second.vol << std::endl;
    1894                 :            :                       }
    1895                 :            :                     }
    1896                 :            :                   }
    1897         [ #  # ]:          0 :                   else if (nParent == 1) { // overlapped surface
    1898         [ #  # ]:          0 :                     if (bOverlapSecond) { // second intersection
    1899                 :            :                       /*
    1900                 :            :                       for (int m = 0; m < 3; m++) {
    1901                 :            :                         ePnt[m] = startPnt[m];
    1902                 :            :                       }
    1903                 :            :                       ePnt[dir] += dDistance;
    1904                 :            :                       */
    1905                 :          0 :                       dDistance *= -1.;
    1906                 :          0 :                       bClosed = false;
    1907                 :          0 :                       bOverlapSecond = false;
    1908                 :            :                     }
    1909                 :            :                     else {
    1910                 :            :                       /*
    1911                 :            :                       // make edge
    1912                 :            :                       for (int m = 0; m < 3; m++) {
    1913                 :            :                         if (bClosed) ePnt[m] = startPnt[m];
    1914                 :            :                         ePnt[m + 3] = ePnt[m];
    1915                 :            :                       }
    1916                 :            :                       ePnt[dir + 3] += dDistance;
    1917                 :            :                       if (!make_edge(ePnt, edge_handles)) return iBase_FAILURE;
    1918                 :            :                       */
    1919                 :          0 :                       bOverlapSecond = true;// first intersection
    1920                 :          0 :                       bClosed = true;
    1921                 :            :                     }
    1922                 :            :                     
    1923 [ #  # ][ #  # ]:          0 :                     vf_iter = vol_fraction.find(parents[0]);
    1924 [ #  # ][ #  # ]:          0 :                     if (vf_iter == vol_fraction.end()) {
    1925         [ #  # ]:          0 :                       VolFrac temp_vf(dDistance, bClosed);
    1926 [ #  # ][ #  # ]:          0 :                       vol_fraction[parents[0]] = temp_vf;
    1927                 :            :                       //std::cout << "iHex=" << iHex << ", vh="
    1928                 :            :                       //        << parents[0] << ", dDistance2="
    1929                 :            :                       //        << dDistance << ", vol="
    1930                 :            :                       //        << temp_vf.vol << std::endl;
    1931                 :            :                     }
    1932                 :            :                     else {
    1933         [ #  # ]:          0 :                       vf_iter->second.vol += dDistance;
    1934         [ #  # ]:          0 :                       vf_iter->second.closed = bClosed;
    1935                 :            :                       //std::cout << "iHex=" << iHex << ", vh="
    1936                 :            :                       //        << vf_iter->first << ", dir=" << dir << ", dDistance2="
    1937                 :            :                       //        << dDistance << ", vol="
    1938                 :            :                       //        << vf_iter->second.vol << std::endl;
    1939                 :            :                     }
    1940                 :            :                   }
    1941                 :          0 :                   else return iBase_FAILURE;
    1942                 :            :                 }
    1943                 :            :                 else { // normal case
    1944         [ #  # ]:          0 :                   if (nParent != 1) return iBase_FAILURE;
    1945                 :            : 
    1946 [ #  # ][ #  # ]:          0 :                   if (!is_same_direct_to_ray(k, dir)) {
    1947                 :          0 :                     dDistance *= -1.; // outside
    1948                 :          0 :                     bClosed = false;
    1949                 :            :                   }
    1950                 :          0 :                   else bClosed = true;
    1951                 :            :                   
    1952 [ #  # ][ #  # ]:          0 :                   vf_iter = vol_fraction.find(parents[0]);
    1953 [ #  # ][ #  # ]:          0 :                   if (vf_iter == vol_fraction.end()) {
    1954         [ #  # ]:          0 :                     VolFrac temp_vf(dDistance, bClosed);
    1955 [ #  # ][ #  # ]:          0 :                     vol_fraction[parents[0]] = temp_vf;
    1956                 :            :                     //std::cout << "iHex=" << iHex << ", vh="
    1957                 :            :                     //        << parents[0] << ", dir=" << dir << ", dDistance3="
    1958                 :            :                     //        << dDistance << ", vol="
    1959                 :            :                     //        << temp_vf.vol << std::endl;
    1960                 :            :                   }
    1961                 :            :                   else {
    1962         [ #  # ]:          0 :                     vf_iter->second.vol += dDistance;
    1963 [ #  # ][ #  # ]:          0 :                     vf_iter->second.closed = bClosed;
    1964                 :            :                     //std::cout << "iHex=" << iHex << ", vh="
    1965                 :            :                     //        << vf_iter->first << ", dir=" << dir << ", dDistance3="
    1966                 :            :                     //        << dDistance << ", vol="
    1967                 :            :                     //        << vf_iter->second.vol << std::endl;
    1968                 :            :                   }
    1969                 :            :                 }
    1970                 :          0 :               }
    1971                 :            : 
    1972                 :            :               // if fraction is not closed, add interval size to close
    1973                 :          0 :               vf_iter = vol_fraction.begin();
    1974                 :          0 :               vf_end_iter = vol_fraction.end();
    1975 [ #  # ][ #  # ]:          0 :               for (; vf_iter != vf_end_iter; vf_iter++) {
                 [ #  # ]
    1976 [ #  # ][ #  # ]:          0 :                 if (!vf_iter->second.closed) {
    1977         [ #  # ]:          0 :                   vf_iter->second.vol += m_dIntervalSize[dir];
    1978         [ #  # ]:          0 :                   vf_iter->second.closed = true;
    1979                 :            :                   /*
    1980                 :            :                   for (int m = 0; m < 3; m++) {
    1981                 :            :                     ePnt[m + 3] = startPnt[m];
    1982                 :            :                   }
    1983                 :            :                   ePnt[dir + 3] += m_dIntervalSize[dir];
    1984                 :            :                   if (!make_edge(ePnt, edge_handles)) return iBase_FAILURE;
    1985                 :            :                   */
    1986                 :            :                   //std::cout << "iHex=" << iHex << ", vh="
    1987                 :            :                   //        << vf_iter->first << ", dir=" << dir << ", dDistance4="
    1988                 :            :                   //        << m_dIntervalSize[dir] << ", vol="
    1989                 :            :                   //        << vf_iter->second.vol << std::endl;
    1990                 :            :                 }
    1991                 :            :               }
    1992                 :            :             }
    1993                 :            :             else { // decide if it is fully inside
    1994         [ #  # ]:          0 :               if (!fire_ray(nIntersect, startPnt, rayMaxEnd,
    1995         [ #  # ]:          0 :                             tolerance, dir, m_nDiv[dir]*m_dIntervalSize[dir])) return iBase_FAILURE;
    1996                 :            :               
    1997         [ #  # ]:          0 :               if (nIntersect > 0) { // fully inside
    1998 [ #  # ][ #  # ]:          0 :                 if (is_shared_overlapped_surf(0) || // shared or overlapped
         [ #  # ][ #  # ]
    1999         [ #  # ]:          0 :                     is_same_direct_to_ray(0, dir)) { // other inside case
    2000         [ #  # ]:          0 :                   moab::Range parents;
    2001 [ #  # ][ #  # ]:          0 :                   rval = moab_instance()->get_parent_meshsets(m_vhInterSurf[m_vIntersection[0].index],
                 [ #  # ]
    2002         [ #  # ]:          0 :                                                               parents);
    2003         [ #  # ]:          0 :                   if (rval != moab::MB_SUCCESS) {
    2004 [ #  # ][ #  # ]:          0 :                     std::cerr << "Couldn't get parents." << std::endl;
    2005                 :          0 :                     return false;
    2006                 :            :                   }
    2007                 :            : 
    2008         [ #  # ]:          0 :                   moab::EntityHandle parent_entity = parents.pop_front();
    2009         [ #  # ]:          0 :                   vf_iter = vol_fraction.find(parent_entity);
    2010 [ #  # ][ #  # ]:          0 :                   if (vf_iter == vf_end_iter) {
    2011         [ #  # ]:          0 :                     VolFrac temp_vf(m_dIntervalSize[dir], true);
    2012         [ #  # ]:          0 :                     vol_fraction[parent_entity] = temp_vf;
    2013                 :            :                     //std::cout << "iHex=" << iHex << ", vh="
    2014                 :            :                     //        << parents[0] << ", dir=" << dir << ", dDistance5="
    2015                 :            :                     //                             << dDistance << ", vol="
    2016                 :            :                     //        << temp_vf.vol << std::endl;
    2017                 :            :                   }
    2018                 :            :                   else {
    2019         [ #  # ]:          0 :                     vf_iter->second.vol += m_dIntervalSize[dir];
    2020 [ #  # ][ #  # ]:          0 :                     vf_iter->second.closed = bClosed;
    2021                 :            :                     //std::cout << "iHex=" << iHex << ", vh="
    2022                 :            :                     //        << vf_iter->first << ", dir=" << dir << ", dDistance5="
    2023                 :            :                     //                         << dDistance << ", vol="
    2024                 :            :                     //        << vf_iter->second.vol << std::endl;
    2025                 :          0 :                   }
    2026                 :            :                 }
    2027                 :            :               }
    2028                 :            :             }
    2029                 :            :           }
    2030                 :            :         }
    2031                 :            :       }
    2032                 :            : 
    2033                 :          0 :       int vol_frac_length = vol_fraction.size();
    2034 [ #  # ][ #  # ]:          0 :       std::vector<int> vol_frac_id(vol_frac_length);
    2035         [ #  # ]:          0 :       std::vector<double> vol_frac(vol_frac_length);
    2036                 :          0 :       int vol_frac_id_size = vol_frac_length*sizeof(int);
    2037                 :          0 :       int vol_frac_size = vol_frac_length*sizeof(double);
    2038                 :          0 :       vf_iter = vol_fraction.begin();
    2039                 :          0 :       vf_end_iter = vol_fraction.end();
    2040 [ #  # ][ #  # ]:          0 :       for (int m = 0; vf_iter != vf_end_iter; vf_iter++, m++) {
                 [ #  # ]
    2041 [ #  # ][ #  # ]:          0 :         vol_frac_id[m] = vf_iter->first;
    2042 [ #  # ][ #  # ]:          0 :         vol_frac[m] = vf_iter->second.vol/dTotEdgeElem;
    2043                 :            :         //std::cout << "iHex=" << iHex << ", i=" << index[0]
    2044                 :            :         //        << ", j=" << index[1] << ", k=" << index[2]
    2045                 :            :         //        << ", vol_handle=" << vf_iter->first
    2046                 :            :         //        << ", vol=" << vf_iter->second.vol
    2047                 :            :         //        << ", vol_fraction=" << vf_iter->second.vol/dTotEdgeElem
    2048                 :            :         //        << std::endl;
    2049                 :            :       }
    2050         [ #  # ]:          0 :       const void* vol_frac_ids = &vol_frac_id[0];
    2051         [ #  # ]:          0 :       const void* vol_fracs = &vol_frac[0];
    2052                 :            : 
    2053                 :            :       // set volume fraction information as tag
    2054         [ #  # ]:          0 :       rval = moab_instance()->tag_set_data(reinterpret_cast<moab::Tag> (m_volFracLengthTag),
    2055         [ #  # ]:          0 :                                            reinterpret_cast<moab::EntityHandle*> (&hex_handles[n]),
    2056         [ #  # ]:          0 :                                            1, &vol_frac_length);
    2057 [ #  # ][ #  # ]:          0 :       MBERRCHK(rval, mk_core()->moab_instance());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2058                 :            : 
    2059         [ #  # ]:          0 :       rval = moab_instance()->tag_set_by_ptr(reinterpret_cast<moab::Tag> (m_volFracHandleTag),
    2060         [ #  # ]:          0 :                                            reinterpret_cast<moab::EntityHandle*> (&hex_handles[n]),
    2061         [ #  # ]:          0 :                                            1, &vol_frac_ids, &vol_frac_id_size);
    2062 [ #  # ][ #  # ]:          0 :       MBERRCHK(rval, mk_core()->moab_instance());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2063                 :            : 
    2064         [ #  # ]:          0 :       rval = moab_instance()->tag_set_by_ptr(reinterpret_cast<moab::Tag> (m_volFracTag),
    2065         [ #  # ]:          0 :                                            reinterpret_cast<moab::EntityHandle*> (&hex_handles[n]),
    2066         [ #  # ]:          0 :                                            1, &vol_fracs, &vol_frac_size);
    2067 [ #  # ][ #  # ]:          0 :       MBERRCHK(rval, mk_core()->moab_instance());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2068                 :            : 
    2069                 :            :       if (debug_ebmesh) {
    2070                 :            :         for (int v = 0; v < vol_frac_length; v++) {
    2071                 :            :           std::cout << "#_boundary_hex_handles=" << hex_handles[n]
    2072                 :            :                     << ",vol_frac_handle[" << v << "]=" << vol_frac_id[v]
    2073                 :            :                     << ",vol_fracs[" << v << "]=" << vol_frac[v]
    2074                 :            :                     << std::endl;
    2075                 :            :         }
    2076                 :          0 :       }
    2077                 :            :     }
    2078                 :            :   }  
    2079                 :            : 
    2080 [ #  # ][ #  # ]:          0 :   std::cout << "end get_volume_fraction." << std::endl;
    2081         [ #  # ]:          0 :   delete [] hex_status;
    2082                 :            : 
    2083                 :          0 :   return true;
    2084                 :            : }
    2085                 :            : 
    2086                 :          0 : bool EBMesher::is_same_direct_to_ray(int i, int dir)
    2087                 :            : {
    2088 [ #  # ][ #  # ]:          0 :   moab::CartVect coords[3], normal(0.0), ray_dir(rayDir[dir]);
         [ #  # ][ #  # ]
    2089                 :            :   const moab::EntityHandle *conn;
    2090                 :            :   int len;
    2091                 :            : 
    2092                 :            :   // get triangle normal vector
    2093 [ #  # ][ #  # ]:          0 :   moab::ErrorCode rval = moab_instance()->get_connectivity(m_vhInterFacet[m_vIntersection[i].index],
                 [ #  # ]
    2094         [ #  # ]:          0 :                                                            conn, len);
    2095 [ #  # ][ #  # ]:          0 :   assert(moab::MB_SUCCESS == rval && 3 == len);
    2096                 :            :   
    2097 [ #  # ][ #  # ]:          0 :   rval = moab_instance()->get_coords(conn, 3, coords[0].array());
                 [ #  # ]
    2098                 :            :   (void) rval;
    2099         [ #  # ]:          0 :   assert(moab::MB_SUCCESS == rval);
    2100                 :            : 
    2101         [ #  # ]:          0 :   coords[1] -= coords[0];
    2102         [ #  # ]:          0 :   coords[2] -= coords[0];
    2103 [ #  # ][ #  # ]:          0 :   normal += coords[1] * coords[2];
    2104         [ #  # ]:          0 :   normal.normalize();
    2105                 :            : 
    2106         [ #  # ]:          0 :   return angle(normal, ray_dir) < .5*PI;
    2107                 :            : }
    2108                 :            : 
    2109                 :          0 : void EBMesher::set_obb_tree_box_dimension()
    2110                 :            : {
    2111 [ #  # ][ #  # ]:          0 :   std::cout << "starting to construct obb tree." << std::endl;
    2112         [ #  # ]:          0 :   moab::ErrorCode rval = m_GeomTopoTool->construct_obb_trees(m_bUseWholeGeom);
    2113 [ #  # ][ #  # ]:          0 :   MBERRCHK(rval, mk_core()->moab_instance());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2114                 :            : 
    2115         [ #  # ]:          0 :   m_hObbTree = m_GeomTopoTool->obb_tree();
    2116         [ #  # ]:          0 :   m_hTreeRoot = m_GeomTopoTool->get_one_vol_root();
    2117                 :            : 
    2118 [ #  # ][ #  # ]:          0 :   moab::CartVect box_center, box_axis1, box_axis2, box_axis3;
         [ #  # ][ #  # ]
    2119         [ #  # ]:          0 :   for (int i = 0; i < 3; i++) {
    2120                 :          0 :     m_minCoord[i] = HUGE_VAL;
    2121                 :          0 :     m_maxCoord[i] = 0.;
    2122                 :            :   }
    2123                 :            :   rval = m_hObbTree->box(m_hTreeRoot, box_center.array(),
    2124                 :            :                          box_axis1.array(), box_axis2.array(),
    2125 [ #  # ][ #  # ]:          0 :                          box_axis3.array());
         [ #  # ][ #  # ]
                 [ #  # ]
    2126 [ #  # ][ #  # ]:          0 :   MBERRCHK(rval, mk_core()->moab_instance());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2127                 :            :   
    2128                 :            :   // cartesian box corners
    2129 [ #  # ][ #  # ]:          0 :   moab::CartVect corners[8] = {box_center + box_axis1 + box_axis2 + box_axis3,
    2130 [ #  # ][ #  # ]:          0 :                                box_center + box_axis1 + box_axis2 - box_axis3,
    2131 [ #  # ][ #  # ]:          0 :                                box_center + box_axis1 - box_axis2 + box_axis3,
    2132 [ #  # ][ #  # ]:          0 :                                box_center + box_axis1 - box_axis2 - box_axis3,
    2133 [ #  # ][ #  # ]:          0 :                                box_center - box_axis1 + box_axis2 + box_axis3,
    2134 [ #  # ][ #  # ]:          0 :                                box_center - box_axis1 + box_axis2 - box_axis3,
    2135 [ #  # ][ #  # ]:          0 :                                box_center - box_axis1 - box_axis2 + box_axis3,
    2136 [ #  # ][ #  # ]:          0 :                                box_center - box_axis1 - box_axis2 - box_axis3};
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2137                 :            :   
    2138                 :            :   // get the max, min cartesian box corners
    2139         [ #  # ]:          0 :   for (int i = 0; i < 8; i++) {
    2140         [ #  # ]:          0 :     for (int j = 0; j < 3; j++) {
    2141 [ #  # ][ #  # ]:          0 :       if (corners[i][j] < m_minCoord[j]) m_minCoord[j] = corners[i][j];
                 [ #  # ]
    2142 [ #  # ][ #  # ]:          0 :       if (corners[i][j] > m_maxCoord[j]) m_maxCoord[j] = corners[i][j];
                 [ #  # ]
    2143                 :            :     }
    2144                 :            :   }
    2145 [ #  # ][ #  # ]:          0 :   std::cout << "finished to construct obb tree." << std::endl;
    2146                 :          0 : }
    2147 [ +  - ][ +  - ]:        156 : } // namespace MeshKit

Generated by: LCOV version 1.11