source: CIVL/examples/mpi-omp/AMG2013/seq_mv/csr_matrix.c

main
Last change on this file was ea777aa, checked in by Alex Wilton <awilton@…>, 3 years ago

Moved examples, include, build_default.properties, common.xml, and README out from dev.civl.com into the root of the repo.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@5704 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 14.6 KB
Line 
1/*BHEADER**********************************************************************
2 * Copyright (c) 2008, Lawrence Livermore National Security, LLC.
3 * Produced at the Lawrence Livermore National Laboratory.
4 * This file is part of HYPRE. See file COPYRIGHT for details.
5 *
6 * HYPRE is free software; you can redistribute it and/or modify it under the
7 * terms of the GNU Lesser General Public License (as published by the Free
8 * Software Foundation) version 2.1 dated February 1999.
9 *
10 * $Revision: 2.4 $
11 ***********************************************************************EHEADER*/
12
13
14
15/******************************************************************************
16 *
17 * Member functions for hypre_CSRMatrix class.
18 *
19 *****************************************************************************/
20
21#include "headers.h"
22
23/*--------------------------------------------------------------------------
24 * hypre_CSRMatrixCreate
25 *--------------------------------------------------------------------------*/
26
27hypre_CSRMatrix *
28hypre_CSRMatrixCreate( int num_rows,
29 int num_cols,
30 int num_nonzeros )
31{
32 hypre_CSRMatrix *matrix;
33
34 matrix = hypre_CTAlloc(hypre_CSRMatrix, 1);
35
36 hypre_CSRMatrixData(matrix) = NULL;
37 hypre_CSRMatrixI(matrix) = NULL;
38 hypre_CSRMatrixJ(matrix) = NULL;
39 hypre_CSRMatrixRownnz(matrix) = NULL;
40 hypre_CSRMatrixNumRows(matrix) = num_rows;
41 hypre_CSRMatrixNumCols(matrix) = num_cols;
42 hypre_CSRMatrixNumNonzeros(matrix) = num_nonzeros;
43
44 /* set defaults */
45 hypre_CSRMatrixOwnsData(matrix) = 1;
46 hypre_CSRMatrixNumRownnz(matrix) = num_rows;
47
48
49 return matrix;
50}
51/*--------------------------------------------------------------------------
52 * hypre_CSRMatrixDestroy
53 *--------------------------------------------------------------------------*/
54
55int
56hypre_CSRMatrixDestroy( hypre_CSRMatrix *matrix )
57{
58 int ierr=0;
59
60 if (matrix)
61 {
62
63 hypre_TFree(hypre_CSRMatrixI(matrix));
64 if (hypre_CSRMatrixRownnz(matrix))
65 hypre_TFree(hypre_CSRMatrixRownnz(matrix));
66 if ( hypre_CSRMatrixOwnsData(matrix) )
67 {
68 hypre_TFree(hypre_CSRMatrixData(matrix));
69 hypre_TFree(hypre_CSRMatrixJ(matrix));
70 }
71
72 hypre_TFree(matrix);
73 }
74
75 return ierr;
76}
77
78/*--------------------------------------------------------------------------
79 * hypre_CSRMatrixInitialize
80 *--------------------------------------------------------------------------*/
81
82int
83hypre_CSRMatrixInitialize( hypre_CSRMatrix *matrix )
84{
85 int num_rows = hypre_CSRMatrixNumRows(matrix);
86 int num_nonzeros = hypre_CSRMatrixNumNonzeros(matrix);
87 int ierr=0;
88
89
90 if ( ! hypre_CSRMatrixData(matrix) && num_nonzeros )
91 hypre_CSRMatrixData(matrix) = hypre_CTAlloc(double, num_nonzeros);
92 if ( ! hypre_CSRMatrixI(matrix) )
93 hypre_CSRMatrixI(matrix) = hypre_CTAlloc(int, num_rows + 1);
94 if ( ! hypre_CSRMatrixJ(matrix) && num_nonzeros )
95 hypre_CSRMatrixJ(matrix) = hypre_CTAlloc(int, num_nonzeros);
96
97 return ierr;
98}
99
100/*--------------------------------------------------------------------------
101 * hypre_CSRMatrixSetDataOwner
102 *--------------------------------------------------------------------------*/
103
104int
105hypre_CSRMatrixSetDataOwner( hypre_CSRMatrix *matrix,
106 int owns_data )
107{
108 int ierr=0;
109
110 hypre_CSRMatrixOwnsData(matrix) = owns_data;
111
112 return ierr;
113}
114
115/*--------------------------------------------------------------------------
116 * hypre_CSRMatrixSetRownnz
117 *
118 * function to set the substructure rownnz and num_rowsnnz inside the CSRMatrix
119 * it needs the A_i substructure of CSRMatrix to find the nonzero rows.
120 * It runs after the create CSR and when A_i is known..It does not check for
121 * the existence of A_i or of the CSR matrix.
122 *--------------------------------------------------------------------------*/
123
124int
125hypre_CSRMatrixSetRownnz( hypre_CSRMatrix *matrix )
126{
127 int ierr=0;
128 int num_rows = hypre_CSRMatrixNumRows(matrix);
129 int *A_i = hypre_CSRMatrixI(matrix);
130 int *Arownnz;
131
132 int i, adiag;
133 int irownnz=0;
134
135 for (i=0; i < num_rows; i++)
136 {
137 adiag = (A_i[i+1] - A_i[i]);
138 if(adiag > 0) irownnz++;
139 }
140
141 hypre_CSRMatrixNumRownnz(matrix) = irownnz;
142
143 if ((irownnz == 0) || (irownnz == num_rows))
144 {
145 hypre_CSRMatrixRownnz(matrix) = NULL;
146 }
147 else
148 {
149 Arownnz = hypre_CTAlloc(int, irownnz);
150 irownnz = 0;
151 for (i=0; i < num_rows; i++)
152 {
153 adiag = A_i[i+1]-A_i[i];
154 if(adiag > 0) Arownnz[irownnz++] = i;
155 }
156 hypre_CSRMatrixRownnz(matrix) = Arownnz;
157 }
158 return ierr;
159}
160
161/*--------------------------------------------------------------------------
162 * hypre_CSRMatrixRead
163 *--------------------------------------------------------------------------*/
164
165hypre_CSRMatrix *
166hypre_CSRMatrixRead( char *file_name )
167{
168 hypre_CSRMatrix *matrix;
169
170 FILE *fp;
171
172 double *matrix_data;
173 int *matrix_i;
174 int *matrix_j;
175 int num_rows;
176 int num_nonzeros;
177 int max_col = 0;
178
179 int file_base = 1;
180
181 int j;
182
183 /*----------------------------------------------------------
184 * Read in the data
185 *----------------------------------------------------------*/
186
187 fp = fopen(file_name, "r");
188
189 fscanf(fp, "%d", &num_rows);
190
191 matrix_i = hypre_CTAlloc(int, num_rows + 1);
192 for (j = 0; j < num_rows+1; j++)
193 {
194 fscanf(fp, "%d", &matrix_i[j]);
195 matrix_i[j] -= file_base;
196 }
197
198 num_nonzeros = matrix_i[num_rows];
199
200 matrix = hypre_CSRMatrixCreate(num_rows, num_rows, matrix_i[num_rows]);
201 hypre_CSRMatrixI(matrix) = matrix_i;
202 hypre_CSRMatrixInitialize(matrix);
203
204 matrix_j = hypre_CSRMatrixJ(matrix);
205 for (j = 0; j < num_nonzeros; j++)
206 {
207 fscanf(fp, "%d", &matrix_j[j]);
208 matrix_j[j] -= file_base;
209
210 if (matrix_j[j] > max_col)
211 {
212 max_col = matrix_j[j];
213 }
214 }
215
216 matrix_data = hypre_CSRMatrixData(matrix);
217 for (j = 0; j < matrix_i[num_rows]; j++)
218 {
219 fscanf(fp, "%le", &matrix_data[j]);
220 }
221
222 fclose(fp);
223
224 hypre_CSRMatrixNumNonzeros(matrix) = num_nonzeros;
225 hypre_CSRMatrixNumCols(matrix) = ++max_col;
226
227 return matrix;
228}
229
230/*--------------------------------------------------------------------------
231 * hypre_CSRMatrixPrint
232 *--------------------------------------------------------------------------*/
233
234int
235hypre_CSRMatrixPrint( hypre_CSRMatrix *matrix,
236 char *file_name )
237{
238 FILE *fp;
239
240 double *matrix_data;
241 int *matrix_i;
242 int *matrix_j;
243 int num_rows;
244
245 int file_base = 1;
246
247 int j;
248
249 int ierr = 0;
250
251 /*----------------------------------------------------------
252 * Print the matrix data
253 *----------------------------------------------------------*/
254
255 matrix_data = hypre_CSRMatrixData(matrix);
256 matrix_i = hypre_CSRMatrixI(matrix);
257 matrix_j = hypre_CSRMatrixJ(matrix);
258 num_rows = hypre_CSRMatrixNumRows(matrix);
259
260 fp = fopen(file_name, "w");
261
262 fprintf(fp, "%d\n", num_rows);
263
264 for (j = 0; j <= num_rows; j++)
265 {
266 fprintf(fp, "%d\n", matrix_i[j] + file_base);
267 }
268
269 for (j = 0; j < matrix_i[num_rows]; j++)
270 {
271 fprintf(fp, "%d\n", matrix_j[j] + file_base);
272 }
273
274 if (matrix_data)
275 {
276 for (j = 0; j < matrix_i[num_rows]; j++)
277 {
278 fprintf(fp, "%.14e\n", matrix_data[j]);
279 }
280 }
281 else
282 {
283 fprintf(fp, "Warning: No matrix data!\n");
284 }
285
286 fclose(fp);
287
288 return ierr;
289}
290
291/*--------------------------------------------------------------------------
292 * hypre_CSRMatrixCopy:
293 * copys A to B,
294 * if copy_data = 0 only the structure of A is copied to B.
295 * the routine does not check if the dimensions of A and B match !!!
296 *--------------------------------------------------------------------------*/
297
298int
299hypre_CSRMatrixCopy( hypre_CSRMatrix *A, hypre_CSRMatrix *B, int copy_data )
300{
301 int ierr=0;
302 int num_rows = hypre_CSRMatrixNumRows(A);
303 int *A_i = hypre_CSRMatrixI(A);
304 int *A_j = hypre_CSRMatrixJ(A);
305 double *A_data;
306 int *B_i = hypre_CSRMatrixI(B);
307 int *B_j = hypre_CSRMatrixJ(B);
308 double *B_data;
309
310 int i, j;
311
312 for (i=0; i < num_rows; i++)
313 {
314 B_i[i] = A_i[i];
315 for (j=A_i[i]; j < A_i[i+1]; j++)
316 {
317 B_j[j] = A_j[j];
318 }
319 }
320 B_i[num_rows] = A_i[num_rows];
321 if (copy_data)
322 {
323 A_data = hypre_CSRMatrixData(A);
324 B_data = hypre_CSRMatrixData(B);
325 for (i=0; i < num_rows; i++)
326 {
327 for (j=A_i[i]; j < A_i[i+1]; j++)
328 {
329 B_data[j] = A_data[j];
330 }
331 }
332 }
333 return ierr;
334}
335
336/*--------------------------------------------------------------------------
337 * hypre_CSRMatrixClone
338 * Creates and returns a new copy of the argument, A.
339 * Data is not copied, only structural information is reproduced.
340 * Copying is a deep copy in that no pointers are copied; new arrays are
341 * created where necessary.
342 *--------------------------------------------------------------------------*/
343
344hypre_CSRMatrix * hypre_CSRMatrixClone( hypre_CSRMatrix * A )
345{
346 int num_rows = hypre_CSRMatrixNumRows( A );
347 int num_cols = hypre_CSRMatrixNumCols( A );
348 int num_nonzeros = hypre_CSRMatrixNumNonzeros( A );
349 hypre_CSRMatrix * B = hypre_CSRMatrixCreate( num_rows, num_cols, num_nonzeros );
350 int * A_i;
351 int * A_j;
352 int * B_i;
353 int * B_j;
354 int i, j;
355
356 hypre_CSRMatrixInitialize( B );
357
358 A_i = hypre_CSRMatrixI(A);
359 A_j = hypre_CSRMatrixJ(A);
360 B_i = hypre_CSRMatrixI(B);
361 B_j = hypre_CSRMatrixJ(B);
362
363 for ( i=0; i<num_rows+1; ++i ) B_i[i] = A_i[i];
364 for ( j=0; j<num_nonzeros; ++j ) B_j[j] = A_j[j];
365 hypre_CSRMatrixNumRownnz(B) = hypre_CSRMatrixNumRownnz(A);
366 if ( hypre_CSRMatrixRownnz(A) ) hypre_CSRMatrixSetRownnz( B );
367
368 return B;
369}
370
371/*--------------------------------------------------------------------------
372 * hypre_CSRMatrixUnion
373 * Creates and returns a matrix whose elements are the union of those of A and B.
374 * Data is not computed, only structural information is created.
375 * A and B must have the same numbers of rows.
376 * Nothing is done about Rownnz.
377 *
378 * If col_map_offd_A and col_map_offd_B are zero, A and B are expected to have
379 * the same column indexing. Otherwise, col_map_offd_A, col_map_offd_B should
380 * be the arrays of that name from two ParCSRMatrices of which A and B are the
381 * offd blocks.
382 *
383 * The algorithm can be expected to have reasonable efficiency only for very
384 * sparse matrices (many rows, few nonzeros per row).
385 * The nonzeros of a computed row are NOT necessarily in any particular order.
386 *--------------------------------------------------------------------------*/
387
388hypre_CSRMatrix * hypre_CSRMatrixUnion(
389 hypre_CSRMatrix * A, hypre_CSRMatrix * B,
390 HYPRE_BigInt * col_map_offd_A, HYPRE_BigInt * col_map_offd_B,
391 HYPRE_BigInt ** col_map_offd_C )
392{
393 int num_rows = hypre_CSRMatrixNumRows( A );
394 int num_cols_A = hypre_CSRMatrixNumCols( A );
395 int num_cols_B = hypre_CSRMatrixNumCols( B );
396 int num_cols;
397 int num_nonzeros;
398 int * A_i = hypre_CSRMatrixI(A);
399 int * A_j = hypre_CSRMatrixJ(A);
400 int * B_i = hypre_CSRMatrixI(B);
401 int * B_j = hypre_CSRMatrixJ(B);
402 int * C_i;
403 int * C_j;
404 int * jC = NULL;
405 int i, jA, jB, jBg;
406 int ma, mb, mc, ma_min, ma_max, match;
407 hypre_CSRMatrix * C;
408
409 hypre_assert( num_rows == hypre_CSRMatrixNumRows(B) );
410 if ( col_map_offd_B ) hypre_assert( col_map_offd_A );
411 if ( col_map_offd_A ) hypre_assert( col_map_offd_B );
412
413 /* ==== First, go through the columns of A and B to count the columns of C. */
414 if ( col_map_offd_A==0 )
415 { /* The matrices are diagonal blocks.
416 Normally num_cols_A==num_cols_B, col_starts is the same, etc.
417 */
418 num_cols = hypre_max( num_cols_A, num_cols_B );
419 }
420 else
421 { /* The matrices are offdiagonal blocks. */
422 jC = hypre_CTAlloc( int, num_cols_B );
423 num_cols = num_cols_A; /* initialization; we'll compute the actual value */
424 for ( jB=0; jB<num_cols_B; ++jB )
425 {
426 match = 0;
427 jBg = col_map_offd_B[jB];
428 for ( ma=0; ma<num_cols_A; ++ma )
429 {
430 if ( col_map_offd_A[ma]==jBg )
431 match = 1;
432 }
433 if ( match==0 )
434 {
435 jC[jB] = num_cols;
436 ++num_cols;
437 }
438 }
439 }
440
441 /* ==== If we're working on a ParCSRMatrix's offd block,
442 make and load col_map_offd_C */
443 if ( col_map_offd_A )
444 {
445 *col_map_offd_C = hypre_CTAlloc( HYPRE_BigInt, num_cols );
446 for ( jA=0; jA<num_cols_A; ++jA )
447 (*col_map_offd_C)[jA] = col_map_offd_A[jA];
448 for ( jB=0; jB<num_cols_B; ++jB )
449 {
450 match = 0;
451 jBg = col_map_offd_B[jB];
452 for ( ma=0; ma<num_cols_A; ++ma )
453 {
454 if ( col_map_offd_A[ma]==jBg )
455 match = 1;
456 }
457 if ( match==0 )
458 (*col_map_offd_C)[ jC[jB] ] = jBg;
459 }
460 }
461
462
463 /* ==== The first run through A and B is to count the number of nonzero elements,
464 without double-counting duplicates. Then we can create C. */
465 num_nonzeros = hypre_CSRMatrixNumNonzeros(A);
466 for ( i=0; i<num_rows; ++i )
467 {
468 ma_min = A_i[i]; ma_max = A_i[i+1];
469 for ( mb=B_i[i]; mb<B_i[i+1]; ++mb )
470 {
471 jB = B_j[mb];
472 if ( col_map_offd_B ) jB = col_map_offd_B[jB];
473 match = 0;
474 for ( ma=ma_min; ma<ma_max; ++ma )
475 {
476 jA = A_j[ma];
477 if ( col_map_offd_A ) jA = col_map_offd_A[jA];
478 if ( jB == jA )
479 {
480 match = 1;
481 if( ma==ma_min ) ++ma_min;
482 break;
483 }
484 }
485 if ( match==0 )
486 ++num_nonzeros;
487 }
488 }
489
490 C = hypre_CSRMatrixCreate( num_rows, num_cols, num_nonzeros );
491 hypre_CSRMatrixInitialize( C );
492
493
494 /* ==== The second run through A and B is to pick out the column numbers
495 for each row, and put them in C. */
496 C_i = hypre_CSRMatrixI(C);
497 C_i[0] = 0;
498 C_j = hypre_CSRMatrixJ(C);
499 mc = 0;
500 for ( i=0; i<num_rows; ++i )
501 {
502 ma_min = A_i[i]; ma_max = A_i[i+1];
503 for ( ma=ma_min; ma<ma_max; ++ma )
504 {
505 C_j[mc] = A_j[ma];
506 ++mc;
507 }
508 for ( mb=B_i[i]; mb<B_i[i+1]; ++mb )
509 {
510 jB = B_j[mb];
511 if ( col_map_offd_B ) jB = col_map_offd_B[jB];
512 match = 0;
513 for ( ma=ma_min; ma<ma_max; ++ma )
514 {
515 jA = A_j[ma];
516 if ( col_map_offd_A ) jA = col_map_offd_A[jA];
517 if ( jB == jA )
518 {
519 match = 1;
520 if( ma==ma_min ) ++ma_min;
521 break;
522 }
523 }
524 if ( match==0 )
525 {
526 C_j[mc] = jC[ B_j[mb] ];
527 ++mc;
528 }
529 }
530 C_i[i+1] = mc;
531 }
532
533 hypre_assert( mc == num_nonzeros );
534 if (jC) hypre_TFree( jC );
535
536 return C;
537}
Note: See TracBrowser for help on using the repository browser.