/[escript]/trunk/finley/src/Assemble_CopyNodalData.c
ViewVC logotype

Diff of /trunk/finley/src/Assemble_CopyNodalData.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 751 by bcumming, Mon Jun 26 01:46:34 2006 UTC revision 782 by bcumming, Tue Jul 18 00:47:47 2006 UTC
# Line 37  Line 37 
37    
38    bufferExternal must be large enough to accomdate the external nodal data (numComps*numExternal)    bufferExternal must be large enough to accomdate the external nodal data (numComps*numExternal)
39  */  */
40  static bool_t getExternalDOF( Finley_NodeFile *nodes, escriptDataC* in, double *externalBuffer, dim_t numComps )  static bool_t getExternalDOF( Finley_NodeFile *nodes, escriptDataC* in, double *externalBuffer, dim_t numComps, bool_t doReduced )
41  {  {
42    double *sendBuffer=NULL;    double *sendBuffer=NULL;
43    index_t n, i, myMax=0;    index_t n, i, myMax=0;
44    bool_t result;    bool_t result=TRUE;
45        Finley_NodeDistribution *distribution=NULL;
46    for( i=0; i<nodes->degreeOfFreedomDistribution->numNeighbours; i++ )      Paso_CommBuffer *CommBuffer=NULL;
47      if( myMax < nodes->degreeOfFreedomDistribution->edges[i]->numForward )      if( doReduced ) {
48        myMax = nodes->degreeOfFreedomDistribution->edges[i]->numForward;          distribution = nodes->reducedDegreeOfFreedomDistribution;
49            CommBuffer = nodes->reducedCommBuffer;
50        }
51        else {
52            distribution = nodes->degreeOfFreedomDistribution;
53            CommBuffer = nodes->CommBuffer;
54        }
55    
56      for( i=0; i<distribution->numNeighbours; i++ )
57        if( myMax < distribution->edges[i]->numForward )
58          myMax = distribution->edges[i]->numForward;
59    if( myMax )    if( myMax )
60      sendBuffer = MEMALLOC( myMax*numComps, double );      sendBuffer = MEMALLOC( myMax*numComps, double );
61    
62    /* pack and send DOF information to neighbour domains */    /* pack and send DOF information to neighbour domains */
63    for( n=0; n<nodes->degreeOfFreedomDistribution->numNeighbours; n++ )    for( n=0; n<distribution->numNeighbours; n++ )
64    {    {
65      /* pack data */      /* pack data */
66      for( i=0; i<nodes->degreeOfFreedomDistribution->edges[n]->numForward; i++ )        for( i=0; i<distribution->edges[n]->numForward; i++ )
67        memcpy( sendBuffer + i*numComps, getSampleData(in,nodes->degreeOfFreedomDistribution->edges[n]->indexForward[i]), numComps*sizeof(double) );        memcpy( sendBuffer + i*numComps, getSampleData(in,distribution->edges[n]->indexForward[i]), numComps*sizeof(double) );
68            
69      /* place it in the send buffer */      /* place it in the send buffer */
70      Paso_CommBuffer_pack( nodes->CommBuffer, nodes->degreeOfFreedomDistribution->neighbours[n], NULL, sendBuffer, numComps*sizeof(double), 0 );      Paso_CommBuffer_pack( CommBuffer, distribution->neighbours[n], NULL, sendBuffer, numComps*sizeof(double), 0 );
71        
72      /* send it */      /* send it */
73      result = Paso_CommBuffer_send( nodes->CommBuffer, nodes->degreeOfFreedomDistribution->neighbours[n], numComps*sizeof(double) );      result = Paso_CommBuffer_send( CommBuffer, distribution->neighbours[n], numComps*sizeof(double) );
74      if( result==FALSE )      if( result==FALSE )
75        return FALSE;        return FALSE;
76    }    }
# Line 68  static bool_t getExternalDOF( Finley_Nod Line 78  static bool_t getExternalDOF( Finley_Nod
78    MEMFREE( sendBuffer );    MEMFREE( sendBuffer );
79    
80    /* receive and unpack external DOF information from neigbours */    /* receive and unpack external DOF information from neigbours */
81    for( n=0; n<nodes->degreeOfFreedomDistribution->numNeighbours; n++ )    for( n=0; n<distribution->numNeighbours; n++ )
82    {    {
83      /* receive data */      /* receive data */
84      result = Paso_CommBuffer_recv( nodes->CommBuffer, nodes->degreeOfFreedomDistribution->neighbours[n], numComps*sizeof(double) );      result = Paso_CommBuffer_recv( CommBuffer, distribution->neighbours[n], numComps*sizeof(double) );
85      if( result==FALSE )      if( result==FALSE )
86        return FALSE;        return FALSE;
87    
88      /* unpack the data */      /* unpack the data */
89      Paso_CommBuffer_unpack( nodes->CommBuffer, nodes->degreeOfFreedomDistribution->neighbours[n], nodes->degreeOfFreedomDistribution->edges[n]->indexBackward, externalBuffer, numComps*sizeof(double), -nodes->degreeOfFreedomDistribution->numLocal );      Paso_CommBuffer_unpack( CommBuffer, distribution->neighbours[n], distribution->edges[n]->indexBackward, externalBuffer, numComps*sizeof(double), -distribution->numLocal );
90    }    }
91    
92    return TRUE;    return TRUE;
# Line 159  void Finley_Assemble_CopyNodalData(Finle Line 169  void Finley_Assemble_CopyNodalData(Finle
169        corresponding to external nodes from neighbouring domains. Communication is handled by        corresponding to external nodes from neighbouring domains. Communication is handled by
170        the Paso_CommBuffer that is attached to nodes. Copying the other direction (nodes to DOF)        the Paso_CommBuffer that is attached to nodes. Copying the other direction (nodes to DOF)
171        is similar to the serial case, with just a little bit more care required to ensure that        is similar to the serial case, with just a little bit more care required to ensure that
172        only local values are copied. Piece of cake. */        only local values are copied. */
173      if (Finley_noError()) {      if (Finley_noError()) {
174          if (in_data_type == FINLEY_NODES) {          if (in_data_type == FINLEY_NODES) {
175             if  (out_data_type == FINLEY_NODES) {             if  (out_data_type == FINLEY_NODES) {
# Line 190  void Finley_Assemble_CopyNodalData(Finle Line 200  void Finley_Assemble_CopyNodalData(Finle
200              {              {
201  #ifdef PASO_MPI  #ifdef PASO_MPI
202                double *externalBuffer = MEMALLOC( numComps*nodes->degreeOfFreedomDistribution->numExternal, double );                double *externalBuffer = MEMALLOC( numComps*nodes->degreeOfFreedomDistribution->numExternal, double );
203                getExternalDOF( nodes, in, externalBuffer, numComps );                getExternalDOF( nodes, in, externalBuffer, numComps, FALSE );
204                for (n=0;n<nodes->numNodes;n++) {                for (n=0;n<nodes->numNodes;n++) {
205                  if( nodes->degreeOfFreedom[n]<nodes->degreeOfFreedomDistribution->numLocal )                  if( nodes->degreeOfFreedom[n]<nodes->degreeOfFreedomDistribution->numLocal )
206                    Finley_copyDouble(numComps,getSampleData(in,nodes->degreeOfFreedom[n]),getSampleData(out,n));                    Finley_copyDouble(numComps,getSampleData(in,nodes->degreeOfFreedom[n]),getSampleData(out,n));
# Line 213  void Finley_Assemble_CopyNodalData(Finle Line 223  void Finley_Assemble_CopyNodalData(Finle
223                for (i=0;i<nodes->numNodes;i++) {                for (i=0;i<nodes->numNodes;i++) {
224                    n=nodes->reducedDegreeOfFreedom[i];                    n=nodes->reducedDegreeOfFreedom[i];
225  #ifdef PASO_MPI  #ifdef PASO_MPI
226                  if( n>=0 && nodes->degreeOfFreedom[n]<nodes->degreeOfFreedomDistribution->numLocal )                  if( n>=0 && n<nodes->reducedDegreeOfFreedomDistribution->numLocal )
227  #else  #else
228                  if (n>=0)                  if (n>=0)
229  #endif    #endif  
# Line 221  void Finley_Assemble_CopyNodalData(Finle Line 231  void Finley_Assemble_CopyNodalData(Finle
231                }                }
232             }             }
233          }          }
 #ifndef PASO_MPI  
234          else if (in_data_type == FINLEY_REDUCED_DEGREES_OF_FREEDOM) {          else if (in_data_type == FINLEY_REDUCED_DEGREES_OF_FREEDOM) {
235             if (out_data_type == FINLEY_REDUCED_DEGREES_OF_FREEDOM) {             if (out_data_type == FINLEY_REDUCED_DEGREES_OF_FREEDOM) {
236                #pragma omp parallel for private(n) schedule(static)                #pragma omp parallel for private(n) schedule(static)
237                for (n=0;n<nodes->reducedNumDegreesOfFreedom;n++)                for (n=0;n<nodes->reducedNumDegreesOfFreedom;n++)
238                      Finley_copyDouble(numComps,getSampleData(in,n),getSampleData(out,n));                      Finley_copyDouble(numComps,getSampleData(in,n),getSampleData(out,n));
239             } else if (out_data_type == FINLEY_DEGREES_OF_FREEDOM && numSamplesEqual(out,1,nodes->reducedNumDegreesOfFreedom)) {             } else if (out_data_type == FINLEY_DEGREES_OF_FREEDOM ) {
240                #pragma omp parallel for private(n) schedule(static)                #pragma omp parallel for private(n) schedule(static)
241                for (i=0;i<nodes->numNodes;i++) {                for (i=0;i<nodes->numNodes;i++) {
242                    n=nodes->reducedDegreeOfFreedom[i];                    n=nodes->reducedDegreeOfFreedom[i];
243                    if (n>=0) Finley_copyDouble(numComps,getSampleData(in,n),getSampleData(out,nodes->degreeOfFreedom[i]));  #ifdef PASO_MPI
244                        if( n>=0 && nodes->reducedDegreeOfFreedom[n]<nodes->reducedDegreeOfFreedomDistribution->numLocal )
245    #else
246                      if (n>=0)
247    #endif
248                        Finley_copyDouble(numComps,getSampleData(in,n),getSampleData(out,nodes->degreeOfFreedom[i]));
249                }                }
250             } else if (out_data_type == FINLEY_NODES && numSamplesEqual(out,1,nodes->reducedNumDegreesOfFreedom)) {             } else if (out_data_type == FINLEY_NODES ) {
251    #ifdef PASO_MPI
252                  double *externalBuffer = MEMALLOC( numComps*nodes->reducedDegreeOfFreedomDistribution->numExternal, double );
253                  getExternalDOF( nodes, in, externalBuffer, numComps, TRUE );
254                  for (n=0;n<nodes->numNodes;n++) {
255                                    i = nodes->reducedDegreeOfFreedom[n];
256                                    if( i>=0 ) {
257                                        if( i<nodes->reducedDegreeOfFreedomDistribution->numLocal )
258                                            Finley_copyDouble(numComps,getSampleData(in,i),getSampleData(out,n));
259                                        else
260                                            Finley_copyDouble(numComps,externalBuffer + numComps*(i - nodes->reducedDegreeOfFreedomDistribution->numLocal),getSampleData(out,n));
261                                    }
262                                }
263                  
264                  MEMFREE( externalBuffer );
265    #else
266                #pragma omp parallel for private(n) schedule(static)                #pragma omp parallel for private(n) schedule(static)
267                for (i=0;i<nodes->numNodes;i++) {                for (i=0;i<nodes->numNodes;i++) {
268                    n=nodes->reducedDegreeOfFreedom[i];                    n=nodes->reducedDegreeOfFreedom[i];
269                    if (n>=0) Finley_copyDouble(numComps,getSampleData(in,n),getSampleData(out,i));                    if (n>=0)
270                                            Finley_copyDouble(numComps,getSampleData(in,n),getSampleData(out,i));
271                }                }
272    #endif
273             } else {             } else {
274               Finley_setError(TYPE_ERROR,"__FILE__: cannot copy from data on reduced degrees of freedom");               Finley_setError(TYPE_ERROR,"__FILE__: cannot copy from data on reduced degrees of freedom");
275             }             }
276          }          }
 #else  
         else if (in_data_type == FINLEY_REDUCED_DEGREES_OF_FREEDOM) {  
           Finley_setError(TYPE_ERROR,"__FILE__: cannot copy from data on reduced degrees of freedom : MPI implementation does not support this yet");  
         }  
 #endif  
277     }     }
278     return;     return;
279  }  }

Legend:
Removed from v.751  
changed lines
  Added in v.782

  ViewVC Help
Powered by ViewVC 1.1.26