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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 782 - (hide annotations)
Tue Jul 18 00:47:47 2006 UTC (13 years, 3 months ago) by bcumming
File MIME type: text/plain
File size: 13113 byte(s)
Large number of changes to Finley for meshing in MPI.

- optimisation and neatening up of rectcanglular mesh generation code
- first and second order 1D, 2D and 3D rectangular meshes are now
  available in finley and escript using MPI.
- reduced meshes now generated in MPI, and interpolation to and from 
  reduced data types now supported.  

1 jgs 150 /*
2 elspeth 616 ************************************************************
3     * Copyright 2006 by ACcESS MNRF *
4     * *
5     * http://www.access.edu.au *
6     * Primary Business: Queensland, Australia *
7     * Licensed under the Open Software License version 3.0 *
8     * http://www.opensource.org/licenses/osl-3.0.php *
9     * *
10     ************************************************************
11 jgs 150 */
12 jgs 82 /**************************************************************/
13    
14     /* assemblage routines: copies data between different types nodal representation */
15    
16     /**************************************************************/
17    
18     /* author: gross@access.edu.au */
19     /* Version: $Id$ */
20    
21     /**************************************************************/
22    
23     #include "Util.h"
24     #include "Assemble.h"
25     #ifdef _OPENMP
26     #include <omp.h>
27     #endif
28 bcumming 751 #ifdef PASO_MPI
29     #include "./paso/CommBuffer.h"
30     #endif
31 jgs 82
32 bcumming 751
33     #ifdef PASO_MPI
34     /*
35     this function does no checking that the input are OK, so it has been put here, to
36     only be used in Finley_Assemble_CopyNodalData() which does the checking for it.
37    
38     bufferExternal must be large enough to accomdate the external nodal data (numComps*numExternal)
39     */
40 bcumming 782 static bool_t getExternalDOF( Finley_NodeFile *nodes, escriptDataC* in, double *externalBuffer, dim_t numComps, bool_t doReduced )
41 bcumming 751 {
42     double *sendBuffer=NULL;
43     index_t n, i, myMax=0;
44 bcumming 782 bool_t result=TRUE;
45     Finley_NodeDistribution *distribution=NULL;
46     Paso_CommBuffer *CommBuffer=NULL;
47     if( doReduced ) {
48     distribution = nodes->reducedDegreeOfFreedomDistribution;
49     CommBuffer = nodes->reducedCommBuffer;
50     }
51     else {
52     distribution = nodes->degreeOfFreedomDistribution;
53     CommBuffer = nodes->CommBuffer;
54     }
55 bcumming 751
56 bcumming 782 for( i=0; i<distribution->numNeighbours; i++ )
57     if( myMax < distribution->edges[i]->numForward )
58     myMax = distribution->edges[i]->numForward;
59 bcumming 751 if( myMax )
60     sendBuffer = MEMALLOC( myMax*numComps, double );
61    
62     /* pack and send DOF information to neighbour domains */
63 bcumming 782 for( n=0; n<distribution->numNeighbours; n++ )
64 bcumming 751 {
65     /* pack data */
66 bcumming 782 for( i=0; i<distribution->edges[n]->numForward; i++ )
67     memcpy( sendBuffer + i*numComps, getSampleData(in,distribution->edges[n]->indexForward[i]), numComps*sizeof(double) );
68 bcumming 751
69     /* place it in the send buffer */
70 bcumming 782 Paso_CommBuffer_pack( CommBuffer, distribution->neighbours[n], NULL, sendBuffer, numComps*sizeof(double), 0 );
71 bcumming 751
72     /* send it */
73 bcumming 782 result = Paso_CommBuffer_send( CommBuffer, distribution->neighbours[n], numComps*sizeof(double) );
74 bcumming 751 if( result==FALSE )
75     return FALSE;
76     }
77    
78     MEMFREE( sendBuffer );
79    
80     /* receive and unpack external DOF information from neigbours */
81 bcumming 782 for( n=0; n<distribution->numNeighbours; n++ )
82 bcumming 751 {
83     /* receive data */
84 bcumming 782 result = Paso_CommBuffer_recv( CommBuffer, distribution->neighbours[n], numComps*sizeof(double) );
85 bcumming 751 if( result==FALSE )
86     return FALSE;
87    
88     /* unpack the data */
89 bcumming 782 Paso_CommBuffer_unpack( CommBuffer, distribution->neighbours[n], distribution->edges[n]->indexBackward, externalBuffer, numComps*sizeof(double), -distribution->numLocal );
90 bcumming 751 }
91    
92     return TRUE;
93     }
94     #endif
95    
96 jgs 82 /******************************************************************************************************/
97    
98    
99     void Finley_Assemble_CopyNodalData(Finley_NodeFile* nodes,escriptDataC* out,escriptDataC* in) {
100     if (nodes==NULL) return;
101 jgs 123 dim_t n,i;
102     dim_t numComps=getDataPointSize(out);
103     type_t in_data_type=getFunctionSpaceType(in);
104     type_t out_data_type=getFunctionSpaceType(out);
105 jgs 150 Finley_resetError();
106 jgs 82
107     /* check out and in */
108     if (numComps!=getDataPointSize(in)) {
109 jgs 150 Finley_setError(TYPE_ERROR,"__FILE__: number of components of input and output Data do not match.");
110 jgs 82 } else if (!isExpanded(out)) {
111 jgs 150 Finley_setError(TYPE_ERROR,"__FILE__: expanded Data object is expected for output data.");
112 jgs 82 }
113    
114 bcumming 751 /* TODO */
115     /* more sophisticated test needed for overlapping node/DOF counts */
116 jgs 82 if (in_data_type == FINLEY_NODES) {
117     if (! numSamplesEqual(in,1,nodes->numNodes)) {
118 jgs 150 Finley_setError(TYPE_ERROR,"__FILE__: illegal number of samples of input Data object");
119 jgs 82 }
120     } else if (in_data_type == FINLEY_DEGREES_OF_FREEDOM) {
121 bcumming 751 #ifdef PASO_MPI
122     if (! numSamplesEqual(in,1,nodes->degreeOfFreedomDistribution->numLocal)) {
123     #else
124 jgs 82 if (! numSamplesEqual(in,1,nodes->numDegreesOfFreedom)) {
125 bcumming 751 #endif
126 jgs 150 Finley_setError(TYPE_ERROR,"__FILE__: illegal number of samples of input Data object");
127 jgs 82 }
128     } else if (in_data_type == FINLEY_REDUCED_DEGREES_OF_FREEDOM) {
129 bcumming 751 #ifdef PASO_MPI
130     if (! numSamplesEqual(in,1,nodes->reducedDegreeOfFreedomDistribution->numLocal)) {
131     #else
132 jgs 82 if (! numSamplesEqual(in,1,nodes->reducedNumDegreesOfFreedom)) {
133 bcumming 751 #endif
134 jgs 150 Finley_setError(TYPE_ERROR,"__FILE__: illegal number of samples of input Data object");
135 jgs 82 }
136     } else {
137 jgs 150 Finley_setError(TYPE_ERROR,"__FILE__: illegal function space type for target object");
138 jgs 82 }
139    
140     if (out_data_type == FINLEY_NODES) {
141     if (! numSamplesEqual(out,1,nodes->numNodes)) {
142 jgs 150 Finley_setError(TYPE_ERROR,"__FILE__: illegal number of samples of output Data object");
143 jgs 82 }
144     } else if (out_data_type == FINLEY_DEGREES_OF_FREEDOM) {
145 bcumming 751 #ifdef PASO_MPI
146     if (! numSamplesEqual(out,1,nodes->degreeOfFreedomDistribution->numLocal)) {
147     #else
148 jgs 82 if (! numSamplesEqual(out,1,nodes->numDegreesOfFreedom)) {
149 bcumming 751 #endif
150 jgs 150 Finley_setError(TYPE_ERROR,"__FILE__: illegal number of samples of output Data object");
151 jgs 82 }
152     } else if (out_data_type == FINLEY_REDUCED_DEGREES_OF_FREEDOM) {
153 bcumming 751 #ifdef PASO_MPI
154     if (! numSamplesEqual(out,1,nodes->reducedDegreeOfFreedomDistribution->numLocal)) {
155     #else
156 jgs 82 if (! numSamplesEqual(out,1,nodes->reducedNumDegreesOfFreedom)) {
157 bcumming 751 #endif
158 jgs 150 Finley_setError(TYPE_ERROR,"__FILE__: illegal number of samples of output Data object");
159 jgs 82 }
160     } else {
161 jgs 150 Finley_setError(TYPE_ERROR,"__FILE__: illegal function space type for source object");
162 jgs 82 }
163    
164     /* now we can start */
165 bcumming 751
166     /* This is where the "MPI magic" that shares the data accross domain boundaries occurs.
167     when the user asks to copy from DegreesOfFreedom (non-overlapping solution) to
168     Nodes (overlapping continuous), communication is required to get the DOF values
169     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)
171     is similar to the serial case, with just a little bit more care required to ensure that
172 bcumming 782 only local values are copied. */
173 jgs 150 if (Finley_noError()) {
174 jgs 82 if (in_data_type == FINLEY_NODES) {
175     if (out_data_type == FINLEY_NODES) {
176     #pragma omp parallel for private(n) schedule(static)
177     for (n=0;n<nodes->numNodes;n++)
178     Finley_copyDouble(numComps,getSampleData(in,n),getSampleData(out,n));
179     } else if (out_data_type == FINLEY_DEGREES_OF_FREEDOM) {
180     #pragma omp parallel for private(n) schedule(static)
181 bcumming 751 for (n=0;n<nodes->numNodes;n++)
182     #ifdef PASO_MPI
183     if( nodes->degreeOfFreedom[n]<nodes->degreeOfFreedomDistribution->numLocal )
184     #endif
185 jgs 82 Finley_copyDouble(numComps,getSampleData(in,n),getSampleData(out,nodes->degreeOfFreedom[n]));
186     } else if (out_data_type == FINLEY_REDUCED_DEGREES_OF_FREEDOM) {
187     #pragma omp parallel for private(n,i) schedule(static)
188     for (i=0;i<nodes->numNodes;i++) {
189     n=nodes->reducedDegreeOfFreedom[i];
190 bcumming 751 #ifdef PASO_MPI
191     if( n>=0 && nodes->degreeOfFreedom[n]<nodes->degreeOfFreedomDistribution->numLocal )
192     #else
193     if (n>=0)
194     #endif
195     Finley_copyDouble(numComps,getSampleData(in,i),getSampleData(out,n));
196 jgs 82 }
197     }
198     } else if (in_data_type == FINLEY_DEGREES_OF_FREEDOM) {
199 bcumming 751 if (out_data_type == FINLEY_NODES)
200     {
201     #ifdef PASO_MPI
202     double *externalBuffer = MEMALLOC( numComps*nodes->degreeOfFreedomDistribution->numExternal, double );
203 bcumming 782 getExternalDOF( nodes, in, externalBuffer, numComps, FALSE );
204 bcumming 751 for (n=0;n<nodes->numNodes;n++) {
205     if( nodes->degreeOfFreedom[n]<nodes->degreeOfFreedomDistribution->numLocal )
206     Finley_copyDouble(numComps,getSampleData(in,nodes->degreeOfFreedom[n]),getSampleData(out,n));
207     else
208     Finley_copyDouble(numComps,externalBuffer + numComps*(nodes->degreeOfFreedom[n] - nodes->degreeOfFreedomDistribution->numLocal),getSampleData(out,n));
209     }
210    
211     MEMFREE( externalBuffer );
212     #else
213 jgs 82 #pragma omp parallel for private(n) schedule(static)
214 bcumming 751 for (n=0;n<nodes->numNodes;n++)
215 jgs 82 Finley_copyDouble(numComps,getSampleData(in,nodes->degreeOfFreedom[n]),getSampleData(out,n));
216 bcumming 751 #endif
217 jgs 82 } else if (out_data_type == FINLEY_DEGREES_OF_FREEDOM) {
218     #pragma omp parallel for private(n) schedule(static)
219     for (n=0;n<nodes->numDegreesOfFreedom;n++)
220     Finley_copyDouble(numComps,getSampleData(in,n),getSampleData(out,n));
221     } else if (out_data_type == FINLEY_REDUCED_DEGREES_OF_FREEDOM) {
222     #pragma omp parallel for private(n,i) schedule(static)
223     for (i=0;i<nodes->numNodes;i++) {
224     n=nodes->reducedDegreeOfFreedom[i];
225 bcumming 751 #ifdef PASO_MPI
226 bcumming 782 if( n>=0 && n<nodes->reducedDegreeOfFreedomDistribution->numLocal )
227 bcumming 751 #else
228     if (n>=0)
229     #endif
230     Finley_copyDouble(numComps,getSampleData(in,nodes->degreeOfFreedom[i]),getSampleData(out,n));
231 jgs 82 }
232     }
233 bcumming 751 }
234     else if (in_data_type == FINLEY_REDUCED_DEGREES_OF_FREEDOM) {
235 jgs 82 if (out_data_type == FINLEY_REDUCED_DEGREES_OF_FREEDOM) {
236     #pragma omp parallel for private(n) schedule(static)
237     for (n=0;n<nodes->reducedNumDegreesOfFreedom;n++)
238     Finley_copyDouble(numComps,getSampleData(in,n),getSampleData(out,n));
239 bcumming 782 } else if (out_data_type == FINLEY_DEGREES_OF_FREEDOM ) {
240 jgs 147 #pragma omp parallel for private(n) schedule(static)
241     for (i=0;i<nodes->numNodes;i++) {
242     n=nodes->reducedDegreeOfFreedom[i];
243 bcumming 782 #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 jgs 147 }
250 bcumming 782 } 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 jgs 147 #pragma omp parallel for private(n) schedule(static)
267     for (i=0;i<nodes->numNodes;i++) {
268     n=nodes->reducedDegreeOfFreedom[i];
269 bcumming 782 if (n>=0)
270     Finley_copyDouble(numComps,getSampleData(in,n),getSampleData(out,i));
271 jgs 147 }
272 bcumming 782 #endif
273 jgs 82 } else {
274 jgs 150 Finley_setError(TYPE_ERROR,"__FILE__: cannot copy from data on reduced degrees of freedom");
275 jgs 82 }
276 jgs 147 }
277 jgs 82 }
278     return;
279     }
280 bcumming 751
281    
282    
283 jgs 82 /*
284     * $Log$
285 jgs 150 * Revision 1.4 2005/09/15 03:44:21 jgs
286     * Merge of development branch dev-02 back to main trunk on 2005-09-15
287     *
288 jgs 147 * Revision 1.3 2005/08/12 01:45:42 jgs
289     * erge of development branch dev-02 back to main trunk on 2005-08-12
290     *
291 jgs 150 * Revision 1.2.2.3 2005/09/07 06:26:17 gross
292     * the solver from finley are put into the standalone package paso now
293     *
294 jgs 147 * Revision 1.2.2.2 2005/08/09 02:23:12 gross
295     * print statement removed
296     *
297     * Revision 1.2.2.1 2005/08/03 09:55:33 gross
298     * ContactTest is passing now./mk install!
299     *
300 jgs 123 * Revision 1.2 2005/07/08 04:07:45 jgs
301     * Merge of development branch back to main trunk on 2005-07-08
302 jgs 82 *
303 jgs 123 * Revision 1.1.1.1.2.1 2005/06/29 02:34:46 gross
304     * some changes towards 64 integers in finley
305     *
306     * Revision 1.1.1.1 2004/10/26 06:53:56 jgs
307     * initial import of project esys2
308     *
309 jgs 82 * Revision 1.2 2004/07/21 05:00:54 gross
310     * name changes in DataC
311     *
312     * Revision 1.1 2004/07/02 04:21:13 gross
313     * Finley C code has been included
314     *
315     *
316     */

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.26