xref: /petsc/src/mat/utils/freespace.c (revision ac450b4331df367ad8a5a6b9d70f54001dfe8d46)
1 #define PETSCMAT_DLL
2 
3 #include "../src/mat/utils/freespace.h"
4 
5 #undef __FUNCT__
6 #define __FUNCT__ "PetscFreeSpaceGet"
7 PetscErrorCode PetscFreeSpaceGet(PetscInt n,PetscFreeSpaceList *list)
8 {
9   PetscFreeSpaceList a;
10   PetscErrorCode     ierr;
11 
12   PetscFunctionBegin;
13   ierr = PetscMalloc(sizeof(struct _Space),&a);CHKERRQ(ierr);
14   ierr = PetscMalloc(n*sizeof(PetscInt),&(a->array_head));CHKERRQ(ierr);
15   a->array            = a->array_head;
16   a->local_remaining  = n;
17   a->local_used       = 0;
18   a->total_array_size = 0;
19   a->more_space       = NULL;
20 
21   if (*list) {
22     (*list)->more_space = a;
23     a->total_array_size = (*list)->total_array_size;
24   }
25 
26   a->total_array_size += n;
27   *list               =  a;
28   PetscFunctionReturn(0);
29 }
30 
31 #undef __FUNCT__
32 #define __FUNCT__ "PetscFreeSpaceContiguous"
33 PetscErrorCode PetscFreeSpaceContiguous(PetscFreeSpaceList *head,PetscInt *space)
34 {
35   PetscFreeSpaceList a;
36   PetscErrorCode     ierr;
37 
38   PetscFunctionBegin;
39   while ((*head)!=NULL) {
40     a     =  (*head)->more_space;
41     ierr  =  PetscMemcpy(space,(*head)->array_head,((*head)->local_used)*sizeof(PetscInt));CHKERRQ(ierr);
42     space += (*head)->local_used;
43     ierr  =  PetscFree((*head)->array_head);CHKERRQ(ierr);
44     ierr  =  PetscFree(*head);CHKERRQ(ierr);
45     *head =  a;
46   }
47   PetscFunctionReturn(0);
48 }
49 
50 #undef __FUNCT__
51 #define __FUNCT__ "PetscFreeSpaceContiguous_newdatastruct"
52 PetscErrorCode PetscFreeSpaceContiguous_newdatastruct(PetscFreeSpaceList *head,PetscInt *space,PetscInt n,PetscInt *bi,PetscInt *bdiag)
53 {
54   PetscFreeSpaceList a;
55   PetscErrorCode     ierr;
56   PetscInt           row,nnz,*bj,*array,total;
57   PetscInt           nnzL,nnzU;
58 
59   PetscFunctionBegin;
60   bi[2*n+1] = bi[n];
61   row   = 1;
62   total = 0;
63   nnzL  = bdiag[0];
64   while ((*head)!=NULL) {
65     total += (*head)->local_used;
66     array  = (*head)->array_head;
67 
68     while (bi[row] <= total && row <=n){
69       /* copy array entries into bj for row-1 */
70       nnz  = bi[row] - bi[row-1];
71       /* set bi[row-1] for new datastruct */
72       if (row -1 <= 1 ){
73         bi[row -1] = 0;
74       } else {
75         bi[row-1] = bi[row-2] + nnzL; /* nnzL of previous row */
76       }
77 
78       /* L part */
79       nnzL = bdiag[row-1];
80       bj   = space+bi[row-1];
81       ierr = PetscMemcpy(bj,array,nnzL*sizeof(PetscInt));CHKERRQ(ierr);
82 
83       /* diagonal entry */
84       bdiag[row-1]        = bi[2*n-(row-1)+1]-1;
85       space[bdiag[row-1]] = row-1;
86 
87       /* U part */
88       nnzU = nnz - nnzL;
89       bi[2*n-(row-1)] = bi[2*n-(row-1)+1] - nnzU;
90       nnzU --; /* exclude diagonal */
91       bj  = space + bi[2*n-(row-1)];
92       ierr = PetscMemcpy(bj,array+nnzL+1,nnzU*sizeof(PetscInt));CHKERRQ(ierr);
93 
94       array += nnz;
95       row++;
96     }
97 
98     a     =  (*head)->more_space;
99     ierr  =  PetscFree((*head)->array_head);CHKERRQ(ierr);
100     ierr  =  PetscFree(*head);CHKERRQ(ierr);
101     *head =  a;
102   }
103   bi[n] = bi[n-1] + nnzL;
104   if (bi[n] != bi[n+1]) SETERRQ2(1,"bi[n] %d != bi[n+1] %d",bi[n],bi[n+1]);
105   PetscFunctionReturn(0);
106 }
107 
108 #undef __FUNCT__
109 #define __FUNCT__ "PetscFreeSpaceDestroy"
110 PetscErrorCode PetscFreeSpaceDestroy(PetscFreeSpaceList head)
111 {
112   PetscFreeSpaceList a;
113   PetscErrorCode     ierr;
114 
115   PetscFunctionBegin;
116   while ((head)!=NULL) {
117     a    = (head)->more_space;
118     ierr = PetscFree((head)->array_head);CHKERRQ(ierr);
119     ierr = PetscFree(head);CHKERRQ(ierr);
120     head = a;
121   }
122   PetscFunctionReturn(0);
123 }
124