/[escript]/trunk-mpi-branch/finley/src/IndexList.c
ViewVC logotype

Contents of /trunk-mpi-branch/finley/src/IndexList.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1120 - (show annotations)
Tue May 1 01:17:46 2007 UTC (13 years ago) by ksteube
File MIME type: text/plain
File size: 7537 byte(s)
MPI branch now runs simplesolve.py with both useMPI=yes and useMPI=no

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
15 /* Finley: Converting an element list into a matrix shape */
16
17 /**************************************************************/
18
19 /* Author: gross@access.edu.au */
20 /* Version: $Id$ */
21
22 /**************************************************************/
23
24 #include "IndexList.h"
25
26 /* Translate from distributed/local array indices to global indices */
27
28 int Finley_IndexList_localToGlobal(Finley_NodeDistribution *dofDistribution, int localIndex) {
29 /*
30 get global id of icol
31 if icol is internal node (on this CPU): use icol+vtxdist[my_CPU]
32 else use indexExternal[icol-numLocal] to get global index of node
33 (actually DOF...the NodeDistribution structure should have been called DofDistribution)
34 */
35 index_t my_CPU=dofDistribution->MPIInfo->rank;
36 if (localIndex < dofDistribution->numLocal) {
37 localIndex = localIndex + dofDistribution->vtxdist[my_CPU];
38 }
39 else {
40 localIndex = dofDistribution->indexExternal[localIndex-dofDistribution->numLocal];
41 }
42 return(localIndex);
43 }
44
45 /**************************************************************/
46 /* inserts the contributions from the element matrices of elements
47 into the row index col. If symmetric is set, only the upper
48 triangle of the matrix is stored. */
49
50 void Finley_IndexList_insertElements(Finley_IndexList* index_list, Finley_Mesh* mesh, Finley_ElementFile* elements,
51 bool_t reduce_row_order, index_t* row_Label,
52 bool_t reduce_col_order, index_t* col_Label) {
53 /* index_list is an array of linked lists. Each entry is a row (DOF) and contains the indices to the non-zero columns */
54 index_t color, num_CPUs = 1, my_CPU = 0;
55 dim_t e,kr,kc,NN_row,NN_col,i,icol,irow;
56 #ifdef PASO_MPI
57 num_CPUs = mesh->MPIInfo->size;
58 my_CPU = mesh->MPIInfo->rank;
59 #endif
60 /* print_mesh_statistics( mesh, TRUE ); */
61
62 if (elements!=NULL) {
63 dim_t NN=elements->ReferenceElement->Type->numNodes;
64 index_t id[NN],*row_node,*col_node;
65 for (i=0;i<NN;i++) id[i]=i;
66 if (reduce_col_order) {
67 col_node=elements->ReferenceElement->Type->linearNodes;
68 NN_col=elements->LinearReferenceElement->Type->numNodes;
69 } else {
70 col_node=id;
71 NN_col=elements->ReferenceElement->Type->numNodes;
72 }
73 if (reduce_row_order) {
74 row_node=elements->ReferenceElement->Type->linearNodes;
75 NN_row=elements->LinearReferenceElement->Type->numNodes;
76 } else {
77 row_node=id;
78 NN_row=elements->ReferenceElement->Type->numNodes;
79 }
80 if (num_CPUs == 1) {
81 for (color=elements->minColor;color<=elements->maxColor;color++) {
82 #pragma omp for private(e,irow,kr,kc,icol) schedule(static)
83 for (e=0;e<elements->numElements;e++) {
84 if (elements->Color[e]==color) {
85 for (kr=0;kr<NN_row;kr++) {
86 irow=row_Label[elements->Nodes[INDEX2(row_node[kr],e,NN)]];
87 for (kc=0;kc<NN_col;kc++) {
88 icol=col_Label[elements->Nodes[INDEX2(col_node[kc],e,NN)]];
89 Finley_IndexList_insertIndex(&(index_list[irow]),icol);
90 }
91 }
92 }
93 }
94 }
95 } else { /* More than one CPU (what's below should also work for one CPU, but let's build confidence in it first) */
96 #ifdef PASO_MPI
97 Finley_NodeDistribution *row_degreeOfFreedomDistribution;
98 Finley_NodeDistribution *col_degreeOfFreedomDistribution;
99 if (reduce_col_order) {
100 col_degreeOfFreedomDistribution = mesh->Nodes->reducedDegreeOfFreedomDistribution;
101 }
102 else {
103 col_degreeOfFreedomDistribution = mesh->Nodes->degreeOfFreedomDistribution;
104 }
105 if (reduce_row_order) {
106 row_degreeOfFreedomDistribution = mesh->Nodes->reducedDegreeOfFreedomDistribution;
107 }
108 else {
109 row_degreeOfFreedomDistribution = mesh->Nodes->degreeOfFreedomDistribution;
110 }
111 /* Not using loop over colors as above */ {
112 #pragma omp for private(e,irow,kr,kc,icol) schedule(static)
113 for (e=0;e<elements->numElements;e++) {
114 for (kr=0;kr<NN_row;kr++) {
115 irow=row_Label[elements->Nodes[INDEX2(row_node[kr],e,NN)]];
116 if (irow < row_degreeOfFreedomDistribution->numLocal) {
117 for (kc=0;kc<NN_col;kc++) {
118 /* Get the local col ID */
119 icol=col_Label[elements->Nodes[INDEX2(col_node[kc],e,NN)]];
120 /* Convert to global col ID (row ID is saved as local value) */
121 icol = Finley_IndexList_localToGlobal(col_degreeOfFreedomDistribution, icol);
122 Finley_IndexList_insertIndex(&(index_list[irow]),icol);
123 }
124 }
125 }
126 }
127 }
128 #endif
129 } /* More than one CPU */
130 }
131 return;
132 }
133
134 /* inserts row index row into the Finley_IndexList in if it does not exist */
135
136 void Finley_IndexList_insertIndex(Finley_IndexList* in, index_t index) {
137 dim_t i;
138 /* is index in in? */
139 for (i=0;i<in->n;i++) {
140 if (in->index[i]==index) return;
141 }
142 /* index could not be found */
143 if (in->n==INDEXLIST_LENGTH) {
144 /* if in->index is full check the extension */
145 if (in->extension==NULL) {
146 in->extension=TMPMEMALLOC(1,Finley_IndexList);
147 if (Finley_checkPtr(in->extension)) return;
148 in->extension->n=0;
149 in->extension->extension=NULL;
150 }
151 Finley_IndexList_insertIndex(in->extension,index);
152 } else {
153 /* insert index into in->index*/
154 in->index[in->n]=index;
155 in->n++;
156 }
157 }
158
159 /* counts the number of row indices in the Finley_IndexList in */
160
161 dim_t Finley_IndexList_count(Finley_IndexList* in) {
162 if (in==NULL) {
163 return 0;
164 } else {
165 return (in->n)+Finley_IndexList_count(in->extension);
166 }
167 }
168
169 /* count the number of row indices in the Finley_IndexList in */
170
171 void Finley_IndexList_toArray(Finley_IndexList* in, index_t* array) {
172 dim_t i;
173 if (in!=NULL) {
174 for (i=0;i<in->n;i++) array[i]=in->index[i];
175 Finley_IndexList_toArray(in->extension,&(array[in->n]));
176 }
177 }
178
179 /* deallocates the Finley_IndexList in by recursive calls */
180
181 void Finley_IndexList_free(Finley_IndexList* in) {
182 if (in!=NULL) {
183 Finley_IndexList_free(in->extension);
184 TMPMEMFREE(in);
185 }
186 }
187
188 /*
189 * $Log$
190 * Revision 1.6 2005/09/15 03:44:22 jgs
191 * Merge of development branch dev-02 back to main trunk on 2005-09-15
192 *
193 * Revision 1.5.2.1 2005/09/07 06:26:18 gross
194 * the solver from finley are put into the standalone package paso now
195 *
196 * Revision 1.5 2005/07/08 04:07:51 jgs
197 * Merge of development branch back to main trunk on 2005-07-08
198 *
199 * Revision 1.4 2004/12/15 07:08:32 jgs
200 * *** empty log message ***
201 * Revision 1.1.1.1.2.3 2005/06/29 02:34:50 gross
202 * some changes towards 64 integers in finley
203 *
204 * Revision 1.1.1.1.2.2 2004/11/24 01:37:13 gross
205 * some changes dealing with the integer overflow in memory allocation. Finley solves 4M unknowns now
206 *
207 *
208 *
209 */

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26