/[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 1062 - (hide annotations)
Mon Mar 26 06:17:53 2007 UTC (12 years, 4 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 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 jgs 123 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 jgs 150 Finley_resetError();
105 gross 1028 if (nodes==NULL) return;
106 jgs 82
107     /* check out and in */
108     if (numComps!=getDataPointSize(in)) {
109 gross 1062 Finley_setError(TYPE_ERROR,"Finley_Assemble_CopyNodalData: number of components of input and output Data do not match.");
110 jgs 82 } else if (!isExpanded(out)) {
111 gross 1062 Finley_setError(TYPE_ERROR,"Finley_Assemble_CopyNodalData: 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 gross 1062 Finley_setError(TYPE_ERROR,"Finley_Assemble_CopyNodalData: illegal number of samples of input Data object");
119 jgs 82 }
120 gross 1062 } 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 jgs 82 } else if (in_data_type == FINLEY_DEGREES_OF_FREEDOM) {
124 bcumming 751 #ifdef PASO_MPI
125     if (! numSamplesEqual(in,1,nodes->degreeOfFreedomDistribution->numLocal)) {
126     #else
127 jgs 82 if (! numSamplesEqual(in,1,nodes->numDegreesOfFreedom)) {
128 bcumming 751 #endif
129 gross 1062 Finley_setError(TYPE_ERROR,"Finley_Assemble_CopyNodalData: illegal number of samples of input Data object");
130 jgs 82 }
131     } else if (in_data_type == FINLEY_REDUCED_DEGREES_OF_FREEDOM) {
132 bcumming 751 #ifdef PASO_MPI
133     if (! numSamplesEqual(in,1,nodes->reducedDegreeOfFreedomDistribution->numLocal)) {
134     #else
135 jgs 82 if (! numSamplesEqual(in,1,nodes->reducedNumDegreesOfFreedom)) {
136 bcumming 751 #endif
137 gross 1062 Finley_setError(TYPE_ERROR,"Finley_Assemble_CopyNodalData: illegal number of samples of input Data object");
138 jgs 82 }
139     } else {
140 gross 1062 Finley_setError(TYPE_ERROR,"Finley_Assemble_CopyNodalData: illegal function space type for target object");
141 jgs 82 }
142    
143     if (out_data_type == FINLEY_NODES) {
144     if (! numSamplesEqual(out,1,nodes->numNodes)) {
145 gross 1062 Finley_setError(TYPE_ERROR,"Finley_Assemble_CopyNodalData: illegal number of samples of output Data object");
146 jgs 82 }
147 gross 1062 } 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 jgs 82 } else if (out_data_type == FINLEY_DEGREES_OF_FREEDOM) {
151 bcumming 751 #ifdef PASO_MPI
152     if (! numSamplesEqual(out,1,nodes->degreeOfFreedomDistribution->numLocal)) {
153     #else
154 jgs 82 if (! numSamplesEqual(out,1,nodes->numDegreesOfFreedom)) {
155 bcumming 751 #endif
156 gross 1062 Finley_setError(TYPE_ERROR,"Finley_Assemble_CopyNodalData: illegal number of samples of output Data object");
157 jgs 82 }
158     } else if (out_data_type == FINLEY_REDUCED_DEGREES_OF_FREEDOM) {
159 bcumming 751 #ifdef PASO_MPI
160     if (! numSamplesEqual(out,1,nodes->reducedDegreeOfFreedomDistribution->numLocal)) {
161     #else
162 jgs 82 if (! numSamplesEqual(out,1,nodes->reducedNumDegreesOfFreedom)) {
163 bcumming 751 #endif
164 gross 1062 Finley_setError(TYPE_ERROR,"Finley_Assemble_CopyNodalData: illegal number of samples of output Data object");
165 jgs 82 }
166     } else {
167 gross 1062 Finley_setError(TYPE_ERROR,"Finley_Assemble_CopyNodalData: illegal function space type for source object");
168 jgs 82 }
169    
170     /* now we can start */
171 bcumming 751
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 bcumming 782 only local values are copied. */
179 jgs 150 if (Finley_noError()) {
180 jgs 82 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 gross 1062 } 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 jgs 82 } else if (out_data_type == FINLEY_DEGREES_OF_FREEDOM) {
188     #pragma omp parallel for private(n) schedule(static)
189 bcumming 751 for (n=0;n<nodes->numNodes;n++)
190     #ifdef PASO_MPI
191     if( nodes->degreeOfFreedom[n]<nodes->degreeOfFreedomDistribution->numLocal )
192     #endif
193 jgs 82 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 bcumming 751 #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 jgs 82 }
205     }
206 gross 1062 } 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 jgs 82 } else if (in_data_type == FINLEY_DEGREES_OF_FREEDOM) {
217 bcumming 751 if (out_data_type == FINLEY_NODES)
218     {
219     #ifdef PASO_MPI
220     double *externalBuffer = MEMALLOC( numComps*nodes->degreeOfFreedomDistribution->numExternal, double );
221 bcumming 782 getExternalDOF( nodes, in, externalBuffer, numComps, FALSE );
222 bcumming 751 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 jgs 82 #pragma omp parallel for private(n) schedule(static)
232 bcumming 751 for (n=0;n<nodes->numNodes;n++)
233 jgs 82 Finley_copyDouble(numComps,getSampleData(in,nodes->degreeOfFreedom[n]),getSampleData(out,n));
234 bcumming 751 #endif
235 jgs 82 } 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 bcumming 751 #ifdef PASO_MPI
244 bcumming 782 if( n>=0 && n<nodes->reducedDegreeOfFreedomDistribution->numLocal )
245 bcumming 751 #else
246     if (n>=0)
247     #endif
248     Finley_copyDouble(numComps,getSampleData(in,nodes->degreeOfFreedom[i]),getSampleData(out,n));
249 jgs 82 }
250     }
251 gross 1062 } else if (in_data_type == FINLEY_REDUCED_DEGREES_OF_FREEDOM) {
252 jgs 82 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 bcumming 782 } else if (out_data_type == FINLEY_DEGREES_OF_FREEDOM ) {
257 jgs 147 #pragma omp parallel for private(n) schedule(static)
258     for (i=0;i<nodes->numNodes;i++) {
259     n=nodes->reducedDegreeOfFreedom[i];
260 bcumming 782 #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 jgs 147 }
267 bcumming 782 } 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 jgs 147 #pragma omp parallel for private(n) schedule(static)
284     for (i=0;i<nodes->numNodes;i++) {
285     n=nodes->reducedDegreeOfFreedom[i];
286 bcumming 782 if (n>=0)
287     Finley_copyDouble(numComps,getSampleData(in,n),getSampleData(out,i));
288 jgs 147 }
289 bcumming 782 #endif
290 jgs 82 } else {
291 gross 1062 Finley_setError(TYPE_ERROR,"Finley_Assemble_CopyNodalData: cannot copy from data on reduced degrees of freedom");
292 jgs 82 }
293 jgs 147 }
294 jgs 82 }
295     return;
296     }
297 bcumming 751
298    
299    
300 jgs 82 /*
301     * $Log$
302 jgs 150 * 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 jgs 147 * 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 jgs 150 * 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 jgs 147 * 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 jgs 123 * Revision 1.2 2005/07/08 04:07:45 jgs
318     * Merge of development branch back to main trunk on 2005-07-08
319 jgs 82 *
320 jgs 123 * 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 jgs 82 * 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