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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 782 - (show annotations)
Tue Jul 18 00:47:47 2006 UTC (12 years, 9 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 /*
2 ************************************************************
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 */
12 /**************************************************************/
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 #ifdef PASO_MPI
29 #include "./paso/CommBuffer.h"
30 #endif
31
32
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 static bool_t getExternalDOF( Finley_NodeFile *nodes, escriptDataC* in, double *externalBuffer, dim_t numComps, bool_t doReduced )
41 {
42 double *sendBuffer=NULL;
43 index_t n, i, myMax=0;
44 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
56 for( i=0; i<distribution->numNeighbours; i++ )
57 if( myMax < distribution->edges[i]->numForward )
58 myMax = distribution->edges[i]->numForward;
59 if( myMax )
60 sendBuffer = MEMALLOC( myMax*numComps, double );
61
62 /* pack and send DOF information to neighbour domains */
63 for( n=0; n<distribution->numNeighbours; n++ )
64 {
65 /* pack data */
66 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
69 /* place it in the send buffer */
70 Paso_CommBuffer_pack( CommBuffer, distribution->neighbours[n], NULL, sendBuffer, numComps*sizeof(double), 0 );
71
72 /* send it */
73 result = Paso_CommBuffer_send( CommBuffer, distribution->neighbours[n], numComps*sizeof(double) );
74 if( result==FALSE )
75 return FALSE;
76 }
77
78 MEMFREE( sendBuffer );
79
80 /* receive and unpack external DOF information from neigbours */
81 for( n=0; n<distribution->numNeighbours; n++ )
82 {
83 /* receive data */
84 result = Paso_CommBuffer_recv( CommBuffer, distribution->neighbours[n], numComps*sizeof(double) );
85 if( result==FALSE )
86 return FALSE;
87
88 /* unpack the data */
89 Paso_CommBuffer_unpack( CommBuffer, distribution->neighbours[n], distribution->edges[n]->indexBackward, externalBuffer, numComps*sizeof(double), -distribution->numLocal );
90 }
91
92 return TRUE;
93 }
94 #endif
95
96 /******************************************************************************************************/
97
98
99 void Finley_Assemble_CopyNodalData(Finley_NodeFile* nodes,escriptDataC* out,escriptDataC* in) {
100 if (nodes==NULL) return;
101 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 Finley_resetError();
106
107 /* check out and in */
108 if (numComps!=getDataPointSize(in)) {
109 Finley_setError(TYPE_ERROR,"__FILE__: number of components of input and output Data do not match.");
110 } else if (!isExpanded(out)) {
111 Finley_setError(TYPE_ERROR,"__FILE__: expanded Data object is expected for output data.");
112 }
113
114 /* TODO */
115 /* more sophisticated test needed for overlapping node/DOF counts */
116 if (in_data_type == FINLEY_NODES) {
117 if (! numSamplesEqual(in,1,nodes->numNodes)) {
118 Finley_setError(TYPE_ERROR,"__FILE__: illegal number of samples of input Data object");
119 }
120 } else if (in_data_type == FINLEY_DEGREES_OF_FREEDOM) {
121 #ifdef PASO_MPI
122 if (! numSamplesEqual(in,1,nodes->degreeOfFreedomDistribution->numLocal)) {
123 #else
124 if (! numSamplesEqual(in,1,nodes->numDegreesOfFreedom)) {
125 #endif
126 Finley_setError(TYPE_ERROR,"__FILE__: illegal number of samples of input Data object");
127 }
128 } else if (in_data_type == FINLEY_REDUCED_DEGREES_OF_FREEDOM) {
129 #ifdef PASO_MPI
130 if (! numSamplesEqual(in,1,nodes->reducedDegreeOfFreedomDistribution->numLocal)) {
131 #else
132 if (! numSamplesEqual(in,1,nodes->reducedNumDegreesOfFreedom)) {
133 #endif
134 Finley_setError(TYPE_ERROR,"__FILE__: illegal number of samples of input Data object");
135 }
136 } else {
137 Finley_setError(TYPE_ERROR,"__FILE__: illegal function space type for target object");
138 }
139
140 if (out_data_type == FINLEY_NODES) {
141 if (! numSamplesEqual(out,1,nodes->numNodes)) {
142 Finley_setError(TYPE_ERROR,"__FILE__: illegal number of samples of output Data object");
143 }
144 } else if (out_data_type == FINLEY_DEGREES_OF_FREEDOM) {
145 #ifdef PASO_MPI
146 if (! numSamplesEqual(out,1,nodes->degreeOfFreedomDistribution->numLocal)) {
147 #else
148 if (! numSamplesEqual(out,1,nodes->numDegreesOfFreedom)) {
149 #endif
150 Finley_setError(TYPE_ERROR,"__FILE__: illegal number of samples of output Data object");
151 }
152 } else if (out_data_type == FINLEY_REDUCED_DEGREES_OF_FREEDOM) {
153 #ifdef PASO_MPI
154 if (! numSamplesEqual(out,1,nodes->reducedDegreeOfFreedomDistribution->numLocal)) {
155 #else
156 if (! numSamplesEqual(out,1,nodes->reducedNumDegreesOfFreedom)) {
157 #endif
158 Finley_setError(TYPE_ERROR,"__FILE__: illegal number of samples of output Data object");
159 }
160 } else {
161 Finley_setError(TYPE_ERROR,"__FILE__: illegal function space type for source object");
162 }
163
164 /* now we can start */
165
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 only local values are copied. */
173 if (Finley_noError()) {
174 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 for (n=0;n<nodes->numNodes;n++)
182 #ifdef PASO_MPI
183 if( nodes->degreeOfFreedom[n]<nodes->degreeOfFreedomDistribution->numLocal )
184 #endif
185 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 #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 }
197 }
198 } else if (in_data_type == FINLEY_DEGREES_OF_FREEDOM) {
199 if (out_data_type == FINLEY_NODES)
200 {
201 #ifdef PASO_MPI
202 double *externalBuffer = MEMALLOC( numComps*nodes->degreeOfFreedomDistribution->numExternal, double );
203 getExternalDOF( nodes, in, externalBuffer, numComps, FALSE );
204 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 #pragma omp parallel for private(n) schedule(static)
214 for (n=0;n<nodes->numNodes;n++)
215 Finley_copyDouble(numComps,getSampleData(in,nodes->degreeOfFreedom[n]),getSampleData(out,n));
216 #endif
217 } 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 #ifdef PASO_MPI
226 if( n>=0 && n<nodes->reducedDegreeOfFreedomDistribution->numLocal )
227 #else
228 if (n>=0)
229 #endif
230 Finley_copyDouble(numComps,getSampleData(in,nodes->degreeOfFreedom[i]),getSampleData(out,n));
231 }
232 }
233 }
234 else if (in_data_type == FINLEY_REDUCED_DEGREES_OF_FREEDOM) {
235 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 } else if (out_data_type == FINLEY_DEGREES_OF_FREEDOM ) {
240 #pragma omp parallel for private(n) schedule(static)
241 for (i=0;i<nodes->numNodes;i++) {
242 n=nodes->reducedDegreeOfFreedom[i];
243 #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 ) {
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)
267 for (i=0;i<nodes->numNodes;i++) {
268 n=nodes->reducedDegreeOfFreedom[i];
269 if (n>=0)
270 Finley_copyDouble(numComps,getSampleData(in,n),getSampleData(out,i));
271 }
272 #endif
273 } else {
274 Finley_setError(TYPE_ERROR,"__FILE__: cannot copy from data on reduced degrees of freedom");
275 }
276 }
277 }
278 return;
279 }
280
281
282
283 /*
284 * $Log$
285 * 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 * 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 * 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 * 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 * Revision 1.2 2005/07/08 04:07:45 jgs
301 * Merge of development branch back to main trunk on 2005-07-08
302 *
303 * 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 * 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