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 : 3257672 : chareindex = colls[i].B.chunk - chunkoffset; 186 : 3257672 : pColl.dest_index = static_cast<std::size_t>(colls[i].A.number); 187 : 3257672 : pColl.source_index = static_cast<std::size_t>(colls[i].B.number); 188 : : } else { 189 : 203350 : chareindex = colls[i].A.chunk - chunkoffset; 190 : 203350 : pColl.dest_index = static_cast<std::size_t>(colls[i].B.number); 191 : 203350 : 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"