From 7caff943841b0f2b0c9421de6122218766fc9c96 Mon Sep 17 00:00:00 2001 From: vbd Date: Wed, 23 Jul 2008 14:55:13 +0000 Subject: [PATCH] correcting bug in the case when a processor pair interaction is detected while no elements actually intersect. --- src/ParaMEDMEM/ElementLocator.cxx | 106 +++++++++++++++++++----------- 1 file changed, 69 insertions(+), 37 deletions(-) diff --git a/src/ParaMEDMEM/ElementLocator.cxx b/src/ParaMEDMEM/ElementLocator.cxx index b0d32fece..a3e1ee4c7 100644 --- a/src/ParaMEDMEM/ElementLocator.cxx +++ b/src/ParaMEDMEM/ElementLocator.cxx @@ -95,22 +95,25 @@ void ElementLocator::exchangeMesh(int idistantrank, MEDMEM::MESH*& distant_mesh, } } + //send_mesh contains null pointer if elems is empty MEDMEM::MESH* send_mesh= _meshFromElems(elems); // Constituting an array containing the ids of the elements that are // going to be sent to the distant subdomain. // This array enables the correct redistribution of the data when the // interpolated field is transmitted to the target array - - int* distant_ids_send = new int[elems.size()]; - - int index=0; - for (std::set::const_iterator iter = elems.begin(); iter!= elems.end(); iter++) - { - distant_ids_send[index]=*iter; - index++; - } - + int* distant_ids_send=0; + if (elems.size()>0) + { + distant_ids_send = new int[elems.size()]; + + int index=0; + for (std::set::const_iterator iter = elems.begin(); iter!= elems.end(); iter++) + { + distant_ids_send[index]=*iter; + index++; + } + } _exchangeMesh(send_mesh, distant_mesh, idistantrank, distant_ids_send, distant_ids); delete[] distant_ids_send; delete[] elem_bb; @@ -197,11 +200,18 @@ void ElementLocator::_exchangeMesh(MEDMEM::MESH* local_mesh, MEDMEM::MESH*& dist // First stage : exchanging sizes int* send_buffer = new int[6]; int* recv_buffer = new int[6]; - int nbtypes= local_mesh->getNumberOfTypes(MED_EN::MED_CELL); - int nbconn = local_mesh->getConnectivityLength(MED_EN::MED_FULL_INTERLACE, MED_EN::MED_NODAL,MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS); - int nbelems = local_mesh->getNumberOfElements(MED_EN::MED_CELL,MED_EN::MED_ALL_ELEMENTS); + + //treatment for non-empty mesh + int nbtypes=0; + int nbconn=0; + int nbelems=0; + if (local_mesh !=0) { + nbtypes= local_mesh->getNumberOfTypes(MED_EN::MED_CELL); + nbconn = local_mesh->getConnectivityLength(MED_EN::MED_FULL_INTERLACE, MED_EN::MED_NODAL,MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS); + nbelems = local_mesh->getNumberOfElements(MED_EN::MED_CELL,MED_EN::MED_ALL_ELEMENTS); + send_buffer[0] = local_mesh->getSpaceDimension(); send_buffer[1] = local_mesh->getMeshDimension(); send_buffer[2] = local_mesh->getNumberOfNodes(); @@ -234,42 +244,61 @@ void ElementLocator::_exchangeMesh(MEDMEM::MESH* local_mesh, MEDMEM::MESH*& dist //Second stage : exchanging connectivity buffers int nb_integers = nbtypes*2+nbconn+1+nbelems; send_buffer = new int[nb_integers]; - const MED_EN::medGeometryElement* types = local_mesh->getTypes(MED_EN::MED_CELL); - int* ptr_buffer=send_buffer; - const int* conn = local_mesh->getConnectivity(MED_EN::MED_FULL_INTERLACE, MED_EN::MED_NODAL, - MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS); - const int* global_numbering = local_mesh->getGlobalNumberingIndex(MED_EN::MED_CELL); - - memcpy(ptr_buffer, types, nbtypes*sizeof(int)); - ptr_buffer+=nbtypes; - memcpy(ptr_buffer, global_numbering, (nbtypes+1)*sizeof(int)); - ptr_buffer+=nbtypes+1; - memcpy(ptr_buffer,conn, nbconn*sizeof(int)); - ptr_buffer+=nbconn; - memcpy(ptr_buffer, distant_ids_send, nbelems*sizeof(int)); - - //preparing the recv buffers - int nb_recv_integers = 2*distant_nb_types+1+distant_nb_conn+distant_nb_elems; - recv_buffer=new int[nb_recv_integers]; + const MED_EN::medGeometryElement* types=0; + const int* conn = 0; + const int* global_numbering=0; + int* ptr_buffer=send_buffer; + if (local_mesh!=0) + { + conn=local_mesh->getConnectivity(MED_EN::MED_FULL_INTERLACE, MED_EN::MED_NODAL, + MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS); + + global_numbering = local_mesh->getGlobalNumberingIndex(MED_EN::MED_CELL); + types = local_mesh->getTypes(MED_EN::MED_CELL); + + //copying the data in the integer buffer + + memcpy(ptr_buffer, types, nbtypes*sizeof(int)); + ptr_buffer+=nbtypes; + memcpy(ptr_buffer, global_numbering, (nbtypes+1)*sizeof(int)); + ptr_buffer+=nbtypes+1; + memcpy(ptr_buffer,conn, nbconn*sizeof(int)); + ptr_buffer+=nbconn; + memcpy(ptr_buffer, distant_ids_send, nbelems*sizeof(int)); + } + //preparing the recv buffers + int nb_recv_integers = 2*distant_nb_types+1+distant_nb_conn+distant_nb_elems; + recv_buffer=new int[nb_recv_integers]; + //exchanging integer buffer comm_interface.sendRecv(send_buffer, nb_integers, MPI_INT, iprocdistant_in_union, 1111, recv_buffer, nb_recv_integers, MPI_INT, iprocdistant_in_union,1111, *comm, &status); if (nb_integers>0) delete[] send_buffer; - //Third stage : exchanging coordinates - + + //Third stage : exchanging coordinates int nb_recv_floats = distant_space_dim*distant_nnodes; - int nb_send_floats = local_mesh->getSpaceDimension()* local_mesh->getNumberOfNodes(); - double* recv_coords = new double[nb_recv_floats]; - double* coords = const_cast (local_mesh->getCoordinates(MED_EN::MED_FULL_INTERLACE)); - comm_interface.sendRecv(coords, nb_send_floats, MPI_DOUBLE, iprocdistant_in_union, 1112, + int nb_send_floats=0; + double* coords=0; + double* recv_coords=0; + + if (local_mesh!=0) + { + nb_send_floats = local_mesh->getSpaceDimension()* local_mesh->getNumberOfNodes(); + coords = const_cast (local_mesh->getCoordinates(MED_EN::MED_FULL_INTERLACE)); + } + + if (nb_recv_floats>0) + recv_coords = new double[nb_recv_floats]; + + comm_interface.sendRecv(coords, nb_send_floats, MPI_DOUBLE, iprocdistant_in_union, 1112, recv_coords, nb_recv_floats, MPI_DOUBLE, iprocdistant_in_union, 1112, *group->getComm(), &status); //Reconstructing an image of the distant mesh locally - if (nb_recv_integers>0) + if (nb_recv_integers>0 && distant_space_dim !=0) { MEDMEM::MESHING* meshing = new MEDMEM::MESHING (); int* recv_buffer_ptr = recv_buffer; @@ -314,6 +343,9 @@ void ElementLocator::_exchangeMesh(MEDMEM::MESH* local_mesh, MEDMEM::MESH*& dist MEDMEM::MESH* ElementLocator::_meshFromElems(set& elems) { + //returns null pointer if there are no elems in the mesh + if (elems.size()==0) return 0; + //defining pointers to med const int* conn_mesh=_local_mesh->getConnectivity(MED_EN::MED_FULL_INTERLACE, MED_EN::MED_NODAL, -- 2.39.2