33#include "fasp_functs.h"
44static void fasp_aux_uuplv0_ (
REAL *,
REAL *,
INT *);
77 REAL *Dinv = NULL, *r = NULL, *rbar = NULL, *v0 = NULL, *v1 = NULL;
78 REAL *error = NULL, *k = NULL;
79 REAL mu0, mu1, smu0, smu1;
94 mu0 = DinvAnorminf(Amat, Dinv);
96 mu0 = 1.0/mu0; mu1 = 4.0*mu0;
97 smu0 = sqrt(mu0); smu1 = sqrt(mu1);
100 k[2] = (smu0 + smu1)*(smu0 + smu1)/2.0;
104 k[4] = 2.0*k[3]/k[2];
107 k[5] = (mu1-2.0*smu0*smu1+mu0)/(mu1+2.0*smu0*smu1+mu0);
110 printf(
"### DEBUG: [-Begin-] %s ...\n", __FUNCTION__);
114 for ( i=0; i<L; i++ ) {
120 Rr(Amat, Dinv, r, rbar, v0, v1, error, k, ndeg);
128 printf(
"### DEBUG: Degree of polysmoothing is: %d\n",ndeg);
141 printf(
"### DEBUG: [--End--] %s ...\n", __FUNCTION__);
173 INT i,j,k,it,jk,iaa,iab,ndeg0;
176 REAL *v,*v0,*r,*vsave;
177 REAL smaxa,smina,delinv,s,smu0,smu1,skappa,th,th1,sq;
178 REAL ri,ari,vj,ravj,snj,sm,sm01,smsqrt,delta,delta2,chi;
182 INT myid, mybegin, myend;
183 INT nthreads = fasp_get_num_threads();
187 printf(
"### DEBUG: [-Begin-] %s ...\n", __FUNCTION__);
199 fasp_aux_norm1_(ia,ja,a,&n,&smaxa);
201 delinv=(smaxa+smina)/(smaxa-smina);
202 th=delinv+sqrt(delinv*delinv-1e+00);
204 sq=(th-th1)*(th-th1);
206 ndeg0=(int)floor(log(2*(2e0+th+th1)/sq)/log(th)+1e0);
207 if (ndeg0 < ndeg) ndeg0=ndeg;
211 skappa=sqrt(smaxa/smina);
212 delta=(skappa-1e+00)/(skappa+1);
214 s=sqrt(smu0)+sqrt(smu1);
217 chi=4e+00*smu0*smu1/s;
218 sm=0.5e+00*(smu0+smu1);
222 printf(
"### DEBUG: Degree of polysmoothing is: %d\n",ndeg);
232 for (it = 0 ; it < L; it++) {
233 bminax(b,ia,ja,a,u,&n,r);
235#pragma omp parallel for private(myid,mybegin,myend,i,iaa,iab,ari,jk,j,ri) if(n>OPENMP_HOLDS)
236 for (myid=0; myid<nthreads; ++myid) {
238 for (i=mybegin; i<myend; ++i) {
240 for (i=0; i < n ; ++i) {
246 for (jk = iaa; jk < iab; jk++) {
253 v[i]=smsqrt*ri-sm01*ari;
258 for (i=1; i < ndeg0; ++i) {
263#pragma omp parallel for private(myid,mybegin,myend,j,ravj,iaa,iab,jk,k,vj,snj) if(n>OPENMP_HOLDS)
264 for (myid=0; myid<nthreads; ++myid) {
266 for (j=mybegin; j<myend; ++j) {
268 for (j=0; j < n ; ++j) {
275 for (jk = iaa; jk < iab; jk++) {
277 ravj -= a[jk] * vsave[k];
281 snj = chi*ravj+delta2*(vj-v0[j]);
289 fasp_aux_uuplv0_(u,v,&n);
306 printf(
"### DEBUG: [--End--] %s ...\n", __FUNCTION__);
334static void bminax (
REAL *b,
351 INT myid, mybegin, myend;
352 INT nthreads = fasp_get_num_threads();
356#pragma omp parallel for private(myid,mybegin,myend,i,iaa,iab,u,jk,j) if(n>OPENMP_HOLDS)
357 for (myid=0; myid<nthreads; ++myid) {
359 for (i=mybegin; i<myend; ++i) {
361 for (i=0; i < n ; ++i) {
367 for (jk = iaa; jk < iab; jk++) {
392static void Diaginv (
dCSRmat *Amat,
396 const INT *ia = Amat->
IA, *ja = Amat->
JA;
401#pragma omp parallel for private(j) if(n>OPENMP_HOLDS)
403 for (i=0; i<n; i++) {
404 for(j=ia[i]; j<ia[i+1]; j++) {
433 const INT *ia = Amat->
IA;
441 INT myid, mybegin, myend;
443 INT nthreads = fasp_get_num_threads();
450#pragma omp parallel for private(myid,mybegin,myend,i,temp,sub_norm) if(n>OPENMP_HOLDS)
451 for (myid=0; myid<nthreads; ++myid) {
454 for (i=mybegin; i<myend; ++i) {
456 for (i=0; i<n; i++) {
459 for (j=ia[i]; j<ia[i+1]; j++) {
464 sub_norm =
MAX(sub_norm, temp);
466 norm =
MAX(norm, temp);
470#pragma omp critical(norm)
471 norm =
MAX(norm, sub_norm);
493static void Diagx (
REAL *Dinv,
502 INT myid, mybegin, myend;
507 nthreads = fasp_get_num_threads();
513#pragma omp parallel for private(myid, mybegin, myend, i)
515 for (myid = 0; myid < nthreads; myid++) {
517 for (i = mybegin; i < myend; i++) {
518 b[i] = Dinv[i] * x[i];
523 for (i=0; i<n; i++) {
524 b[i] = Dinv[i] * x[i];
567 INT myid, mybegin, myend;
568 INT nthreads = fasp_get_num_threads();
572 Diagx(Dinv, n, r, rbar);
576 Diagx(Dinv, n, v1, v1);
579#pragma omp parallel for if(n>OPENMP_HOLDS)
582 v0[i] = k[1] * rbar[i];
583 v1[i] = k[2] * rbar[i] - k[3] * v1[i];
592#pragma omp parallel for private(myid,mybegin,myend,i) if(n>OPENMP_HOLDS)
593 for (myid=0; myid<nthreads; ++myid) {
595 for (i=mybegin; i<myend; ++i) {
599 rbar[i] = (r[i] - rbar[i])*Dinv[i];
600 vnew[i] = v1[i] + k[5] *(v1[i] - v0[i]) + k[4] * rbar[i];
611static void fasp_aux_uuplv0_ (
REAL *u,
619 for ( i=0; i < *n; i++ ) u[i] += v[i];
623static void fasp_aux_norm1_ (
INT *ia,
635 for ( i=0; i < n ; i++ ) {
639 for ( jk = iaa; jk < iab; jk++ ) sum += fabs(a[jk]);
640 if ( sum > s ) s = sum;
void fasp_darray_cp(const INT n, const REAL *x, REAL *y)
Copy an array to the other y=x.
void fasp_mem_free(void *mem)
Free up previous allocated memory body and set pointer to NULL.
void * fasp_mem_calloc(const unsigned int size, const unsigned int type)
Allocate, initiate, and check memory.
void fasp_get_start_end(const INT procid, const INT nprocs, const INT n, INT *start, INT *end)
Assign Load to each thread.
void fasp_blas_darray_axpyz(const INT n, const REAL a, const REAL *x, const REAL *y, REAL *z)
z = a*x + y
void fasp_blas_darray_axpy(const INT n, const REAL a, const REAL *x, REAL *y)
y = a*x + y
void fasp_blas_dcsr_mxv(const dCSRmat *A, const REAL *x, REAL *y)
Matrix-vector multiplication y = A*x.
void fasp_smoother_dcsr_poly_old(dCSRmat *Amat, dvector *brhs, dvector *usol, INT n, INT ndeg, INT L)
poly approx to A^{-1} as MG smoother: JK<Z2010
void fasp_smoother_dcsr_poly(dCSRmat *Amat, dvector *brhs, dvector *usol, INT n, INT ndeg, INT L)
poly approx to A^{-1} as MG smoother
Main header file for the FASP project.
#define SHORT
FASP integer and floating point numbers.
#define MAX(a, b)
Definition of max, min, abs.
#define TRUE
Definition of logic type.
Sparse matrix of REAL type in CSR format.
REAL * val
nonzero entries of A
INT row
row number of matrix A, m
INT * IA
integer array of row pointers, the size is m+1
INT * JA
integer array of column indexes, the size is nnz
Vector with n entries of REAL type.
REAL * val
actual vector entries