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

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

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

trunk/esys2/finley/src/finleyC/NodeFile_gatter.c revision 150 by jgs, Thu Sep 15 03:44:45 2005 UTC trunk/finley/src/NodeFile_gather.c revision 1766 by gross, Mon Sep 8 02:51:14 2008 UTC
# Line 1  Line 1 
 /*  
  ******************************************************************************  
  *                                                                            *  
  *       COPYRIGHT  ACcESS 2003,2004,2005 -  All Rights Reserved              *  
  *                                                                            *  
  * This software is the property of ACcESS. No part of this code              *  
  * may be copied in any form or by any means without the expressed written    *  
  * consent of ACcESS.  Copying, use or modification of this software          *  
  * by any unauthorised person is illegal unless that person has a software    *  
  * license agreement with ACcESS.                                             *  
  *                                                                            *  
  ******************************************************************************  
 */  
1    
2  /**************************************************************/  /* $Id$ */
   
 /*   Finley: Mesh: NodeFile                                   */  
   
 /*   gathers the NodeFile out from the  NodeFile in using index[0:out->numNodes-1].  */  
 /*   index has to be between 0 and in->numNodes-1. */  
3    
4  /**************************************************************/  /*******************************************************
5     *
6  /*   Author: gross@access.edu.au */   *           Copyright 2003-2007 by ACceSS MNRF
7  /*   Version: $Id$ */   *       Copyright 2007 by University of Queensland
8     *
9  /**************************************************************/   *                http://esscc.uq.edu.au
10     *        Primary Business: Queensland, Australia
11     *  Licensed under the Open Software License version 3.0
12     *     http://www.opensource.org/licenses/osl-3.0.php
13     *
14     *******************************************************/
15    
16    /**************************************************************
17     *
18     *   Finley: Mesh: NodeFile                                  
19     *   gathers the NodeFile out from the NodeFile in using the entries
20     *   in index[0:out->numNodes-1] which are between min_index and max_index (exclusive)
21     *   the node index[i]
22     *
23     **************************************************************/
24    
25  #include "NodeFile.h"  #include "NodeFile.h"
26    
27  /**************************************************************/  /**************************************************************/
28    
29  void Finley_NodeFile_gather(int* index, Finley_NodeFile* in, Finley_NodeFile* out) {  void Finley_NodeFile_gatherEntries(dim_t n, index_t* index, index_t min_index, index_t max_index,
30     dim_t i,j;                                     index_t* Id_out, index_t* Id_in,
31     index_t k;                                     index_t* Tag_out, index_t* Tag_in,
32     if (in->Id!=NULL) {                                     index_t* globalDegreesOfFreedom_out, index_t* globalDegreesOfFreedom_in,
33       #pragma omp parallel for private(i,j,k) schedule(static)                                     dim_t numDim, double* Coordinates_out, double* Coordinates_in)
34       for (i=0;i<out->numNodes;i++) {  {
35          k=index[i];     dim_t i;
36          out->Id[i]=in->Id[k];     register index_t k;
37          out->Tag[i]=in->Tag[k];     const index_t range=max_index-min_index;
38          out->degreeOfFreedom[i]=in->degreeOfFreedom[k];     const  size_t numDim_size=(size_t)numDim*sizeof(double);
39          out->reducedDegreeOfFreedom[i]=in->reducedDegreeOfFreedom[k];     #pragma omp parallel for private(i,k) schedule(static)
40          out->toReduced[i]=in->toReduced[k];     for (i=0;i<n;i++) {
41          for(j=0;j<in->numDim;j++) out->Coordinates[INDEX2(j,i,in->numDim)]=in->Coordinates[INDEX2(j,k,in->numDim)];        k=index[i]-min_index;
42       }        if ((k>=0) && (k <range)) {
43             Id_out[i]=Id_in[k];
44             Tag_out[i]=Tag_in[k];
45             globalDegreesOfFreedom_out[i]=globalDegreesOfFreedom_in[k];
46             memcpy(&(Coordinates_out[INDEX2(0,i,numDim)]), &(Coordinates_in[INDEX2(0,k,numDim)]), numDim_size);
47          }
48     }     }
49  }  }
50  /*  
51  * $Log$  void Finley_NodeFile_gather(index_t* index, Finley_NodeFile* in, Finley_NodeFile* out)
52  * Revision 1.3  2005/09/15 03:44:23  jgs  {
53  * Merge of development branch dev-02 back to main trunk on 2005-09-15     index_t min_id, max_id;
54  *     Finley_NodeFile_setGlobalIdRange(&min_id,&max_id,in);
55  * Revision 1.2.2.1  2005/09/07 06:26:20  gross     Finley_NodeFile_gatherEntries(out->numNodes, index, min_id, max_id,
56  * the solver from finley are put into the standalone package paso now                                   out->Id, in->Id,
57  *                                   out->Tag, in->Tag,
58  * Revision 1.2  2005/07/08 04:07:55  jgs                                   out->globalDegreesOfFreedom, in->globalDegreesOfFreedom,
59  * Merge of development branch back to main trunk on 2005-07-08                                   out->numDim, out->Coordinates, in->Coordinates);
60  *  }
61  * Revision 1.1.1.1.2.1  2005/06/29 02:34:54  gross  
62  * some changes towards 64 integers in finley  void Finley_NodeFile_gather_global(index_t* index, Finley_NodeFile* in, Finley_NodeFile* out)
63  *  {
64  * Revision 1.1.1.1  2004/10/26 06:53:57  jgs    index_t min_id, max_id, undefined_node;
65  * initial import of project esys2    Paso_MPI_rank buffer_rank, dest, source, *distribution=NULL;
66  *    index_t  *Id_buffer=NULL, *Tag_buffer=NULL, *globalDegreesOfFreedom_buffer=NULL;
67  * Revision 1.1.1.1  2004/06/24 04:00:40  johng    double* Coordinates_buffer=NULL;
68  * Initial version of eys using boost-python.    dim_t p, buffer_len,n;
69  *    char error_msg[100];
70  *    #ifdef PASO_MPI
71  */    MPI_Status status;
72      #endif
73    
74      /* get the global range of node ids */
75      Finley_NodeFile_setGlobalIdRange(&min_id,&max_id,in);
76      undefined_node=min_id-1;
77    
78      distribution=TMPMEMALLOC(in->MPIInfo->size+1, index_t);
79    
80      if ( !Finley_checkPtr(distribution) ) {
81          /* distribute the range of node ids */
82          buffer_len=Paso_MPIInfo_setDistribution(in->MPIInfo,min_id,max_id,distribution);
83          /* allocate buffers */
84          Id_buffer=TMPMEMALLOC(buffer_len,index_t);
85          Tag_buffer=TMPMEMALLOC(buffer_len,index_t);
86          globalDegreesOfFreedom_buffer=TMPMEMALLOC(buffer_len,index_t);
87          Coordinates_buffer=TMPMEMALLOC(buffer_len*out->numDim,double);
88          if (! (Finley_checkPtr(Id_buffer) || Finley_checkPtr(Tag_buffer) ||
89                         Finley_checkPtr(globalDegreesOfFreedom_buffer) || Finley_checkPtr(Coordinates_buffer) ) ) {
90                /* fill Id_buffer by the undefined_node marker to check if nodes are defined */
91                #pragma omp parallel for private(n) schedule(static)
92                for (n=0;n<buffer_len;n++) Id_buffer[n]=undefined_node;
93                
94                /* fill the buffer by sending portions around in a circle */
95                dest=Paso_MPIInfo_mod(in->MPIInfo->size, in->MPIInfo->rank + 1);
96                source=Paso_MPIInfo_mod(in->MPIInfo->size, in->MPIInfo->rank - 1);
97                buffer_rank=in->MPIInfo->rank;
98                for (p=0; p< in->MPIInfo->size; ++p) {
99                     if (p>0) {  /* the initial send can be skipped */
100                         #ifdef PASO_MPI
101                         MPI_Sendrecv_replace(Id_buffer, buffer_len, MPI_INT,
102                                              dest, in->MPIInfo->msg_tag_counter, source, in->MPIInfo->msg_tag_counter,
103                                              in->MPIInfo->comm,&status);
104                         MPI_Sendrecv_replace(Tag_buffer, buffer_len, MPI_INT,
105                                              dest, in->MPIInfo->msg_tag_counter+1, source, in->MPIInfo->msg_tag_counter+1,
106                                              in->MPIInfo->comm,&status);
107                         MPI_Sendrecv_replace(globalDegreesOfFreedom_buffer, buffer_len, MPI_INT,
108                                              dest, in->MPIInfo->msg_tag_counter+2, source, in->MPIInfo->msg_tag_counter+2,
109                                              in->MPIInfo->comm,&status);
110                         MPI_Sendrecv_replace(Coordinates_buffer, buffer_len*out->numDim, MPI_DOUBLE,
111                                              dest, in->MPIInfo->msg_tag_counter+3, source, in->MPIInfo->msg_tag_counter+3,
112                                              in->MPIInfo->comm,&status);
113                         #endif
114                         in->MPIInfo->msg_tag_counter+=4;
115                     }
116                     buffer_rank=Paso_MPIInfo_mod(in->MPIInfo->size, buffer_rank-1);
117                     Finley_NodeFile_scatterEntries(in->numNodes, in->Id,
118                                                    distribution[buffer_rank], distribution[buffer_rank+1],
119                                                    Id_buffer, in->Id,
120                                                    Tag_buffer, in->Tag,
121                                                    globalDegreesOfFreedom_buffer, in->globalDegreesOfFreedom,
122                                                    out->numDim, Coordinates_buffer, in->Coordinates);
123                }
124                /* now entries are collected from the buffer again by sending the entries around in a circle */
125                dest=Paso_MPIInfo_mod(in->MPIInfo->size, in->MPIInfo->rank + 1);
126                source=Paso_MPIInfo_mod(in->MPIInfo->size, in->MPIInfo->rank - 1);
127                buffer_rank=in->MPIInfo->rank;
128                for (p=0; p< in->MPIInfo->size; ++p) {
129                     Finley_NodeFile_gatherEntries(out->numNodes, index,
130                                                   distribution[buffer_rank], distribution[buffer_rank+1],
131                                                   out->Id, Id_buffer,
132                                                   out->Tag, Tag_buffer,
133                                                   out->globalDegreesOfFreedom, globalDegreesOfFreedom_buffer,
134                                                   out->numDim, out->Coordinates, Coordinates_buffer);
135                     if (p<in->MPIInfo->size-1) {  /* the last send can be skipped */
136                         #ifdef PASO_MPI
137                         MPI_Sendrecv_replace(Id_buffer, buffer_len, MPI_INT,
138                                              dest, in->MPIInfo->msg_tag_counter, source, in->MPIInfo->msg_tag_counter,
139                                              in->MPIInfo->comm,&status);
140                         MPI_Sendrecv_replace(Tag_buffer, buffer_len, MPI_INT,
141                                              dest, in->MPIInfo->msg_tag_counter+1, source, in->MPIInfo->msg_tag_counter+1,
142                                              in->MPIInfo->comm,&status);
143                         MPI_Sendrecv_replace(globalDegreesOfFreedom_buffer, buffer_len, MPI_INT,
144                                              dest, in->MPIInfo->msg_tag_counter+2, source, in->MPIInfo->msg_tag_counter+2,
145                                              in->MPIInfo->comm,&status);
146                         MPI_Sendrecv_replace(Coordinates_buffer, buffer_len*out->numDim, MPI_DOUBLE,
147                                              dest, in->MPIInfo->msg_tag_counter+3, source, in->MPIInfo->msg_tag_counter+3,
148                                              in->MPIInfo->comm,&status);
149                         #endif
150                         in->MPIInfo->msg_tag_counter+=4;
151                     }
152                     buffer_rank=Paso_MPIInfo_mod(in->MPIInfo->size, buffer_rank-1);
153                }
154                /* check if all nodes are set: */
155                #pragma omp parallel for private(n) schedule(static)
156                for (n=0; n< out->numNodes; ++n) {
157                    if (out->Id[n] == undefined_node ) {
158                     sprintf(error_msg,"Finley_NodeFile_gather_global: Node id %d at position %d is referenced but is not defined.",out->Id[n],n);
159                     Finley_setError(VALUE_ERROR,error_msg);
160                   }
161                 }
162    
163          }
164          TMPMEMFREE(Id_buffer);
165          TMPMEMFREE(Tag_buffer);
166          TMPMEMFREE(globalDegreesOfFreedom_buffer);
167          TMPMEMFREE(Coordinates_buffer);
168      }
169      TMPMEMFREE(distribution);
170      /* make sure that the error is global */
171      Paso_MPIInfo_noError(in->MPIInfo);
172    }

Legend:
Removed from v.150  
changed lines
  Added in v.1766

  ViewVC Help
Powered by ViewVC 1.1.26