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