Fast Auxiliary Space Preconditioning 2.7.7 Aug/28/2022
Loading...
Searching...
No Matches
PreAMGCoarsenCR.c
Go to the documentation of this file.
1
16#include <math.h>
17
18#ifdef _OPENMP
19#include <omp.h>
20#endif
21
22#include "fasp.h"
23#include "fasp_functs.h"
24
25#define AMG_COARSEN_CR
26
27/*---------------------------------*/
28/*-- Declare Private Functions --*/
29/*---------------------------------*/
30
31#include "PreAMGUtil.inl"
32
33static INT GraphAdd(Link *, INT *, INT *, INT, INT);
34static INT GraphRemove(Link *, INT *, INT *, INT );
35static INT indset(INT, INT, INT, INT *, INT *, INT, INT *, REAL *);
36
37/*---------------------------------*/
38/*-- Public Functions --*/
39/*---------------------------------*/
40
63 const INT i_n,
64 dCSRmat *A,
65 ivector *vertices,
66 AMG_param *param)
67{
68 const SHORT prtlvl = param->print_level;
69
70 // local variables
71 INT cand=0,cpt=-1,fpt=1; // internal labeling
72 INT nc,ns=1; // # cpts, # stages
73 INT i,j,in1,nu=3,num1 = nu-1; // nu is number of cr sweeps
74 INT *cf=NULL,*ia=NULL,*ja=NULL;
75
76 REAL temp0=0.0e0,temp1=0.0e0,rho=0.0e0,tg=8.0e-01;
77 REAL *a=NULL;
78
79 /* WORKING MEMORY -- b not needed, remove later */
80 REAL *b=NULL,*u=NULL,*ma=NULL;
81
82 ia = A->IA;
83 ja = A->JA;
84 a = A->val;
85
86 if (i_0 == 0) {
87 in1 = i_n+1;
88 } else {
89 in1 = i_n;
90 }
91
92 /* CF, RHS, INITIAL GUESS, and MEAS. ARRAY */
93 cf = (INT*)fasp_mem_calloc(in1,sizeof(INT));
94 b = (REAL*)fasp_mem_calloc(in1,sizeof(REAL));
95 u = (REAL*)fasp_mem_calloc(in1,sizeof(REAL));
96 ma = (REAL*)fasp_mem_calloc(in1,sizeof(REAL));
97
98#ifdef _OPENMP
99#pragma omp parallel for if(i_n>OPENMP_HOLDS)
100#endif
101 for(i=i_0;i<=i_n;++i) {
102 b[i] = 0.0e0; // ZERO RHS
103 cf[i] = fpt; // ALL FPTS
104 }
105
107 while (TRUE) {
108
109 nc = 0;
110#ifdef _OPENMP
111#pragma omp parallel for if(i_n>OPENMP_HOLDS)
112#endif
113 for(i=i_0; i<=i_n; ++i) {
114 if (cf[i] == cpt) {
115 nc += 1;
116 u[i] = 0.0e0;
117 } else {
118 u[i] = 1.0e0;
119 }
120 }
121
122 for (i=i_0;i<=nu;++i) {
123
124 if (i == num1)
125 for (j = i_0; j<= i_n; ++j) {
126 if (cf[j] == fpt) {
127 temp0 += u[j]*u[j];
128 }
129 }
130 fasp_smoother_dcsr_gscr(fpt,i_n,u,ia,ja,a,b,1,cf);
131 }
132
133#ifdef _OPENMP
134#pragma omp parallel for reduction(+:temp1) if(i_n>OPENMP_HOLDS)
135#endif
136 for (i = i_0; i<= i_n; ++i) {
137 if (cf[i] == fpt) {
138 temp1 += u[i]*u[i];
139 }
140 }
141 rho = sqrt(temp1)/sqrt(temp0);
142
143 if ( prtlvl > PRINT_MIN ) printf("rho=%2.13lf\n",rho);
144
145 if ( rho > tg ) {
146 /* FORM CAND. SET & COMPUTE IND SET */
147 temp0 = 0.0e0;
148
149 for (i = i_0; i<= i_n; ++i) {
150 temp1 = fabs(u[i]);
151 if (cf[i] == cpt && temp1 > 0.0e0) {
152 temp0 = temp1; // max.
153 }
154 }
155 if (ns == 1) {
156 temp1 = pow(0.3, nu);
157 } else {
158 temp1 = 0.5;
159 }
160
161#ifdef _OPENMP
162#pragma omp parallel for if(i_n>OPENMP_HOLDS)
163#endif
164 for (i = i_0; i <= i_n; ++i) {
165 if (cf[i] == fpt && fabs(u[i])/temp0 > temp1 && ia[i+1]-ia[i] > 1)
166 cf[i] = cand;
167 }
168 temp1 = 0.0e0;
169 indset(cand,cpt,fpt,ia,ja,i_n,cf,ma);
170 ns++;
171 }
172 else {
173 /* back to fasp labeling */
174
175#ifdef _OPENMP
176#pragma omp parallel for if(i_n>OPENMP_HOLDS)
177#endif
178 for (i = i_0; i<= i_n; ++i) {
179 if (cf[i] == cpt) {
180 cf[i] = 1; // cpt
181 } else {
182 cf[i] = 0; // fpt
183 }
184 // printf("cf[%i] = %i\n",i,cf[i]);
185 }
186 vertices->row=i_n;
187 if ( prtlvl >= PRINT_MORE ) printf("vertices = %i\n",vertices->row);
188 vertices->val= cf;
189 if ( prtlvl >= PRINT_MORE ) printf("nc=%i\n",nc);
190 break;
191 }
192 }
193
194 fasp_mem_free(u); u = NULL;
195 fasp_mem_free(b); b = NULL;
196 fasp_mem_free(ma); ma = NULL;
197
198 return nc;
199}
200
201/*---------------------------------*/
202/*-- Private Functions --*/
203/*---------------------------------*/
204
209static INT GraphAdd (Link *list,
210 INT *head,
211 INT *tail,
212 INT index,
213 INT istack)
214{
215 INT prev = tail[-istack];
216
217 list[index].prev = prev;
218 if (prev < 0)
219 head[-istack] = index;
220 else
221 list[prev].next = index;
222 list[index].next = -istack;
223 tail[-istack] = index;
224
225 return 0;
226}
227
232static INT GraphRemove (Link *list,
233 INT *head,
234 INT *tail,
235 INT index)
236{
237 INT prev = list[index].prev;
238 INT next = list[index].next;
239
240 if (prev < 0)
241 head[prev] = next;
242 else
243 list[prev].next = next;
244 if (next < 0)
245 tail[next] = prev;
246 else
247 list[next].prev = prev;
248
249 return 0;
250}
251
272static INT indset (INT cand,
273 INT cpt,
274 INT fpt,
275 INT *ia,
276 INT *ja,
277 INT n,
278 INT *cf,
279 REAL *ma)
280{
281 /* ma: candidates >= 1, cpts = -1, otherwise = 0
282 * Note: graph contains candidates only */
283
284 Link *list;
285 INT *head, *head_mem;
286 INT *tail, *tail_mem;
287
288 INT i, ji, jj, jl, index, istack, stack_size;
289
290 for (istack = i = 0; i < n; ++i) {
291
292 if (cf[i] == cand) {
293 ma[i] = 1;
294 for (ji = ia[i]+1; ji < ia[i+1]; ++ji) {
295 jj = ja[ji];
296 if (cf[jj] != cpt) {
297 ma[i]++;
298 }
299 }
300
301 if (ma[i] > istack) {
302 istack = (INT) ma[i];
303 }
304 }
305 else if (cf[i] == cpt) {
306 ma[i] = -1;
307 }
308 else {
309 ma[i] = 0;
310 }
311 }
312
313 stack_size = 2*istack;
314
315 /* INITIALIZE GRAPH */
316 list = (Link*)fasp_mem_calloc(n,sizeof(Link));
317 head_mem = (INT*)fasp_mem_calloc(stack_size,sizeof(INT));
318 tail_mem = (INT*)fasp_mem_calloc(stack_size,sizeof(INT));
319 head = head_mem + stack_size;
320 tail = tail_mem + stack_size;
321
322#ifdef _OPENMP
323#pragma omp parallel for if(stack_size>OPENMP_HOLDS)
324#endif
325 for (i = -1; i >= -stack_size; i--) {
326 head[i] = i;
327 tail[i] = i;
328 }
329
330#ifdef _OPENMP
331#pragma omp parallel for if(stack_size>OPENMP_HOLDS)
332#endif
333 for (i = 0; i < n; ++i) {
334 if (ma[i] > 0) {
335 GraphAdd(list, head, tail, i, (INT) ma[i]);
336 }
337 }
338
339 while (istack > 0) {
340 /* i with maximal measure is at the head of the stacks */
341 i = head[-istack];
342 /* make i a c-point */
343 cf[i] = cpt;
344 ma[i] = -1;
345 /* remove i from graph */
346 GraphRemove(list, head, tail, i);
347
348 /* update neighbors and neighbors-of-neighbors */
349 for (ji = ia[i]+1; ji < ia[i+1]; ++ji) {
350 jj = ja[ji];
351 /* if not "decided" c or f */
352 if (ma[jj] > -1) {
353 /* if a candidate, remove jj from graph */
354 if (ma[jj] > 0) {
355 GraphRemove(list, head, tail, jj);
356 }
357 /* make jj an f-point and mark "decided" */
358 cf[jj] = fpt;
359 ma[jj] = -1;
360
361 for (jl = ia[jj]+1; jl < ia[jj+1]; jl++) {
362 index = ja[jl];
363 /* if a candidate, increase likehood of being chosen */
364 if (ma[index] > 0) {
365 ma[index]++;
366 /* move index in graph */
367 GraphRemove(list, head, tail, index);
368 GraphAdd(list, head, tail, index, (INT) ma[index]);
369 if (ma[index] > istack) {
370 istack = (INT) ma[index];
371 }
372 }
373 }
374 }
375 }
376
377 /* reset istack to point to the biggest non-empty stack */
378 for ( ; istack > 0; istack-- ) {
379 /* if non-negative, break */
380 if (head[-istack] > -1) {
381 break;
382 }
383 }
384 }
385
386 fasp_mem_free(list); list = NULL;
387 fasp_mem_free(head_mem); head_mem = NULL;
388 fasp_mem_free(tail_mem); tail_mem = NULL;
389
390 return 0;
391}
392
393/*---------------------------------*/
394/*-- End of File --*/
395/*---------------------------------*/
void fasp_mem_free(void *mem)
Free up previous allocated memory body and set pointer to NULL.
Definition: AuxMemory.c:152
void * fasp_mem_calloc(const unsigned int size, const unsigned int type)
Allocate, initiate, and check memory.
Definition: AuxMemory.c:65
void fasp_smoother_dcsr_gscr(INT pt, INT n, REAL *u, INT *ia, INT *ja, REAL *a, REAL *b, INT L, INT *CF)
Gauss Seidel method restriced to a block.
INT fasp_amg_coarsening_cr(const INT i_0, const INT i_n, dCSRmat *A, ivector *vertices, AMG_param *param)
CR coarsening.
Main header file for the FASP project.
#define REAL
Definition: fasp.h:75
#define SHORT
FASP integer and floating point numbers.
Definition: fasp.h:71
#define INT
Definition: fasp.h:72
#define TRUE
Definition of logic type.
Definition: fasp_const.h:61
#define PRINT_MORE
Definition: fasp_const.h:76
#define PRINT_MIN
Definition: fasp_const.h:74
Parameters for AMG methods.
Definition: fasp.h:455
SHORT print_level
print level for AMG
Definition: fasp.h:461
Sparse matrix of REAL type in CSR format.
Definition: fasp.h:151
REAL * val
nonzero entries of A
Definition: fasp.h:169
INT * IA
integer array of row pointers, the size is m+1
Definition: fasp.h:163
INT * JA
integer array of column indexes, the size is nnz
Definition: fasp.h:166
Vector with n entries of INT type.
Definition: fasp.h:368
INT row
number of rows
Definition: fasp.h:371
INT * val
actual vector entries
Definition: fasp.h:374