xref: /petsc/src/mat/utils/freespace.c (revision df4cd43f92eaa320656440c40edb1046daee8f75)
1 
2 #include <../src/mat/utils/freespace.h>
3 
4 PetscErrorCode PetscFreeSpaceGet(PetscInt n, PetscFreeSpaceList *list)
5 {
6   PetscFreeSpaceList a;
7 
8   PetscFunctionBegin;
9   PetscCall(PetscNew(&a));
10   PetscCall(PetscMalloc1(n, &(a->array_head)));
11 
12   a->array            = a->array_head;
13   a->local_remaining  = n;
14   a->local_used       = 0;
15   a->total_array_size = 0;
16   a->more_space       = NULL;
17 
18   if (*list) {
19     (*list)->more_space = a;
20     a->total_array_size = (*list)->total_array_size;
21   }
22 
23   a->total_array_size += n;
24   *list = a;
25   PetscFunctionReturn(PETSC_SUCCESS);
26 }
27 
28 PetscErrorCode PetscFreeSpaceContiguous(PetscFreeSpaceList *head, PetscInt *space)
29 {
30   PetscFreeSpaceList a;
31 
32   PetscFunctionBegin;
33   while ((*head)) {
34     a = (*head)->more_space;
35     PetscCall(PetscArraycpy(space, (*head)->array_head, (*head)->local_used));
36     space += (*head)->local_used;
37     PetscCall(PetscFree((*head)->array_head));
38     PetscCall(PetscFree(*head));
39     *head = a;
40   }
41   PetscFunctionReturn(PETSC_SUCCESS);
42 }
43 
44 /*
45   PetscFreeSpaceContiguous_LU -
46     Copy a linket list obtained from matrix symbolic ILU or LU factorization into a contiguous array
47   that enables an efficient matrix triangular solve.
48 
49    Input Parameters:
50 +  head - linked list of column indices obtained from matrix symbolic ILU or LU factorization
51 .  space - an allocated array with length nnz of factored matrix.
52 .  n - order of the matrix
53 .  bi - row pointer of factored matrix L with length n+1.
54 -  bdiag - array of length n+1. bdiag[i] points to diagonal of U(i,:), and bdiag[n] points to entry of U(n-1,0)-1.
55 
56    Output Parameter:
57 .  space - column indices are copied into this array with contiguous layout of L and U
58 
59    See MatILUFactorSymbolic_SeqAIJ_ilu0() for detailed data structure of L and U
60 */
61 PetscErrorCode PetscFreeSpaceContiguous_LU(PetscFreeSpaceList *head, PetscInt *space, PetscInt n, PetscInt *bi, PetscInt *bdiag)
62 {
63   PetscFreeSpaceList a;
64   PetscInt           row, nnz, *bj, *array, total, bi_temp;
65   PetscInt           nnzL, nnzU;
66 
67   PetscFunctionBegin;
68   bi_temp = bi[n];
69   row     = 0;
70   total   = 0;
71   nnzL    = bdiag[0];
72   while ((*head)) {
73     total += (*head)->local_used;
74     array = (*head)->array_head;
75 
76     while (row < n) {
77       if (bi[row + 1] > total) break;
78       /* copy array entries into bj for this row */
79       nnz = bi[row + 1] - bi[row];
80       /* set bi[row] for new datastruct */
81       if (row == 0) {
82         bi[row] = 0;
83       } else {
84         bi[row] = bi[row - 1] + nnzL; /* nnzL of previous row */
85       }
86 
87       /* L part */
88       nnzL = bdiag[row];
89       bj   = space + bi[row];
90       PetscCall(PetscArraycpy(bj, array, nnzL));
91 
92       /* diagonal entry */
93       bdiag[row]        = bi_temp - 1;
94       space[bdiag[row]] = row;
95 
96       /* U part */
97       nnzU    = nnz - nnzL;
98       bi_temp = bi_temp - nnzU;
99       nnzU--; /* exclude diagonal */
100       bj = space + bi_temp;
101       PetscCall(PetscArraycpy(bj, array + nnzL + 1, nnzU));
102       array += nnz;
103       row++;
104     }
105 
106     a = (*head)->more_space;
107     PetscCall(PetscFree((*head)->array_head));
108     PetscCall(PetscFree(*head));
109     *head = a;
110   }
111   if (n) {
112     bi[n]    = bi[n - 1] + nnzL;
113     bdiag[n] = bdiag[n - 1] - 1;
114   }
115   PetscFunctionReturn(PETSC_SUCCESS);
116 }
117 
118 /*
119   PetscFreeSpaceContiguous_Cholesky -
120     Copy a linket list obtained from matrix symbolic ICC or Cholesky factorization into a contiguous array
121   that enables an efficient matrix triangular solve.
122 
123    Input Parameters:
124 +  head - linked list of column indices obtained from matrix symbolic ICC or Cholesky factorization
125 .  space - an allocated array with length nnz of factored matrix.
126 .  n - order of the matrix
127 .  ui - row pointer of factored matrix with length n+1. All entries are set based on the traditional layout U matrix.
128 -  udiag - array of length n.
129 
130    Output Parameter:
131 +  space - column indices are copied into this array with contiguous layout of U, with diagonal located as the last entry in each row
132 -  udiag - indices of diagonal entries
133 
134    See MatICCFactorSymbolic_SeqAIJ_newdatastruct() for detailed description.
135 */
136 
137 PetscErrorCode PetscFreeSpaceContiguous_Cholesky(PetscFreeSpaceList *head, PetscInt *space, PetscInt n, PetscInt *ui, PetscInt *udiag)
138 {
139   PetscFreeSpaceList a;
140   PetscInt           row, nnz, *uj, *array, total;
141 
142   PetscFunctionBegin;
143   row   = 0;
144   total = 0;
145   while (*head) {
146     total += (*head)->local_used;
147     array = (*head)->array_head;
148 
149     while (row < n) {
150       if (ui[row + 1] > total) break;
151       udiag[row] = ui[row + 1] - 1;           /* points to the last entry of U(row,:) */
152       nnz        = ui[row + 1] - ui[row] - 1; /* exclude diagonal */
153       uj         = space + ui[row];
154       PetscCall(PetscArraycpy(uj, array + 1, nnz));
155       uj[nnz] = array[0]; /* diagonal */
156       array += nnz + 1;
157       row++;
158     }
159 
160     a = (*head)->more_space;
161     PetscCall(PetscFree((*head)->array_head));
162     PetscCall(PetscFree(*head));
163     *head = a;
164   }
165   PetscFunctionReturn(PETSC_SUCCESS);
166 }
167 
168 PetscErrorCode PetscFreeSpaceDestroy(PetscFreeSpaceList head)
169 {
170   PetscFreeSpaceList a;
171 
172   PetscFunctionBegin;
173   while ((head)) {
174     a = (head)->more_space;
175     PetscCall(PetscFree((head)->array_head));
176     PetscCall(PetscFree(head));
177     head = a;
178   }
179   PetscFunctionReturn(PETSC_SUCCESS);
180 }
181