/[escript]/branches/doubleplusgood/finley/src/Util.cpp
ViewVC logotype

Contents of /branches/doubleplusgood/finley/src/Util.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4327 - (show annotations)
Wed Mar 20 05:09:11 2013 UTC (6 years, 6 months ago) by jfenwick
File size: 19513 byte(s)
some finley memory
1
2 /*****************************************************************************
3 *
4 * Copyright (c) 2003-2013 by University of Queensland
5 * http://www.uq.edu.au
6 *
7 * Primary Business: Queensland, Australia
8 * Licensed under the Open Software License version 3.0
9 * http://www.opensource.org/licenses/osl-3.0.php
10 *
11 * Development until 2012 by Earth Systems Science Computational Center (ESSCC)
12 * Development since 2012 by School of Earth Sciences
13 *
14 *****************************************************************************/
15
16
17 /************************************************************************************/
18
19 /* Some utility routines: */
20
21 /************************************************************************************/
22
23 #include "Finley.h"
24 #include "Util.h"
25
26 #ifdef _OPENMP
27 #include <omp.h>
28 #endif
29
30 #include "esysUtils/mem.h"
31 #include "esysUtils/index.h"
32 #include <string.h> /* for memcpy */
33
34
35 /************************************************************************************/
36
37 /* returns true if any of the values in the short array values is not equal to Zero */
38
39 bool_t Finley_Util_anyNonZeroDouble(dim_t N, double* values) {
40 dim_t q;
41 for (q=0;q<N;++q) if (ABS(values[q])>0) return TRUE;
42 return FALSE;
43 }
44 /************************************************************************************/
45
46 /* gathers double values out from in by index: */
47
48 /* out(1:numData,1:len)=in(1:numData,index(1:len)) */
49
50 void Finley_Util_Gather_double(dim_t len,index_t* index,dim_t numData,double* in, double * out){
51 dim_t s,i;
52 for (s=0;s<len;s++) {
53 for (i=0;i<numData;i++) {
54 out[INDEX2(i,s,numData)]=in[INDEX2(i,index[s],numData)];
55 }
56 }
57 }
58
59 /************************************************************************************/
60
61
62 /* gathers integer values out from in by index: */
63
64 /* out(1:numData,1:len)=in(1:numData,index(1:len)) */
65
66 void Finley_Util_Gather_int(dim_t len,index_t* index,dim_t numData, index_t* in, index_t * out){
67 dim_t s,i;
68 for (s=0;s<len;s++) {
69 for (i=0;i<numData;i++) {
70 out[INDEX2(i,s,numData)]=in[INDEX2(i,index[s],numData)];
71 }
72 }
73 }
74
75 /************************************************************************************/
76
77 /* adds a vector in into out using an index. */
78
79 /* out(1:numData,index[p])+=in(1:numData,p) where p = {k=1...len , index[k]<upperBound}*/
80
81
82 void Finley_Util_AddScatter(const dim_t len, const index_t* index, const dim_t numData, const double* in,double * out, const index_t upperBound){
83 dim_t i,s;
84 for (s=0;s<len;s++) {
85 for(i=0;i<numData;i++) {
86 if( index[s]<upperBound ) {
87 out[INDEX2(i,index[s],numData)]+=in[INDEX2(i,s,numData)];
88 }
89 }
90 }
91 }
92
93 /* multiplies two matrices */
94
95 /* A(1:A1,1:A2)=B(1:A1,1:B2)*C(1:B2,1:A2) */
96
97 void Finley_Util_SmallMatMult(dim_t A1,dim_t A2, double* A, dim_t B2, double*B, double* C) {
98 dim_t i,j,s;
99 register double rtmp;
100 for (i=0;i<A1;i++) {
101 for (j=0;j<A2;j++) {
102 rtmp=0;
103 for (s=0;s<B2;s++) rtmp+=B[INDEX2(i,s,A1)]*C[INDEX2(s,j,B2)];
104 A[INDEX2(i,j,A1)]=rtmp;
105 }
106 }
107 }
108
109 /* multiplies two sets of matrices: */
110
111 /* A(1:A1,1:A2,i)=B(1:A1,1:B2,i)*C(1:B2,1:A2,i) i=1,len */
112
113 void Finley_Util_SmallMatSetMult(dim_t len,dim_t A1,dim_t A2, double* A, dim_t B2, double*B, double* C) {
114 dim_t q,i,j,s;
115 register double rtmp;
116 for (q=0;q<len;q++) {
117 for (i=0;i<A1;i++) {
118 for (j=0;j<A2;j++) {
119 rtmp=0;
120 for (s=0;s<B2;s++) rtmp+=B[INDEX3(i,s,q,A1,B2)]*C[INDEX3(s,j,q,B2,A2)];
121 A[INDEX3(i,j,q, A1,A2)]=rtmp;
122 }
123 }
124 }
125 }
126 /* multiplies a set of matrices with a single matrix: */
127
128 /* A(1:A1,1:A2,i)=B(1:A1,1:B2,i)*C(1:B2,1:A2) i=1,len */
129
130 void Finley_Util_SmallMatSetMult1(dim_t len,dim_t A1,dim_t A2, double* A, dim_t B2, double*B, double* C) {
131 dim_t q,i,j,s;
132 register double rtmp;
133 for (q=0;q<len;q++) {
134 for (i=0;i<A1;i++) {
135 for (j=0;j<A2;j++) {
136 rtmp=0;
137 for (s=0;s<B2;s++) rtmp+=B[INDEX3(i,s,q, A1,B2)]*C[INDEX2(s,j,B2)];
138 A[INDEX3(i,j,q,A1,A2)]=rtmp;
139 }
140 }
141 }
142 }
143 /* inverts the set of dim x dim matrices A(:,:,1:len) with dim=1,2,3 */
144 /* the determinant is returned. */
145
146 void Finley_Util_InvertSmallMat(dim_t len,dim_t dim,double* A,double *invA, double* det){
147 dim_t q;
148 register double D,A11,A12,A13,A21,A22,A23,A31,A32,A33;
149
150 switch(dim) {
151 case 1:
152 for (q=0;q<len;q++) {
153 D=A[q];
154 if (ABS(D) > 0 ){
155 det[q]=D;
156 D=1./D;
157 invA[q]=D;
158 } else {
159 Finley_setError(ZERO_DIVISION_ERROR, __FILE__ ": Non-regular matrix");
160 return;
161 }
162 }
163 break;
164
165 case 2:
166 for (q=0;q<len;q++) {
167 A11=A[INDEX3(0,0,q,2,2)];
168 A12=A[INDEX3(0,1,q,2,2)];
169 A21=A[INDEX3(1,0,q,2,2)];
170 A22=A[INDEX3(1,1,q,2,2)];
171
172 D = A11*A22-A12*A21;
173 if (ABS(D) > 0 ){
174 det[q]=D;
175 D=1./D;
176 invA[INDEX3(0,0,q,2,2)]= A22*D;
177 invA[INDEX3(1,0,q,2,2)]=-A21*D;
178 invA[INDEX3(0,1,q,2,2)]=-A12*D;
179 invA[INDEX3(1,1,q,2,2)]= A11*D;
180 } else {
181 Finley_setError(ZERO_DIVISION_ERROR, __FILE__ ": Non-regular matrix");
182 return;
183 }
184 }
185 break;
186
187 case 3:
188 for (q=0;q<len;q++) {
189 A11=A[INDEX3(0,0,q,3,3)];
190 A21=A[INDEX3(1,0,q,3,3)];
191 A31=A[INDEX3(2,0,q,3,3)];
192 A12=A[INDEX3(0,1,q,3,3)];
193 A22=A[INDEX3(1,1,q,3,3)];
194 A32=A[INDEX3(2,1,q,3,3)];
195 A13=A[INDEX3(0,2,q,3,3)];
196 A23=A[INDEX3(1,2,q,3,3)];
197 A33=A[INDEX3(2,2,q,3,3)];
198
199 D = A11*(A22*A33-A23*A32)+ A12*(A31*A23-A21*A33)+A13*(A21*A32-A31*A22);
200 if (ABS(D) > 0 ){
201 det[q] =D;
202 D=1./D;
203 invA[INDEX3(0,0,q,3,3)]=(A22*A33-A23*A32)*D;
204 invA[INDEX3(1,0,q,3,3)]=(A31*A23-A21*A33)*D;
205 invA[INDEX3(2,0,q,3,3)]=(A21*A32-A31*A22)*D;
206 invA[INDEX3(0,1,q,3,3)]=(A13*A32-A12*A33)*D;
207 invA[INDEX3(1,1,q,3,3)]=(A11*A33-A31*A13)*D;
208 invA[INDEX3(2,1,q,3,3)]=(A12*A31-A11*A32)*D;
209 invA[INDEX3(0,2,q,3,3)]=(A12*A23-A13*A22)*D;
210 invA[INDEX3(1,2,q,3,3)]=(A13*A21-A11*A23)*D;
211 invA[INDEX3(2,2,q,3,3)]=(A11*A22-A12*A21)*D;
212 } else {
213 Finley_setError(ZERO_DIVISION_ERROR, __FILE__ ": Non-regular matrix");
214 return;
215 }
216 }
217 break;
218
219 }
220 return;
221 }
222
223 /* sets the determinat of a set of dim x dim matrices A(:,:,1:len) with dim=1,2,3 */
224
225 void Finley_Util_DetOfSmallMat(dim_t len,dim_t dim,double* A, double* det){
226 dim_t q;
227 register double A11,A12,A13,A21,A22,A23,A31,A32,A33;
228
229 switch(dim) {
230 case 1:
231 for (q=0;q<len;q++) {
232 det[q]=A[q];
233 }
234 break;
235
236 case 2:
237 for (q=0;q<len;q++) {
238 A11=A[INDEX3(0,0,q,2,2)];
239 A12=A[INDEX3(0,1,q,2,2)];
240 A21=A[INDEX3(1,0,q,2,2)];
241 A22=A[INDEX3(1,1,q,2,2)];
242
243 det[q] = A11*A22-A12*A21;
244 }
245 break;
246
247 case 3:
248 for (q=0;q<len;q++) {
249 A11=A[INDEX3(0,0,q,3,3)];
250 A21=A[INDEX3(1,0,q,3,3)];
251 A31=A[INDEX3(2,0,q,3,3)];
252 A12=A[INDEX3(0,1,q,3,3)];
253 A22=A[INDEX3(1,1,q,3,3)];
254 A32=A[INDEX3(2,1,q,3,3)];
255 A13=A[INDEX3(0,2,q,3,3)];
256 A23=A[INDEX3(1,2,q,3,3)];
257 A33=A[INDEX3(2,2,q,3,3)];
258
259 det[q] = A11*(A22*A33-A23*A32)+ A12*(A31*A23-A21*A33)+A13*(A21*A32-A31*A22);
260 }
261 break;
262
263 }
264 return;
265 }
266 /* returns the normalized vector Normal[dim,len] orthogonal to A(:,0,q) and A(:,1,q) in the case of dim=3 */
267 /* or the vector A(:,0,q) in the case of dim=2 */
268
269 void Finley_NormalVector(dim_t len, dim_t dim, dim_t dim1, double* A,double* Normal) {
270 dim_t q;
271 register double A11,A12,CO_A13,A21,A22,CO_A23,A31,A32,CO_A33,length,invlength;
272
273 switch(dim) {
274 case 1:
275 for (q=0;q<len;q++) Normal[q] =1;
276 break;
277 case 2:
278 for (q=0;q<len;q++) {
279 A11=A[INDEX3(0,0,q,2,dim1)];
280 A21=A[INDEX3(1,0,q,2,dim1)];
281 length = sqrt(A11*A11+A21*A21);
282 if (! length>0) {
283 Finley_setError(ZERO_DIVISION_ERROR, __FILE__ ": area equals zero.");
284 return;
285 } else {
286 invlength=1./length;
287 Normal[INDEX2(0,q,2)]=A21*invlength;
288 Normal[INDEX2(1,q,2)]=-A11*invlength;
289 }
290 }
291 break;
292 case 3:
293 for (q=0;q<len;q++) {
294 A11=A[INDEX3(0,0,q,3,dim1)];
295 A21=A[INDEX3(1,0,q,3,dim1)];
296 A31=A[INDEX3(2,0,q,3,dim1)];
297 A12=A[INDEX3(0,1,q,3,dim1)];
298 A22=A[INDEX3(1,1,q,3,dim1)];
299 A32=A[INDEX3(2,1,q,3,dim1)];
300 CO_A13=A21*A32-A31*A22;
301 CO_A23=A31*A12-A11*A32;
302 CO_A33=A11*A22-A21*A12;
303 length=sqrt(CO_A13*CO_A13+CO_A23*CO_A23+CO_A33*CO_A33);
304 if (! length>0) {
305 Finley_setError(ZERO_DIVISION_ERROR, __FILE__ ": area equals zero.");
306 return;
307 } else {
308 invlength=1./length;
309 Normal[INDEX2(0,q,3)]=CO_A13*invlength;
310 Normal[INDEX2(1,q,3)]=CO_A23*invlength;
311 Normal[INDEX2(2,q,3)]=CO_A33*invlength;
312 }
313
314 }
315 break;
316
317 }
318 return;
319 }
320
321 /* return the length of the vector which is orthogonal to the vectors A(:,0,q) and A(:,1,q) in the case of dim=3 */
322 /* or the vector A(:,0,q) in the case of dim=2 */
323
324 void Finley_LengthOfNormalVector(dim_t len, dim_t dim, dim_t dim1, double* A,double* length) {
325 dim_t q;
326 double A11,A12,CO_A13,A21,A22,CO_A23,A31,A32,CO_A33;
327
328 switch(dim) {
329 case 1:
330 for (q=0;q<len;q++) length[q] =1;
331 break;
332 case 2:
333 for (q=0;q<len;q++) {
334 A11=A[INDEX3(0,0,q,2,dim1)];
335 A21=A[INDEX3(1,0,q,2,dim1)];
336 length[q] = sqrt(A11*A11+A21*A21);
337 }
338 break;
339 case 3:
340 for (q=0;q<len;q++) {
341 A11=A[INDEX3(0,0,q,3,dim1)];
342 A21=A[INDEX3(1,0,q,3,dim1)];
343 A31=A[INDEX3(2,0,q,3,dim1)];
344 A12=A[INDEX3(0,1,q,3,dim1)];
345 A22=A[INDEX3(1,1,q,3,dim1)];
346 A32=A[INDEX3(2,1,q,3,dim1)];
347 CO_A13=A21*A32-A31*A22;
348 CO_A23=A31*A12-A11*A32;
349 CO_A33=A11*A22-A21*A12;
350 length[q]=sqrt(CO_A13*CO_A13+CO_A23*CO_A23+CO_A33*CO_A33);
351 }
352 break;
353
354 }
355 return;
356 }
357
358 /* inverts a map of length len */
359 /* there is no range checking! */
360 /* output: Map[invMap[i]]=i for i=0:lenInvMap */
361
362 void Finley_Util_InvertMap(dim_t lenInvMap, index_t* invMap,dim_t lenMap, index_t* Map) {
363 dim_t i;
364 for (i=0;i<lenInvMap;i++) invMap[i]=0;
365 for (i=0;i<lenMap;i++) {
366 if (Map[i]>=0) invMap[Map[i]]=i;
367 }
368 }
369
370 /* orders a Finley_Util_ValueAndIndex array by value */
371 /* it is assumed that n is large */
372
373 int Finley_Util_ValueAndIndex_compar(const void *arg1 , const void *arg2 ) {
374 Finley_Util_ValueAndIndex *e1,*e2;
375 e1=(Finley_Util_ValueAndIndex*) arg1;
376 e2=(Finley_Util_ValueAndIndex*) arg2;
377 if (e1->value < e2->value) return -1;
378 if (e1->value > e2->value) return 1;
379 if (e1->index < e2->index) return -1;
380 if (e1->index > e2->index) return 1;
381 return 0;
382 }
383
384 void Finley_Util_sortValueAndIndex(dim_t n,Finley_Util_ValueAndIndex* array) {
385 /* TODO: needs OpenMP parallelization !*/
386 qsort(array,n,sizeof(Finley_Util_ValueAndIndex),Finley_Util_ValueAndIndex_compar);
387 }
388
389
390 /************************************************************************************/
391
392 /* calculates the minimum value from a dim X N integer array */
393
394 index_t Finley_Util_getMinInt(dim_t dim,dim_t N,index_t* values) {
395 dim_t i,j;
396 index_t out,out_local;
397 out=INDEX_T_MAX;
398 if (values!=NULL && dim*N>0 ) {
399 out=values[0];
400 #pragma omp parallel private(out_local)
401 {
402 out_local=out;
403 #pragma omp for private(i,j) schedule(static)
404 for (j=0;j<N;j++) {
405 for (i=0;i<dim;i++) out_local=MIN(out_local,values[INDEX2(i,j,dim)]);
406 }
407 #pragma omp critical
408 out=MIN(out_local,out);
409 }
410 }
411 return out;
412 }
413
414 /* calculates the maximum value from a dim X N integer array */
415
416 index_t Finley_Util_getMaxInt(dim_t dim,dim_t N,index_t* values) {
417 dim_t i,j;
418 index_t out,out_local;
419 out=-INDEX_T_MAX;
420 if (values!=NULL && dim*N>0 ) {
421 out=values[0];
422 #pragma omp parallel private(out_local)
423 {
424 out_local=out;
425 #pragma omp for private(i,j) schedule(static)
426 for (j=0;j<N;j++) {
427 for (i=0;i<dim;i++) out_local=MAX(out_local,values[INDEX2(i,j,dim)]);
428 }
429 #pragma omp critical
430 out=MAX(out_local,out);
431 }
432 }
433 return out;
434 }
435 /************************************************************************************/
436
437 /* calculates the minimum value from a dim X N integer array */
438
439 index_t Finley_Util_getFlaggedMinInt(dim_t dim,dim_t N,index_t* values, index_t ignore) {
440 dim_t i,j;
441 index_t out,out_local;
442 out=INDEX_T_MAX;
443 if (values!=NULL && dim*N>0 ) {
444 out=values[0];
445 #pragma omp parallel private(out_local)
446 {
447 out_local=out;
448 #pragma omp for private(i,j) schedule(static)
449 for (j=0;j<N;j++) {
450 for (i=0;i<dim;i++) if (values[INDEX2(i,j,dim)]!=ignore) out_local=MIN(out_local,values[INDEX2(i,j,dim)]);
451 }
452 #pragma omp critical
453 out=MIN(out_local,out);
454 }
455 }
456 return out;
457 }
458
459 /* calculates the maximum value from a dim X N integer array */
460
461 index_t Finley_Util_getFlaggedMaxInt(dim_t dim,dim_t N,index_t* values, index_t ignore) {
462 dim_t i,j;
463 index_t out,out_local;
464 out=-INDEX_T_MAX;
465 if (values!=NULL && dim*N>0 ) {
466 out=values[0];
467 #pragma omp parallel private(out_local)
468 {
469 out_local=out;
470 #pragma omp for private(i,j) schedule(static)
471 for (j=0;j<N;j++) {
472 for (i=0;i<dim;i++) if (values[INDEX2(i,j,dim)]!=ignore) out_local=MAX(out_local,values[INDEX2(i,j,dim)]);
473 }
474 #pragma omp critical
475 out=MAX(out_local,out);
476 }
477 }
478 return out;
479 }
480
481 /* set the index of the positive entries in mask. The length of index is returned. */
482
483 dim_t Finley_Util_packMask(dim_t N,index_t* mask,index_t* index) {
484 dim_t out,k;
485 out=0;
486 /* TODO: OMP */
487 for (k=0;k<N;k++) {
488 if (mask[k]>=0) {
489 index[out]=k;
490 out++;
491 }
492 }
493 return out;
494 }
495
496 /* returns true if array contains value */
497 bool_t Finley_Util_isAny(dim_t N,index_t* array,index_t value) {
498 bool_t out=FALSE;
499 dim_t i;
500 #pragma omp parallel for private(i) schedule(static) reduction(||:out)
501 for (i=0;i<N;i++) out = out || (array[i]==value);
502 return out;
503 }
504
505 /* calculates the cumulative sum in array and returns the total sum */
506 index_t Finley_Util_cumsum(dim_t N,index_t* array) {
507 index_t out=0,tmp;
508 dim_t i;
509 #ifdef _OPENMP
510 index_t *partial_sums=NULL, sum;
511 partial_sums=new index_t[omp_get_max_threads()];
512 #pragma omp parallel private(sum,i,tmp)
513 {
514 sum=0;
515 #pragma omp for schedule(static)
516 for (i=0;i<N;++i) sum+=array[i];
517 partial_sums[omp_get_thread_num()]=sum;
518 #pragma omp barrier
519 #pragma omp master
520 {
521 out=0;
522 for (i=0;i<omp_get_max_threads();++i) {
523 tmp=out;
524 out+=partial_sums[i];
525 partial_sums[i]=tmp;
526 }
527 }
528 #pragma omp barrier
529 sum=partial_sums[omp_get_thread_num()];
530 #pragma omp for schedule(static)
531 for (i=0;i<N;++i) {
532 tmp=sum;
533 sum+=array[i];
534 array[i]=tmp;
535 }
536 }
537 delete[] partial_sums;
538 #else
539 for (i=0;i<N;++i) {
540 tmp=out;
541 out+=array[i];
542 array[i]=tmp;
543 }
544 #endif
545 return out;
546 }
547
548 void Finley_Util_setValuesInUse(const index_t *values, const dim_t numValues, dim_t *numValuesInUse, index_t **valuesInUse, Esys_MPIInfo* mpiinfo)
549 {
550 dim_t i;
551 index_t lastFoundValue=INDEX_T_MIN, minFoundValue, local_minFoundValue, *newValuesInUse=NULL;
552 register index_t itmp;
553 bool_t allFound=FALSE;
554 dim_t nv=0;
555
556 while (! allFound) {
557 /*
558 * find smallest value bigger than lastFoundValue
559 */
560 minFoundValue=INDEX_T_MAX;
561 #pragma omp parallel private(local_minFoundValue)
562 {
563 local_minFoundValue=minFoundValue;
564 #pragma omp for private(i,itmp) schedule(static)
565 for (i=0;i< numValues;i++) {
566 itmp=values[i];
567 if ((itmp>lastFoundValue) && (itmp<local_minFoundValue)) local_minFoundValue=itmp;
568 }
569 #pragma omp critical
570 {
571 if (local_minFoundValue<minFoundValue) minFoundValue=local_minFoundValue;
572 }
573
574 }
575 #ifdef ESYS_MPI
576 local_minFoundValue=minFoundValue;
577 MPI_Allreduce(&local_minFoundValue,&minFoundValue, 1, MPI_INT, MPI_MIN, mpiinfo->comm );
578 #endif
579 /* if we found a new tag we need to add this to the valuesInUseList */
580
581 if (minFoundValue < INDEX_T_MAX) {
582 newValuesInUse=new index_t[nv+1];
583 if (*valuesInUse!=NULL) {
584 memcpy(newValuesInUse,*valuesInUse,sizeof(index_t)*nv);
585 delete[] *valuesInUse;
586 }
587 newValuesInUse[nv]=minFoundValue;
588 *valuesInUse=newValuesInUse;
589 newValuesInUse=NULL;
590 nv++;
591 lastFoundValue=minFoundValue;
592 } else {
593 allFound=TRUE;
594 }
595 }
596 *numValuesInUse=nv;
597 }
598
599
600 #ifdef ESYS_MPI
601 void Finley_printDoubleArray( FILE *fid, dim_t n, double *array, char *name )
602 {
603 index_t i;
604
605 if( name )
606 fprintf( fid, "%s [ ", name );
607 else
608 fprintf( fid, "[ " );
609 for( i=0; i<(n<60 ? n : 60); i++ )
610 fprintf( fid, "%g ", array[i] );
611 if( n>=30 )
612 fprintf( fid, "... " );
613 fprintf( fid, "]\n" );
614 }
615 void Finley_printIntArray( FILE *fid, dim_t n, int *array, char *name )
616 {
617 index_t i;
618
619 if( name )
620 fprintf( fid, "%s [ ", name );
621 else
622 fprintf( fid, "[ " );
623 for( i=0; i<(n<60 ? n : 60); i++ )
624 fprintf( fid, "%d ", array[i] );
625 if( n>=30 )
626 fprintf( fid, "... " );
627 fprintf( fid, "]\n" );
628 }
629 void Finley_printMaskArray( FILE *fid, dim_t n, int *array, char *name )
630 {
631 index_t i;
632
633 if( name )
634 fprintf( fid, "%s [ ", name );
635 else
636 fprintf( fid, "[ " );
637 for( i=0; i<(n<60 ? n : 60); i++ )
638 if( array[i]!=-1 )
639 fprintf( fid, "%3d ", array[i] );
640 else
641 fprintf( fid, " * " );
642 if( n>=30 )
643 fprintf( fid, "... " );
644 fprintf( fid, "]\n" );
645 }
646 #endif

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26