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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1279 - (show annotations)
Mon Aug 27 06:35:15 2007 UTC (12 years, 9 months ago) by gross
File MIME type: text/plain
File size: 21200 byte(s)
bug in the reneration of rectangukar meshed fixed.
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: generates rectangular meshes */
16
17 /* Generates a numElements[0] x numElements[1] x numElements[2] mesh with first order elements (Hex8) in the brick */
18 /* [0,Length[0]] x [0,Length[1]] x [0,Length[2]]. order is the desired accuracy of the */
19 /* integration scheme. */
20
21 /**************************************************************/
22
23 /* Author: gross@access.edu.au */
24 /* Version: $Id$ */
25
26 /**************************************************************/
27
28 #include "RectangularMesh.h"
29
30 Finley_Mesh* Finley_RectangularMesh_Hex8(dim_t* numElements,
31 double* Length,
32 bool_t* periodic,
33 index_t order,
34 index_t reduced_order,
35 bool_t useElementsOnFace,
36 bool_t useFullElementOrder,
37 bool_t optimize)
38 {
39 #define N_PER_E 1
40 #define DIM 3
41 dim_t N0,N1,N2,NE0,NE1,NE2,i0,i1,i2,k,Nstride0,Nstride1,Nstride2, local_NE0, local_NE1, local_NE2, local_N0, local_N1, local_N2;
42 dim_t totalNECount,faceNECount,NDOF0,NDOF1,NDOF2,NFaceElements, NN;
43 index_t node0, myRank, e_offset2, e_offset1, e_offset0, offset1, offset2, offset0, global_i0, global_i1, global_i2;
44 Finley_Mesh* out;
45 Paso_MPIInfo *mpi_info = NULL;
46 char name[50];
47 double time0=Finley_timer();
48
49 /* get MPI information */
50 mpi_info = Paso_MPIInfo_alloc( MPI_COMM_WORLD );
51 if (! Finley_noError()) {
52 return NULL;
53 }
54 myRank=mpi_info->rank;
55
56 /* set up the global dimensions of the mesh */
57
58 NE0=MAX(1,numElements[0]);
59 NE1=MAX(1,numElements[1]);
60 NE2=MAX(1,numElements[2]);
61 N0=N_PER_E*NE0+1;
62 N1=N_PER_E*NE1+1;
63 N2=N_PER_E*NE2+1;
64
65 /* allocate mesh: */
66 sprintf(name,"Rectangular %d x %d x %d mesh",N0,N1,N2);
67 out=Finley_Mesh_alloc(name,DIM,order, reduced_order, mpi_info);
68 if (! Finley_noError()) {
69 Paso_MPIInfo_free( mpi_info );
70 return NULL;
71 }
72
73 Finley_Mesh_setElements(out,Finley_ElementFile_alloc(Hex8,out->order,out->reduced_order,mpi_info));
74 if (useElementsOnFace) {
75 Finley_Mesh_setFaceElements(out,Finley_ElementFile_alloc(Hex8Face,
76 out->order,
77 out->reduced_order,
78 mpi_info));
79 Finley_Mesh_setContactElements(out,Finley_ElementFile_alloc(Hex8Face_Contact,
80 out->order,
81 out->reduced_order,
82 mpi_info));
83 } else {
84 Finley_Mesh_setFaceElements(out,Finley_ElementFile_alloc(Rec4,
85 out->order,
86 out->reduced_order,
87 mpi_info));
88 Finley_Mesh_setContactElements(out,Finley_ElementFile_alloc(Rec4_Contact,
89 out->order,
90 out->reduced_order,
91 mpi_info));
92 }
93 Finley_Mesh_setPoints(out,Finley_ElementFile_alloc(Point1,
94 out->order,
95 out->reduced_order,
96 mpi_info));
97 if (! Finley_noError()) {
98 Paso_MPIInfo_free( mpi_info );
99 Finley_Mesh_free(out);
100 return NULL;
101 }
102
103 /* work out the largest dimension */
104 if (N2==MAX3(N0,N1,N2)) {
105 Nstride0=1;
106 Nstride1=N0;
107 Nstride2=N0*N1;
108 local_NE0=NE0;
109 e_offset0=0;
110 local_NE1=NE1;
111 e_offset1=0;
112 Paso_MPIInfo_Split(mpi_info,NE2,&local_NE2,&e_offset2);
113 } else if (N1==MAX3(N0,N1,N2)) {
114 Nstride0=N2;
115 Nstride1=N0*N2;
116 Nstride2=1;
117 local_NE0=NE0;
118 e_offset0=0;
119 Paso_MPIInfo_Split(mpi_info,NE1,&local_NE1,&e_offset1);
120 local_NE2=NE2;
121 e_offset2=0;
122 } else {
123 Nstride0=N1*N2;
124 Nstride1=1;
125 Nstride2=N1;
126 Paso_MPIInfo_Split(mpi_info,NE0,&local_NE0,&e_offset0);
127 local_NE1=NE1;
128 e_offset1=0;
129 local_NE2=NE2;
130 e_offset2=0;
131 }
132 offset0=e_offset0*N_PER_E;
133 offset1=e_offset1*N_PER_E;
134 offset2=e_offset2*N_PER_E;
135 local_N0=local_NE0*N_PER_E+1;
136 local_N1=local_NE1*N_PER_E+1;
137 local_N2=local_NE2*N_PER_E+1;
138
139 /* get the number of surface elements */
140
141 NFaceElements=0;
142 if (!periodic[2]) {
143 NDOF2=N2;
144 if (offset2==0) NFaceElements+=local_NE1*local_NE0;
145 if (local_NE2+e_offset2 == NE2) NFaceElements+=local_NE1*local_NE0;
146 } else {
147 NDOF2=N2-1;
148 }
149
150 if (!periodic[0]) {
151 NDOF0=N0;
152 if (e_offset0 == 0) NFaceElements+=local_NE1*local_NE2;
153 if (local_NE0+e_offset0 == NE0) NFaceElements+=local_NE1*local_NE2;
154 } else {
155 NDOF0=N0-1;
156 }
157 if (!periodic[1]) {
158 NDOF1=N1;
159 if (e_offset1 == 0) NFaceElements+=local_NE0*local_NE2;
160 if (local_NE1+e_offset1 == NE1) NFaceElements+=local_NE0*local_NE2;
161 } else {
162 NDOF1=N1-1;
163 }
164
165 /* allocate tables: */
166
167 Finley_NodeFile_allocTable(out->Nodes,local_N0*local_N1*local_N2);
168 Finley_ElementFile_allocTable(out->Elements,local_NE0*local_NE1*local_NE2);
169 Finley_ElementFile_allocTable(out->FaceElements,NFaceElements);
170
171 if (Finley_noError()) {
172 /* create nodes */
173
174 #pragma omp parallel for private(i0,i1,i2,k,global_i0,global_i1,global_i2)
175 for (i2=0;i2<local_N2;i2++) {
176 for (i1=0;i1<local_N1;i1++) {
177 for (i0=0;i0<local_N0;i0++) {
178 k=i0+local_N0*i1+local_N0*local_N1*i2;
179 global_i0=i0+offset0;
180 global_i1=i1+offset1;
181 global_i2=i2+offset2;
182 out->Nodes->Coordinates[INDEX2(0,k,DIM)]=DBLE(global_i0)/DBLE(N0-1)*Length[0];
183 out->Nodes->Coordinates[INDEX2(1,k,DIM)]=DBLE(global_i1)/DBLE(N1-1)*Length[1];
184 out->Nodes->Coordinates[INDEX2(2,k,DIM)]=DBLE(global_i2)/DBLE(N2-1)*Length[2];
185 out->Nodes->Id[k]=Nstride0*global_i0+Nstride1*global_i1+Nstride2*global_i2;
186 out->Nodes->Tag[k]=0;
187 out->Nodes->globalDegreesOfFreedom[k]=Nstride0*(global_i0%NDOF0)
188 +Nstride1*(global_i1%NDOF1)
189 +Nstride2*(global_i2%NDOF2);
190 }
191 }
192 }
193 /* set the elements: */
194 NN=out->Elements->numNodes;
195 #pragma omp parallel for private(i0,i1,i2,k,node0)
196 for (i2=0;i2<local_NE2;i2++) {
197 for (i1=0;i1<local_NE1;i1++) {
198 for (i0=0;i0<local_NE0;i0++) {
199
200 k=i0+local_NE0*i1+local_NE0*local_NE1*i2;
201 node0=Nstride0*N_PER_E*(i0+e_offset0)+Nstride1*N_PER_E*(i1+e_offset1)+Nstride2*N_PER_E*(i2+e_offset2);
202
203 out->Elements->Id[k]=(i0+e_offset0)+NE0*(i1+e_offset1)+NE0*NE1*(i2+e_offset2);
204 out->Elements->Tag[k]=0;
205 out->Elements->Owner[k]=myRank;
206
207 out->Elements->Nodes[INDEX2(0,k,NN)] =node0 ;
208 out->Elements->Nodes[INDEX2(1,k,NN)] =node0+ Nstride0;
209 out->Elements->Nodes[INDEX2(2,k,NN)] =node0+ Nstride1+Nstride0;
210 out->Elements->Nodes[INDEX2(3,k,NN)] =node0+ Nstride1;
211 out->Elements->Nodes[INDEX2(4,k,NN)] =node0+Nstride2 ;
212 out->Elements->Nodes[INDEX2(5,k,NN)] =node0+Nstride2 +Nstride0;
213 out->Elements->Nodes[INDEX2(6,k,NN)] =node0+Nstride2+Nstride1+Nstride0;
214 out->Elements->Nodes[INDEX2(7,k,NN)] =node0+Nstride2+Nstride1 ;
215 }
216 }
217 }
218 /* face elements */
219 NN=out->FaceElements->numNodes;
220 totalNECount=NE0*NE1*NE2;
221 faceNECount=0;
222 /* these are the quadrilateral elements on boundary 1 (x3=0): */
223 if (!periodic[2]) {
224 /* ** elements on boundary 100 (x3=0): */
225 if (e_offset2==0) {
226 #pragma omp parallel for private(i0,i1,k,node0)
227 for (i1=0;i1<local_NE1;i1++) {
228 for (i0=0;i0<local_NE0;i0++) {
229
230 k=i0+local_NE0*i1+faceNECount;
231 node0=Nstride0*N_PER_E*(i0+e_offset0)+Nstride1*N_PER_E*(i1+e_offset1);
232
233 out->FaceElements->Id[k]=(i0+e_offset0)+NE0*(i1+e_offset1)+totalNECount;
234 out->FaceElements->Tag[k]=100;
235 out->FaceElements->Owner[k]=myRank;
236
237 if (useElementsOnFace) {
238 out->FaceElements->Nodes[INDEX2(0,k,NN)] =node0 ;
239 out->FaceElements->Nodes[INDEX2(1,k,NN)] =node0 +Nstride1 ;
240 out->FaceElements->Nodes[INDEX2(2,k,NN)] =node0 +Nstride1+Nstride0;
241 out->FaceElements->Nodes[INDEX2(3,k,NN)] =node0+ Nstride0 ;
242 out->FaceElements->Nodes[INDEX2(4,k,NN)] =node0+Nstride2 ;
243 out->FaceElements->Nodes[INDEX2(5,k,NN)] =node0+Nstride2+Nstride1 ;
244 out->FaceElements->Nodes[INDEX2(6,k,NN)] =node0+Nstride2+Nstride1+Nstride0;
245 out->FaceElements->Nodes[INDEX2(7,k,NN)] =node0+Nstride2 +Nstride0;
246 } else {
247 out->FaceElements->Nodes[INDEX2(0,k,NN)] =node0 ;
248 out->FaceElements->Nodes[INDEX2(1,k,NN)] =node0+ Nstride1 ;
249 out->FaceElements->Nodes[INDEX2(2,k,NN)] =node0+ Nstride1+Nstride0;
250 out->FaceElements->Nodes[INDEX2(3,k,NN)] =node0+ Nstride0;
251 }
252 }
253 }
254 faceNECount+=local_NE1*local_NE0;
255 }
256 totalNECount+=NE1*NE0;
257 /* ** elements on boundary 200 (x3=1) */
258 if (local_NE2+e_offset2 == NE2) {
259 #pragma omp parallel for private(i0,i1,k,node0)
260 for (i1=0;i1<local_NE1;i1++) {
261 for (i0=0;i0<local_NE0;i0++) {
262
263 k=i0+local_NE0*i1+faceNECount;
264 node0=Nstride0*N_PER_E*(i0+e_offset0)+Nstride1*N_PER_E*(i1+e_offset1)+Nstride2*N_PER_E*(NE2-1);
265
266 out->FaceElements->Id[k]=(i0+e_offset0)+NE0*(i1+e_offset1)+totalNECount;
267 out->FaceElements->Tag[k]=200;
268 out->FaceElements->Owner[k]=myRank;
269 if (useElementsOnFace) {
270 out->FaceElements->Nodes[INDEX2(0,k,NN)] =node0+Nstride2 ;
271 out->FaceElements->Nodes[INDEX2(1,k,NN)] =node0+Nstride2+ Nstride0;
272 out->FaceElements->Nodes[INDEX2(2,k,NN)] =node0+Nstride2+Nstride1+Nstride0;
273 out->FaceElements->Nodes[INDEX2(3,k,NN)] =node0+Nstride2+Nstride1 ;
274
275 out->FaceElements->Nodes[INDEX2(4,k,NN)] =node0 ;
276 out->FaceElements->Nodes[INDEX2(5,k,NN)] =node0+Nstride0 ;
277 out->FaceElements->Nodes[INDEX2(6,k,NN)] =node0+ Nstride1+Nstride0;
278 out->FaceElements->Nodes[INDEX2(7,k,NN)] =node0+ Nstride1;
279 } else {
280 out->FaceElements->Nodes[INDEX2(0,k,NN)] =node0+Nstride2 ;
281 out->FaceElements->Nodes[INDEX2(1,k,NN)] =node0+Nstride2 +Nstride0;
282 out->FaceElements->Nodes[INDEX2(2,k,NN)] =node0+Nstride2+Nstride1+Nstride0;
283 out->FaceElements->Nodes[INDEX2(3,k,NN)] =node0+Nstride2+Nstride1 ;
284 }
285 }
286 }
287 faceNECount+=local_NE1*local_NE0;
288 }
289 totalNECount+=NE1*NE0;
290 }
291 if (!periodic[0]) {
292 /* ** elements on boundary 001 (x1=0): */
293
294 if (e_offset0 == 0) {
295 #pragma omp parallel for private(i1,i2,k,node0)
296 for (i2=0;i2<local_NE2;i2++) {
297 for (i1=0;i1<local_NE1;i1++) {
298
299 k=i1+local_NE1*i2+faceNECount;
300 node0=Nstride1*N_PER_E*(i1+e_offset1)+Nstride2*N_PER_E*(i2+e_offset2);
301 out->FaceElements->Id[k]=(i1+e_offset1)+NE1*(i2+e_offset2)+totalNECount;
302 out->FaceElements->Tag[k]=1;
303 out->FaceElements->Owner[k]=myRank;
304
305 if (useElementsOnFace) {
306 out->FaceElements->Nodes[INDEX2(0,k,NN)] =node0 ;
307 out->FaceElements->Nodes[INDEX2(1,k,NN)] =node0+Nstride2 ;
308 out->FaceElements->Nodes[INDEX2(2,k,NN)] =node0+Nstride2+Nstride1 ;
309 out->FaceElements->Nodes[INDEX2(3,k,NN)] =node0+Nstride1 ;
310 out->FaceElements->Nodes[INDEX2(4,k,NN)] =node0+Nstride0 ;
311 out->FaceElements->Nodes[INDEX2(5,k,NN)] =node0+Nstride2+Nstride0 ;
312 out->FaceElements->Nodes[INDEX2(6,k,NN)] =node0+Nstride2+Nstride1+Nstride0;
313 out->FaceElements->Nodes[INDEX2(7,k,NN)] =node0+Nstride1+Nstride0 ;
314 } else {
315 out->FaceElements->Nodes[INDEX2(0,k,NN)] =node0 ;
316 out->FaceElements->Nodes[INDEX2(1,k,NN)] =node0+Nstride2 ;
317 out->FaceElements->Nodes[INDEX2(2,k,NN)] =node0+Nstride2+Nstride1 ;
318 out->FaceElements->Nodes[INDEX2(3,k,NN)] =node0+ Nstride1 ;
319 }
320 }
321 }
322 faceNECount+=local_NE1*local_NE2;
323 }
324 totalNECount+=NE1*NE2;
325 /* ** elements on boundary 002 (x1=1): */
326 if (local_NE0+e_offset0 == NE0) {
327 #pragma omp parallel for private(i1,i2,k,node0)
328 for (i2=0;i2<local_NE2;i2++) {
329 for (i1=0;i1<local_NE1;i1++) {
330 k=i1+local_NE1*i2+faceNECount;
331 node0=Nstride0*N_PER_E*(NE0-1)+Nstride1*N_PER_E*(i1+e_offset1)+Nstride2*N_PER_E*(i2+e_offset2);
332 out->FaceElements->Id[k]=(i1+e_offset1)+NE1*(i2+e_offset2)+totalNECount;
333 out->FaceElements->Tag[k]=2;
334 out->FaceElements->Owner[k]=myRank;
335
336 if (useElementsOnFace) {
337 out->FaceElements->Nodes[INDEX2(0,k,NN)]=node0+ Nstride0;
338 out->FaceElements->Nodes[INDEX2(1,k,NN)]=node0+ Nstride1+Nstride0;
339 out->FaceElements->Nodes[INDEX2(2,k,NN)]=node0+Nstride2+Nstride1+Nstride0;
340 out->FaceElements->Nodes[INDEX2(3,k,NN)]=node0+Nstride2+ Nstride0;
341
342 out->FaceElements->Nodes[INDEX2(4,k,NN)]=node0 ;
343 out->FaceElements->Nodes[INDEX2(5,k,NN)]=node0+ Nstride1 ;
344 out->FaceElements->Nodes[INDEX2(6,k,NN)]=node0+Nstride2+Nstride1 ;
345 out->FaceElements->Nodes[INDEX2(7,k,NN)]=node0+Nstride2 ;
346
347 } else {
348 out->FaceElements->Nodes[INDEX2(0,k,NN)]=node0 +Nstride0;
349 out->FaceElements->Nodes[INDEX2(1,k,NN)]=node0+ Nstride1+Nstride0;
350 out->FaceElements->Nodes[INDEX2(2,k,NN)]=node0+Nstride2+Nstride1+Nstride0;
351 out->FaceElements->Nodes[INDEX2(3,k,NN)]=node0+Nstride2+ Nstride0;
352 }
353
354 }
355 }
356 faceNECount+=local_NE1*local_NE2;
357 }
358 totalNECount+=NE1*NE2;
359 }
360 if (!periodic[1]) {
361 /* ** elements on boundary 010 (x2=0): */
362 if (e_offset1 == 0) {
363 #pragma omp parallel for private(i0,i2,k,node0)
364 for (i2=0;i2<local_NE2;i2++) {
365 for (i0=0;i0<local_NE0;i0++) {
366 k=i0+local_NE0*i2+faceNECount;
367 node0=Nstride0*N_PER_E*(i0+e_offset0)+Nstride2*N_PER_E*(i2+e_offset2);
368
369 out->FaceElements->Id[k]=(i2+e_offset2)+NE2*(e_offset0+i0)+totalNECount;
370 out->FaceElements->Tag[k]=10;
371 out->FaceElements->Owner[k]=myRank;
372 if (useElementsOnFace) {
373 out->FaceElements->Nodes[INDEX2(0,k,NN)]=node0 ;
374 out->FaceElements->Nodes[INDEX2(1,k,NN)]=node0+ Nstride0;
375 out->FaceElements->Nodes[INDEX2(2,k,NN)]=node0+Nstride2 +Nstride0;
376 out->FaceElements->Nodes[INDEX2(3,k,NN)]=node0+Nstride2 ;
377
378 out->FaceElements->Nodes[INDEX2(4,k,NN)]=node0+ Nstride1 ;
379 out->FaceElements->Nodes[INDEX2(5,k,NN)]=node0+Nstride1+ Nstride0;
380 out->FaceElements->Nodes[INDEX2(6,k,NN)]=node0+Nstride2+Nstride1+Nstride0;
381 out->FaceElements->Nodes[INDEX2(7,k,NN)]=node0+Nstride2+Nstride1 ;
382 } else {
383 out->FaceElements->Nodes[INDEX2(0,k,NN)]=node0 ;
384 out->FaceElements->Nodes[INDEX2(1,k,NN)]=node0+ Nstride0;
385 out->FaceElements->Nodes[INDEX2(2,k,NN)]=node0+Nstride2+ Nstride0;
386 out->FaceElements->Nodes[INDEX2(3,k,NN)]=node0+Nstride2 ;
387 }
388 }
389 }
390 faceNECount+=local_NE0*local_NE2;
391 }
392 totalNECount+=NE0*NE2;
393 /* ** elements on boundary 020 (x2=1): */
394 if (local_NE1+e_offset1 == NE1) {
395 #pragma omp parallel for private(i0,i2,k,node0)
396 for (i2=0;i2<local_NE2;i2++) {
397 for (i0=0;i0<local_NE0;i0++) {
398 k=i0+local_NE0*i2+faceNECount;
399 node0=Nstride0*N_PER_E*(i0+e_offset0)+Nstride1*N_PER_E*(NE1-1)+Nstride2*N_PER_E*(i2+e_offset2);
400
401 out->FaceElements->Id[k]=(i2+e_offset2)+NE2*(i0+e_offset0)+totalNECount;
402 out->FaceElements->Tag[k]=20;
403 out->FaceElements->Owner[k]=myRank;
404
405 if (useElementsOnFace) {
406 out->FaceElements->Nodes[INDEX2(0,k,NN)]=node0+ Nstride1 ;
407 out->FaceElements->Nodes[INDEX2(1,k,NN)]=node0+Nstride2+Nstride1 ;
408 out->FaceElements->Nodes[INDEX2(2,k,NN)]=node0+Nstride2+Nstride1+Nstride0;
409 out->FaceElements->Nodes[INDEX2(3,k,NN)]=node0+Nstride1+Nstride0 ;
410
411 out->FaceElements->Nodes[INDEX2(4,k,NN)]=node0 ;
412 out->FaceElements->Nodes[INDEX2(5,k,NN)]=node0+Nstride2 ;
413 out->FaceElements->Nodes[INDEX2(6,k,NN)]=node0+Nstride2+ Nstride0;
414 out->FaceElements->Nodes[INDEX2(7,k,NN)]=node0+ Nstride0;
415 } else {
416 out->FaceElements->Nodes[INDEX2(0,k,NN)]=node0+ Nstride1 ;
417 out->FaceElements->Nodes[INDEX2(1,k,NN)]=node0+Nstride2+Nstride1 ;
418 out->FaceElements->Nodes[INDEX2(2,k,NN)]=node0+Nstride2+Nstride1+Nstride0;
419 out->FaceElements->Nodes[INDEX2(3,k,NN)]=node0+ Nstride1+Nstride0;
420 }
421 }
422 }
423 faceNECount+=local_NE0*local_NE2;
424 }
425 totalNECount+=NE0*NE2;
426 }
427 /* add tag names */
428 Finley_Mesh_addTagMap(out,"top", 200);
429 Finley_Mesh_addTagMap(out,"bottom", 100);
430 Finley_Mesh_addTagMap(out,"left", 1);
431 Finley_Mesh_addTagMap(out,"right", 2);
432 Finley_Mesh_addTagMap(out,"front", 10);
433 Finley_Mesh_addTagMap(out,"back", 20);
434
435 /* prepare mesh for further calculatuions:*/
436 if (Finley_noError()) {
437 Finley_Mesh_resolveNodeIds(out);
438 }
439 if (Finley_noError()) {
440 Finley_Mesh_prepare(out, optimize);
441 }
442 }
443
444 if (!Finley_noError()) {
445 Finley_Mesh_free(out);
446 }
447 /* free up memory */
448 Paso_MPIInfo_free( mpi_info );
449 #ifdef Finley_TRACE
450 printf("timing: mesh generation: %.4e sec\n",Finley_timer()-time0);
451 #endif
452
453 return out;
454 }

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26