コード例 #1
0
ファイル: ilu_cpivotL.c プロジェクト: AmEv7Fam/opentoonz
int
ilu_cpivotL(
	const int  jcol,     /* in */
	const double u,      /* in - diagonal pivoting threshold */
	int	   *usepr,   /* re-use the pivot sequence given by
			      * perm_r/iperm_r */
	int	   *perm_r,  /* may be modified */
	int	   diagind,  /* diagonal of Pc*A*Pc' */
	int	   *swap,    /* in/out record the row permutation */
	int	   *iswap,   /* in/out inverse of swap, it is the same as
				perm_r after the factorization */
	int	   *marker,  /* in */
	int	   *pivrow,  /* in/out, as an input if *usepr!=0 */
	double	   fill_tol, /* in - fill tolerance of current column
			      * used for a singular column */
	milu_t	   milu,     /* in */
	complex	   drop_sum, /* in - computed in ilu_ccopy_to_ucol()
                                (MILU only) */
	GlobalLU_t *Glu,     /* modified - global LU data structures */
	SuperLUStat_t *stat  /* output */
       )
{

    int		 n;	 /* number of columns */
    int		 fsupc;  /* first column in the supernode */
    int		 nsupc;  /* no of columns in the supernode */
    int		 nsupr;  /* no of rows in the supernode */
    int		 lptr;	 /* points to the starting subscript of the supernode */
    register int	 pivptr;
    int		 old_pivptr, diag, ptr0;
    register float  pivmax, rtemp;
    float	 thresh;
    complex	 temp;
    complex	 *lu_sup_ptr;
    complex	 *lu_col_ptr;
    int		 *lsub_ptr;
    register int	 isub, icol, k, itemp;
    int		 *lsub, *xlsub;
    complex	 *lusup;
    int		 *xlusup;
    flops_t	 *ops = stat->ops;
    int		 info;
    complex one = {1.0, 0.0};

    /* Initialize pointers */
    n	       = Glu->n;
    lsub       = Glu->lsub;
    xlsub      = Glu->xlsub;
    lusup      = Glu->lusup;
    xlusup     = Glu->xlusup;
    fsupc      = (Glu->xsup)[(Glu->supno)[jcol]];
    nsupc      = jcol - fsupc;		/* excluding jcol; nsupc >= 0 */
    lptr       = xlsub[fsupc];
    nsupr      = xlsub[fsupc+1] - lptr;
    lu_sup_ptr = &lusup[xlusup[fsupc]]; /* start of the current supernode */
    lu_col_ptr = &lusup[xlusup[jcol]];	/* start of jcol in the supernode */
    lsub_ptr   = &lsub[lptr];	/* start of row indices of the supernode */

    /* Determine the largest abs numerical value for partial pivoting;
       Also search for user-specified pivot, and diagonal element. */
    pivmax = -1.0;
    pivptr = nsupc;
    diag = EMPTY;
    old_pivptr = nsupc;
    ptr0 = EMPTY;
    for (isub = nsupc; isub < nsupr; ++isub) {
        if (marker[lsub_ptr[isub]] > jcol)
            continue; /* do not overlap with a later relaxed supernode */

	switch (milu) {
	    case SMILU_1:
                c_add(&temp, &lu_col_ptr[isub], &drop_sum);
		rtemp = c_abs1(&temp);
		break;
	    case SMILU_2:
	    case SMILU_3:
                /* In this case, drop_sum contains the sum of the abs. value */
		rtemp = c_abs1(&lu_col_ptr[isub]);
		break;
	    case SILU:
	    default:
		rtemp = c_abs1(&lu_col_ptr[isub]);
		break;
	}
	if (rtemp > pivmax) { pivmax = rtemp; pivptr = isub; }
	if (*usepr && lsub_ptr[isub] == *pivrow) old_pivptr = isub;
	if (lsub_ptr[isub] == diagind) diag = isub;
	if (ptr0 == EMPTY) ptr0 = isub;
    }

    if (milu == SMILU_2 || milu == SMILU_3) pivmax += drop_sum.r;

    /* Test for singularity */
    if (pivmax < 0.0) {
	fprintf(stderr, "[0]: jcol=%d, SINGULAR!!!\n", jcol);
	fflush(stderr);
	exit(1);
    }
    if ( pivmax == 0.0 ) {
	if (diag != EMPTY)
	    *pivrow = lsub_ptr[pivptr = diag];
	else if (ptr0 != EMPTY)
	    *pivrow = lsub_ptr[pivptr = ptr0];
	else {
	    /* look for the first row which does not
	       belong to any later supernodes */
	    for (icol = jcol; icol < n; icol++)
		if (marker[swap[icol]] <= jcol) break;
	    if (icol >= n) {
		fprintf(stderr, "[1]: jcol=%d, SINGULAR!!!\n", jcol);
		fflush(stderr);
		exit(1);
	    }

	    *pivrow = swap[icol];

	    /* pick up the pivot row */
	    for (isub = nsupc; isub < nsupr; ++isub)
		if ( lsub_ptr[isub] == *pivrow ) { pivptr = isub; break; }
	}
	pivmax = fill_tol;
	lu_col_ptr[pivptr].r = pivmax;
	lu_col_ptr[pivptr].i = 0.0;
	*usepr = 0;
#ifdef DEBUG
	printf("[0] ZERO PIVOT: FILL (%d, %d).\n", *pivrow, jcol);
	fflush(stdout);
#endif
	info =jcol + 1;
    } /* if (*pivrow == 0.0) */
    else {
	thresh = u * pivmax;

	/* Choose appropriate pivotal element by our policy. */
	if ( *usepr ) {
	    switch (milu) {
		case SMILU_1:
                    c_add(&temp, &lu_col_ptr[old_pivptr], &drop_sum);
		    rtemp = c_abs1(&temp);
		    break;
		case SMILU_2:
		case SMILU_3:
		    rtemp = c_abs1(&lu_col_ptr[old_pivptr]) + drop_sum.r;
		    break;
		case SILU:
		default:
		    rtemp = c_abs1(&lu_col_ptr[old_pivptr]);
		    break;
	    }
	    if ( rtemp != 0.0 && rtemp >= thresh ) pivptr = old_pivptr;
	    else *usepr = 0;
	}
	if ( *usepr == 0 ) {
	    /* Use diagonal pivot? */
	    if ( diag >= 0 ) { /* diagonal exists */
		switch (milu) {
		    case SMILU_1:
                        c_add(&temp, &lu_col_ptr[diag], &drop_sum);
         	        rtemp = c_abs1(&temp);
			break;
		    case SMILU_2:
		    case SMILU_3:
			rtemp = c_abs1(&lu_col_ptr[diag]) + drop_sum.r;
			break;
		    case SILU:
		    default:
			rtemp = c_abs1(&lu_col_ptr[diag]);
			break;
		}
		if ( rtemp != 0.0 && rtemp >= thresh ) pivptr = diag;
	    }
	    *pivrow = lsub_ptr[pivptr];
	}
	info = 0;

	/* Reset the diagonal */
	switch (milu) {
	    case SMILU_1:
		c_add(&lu_col_ptr[pivptr], &lu_col_ptr[pivptr], &drop_sum);
		break;
	    case SMILU_2:
	    case SMILU_3:
                temp = c_sgn(&lu_col_ptr[pivptr]);
                cc_mult(&temp, &temp, &drop_sum);
                c_add(&lu_col_ptr[pivptr], &lu_col_ptr[pivptr], &drop_sum);
		break;
	    case SILU:
	    default:
		break;
	}

    } /* else */

    /* Record pivot row */
    perm_r[*pivrow] = jcol;
    if (jcol < n - 1) {
	register int t1, t2, t;
	t1 = iswap[*pivrow]; t2 = jcol;
	if (t1 != t2) {
	    t = swap[t1]; swap[t1] = swap[t2]; swap[t2] = t;
	    t1 = swap[t1]; t2 = t;
	    t = iswap[t1]; iswap[t1] = iswap[t2]; iswap[t2] = t;
	}
    } /* if (jcol < n - 1) */

    /* Interchange row subscripts */
    if ( pivptr != nsupc ) {
	itemp = lsub_ptr[pivptr];
	lsub_ptr[pivptr] = lsub_ptr[nsupc];
	lsub_ptr[nsupc] = itemp;

	/* Interchange numerical values as well, for the whole snode, such 
	 * that L is indexed the same way as A.
	 */
	for (icol = 0; icol <= nsupc; icol++) {
	    itemp = pivptr + icol * nsupr;
	    temp = lu_sup_ptr[itemp];
	    lu_sup_ptr[itemp] = lu_sup_ptr[nsupc + icol*nsupr];
	    lu_sup_ptr[nsupc + icol*nsupr] = temp;
	}
    } /* if */

    /* cdiv operation */
    ops[FACT] += 10 * (nsupr - nsupc);
    c_div(&temp, &one, &lu_col_ptr[nsupc]);
    for (k = nsupc+1; k < nsupr; k++) 
	cc_mult(&lu_col_ptr[k], &lu_col_ptr[k], &temp);

    return info;
}
コード例 #2
0
ファイル: elements_properties.C プロジェクト: TITAN2D/titan2d
void ElementsProperties::get_slopes(ti_ndx_t ndx, double gamma)
{
    int j = 0, bc = 0;
    /* check to see if this is a boundary */
    while (j < 4 && bc == 0)
    {
        if(neigh_proc_[j][ndx] == INIT)
            bc = 1;
        j++;
    }
    if(bc == 1)
    {
        for(j = 0; j < NUM_STATE_VARS * DIMENSION; j++)
            d_state_vars_[j][ndx]=0.0;
        return;
    }

    int xp, xm, yp, ym; //x plus, x minus, y plus, y minus
    xp = positive_x_side_[ndx];
    xm = (2 + xp) % 4;
    yp = (1 + xp) % 4;
    ym = (3 + xp) % 4;

    /* x direction */
    ti_ndx_t ep = neighbor_ndx_[xp][ndx]; //(Element*) (ElemTable->lookup(&neighbor(xp)[0]));
    ti_ndx_t em = neighbor_ndx_[xm][ndx]; //(Element*) (ElemTable->lookup(&neighbor(xm)[0]));
    ti_ndx_t ep2 = ti_ndx_doesnt_exist;
    ti_ndx_t em2 = ti_ndx_doesnt_exist;
    //check if element has 2 neighbors on either side
    ti_ndx_t ndtemp = node_key_ndx_[xp + 4][ndx]; //(Node*) NodeTable->lookup(&node_key[xp + 4][0]);
    if(node_info_[ndtemp] == S_C_CON)
    {
        ep2 = neighbor_ndx_[xp + 4][ndx]; //(Element*) (ElemTable->lookup(&neighbor[xp + 4][0]));
        ASSERT3(neigh_proc_[xp + 4][ndx] >= 0 && ti_ndx_not_negative(ep2));
    }
    ndtemp = node_key_ndx_[xm + 4][ndx]; //(Node*) NodeTable->lookup(&node_key[xm + 4][0]);
    if(node_info_[ndtemp] == S_C_CON)
    {
        em2 = neighbor_ndx_[xm + 4][ndx]; //(Element*) (ElemTable->lookup(&neighbor[xm + 4][0]));
        ASSERT3(neigh_proc_[xm + 4][ndx] >= 0 && ti_ndx_not_negative(em2));
    }

    double dp, dm, dc, dxp, dxm;
    dxp = coord_[0][ep] - coord_[0][ndx];
    dxm = coord_[0][ndx] - coord_[0][em];
    for(j = 0; j < NUM_STATE_VARS; j++)
    {
        dp = (state_vars_[j][ep] - state_vars_[j][ndx]) / dxp;
        if(ti_ndx_not_negative(ep2))
            dp = .5 * (dp + (state_vars_[j][ep2] - state_vars_[j][ndx]) / dxp);
        dm = (state_vars_[j][ndx] - state_vars_[j][em]) / dxm;
        if(ti_ndx_not_negative(em2))
            dm = .5 * (dm + (state_vars_[j][ndx] - state_vars_[j][em2]) / dxm);

        dc = (dp * dxm + dm * dxp) / (dxm + dxp);  // weighted average
        //do slope limiting
        d_state_vars_[j][ndx]=0.5 * (c_sgn(dp) + c_sgn(dm)) * c_dmin1(gamma * dabs(dp), gamma * dabs(dm), dabs(dc));
    }

    /* y direction */
    ep = neighbor_ndx_[yp][ndx];        //(Element*) (ElemTable->lookup(&neighbor(yp)[0]));
    em = neighbor_ndx_[ym][ndx];        //(Element*) (ElemTable->lookup(&neighbor(ym)[0]));
    ep2 = ti_ndx_doesnt_exist;
    em2 = ti_ndx_doesnt_exist;
    //check if element has 2 neighbors on either side
    ndtemp = node_key_ndx_[yp + 4][ndx];        //(Node*) NodeTable->lookup(&node_key[yp + 4][0]);
    if(node_info_[ndtemp] == S_C_CON)
    {
        ep2 = neighbor_ndx_[yp + 4][ndx];       //(Element*) (ElemTable->lookup(&neighbor[yp + 4][0]));
        ASSERT3(neigh_proc_[yp + 4][ndx] >= 0 && ti_ndx_not_negative(ep2));
    }
    ndtemp = node_key_ndx_[ym + 4][ndx];        //(Node*) NodeTable->lookup(&node_key[ym + 4][0]);
    if(node_info_[ndtemp] == S_C_CON)
    {
        em2 = neighbor_ndx_[ym + 4][ndx];       //(Element*) (ElemTable->lookup(&neighbor[ym + 4][0]));
        ASSERT3(neigh_proc_[ym + 4][ndx] >= 0 && ti_ndx_not_negative(em2));
    }

    dxp = coord_[1][ep] - coord_[1][ndx];
    dxm = coord_[1][ndx] - coord_[1][em];
    for(j = 0; j < NUM_STATE_VARS; j++)
    {
        dp = (state_vars_[j][ep] - state_vars_[j][ndx]) / dxp;
        if(ti_ndx_not_negative(ep2))
            dp = .5 * (dp + (state_vars_[j][ep2] - state_vars_[j][ndx]) / dxp);
        dm = (state_vars_[j][ndx] - state_vars_[j][em]) / dxm;
        if(ti_ndx_not_negative(em2))
            dm = .5 * (dm + (state_vars_[j][ndx] - state_vars_[j][em2]) / dxm);

        dc = (dp * dxm + dm * dxp) / (dxm + dxp);  // weighted average
        //do slope limiting
        d_state_vars_[j + NUM_STATE_VARS][ndx]=0.5 * (c_sgn(dp) + c_sgn(dm))
                                           * c_dmin1(gamma * dabs(dp), gamma * dabs(dm), dabs(dc));
    }

    return;
}