/[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 1062 - (show annotations)
Mon Mar 26 06:17:53 2007 UTC (12 years, 3 months ago) by gross
File MIME type: text/plain
File size: 14726 byte(s)
reduced integration schemes are implemented now for grad, integrate, etc. Tests still to be added.
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 dim_t n,i;
101 dim_t numComps=getDataPointSize(out);
102 type_t in_data_type=getFunctionSpaceType(in);
103 type_t out_data_type=getFunctionSpaceType(out);
104 Finley_resetError();
105 if (nodes==NULL) return;
106
107 /* check out and in */
108 if (numComps!=getDataPointSize(in)) {
109 Finley_setError(TYPE_ERROR,"Finley_Assemble_CopyNodalData: number of components of input and output Data do not match.");
110 } else if (!isExpanded(out)) {
111 Finley_setError(TYPE_ERROR,"Finley_Assemble_CopyNodalData: 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,"Finley_Assemble_CopyNodalData: illegal number of samples of input Data object");
119 }
120 } else if (in_data_type == FINLEY_REDUCED_NODES) {
121 /* TODO */
122 Finley_setError(TYPE_ERROR,"Finley_Assemble_CopyNodalData: reduced nodes is not supported yet.");
123 } else if (in_data_type == FINLEY_DEGREES_OF_FREEDOM) {
124 #ifdef PASO_MPI
125 if (! numSamplesEqual(in,1,nodes->degreeOfFreedomDistribution->numLocal)) {
126 #else
127 if (! numSamplesEqual(in,1,nodes->numDegreesOfFreedom)) {
128 #endif
129 Finley_setError(TYPE_ERROR,"Finley_Assemble_CopyNodalData: illegal number of samples of input Data object");
130 }
131 } else if (in_data_type == FINLEY_REDUCED_DEGREES_OF_FREEDOM) {
132 #ifdef PASO_MPI
133 if (! numSamplesEqual(in,1,nodes->reducedDegreeOfFreedomDistribution->numLocal)) {
134 #else
135 if (! numSamplesEqual(in,1,nodes->reducedNumDegreesOfFreedom)) {
136 #endif
137 Finley_setError(TYPE_ERROR,"Finley_Assemble_CopyNodalData: illegal number of samples of input Data object");
138 }
139 } else {
140 Finley_setError(TYPE_ERROR,"Finley_Assemble_CopyNodalData: illegal function space type for target object");
141 }
142
143 if (out_data_type == FINLEY_NODES) {
144 if (! numSamplesEqual(out,1,nodes->numNodes)) {
145 Finley_setError(TYPE_ERROR,"Finley_Assemble_CopyNodalData: illegal number of samples of output Data object");
146 }
147 } else if (out_data_type == FINLEY_REDUCED_NODES) {
148 /* TODO */
149 Finley_setError(TYPE_ERROR,"Finley_Assemble_CopyNodalData: reduced nodes is not supported yet.");
150 } else if (out_data_type == FINLEY_DEGREES_OF_FREEDOM) {
151 #ifdef PASO_MPI
152 if (! numSamplesEqual(out,1,nodes->degreeOfFreedomDistribution->numLocal)) {
153 #else
154 if (! numSamplesEqual(out,1,nodes->numDegreesOfFreedom)) {
155 #endif
156 Finley_setError(TYPE_ERROR,"Finley_Assemble_CopyNodalData: illegal number of samples of output Data object");
157 }
158 } else if (out_data_type == FINLEY_REDUCED_DEGREES_OF_FREEDOM) {
159 #ifdef PASO_MPI
160 if (! numSamplesEqual(out,1,nodes->reducedDegreeOfFreedomDistribution->numLocal)) {
161 #else
162 if (! numSamplesEqual(out,1,nodes->reducedNumDegreesOfFreedom)) {
163 #endif
164 Finley_setError(TYPE_ERROR,"Finley_Assemble_CopyNodalData: illegal number of samples of output Data object");
165 }
166 } else {
167 Finley_setError(TYPE_ERROR,"Finley_Assemble_CopyNodalData: illegal function space type for source object");
168 }
169
170 /* now we can start */
171
172 /* This is where the "MPI magic" that shares the data accross domain boundaries occurs.
173 when the user asks to copy from DegreesOfFreedom (non-overlapping solution) to
174 Nodes (overlapping continuous), communication is required to get the DOF values
175 corresponding to external nodes from neighbouring domains. Communication is handled by
176 the Paso_CommBuffer that is attached to nodes. Copying the other direction (nodes to DOF)
177 is similar to the serial case, with just a little bit more care required to ensure that
178 only local values are copied. */
179 if (Finley_noError()) {
180 if (in_data_type == FINLEY_NODES) {
181 if (out_data_type == FINLEY_NODES) {
182 #pragma omp parallel for private(n) schedule(static)
183 for (n=0;n<nodes->numNodes;n++)
184 Finley_copyDouble(numComps,getSampleData(in,n),getSampleData(out,n));
185 } else if (in_data_type == FINLEY_REDUCED_NODES) { /* TODO */
186 Finley_setError(TYPE_ERROR,"Finley_Assemble_CopyNodalData: cannot copy from nodes to reduced nodes.");
187 } else if (out_data_type == FINLEY_DEGREES_OF_FREEDOM) {
188 #pragma omp parallel for private(n) schedule(static)
189 for (n=0;n<nodes->numNodes;n++)
190 #ifdef PASO_MPI
191 if( nodes->degreeOfFreedom[n]<nodes->degreeOfFreedomDistribution->numLocal )
192 #endif
193 Finley_copyDouble(numComps,getSampleData(in,n),getSampleData(out,nodes->degreeOfFreedom[n]));
194 } else if (out_data_type == FINLEY_REDUCED_DEGREES_OF_FREEDOM) {
195 #pragma omp parallel for private(n,i) schedule(static)
196 for (i=0;i<nodes->numNodes;i++) {
197 n=nodes->reducedDegreeOfFreedom[i];
198 #ifdef PASO_MPI
199 if( n>=0 && nodes->degreeOfFreedom[n]<nodes->degreeOfFreedomDistribution->numLocal )
200 #else
201 if (n>=0)
202 #endif
203 Finley_copyDouble(numComps,getSampleData(in,i),getSampleData(out,n));
204 }
205 }
206 } else if (in_data_type == FINLEY_REDUCED_NODES) {
207 if (out_data_type == FINLEY_NODES) {
208 Finley_setError(TYPE_ERROR,"Finley_Assemble_CopyNodalData: cannot copy from reduced nodes to nodes.");
209 } else if (in_data_type == FINLEY_REDUCED_NODES) { /* TODO */
210 Finley_setError(TYPE_ERROR,"Finley_Assemble_CopyNodalData: cannot copy from reduced nodes to reduced nodes.");
211 } else if (out_data_type == FINLEY_DEGREES_OF_FREEDOM) {
212 Finley_setError(TYPE_ERROR,"Finley_Assemble_CopyNodalData: cannot copy from reduced nodes to degrees of freedom.");
213 } else if (out_data_type == FINLEY_REDUCED_DEGREES_OF_FREEDOM) {
214 Finley_setError(TYPE_ERROR,"Finley_Assemble_CopyNodalData: cannot copy from reduced nodes to reduced degrees of freedom.");
215 }
216 } else if (in_data_type == FINLEY_DEGREES_OF_FREEDOM) {
217 if (out_data_type == FINLEY_NODES)
218 {
219 #ifdef PASO_MPI
220 double *externalBuffer = MEMALLOC( numComps*nodes->degreeOfFreedomDistribution->numExternal, double );
221 getExternalDOF( nodes, in, externalBuffer, numComps, FALSE );
222 for (n=0;n<nodes->numNodes;n++) {
223 if( nodes->degreeOfFreedom[n]<nodes->degreeOfFreedomDistribution->numLocal )
224 Finley_copyDouble(numComps,getSampleData(in,nodes->degreeOfFreedom[n]),getSampleData(out,n));
225 else
226 Finley_copyDouble(numComps,externalBuffer + numComps*(nodes->degreeOfFreedom[n] - nodes->degreeOfFreedomDistribution->numLocal),getSampleData(out,n));
227 }
228
229 MEMFREE( externalBuffer );
230 #else
231 #pragma omp parallel for private(n) schedule(static)
232 for (n=0;n<nodes->numNodes;n++)
233 Finley_copyDouble(numComps,getSampleData(in,nodes->degreeOfFreedom[n]),getSampleData(out,n));
234 #endif
235 } else if (out_data_type == FINLEY_DEGREES_OF_FREEDOM) {
236 #pragma omp parallel for private(n) schedule(static)
237 for (n=0;n<nodes->numDegreesOfFreedom;n++)
238 Finley_copyDouble(numComps,getSampleData(in,n),getSampleData(out,n));
239 } else if (out_data_type == FINLEY_REDUCED_DEGREES_OF_FREEDOM) {
240 #pragma omp parallel for private(n,i) schedule(static)
241 for (i=0;i<nodes->numNodes;i++) {
242 n=nodes->reducedDegreeOfFreedom[i];
243 #ifdef PASO_MPI
244 if( n>=0 && n<nodes->reducedDegreeOfFreedomDistribution->numLocal )
245 #else
246 if (n>=0)
247 #endif
248 Finley_copyDouble(numComps,getSampleData(in,nodes->degreeOfFreedom[i]),getSampleData(out,n));
249 }
250 }
251 } else if (in_data_type == FINLEY_REDUCED_DEGREES_OF_FREEDOM) {
252 if (out_data_type == FINLEY_REDUCED_DEGREES_OF_FREEDOM) {
253 #pragma omp parallel for private(n) schedule(static)
254 for (n=0;n<nodes->reducedNumDegreesOfFreedom;n++)
255 Finley_copyDouble(numComps,getSampleData(in,n),getSampleData(out,n));
256 } else if (out_data_type == FINLEY_DEGREES_OF_FREEDOM ) {
257 #pragma omp parallel for private(n) schedule(static)
258 for (i=0;i<nodes->numNodes;i++) {
259 n=nodes->reducedDegreeOfFreedom[i];
260 #ifdef PASO_MPI
261 if( n>=0 && nodes->reducedDegreeOfFreedom[n]<nodes->reducedDegreeOfFreedomDistribution->numLocal )
262 #else
263 if (n>=0)
264 #endif
265 Finley_copyDouble(numComps,getSampleData(in,n),getSampleData(out,nodes->degreeOfFreedom[i]));
266 }
267 } else if (out_data_type == FINLEY_NODES ) {
268 #ifdef PASO_MPI
269 double *externalBuffer = MEMALLOC( numComps*nodes->reducedDegreeOfFreedomDistribution->numExternal, double );
270 getExternalDOF( nodes, in, externalBuffer, numComps, TRUE );
271 for (n=0;n<nodes->numNodes;n++) {
272 i = nodes->reducedDegreeOfFreedom[n];
273 if( i>=0 ) {
274 if( i<nodes->reducedDegreeOfFreedomDistribution->numLocal )
275 Finley_copyDouble(numComps,getSampleData(in,i),getSampleData(out,n));
276 else
277 Finley_copyDouble(numComps,externalBuffer + numComps*(i - nodes->reducedDegreeOfFreedomDistribution->numLocal),getSampleData(out,n));
278 }
279 }
280
281 MEMFREE( externalBuffer );
282 #else
283 #pragma omp parallel for private(n) schedule(static)
284 for (i=0;i<nodes->numNodes;i++) {
285 n=nodes->reducedDegreeOfFreedom[i];
286 if (n>=0)
287 Finley_copyDouble(numComps,getSampleData(in,n),getSampleData(out,i));
288 }
289 #endif
290 } else {
291 Finley_setError(TYPE_ERROR,"Finley_Assemble_CopyNodalData: cannot copy from data on reduced degrees of freedom");
292 }
293 }
294 }
295 return;
296 }
297
298
299
300 /*
301 * $Log$
302 * Revision 1.4 2005/09/15 03:44:21 jgs
303 * Merge of development branch dev-02 back to main trunk on 2005-09-15
304 *
305 * Revision 1.3 2005/08/12 01:45:42 jgs
306 * erge of development branch dev-02 back to main trunk on 2005-08-12
307 *
308 * Revision 1.2.2.3 2005/09/07 06:26:17 gross
309 * the solver from finley are put into the standalone package paso now
310 *
311 * Revision 1.2.2.2 2005/08/09 02:23:12 gross
312 * print statement removed
313 *
314 * Revision 1.2.2.1 2005/08/03 09:55:33 gross
315 * ContactTest is passing now./mk install!
316 *
317 * Revision 1.2 2005/07/08 04:07:45 jgs
318 * Merge of development branch back to main trunk on 2005-07-08
319 *
320 * Revision 1.1.1.1.2.1 2005/06/29 02:34:46 gross
321 * some changes towards 64 integers in finley
322 *
323 * Revision 1.1.1.1 2004/10/26 06:53:56 jgs
324 * initial import of project esys2
325 *
326 * Revision 1.2 2004/07/21 05:00:54 gross
327 * name changes in DataC
328 *
329 * Revision 1.1 2004/07/02 04:21:13 gross
330 * Finley C code has been included
331 *
332 *
333 */

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26