Quinoa all test code coverage report
Current view: top level - Transfer - TransferDetails.cpp (source / functions) Hit Total Coverage
Commit: -128-NOTFOUND Lines: 107 108 99.1 %
Date: 2024-05-15 16:30:14 Functions: 9 10 90.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 47 72 65.3 %

           Branch data     Line data    Source code
       1                 :            : // *****************************************************************************
       2                 :            : /*!
       3                 :            :   \file      src/Transfer/TransferDetails.cpp
       4                 :            :   \copyright 2020 Charmworks, Inc.
       5                 :            :              All rights reserved. See the LICENSE file for details.
       6                 :            :   \brief     Chare class declaration for mesh transfer workers holding part of a
       7                 :            :     mesh
       8                 :            :   \details   Chare class declaration for mesh transfer workers holding part of a
       9                 :            :     mesh.
      10                 :            : */
      11                 :            : // *****************************************************************************
      12                 :            : 
      13                 :            : #include "TransferDetails.hpp"
      14                 :            : #include "Reorder.hpp"
      15                 :            : #include "DerivedData.hpp"
      16                 :            : #include "M2MTransfer.hpp"
      17                 :            : 
      18                 :            : #include "collidecharm.h"
      19                 :            : 
      20                 :            : #if defined(__clang__)
      21                 :            :   #pragma clang diagnostic push
      22                 :            :   #pragma clang diagnostic ignored "-Wold-style-cast"
      23                 :            : #endif
      24                 :            : 
      25                 :          0 : PUPbytes(Collision);
      26                 :            : 
      27                 :            : #if defined(__clang__)
      28                 :            :   #pragma clang diagnostic pop
      29                 :            : #endif
      30                 :            : 
      31                 :            : namespace exam2m {
      32                 :            : extern CollideHandle collideHandle;
      33                 :            : extern CProxy_M2MTransfer m2mtransferProxy;
      34                 :            : }
      35                 :            : 
      36                 :            : using exam2m::TransferDetails;
      37                 :            : 
      38                 :         14 : TransferDetails::TransferDetails( CkArrayID p, MeshData d, CkCallback cb ) :
      39         [ +  - ]:         14 :     m_firstchunk(d.m_firstchunk)
      40                 :            : // *****************************************************************************
      41                 :            : //  Constructor
      42                 :            : //! \param[in] firstchunk Chunk ID used for the collision detection library
      43                 :            : //! \param[in] cb Callback to inform application that the library is ready
      44                 :            : // *****************************************************************************
      45                 :            : {
      46         [ +  - ]:         14 :   CollideRegister(collideHandle, m_firstchunk + thisIndex);
      47                 :            :   d.m_proxy = thisProxy;
      48         [ +  - ]:         14 :   m2mtransferProxy.ckLocalBranch()->setMesh( p, d );
      49         [ +  - ]:         14 :   contribute(cb);
      50                 :         14 : }
      51                 :            : 
      52                 :            : void
      53                 :       1232 : TransferDetails::setSourceTets(
      54                 :            :     std::vector< std::size_t>* inpoel,
      55                 :            :     tk::UnsMesh::Coords* coords,
      56                 :            :     const tk::Fields& u )
      57                 :            : // *****************************************************************************
      58                 :            : //  Set the data for the source tetrahedrons to be collided
      59                 :            : //! \param[in] inpoel Pointer to the connectivity data for the source mesh
      60                 :            : //! \param[in] coords Pointer to the coordinate data for the source mesh
      61                 :            : //! \param[in] u Pointer to the solution data for the source mesh
      62                 :            : // *****************************************************************************
      63                 :            : {
      64                 :       1232 :   m_coord = coords;
      65                 :       1232 :   m_u = const_cast< tk::Fields* >( &u );
      66                 :       1232 :   m_inpoel = inpoel;
      67                 :            : 
      68                 :            :   // Send tetrahedron data to the collision detection library
      69                 :       1232 :   collideTets();
      70                 :       1232 : }
      71                 :            : 
      72                 :            : void
      73                 :       1232 : TransferDetails::setDestPoints(
      74                 :            :     tk::UnsMesh::Coords* coords,
      75                 :            :     tk::Fields& u,
      76                 :            :     CkCallback cb )
      77                 :            : // *****************************************************************************
      78                 :            : //  Set the data for the destination points to be collided
      79                 :            : //! \param[in] coords Pointer to the coordinate data for the destination mesh
      80                 :            : //! \param[in,out] u Pointer to the solution data for the destination mesh
      81                 :            : //! \param[in] cb Callback to call once this chare received all solution data
      82                 :            : // *****************************************************************************
      83                 :            : {
      84                 :       1232 :   m_coord = coords;
      85                 :       1232 :   m_u = static_cast< tk::Fields* >( &u );
      86                 :       1232 :   m_donecb = cb;
      87                 :            : 
      88                 :            :   // Initialize msg counters, callback, and background solution data
      89                 :       1232 :   m_numsent = 0;
      90                 :       1232 :   m_numreceived = 0;
      91                 :       1232 :   background();
      92                 :            : 
      93                 :            :   // Send vertex data to the collision detection library
      94                 :       1232 :   collideVertices();
      95                 :       1232 : }
      96                 :            : 
      97                 :            : void
      98                 :       1232 : TransferDetails::background()
      99                 :            : // *****************************************************************************
     100                 :            : // Initialize dest mesh solution with background data
     101                 :            : //! \details This is useful to see what points did not receive solution.
     102                 :            : // *****************************************************************************
     103                 :            : {
     104                 :       1232 :   tk::Fields& u = *m_u;
     105         [ +  + ]:     976330 :   for (std::size_t i = 0; i < u.nunk(); ++i) u(i,0) = -1.0;
     106                 :       1232 : }
     107                 :            : 
     108                 :            : void
     109                 :       1232 : TransferDetails::collideVertices()
     110                 :            : // *****************************************************************************
     111                 :            : // Pass vertex information to the collision detection library
     112                 :            : // *****************************************************************************
     113                 :            : {
     114                 :       1232 :   const tk::UnsMesh::Coords& coord = *m_coord;
     115                 :       1232 :   auto nVertices = coord[0].size();
     116                 :            :   std::size_t nBoxes = 0;
     117                 :       1232 :   std::vector< bbox3d > boxes( nVertices );
     118 [ +  - ][ -  - ]:       1232 :   std::vector< int > prio( nVertices );
     119                 :       1232 :   auto firstchunk = static_cast< int >( m_firstchunk );
     120         [ +  + ]:     976330 :   for (std::size_t i=0; i<nVertices; ++i) {
     121                 :     975098 :     boxes[nBoxes].empty();
     122                 :     975098 :     boxes[nBoxes].add(CkVector3d(coord[0][i], coord[1][i], coord[2][i]));
     123                 :     975098 :     prio[nBoxes] = firstchunk;
     124                 :     975098 :     ++nBoxes;
     125                 :            :   }
     126                 :       1232 :   CollideBoxesPrio( collideHandle, firstchunk + thisIndex,
     127         [ +  - ]:       1232 :                     static_cast<int>(nBoxes), boxes.data(), prio.data() );
     128                 :       1232 : }
     129                 :            : 
     130                 :            : void
     131                 :       1232 : TransferDetails::collideTets() const
     132                 :            : // *****************************************************************************
     133                 :            : // Pass tet information to the collision detection library
     134                 :            : // *****************************************************************************
     135                 :            : {
     136                 :       1232 :   const std::vector< std::size_t >& inpoel = *m_inpoel;
     137                 :       1232 :   const tk::UnsMesh::Coords& coord = *m_coord;
     138                 :       1232 :   auto nBoxes = inpoel.size() / 4;
     139                 :       1232 :   std::vector< bbox3d > boxes( nBoxes );
     140 [ +  - ][ -  - ]:       1232 :   std::vector< int > prio( nBoxes );
     141                 :       1232 :   auto firstchunk = static_cast< int >( m_firstchunk );
     142         [ +  + ]:    4107957 :   for (std::size_t i=0; i<nBoxes; ++i) {
     143                 :    4106725 :     boxes[i].empty();
     144                 :    4106725 :     prio[i] = firstchunk;
     145         [ +  + ]:   20533625 :     for (std::size_t j=0; j<4; ++j) {
     146                 :            :       // Get index of the jth point of the ith tet
     147                 :   16426900 :       auto p = inpoel[i * 4 + j];
     148                 :            :       // Add that point to the tets bounding box
     149                 :   32853800 :       boxes[i].add(CkVector3d(coord[0][p], coord[1][p], coord[2][p]));
     150                 :            :     }
     151                 :            :   }
     152                 :       1232 :   CollideBoxesPrio( collideHandle, firstchunk + thisIndex,
     153         [ +  - ]:       1232 :                     static_cast<int>(nBoxes), boxes.data(), prio.data() );
     154                 :       1232 : }
     155                 :            : 
     156                 :            : void
     157                 :       1232 : TransferDetails::processCollisions(
     158                 :            :     CProxy_TransferDetails proxy,
     159                 :            :     int numchares,
     160                 :            :     int chunkoffset,
     161                 :            :     int nColl,
     162                 :            :     Collision* colls )
     163                 :            : // *****************************************************************************
     164                 :            : //  Process potential collisions by sending my points to the source mesh chares
     165                 :            : //  that they potentially collide with.
     166                 :            : //! \param[in] proxy Proxy for the source mesh chares
     167                 :            : //! \param[in] numchares Number of chares in the source mesh chare array
     168                 :            : //! \param[in] chunkoffset First chunk ID of the source mesh
     169                 :            : //! \param[in] nColl Number of potential collisions to process
     170                 :            : //! \param[in] colls List of potential collisions
     171                 :            : // *****************************************************************************
     172                 :            : {
     173                 :       1232 :   const tk::UnsMesh::Coords& coord = *m_coord;
     174                 :       1232 :   int mychunk = thisIndex + m_firstchunk;
     175                 :            : 
     176                 :            :   std::vector< std::vector< PotentialCollision > >
     177                 :       2464 :     pColls( static_cast<std::size_t>(numchares) );
     178                 :            : 
     179                 :            :   // Separate potential collisions into lists based on the source mesh chare
     180                 :            :   // that is involved in the potential collision
     181         [ +  + ]:    3462254 :   for (int i = 0; i < nColl; i++) {
     182                 :            :     int chareindex;
     183                 :            :     PotentialCollision pColl;
     184         [ +  + ]:    3461022 :     if (colls[i].A.chunk == mychunk) {
     185                 :     203350 :       chareindex = colls[i].B.chunk - chunkoffset;
     186                 :     203350 :       pColl.dest_index = static_cast<std::size_t>(colls[i].A.number);
     187                 :     203350 :       pColl.source_index = static_cast<std::size_t>(colls[i].B.number);
     188                 :            :     } else {
     189                 :    3257672 :       chareindex = colls[i].A.chunk - chunkoffset;
     190                 :    3257672 :       pColl.dest_index = static_cast<std::size_t>(colls[i].B.number);
     191                 :    3257672 :       pColl.source_index = static_cast<std::size_t>(colls[i].A.number);
     192                 :            :     }
     193                 :            : 
     194                 :            :     #if defined(STRICT_GNUC)
     195                 :            :       #pragma GCC diagnostic push
     196                 :            :       #pragma GCC diagnostic ignored "-Wdeprecated-copy"
     197                 :            :     #endif
     198         [ +  - ]:    3461022 :     pColl.point = { coord[0][pColl.dest_index],
     199                 :    3461022 :                     coord[1][pColl.dest_index],
     200                 :    3461022 :                     coord[2][pColl.dest_index] };
     201                 :            :     #if defined(STRICT_GNUC)
     202                 :            :       #pragma GCC diagnostic pop
     203                 :            :     #endif
     204                 :            : 
     205         [ +  - ]:    3461022 :     pColls[ static_cast<std::size_t>(chareindex) ].push_back( pColl );
     206                 :            :   }
     207                 :            : 
     208                 :            :   // Send out the lists of potential collisions to the source mesh chares
     209         [ +  + ]:       6136 :   for (int i = 0; i < numchares; i++) {
     210                 :       4904 :     auto I = static_cast< std::size_t >( i );
     211                 :       4904 :     m_numsent++;
     212         [ +  - ]:       9808 :     proxy[i].determineActualCollisions( thisProxy,
     213         [ +  - ]:       4904 :                                         thisIndex,
     214         [ +  - ]:       4904 :                                         static_cast<int>(pColls[I].size()),
     215         [ +  - ]:       4904 :                                         pColls[I].data() );
     216                 :            :   }
     217                 :       1232 : }
     218                 :            : 
     219                 :            : void
     220                 :       4904 : TransferDetails::determineActualCollisions(
     221                 :            :     CProxy_TransferDetails proxy,
     222                 :            :     int index,
     223                 :            :     int nColls,
     224                 :            :     PotentialCollision* colls ) const
     225                 :            : // *****************************************************************************
     226                 :            : //  Identify actual collisions by calling intet on all possible collisions, and
     227                 :            : //  interpolate solution values to send back to the destination mesh.
     228                 :            : //! \param[in] proxy The proxy of the destination mesh chare array
     229                 :            : //! \param[in] index The index in proxy to return the solution data to
     230                 :            : //! \param[in] nColls Number of collisions to be checked
     231                 :            : //! \param[in] colls List of potential collisions
     232                 :            : // *****************************************************************************
     233                 :            : {
     234                 :       4904 :   const std::vector< std::size_t >& inpoel = *m_inpoel;
     235                 :       4904 :   tk::Fields& u = *m_u;
     236                 :            :   //CkPrintf("Source chare %i received data for %i potential collisions\n",
     237                 :            :   //    thisIndex, nColls);
     238                 :            : 
     239                 :            :   std::array< real, 4 > N;
     240                 :            :   int numInTet = 0;
     241                 :       4904 :   std::vector< SolutionData > return_data;
     242                 :            : 
     243                 :            :   // Iterate over my potential collisions and call intet() to determine
     244                 :            :   // if an actual collision occurred, and if so interpolate solution to dest
     245         [ +  + ]:    3465926 :   for (int i = 0; i < nColls; i++) {
     246                 :            :     std::vector< tk::real > point
     247         [ +  - ]:    3461022 :       {colls[i].point.x, colls[i].point.y, colls[i].point.z};
     248 [ +  - ][ +  + ]:    3461022 :     if (tk::intet(*m_coord, *m_inpoel, point, colls[i].source_index, N))
     249                 :            :     {
     250                 :            :       numInTet++;
     251                 :            :       SolutionData data;
     252                 :     460097 :       data.dest_index = colls[i].dest_index;
     253                 :     460097 :       auto e = colls[i].source_index;
     254         [ +  - ]:     460097 :       const auto A = inpoel[e*4+0];
     255                 :     460097 :       const auto B = inpoel[e*4+1];
     256                 :     460097 :       const auto C = inpoel[e*4+2];
     257                 :     460097 :       const auto D = inpoel[e*4+3];
     258         [ +  - ]:     460097 :       data.solution.resize( u.nprop() );
     259         [ +  + ]:    3220679 :       for (std::size_t c=0; c<u.nprop(); ++c) {
     260                 :    2760582 :         data.solution[c] = N[0]*u(A,c) + N[1]*u(B,c) + N[2]*u(C,c) + N[3]*u(D,c);
     261                 :            :       }
     262         [ +  - ]:     460097 :       return_data.push_back(data);
     263                 :            :     }
     264                 :            :   }
     265                 :            :   //CkPrintf("Source chare %i found %i/%i actual collisions\n",
     266                 :            :   //    thisIndex, numInTet, nColls);
     267                 :            :   // Send the solution data for the actual collisions back to the dest mesh
     268 [ +  - ][ +  - ]:       9808 :   proxy[index].transferSolution( return_data );
     269                 :       4904 : }
     270                 :            : 
     271                 :            : void
     272                 :       4904 : TransferDetails::transferSolution( const std::vector< SolutionData >& soln )
     273                 :            : // *****************************************************************************
     274                 :            : //  Receive the solution data for destination mesh points that collided with the
     275                 :            : //  source mesh tetrahedrons
     276                 :            : //! \param[in] soln List of solutions
     277                 :            : // *****************************************************************************
     278                 :            : {
     279                 :       4904 :   tk::Fields& u = *m_u;
     280                 :            : 
     281         [ +  + ]:     465001 :   for (std::size_t i=0; i<soln.size(); ++i) {
     282         [ +  + ]:    3220679 :     for (std::size_t c=0; c<u.nprop(); ++c) {
     283                 :    2760582 :       u(soln[i].dest_index,c) = soln[i].solution[c];
     284                 :            :     }
     285                 :            :   }
     286                 :            : 
     287                 :            :   // Inform the caller if we've received all solution data
     288                 :       4904 :   m_numreceived++;
     289         [ +  + ]:       4904 :   if (m_numreceived == m_numsent) {
     290                 :       1232 :     m_donecb.send();
     291                 :            :   }
     292                 :       4904 : }
     293                 :            : 
     294                 :            : #include "NoWarning/transferdetails.def.h"

Generated by: LCOV version 1.14