⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pzgssvx.c

📁 SuperLU 2.2版本。对大型、稀疏、非对称的线性系统的直接求解
💻 C
📖 第 1 页 / 共 4 页
字号:
		}		break;	      case COL:		for (j = 0; j < m_loc; ++j)		    for (i = rowptr[j]; i < rowptr[j+1]; ++i){		        icol = colind[i];                        zd_mult(&a[i], &a[i], C[icol]); /* Scale columns */		    }		break;	      case BOTH:		irow = fst_row;		for (j = 0; j < m_loc; ++j) {		    for (i = rowptr[j]; i < rowptr[j+1]; ++i) {			icol = colind[i];                        zd_mult(&a[i], &a[i], R[irow]); /* Scale rows */                        zd_mult(&a[i], &a[i], C[icol]); /* Scale columns */		    }		    ++irow;		}	        break;	    }	} else { /* Compute R & C from scratch */            /* Compute the row and column scalings. */	    pzgsequ(A, R, C, &rowcnd, &colcnd, &amax, &iinfo, grid);	    /* Equilibrate matrix A if it is badly-scaled. */	    pzlaqgs(A, R, C, rowcnd, colcnd, amax, equed);	    if ( lsame_(equed, "R") ) {		ScalePermstruct->DiagScale = rowequ = ROW;	    } else if ( lsame_(equed, "C") ) {		ScalePermstruct->DiagScale = colequ = COL;	    } else if ( lsame_(equed, "B") ) {		ScalePermstruct->DiagScale = BOTH;		rowequ = ROW;		colequ = COL;	    } else ScalePermstruct->DiagScale = NOEQUIL;#if ( PRNTlevel>=1 )	    if ( !iam ) {		printf(".. equilibrated? *equed = %c\n", *equed);		/*fflush(stdout);*/	    }#endif	} /* if Fact ... */	stat->utime[EQUIL] = SuperLU_timer_() - t;#if ( DEBUGlevel>=1 )	CHECK_MALLOC(iam, "Exit equil");#endif    } /* if Equil ... */    if ( !factored ) { /* Skip this if already factored. */        /*         * Gather A from the distributed compressed row format to         * global A in compressed column format.         * Numerical values are gathered only when a row permutation         * for large diagonal is sought after.         */	if ( Fact != SamePattern_SameRowPerm ) {            need_value = (options->RowPerm == LargeDiag);            pzCompRow_loc_to_CompCol_global(need_value, A, grid, &GA);            GAstore = (NCformat *) GA.Store;            colptr = GAstore->colptr;            rowind = GAstore->rowind;            nnz = GAstore->nnz;            if ( need_value ) a_GA = (doublecomplex *) GAstore->nzval;            else assert(GAstore->nzval == NULL);	}        /* ------------------------------------------------------------           Find the row permutation for A.           ------------------------------------------------------------*/        if ( options->RowPerm != NO ) {	    t = SuperLU_timer_();	    if ( Fact != SamePattern_SameRowPerm ) {	        if ( options->RowPerm == MY_PERMR ) { /* Use user's perm_r. */	            /* Permute the global matrix GA for symbfact() */	            for (i = 0; i < colptr[n]; ++i) {	            	irow = rowind[i]; 		    	rowind[i] = perm_r[irow];	            }	        } else { /* options->RowPerm == LargeDiag */	            /* Get a new perm_r[] */	            if ( job == 5 ) {		        /* Allocate storage for scaling factors. */		        if ( !(R1 = doubleMalloc_dist(m)) )		            ABORT("SUPERLU_MALLOC fails for R1[]");		    	if ( !(C1 = doubleMalloc_dist(n)) )		            ABORT("SUPERLU_MALLOC fails for C1[]");	            }	            if ( !iam ) {		        /* Process 0 finds a row permutation */		        zldperm(job, m, nnz, colptr, rowind, a_GA,		                perm_r, R1, C1);				        MPI_Bcast( perm_r, m, mpi_int_t, 0, grid->comm );		        if ( job == 5 && Equil ) {		            MPI_Bcast( R1, m, MPI_DOUBLE, 0, grid->comm );		            MPI_Bcast( C1, n, MPI_DOUBLE, 0, grid->comm );		        }	            } else {		        MPI_Bcast( perm_r, m, mpi_int_t, 0, grid->comm );		        if ( job == 5 && Equil ) {		            MPI_Bcast( R1, m, MPI_DOUBLE, 0, grid->comm );		            MPI_Bcast( C1, n, MPI_DOUBLE, 0, grid->comm );		        }	            }#if ( PRNTlevel>=2 )	            dmin = dlamch_("Overflow");	            dsum = 0.0;	            dprod = 1.0;#endif	            if ( job == 5 ) {		        if ( Equil ) {		            for (i = 0; i < n; ++i) {			        R1[i] = exp(R1[i]);			        C1[i] = exp(C1[i]);		            }		            /* Scale the distributed matrix */		            irow = fst_row;		            for (j = 0; j < m_loc; ++j) {			        for (i = rowptr[j]; i < rowptr[j+1]; ++i) {			            icol = colind[i];                                    zd_mult(&a[i], &a[i], R1[irow]);                                    zd_mult(&a[i], &a[i], C1[icol]);#if ( PRNTlevel>=2 )			            if ( perm_r[irow] == icol ) { /* New diagonal */			              if ( job == 2 || job == 3 )			                dmin = SUPERLU_MIN(dmin, z_abs1(&a[i]));			              else if ( job == 4 )				        dsum += z_abs1(&a[i]);			              else if ( job == 5 )				        dprod *= z_abs1(&a[i]);			            }#endif			        }			        ++irow;		            }		            /* Multiply together the scaling factors. */		            if ( rowequ ) for (i = 0; i < m; ++i) R[i] *= R1[i];		            else for (i = 0; i < m; ++i) R[i] = R1[i];		            if ( colequ ) for (i = 0; i < n; ++i) C[i] *= C1[i];		            else for (i = 0; i < n; ++i) C[i] = C1[i];		    		            ScalePermstruct->DiagScale = BOTH;		            rowequ = colequ = 1;		        } /* end Equil */                        /* Now permute global A to prepare for symbfact() */                        for (j = 0; j < n; ++j) {		            for (i = colptr[j]; i < colptr[j+1]; ++i) {	                        irow = rowind[i];		                rowind[i] = perm_r[irow];		            }		        }		        SUPERLU_FREE (R1);		        SUPERLU_FREE (C1);	            } else { /* job = 2,3,4 */		        for (j = 0; j < n; ++j) {		            for (i = colptr[j]; i < colptr[j+1]; ++i) {			        irow = rowind[i];			        rowind[i] = perm_r[irow];		            } /* end for i ... */		        } /* end for j ... */	            } /* end else job ... */#if ( PRNTlevel>=2 )	            if ( job == 2 || job == 3 ) {		        if ( !iam ) printf("\tsmallest diagonal %e\n", dmin);	            } else if ( job == 4 ) {		        if ( !iam ) printf("\tsum of diagonal %e\n", dsum);	            } else if ( job == 5 ) {		        if ( !iam ) printf("\t product of diagonal %e\n", dprod);	            }#endif	                    } /* end if options->RowPerm ... */	        t = SuperLU_timer_() - t;	        stat->utime[ROWPERM] = t;#if ( PRNTlevel>=1 )	        if ( !iam ) printf(".. LDPERM job %d\t time: %.2f\n", job, t);#endif            } /* end if Fact ... */        } else { /* options->RowPerm == NOROWPERM */            for (i = 0; i < m; ++i) perm_r[i] = i;        }#if ( DEBUGlevel>=2 )        if ( !iam ) PrintInt10("perm_r",  m, perm_r);#endif    } /* end if (!factored) */    if ( !factored || options->IterRefine ) {	/* Compute norm(A), which will be used to adjust small diagonal. */	if ( notran ) *(unsigned char *)norm = '1';	else *(unsigned char *)norm = 'I';	anorm = pzlangs(norm, A, grid);#if ( PRNTlevel>=1 )	if ( !iam ) printf(".. anorm %e\n", anorm);#endif    }    /* ------------------------------------------------------------       Perform the LU factorization.       ------------------------------------------------------------*/    if ( !factored ) {	t = SuperLU_timer_();	/*	 * Get column permutation vector perm_c[], according to permc_spec:	 *   permc_spec = NATURAL:  natural ordering 	 *   permc_spec = MMD_AT_PLUS_A: minimum degree on structure of A'+A	 *   permc_spec = MMD_ATA:  minimum degree on structure of A'*A	 *   permc_spec = METIS_AT_PLUS_A: METIS on structure of A'+A	 *   permc_spec = PARMETIS: parallel METIS on structure of A'+A	 *   permc_spec = MY_PERMC: the ordering already supplied in perm_c[]	 */	permc_spec = options->ColPerm;	parSymbFact = options->ParSymbFact;#if ( PRNTlevel>=1 )	if ( parSymbFact && permc_spec != PARMETIS )	    if ( !iam ) printf(".. Parallel symbolic factorization"			       " only works wth ParMetis!\n");#endif	if ( parSymbFact == YES || permc_spec == PARMETIS ) {		    nprocs_num = grid->nprow * grid->npcol;  	    noDomains = (int) ( pow(2, ((int) LOG2( nprocs_num ))));	    /* create a new communicator for the first noDomains processors in	       grid->comm */	    key = iam;    	    if (iam < noDomains) col = 0;	    else col = MPI_UNDEFINED;	    MPI_Comm_split (grid->comm, col, key, &symb_comm );	    permc_spec = PARMETIS; /* only works with PARMETIS */        }	if ( permc_spec != MY_PERMC && Fact == DOFACT ) {	  if ( permc_spec == PARMETIS ) {	      /* Get column permutation vector in perm_c.                    *	       * This routine takes as input the distributed input matrix A  *	       * and does not modify it.  It also allocates memory for       *	       * sizes[] and fstVtxSep[] arrays, that contain information    *	       * on the separator tree computed by ParMETIS.                 */	      flinfo = get_perm_c_parmetis(A, perm_r, perm_c, nprocs_num,                                  	   noDomains, &sizes, &fstVtxSep,                                           grid, &symb_comm);	      if (flinfo > 0)	          ABORT("ERROR in get perm_c parmetis.");	  } else {	      get_perm_c_dist(iam, permc_spec, &GA, perm_c);          }        }	stat->utime[COLPERM] = SuperLU_timer_() - t;	/* Compute the elimination tree of Pc*(A'+A)*Pc' or Pc*A'*A*Pc'	   (a.k.a. column etree), depending on the choice of ColPerm.	   Adjust perm_c[] to be consistent with a postorder of etree.	   Permute columns of A to form A*Pc'. */	if ( Fact != SamePattern_SameRowPerm ) {	    if ( parSymbFact == NO ) {	        int_t *GACcolbeg, *GACcolend, *GACrowind;	        sp_colorder(options, &GA, perm_c, etree, &GAC); 	        /* Form Pc*A*Pc' to preserve the diagonal of the matrix GAC. */	        GACstore = (NCPformat *) GAC.Store;	        GACcolbeg = GACstore->colbeg;	        GACcolend = GACstore->colend;	        GACrowind = GACstore->rowind;	        for (j = 0; j < n; ++j) {	            for (i = GACcolbeg[j]; i < GACcolend[j]; ++i) {		        irow = GACrowind[i];		        GACrowind[i] = perm_c[irow];	            }	        }	        /* Perform a symbolic factorization on Pc*Pr*A*Pc' and set up                   the nonzero data structures for L & U. */#if ( PRNTlevel>=1 )                 if ( !iam )		  printf(".. symbfact(): relax %4d, maxsuper %4d, fill %4d\n",		          sp_ienv_dist(2), sp_ienv_dist(3), sp_ienv_dist(6));#endif  	        t = SuperLU_timer_();	        if ( !(Glu_freeable = (Glu_freeable_t *)		      SUPERLU_MALLOC(sizeof(Glu_freeable_t))) )		    ABORT("Malloc fails for Glu_freeable.");	    	/* Every process does this. */	    	iinfo = symbfact(options, iam, &GAC, perm_c, etree, 			     	 Glu_persist, Glu_freeable);	    	stat->utime[SYMBFAC] = SuperLU_timer_() - t;	    	if ( iinfo < 0 ) { /* Successful return */		    QuerySpace_dist(n, -iinfo, Glu_freeable, &symb_mem_usage);#if ( PRNTlevel>=1 )		    if ( !iam ) {		    	printf("\tNo of supers %ld\n", Glu_persist->supno[n-1]+1);		    	printf("\tSize of G(L) %ld\n", Glu_freeable->xlsub[n]);		    	printf("\tSize of G(U) %ld\n", Glu_freeable->xusub[n]);		    	printf("\tint %d, short %d, float %d, double %d\n", 			       sizeof(int_t), sizeof(short), sizeof(float),			       sizeof(double));		    	printf("\tSYMBfact (MB):\tL\\U %.2f\ttotal %.2f\texpansions %d\n",			   	symb_mem_usage.for_lu*1e-6, 			   	symb_mem_usage.total*1e-6,			   	symb_mem_usage.expansions);		    }#endif	    	} else {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -