コード例 #1
0
ファイル: simplest.c プロジェクト: 00liujj/PHG-On-Windows
static void
build_linear_system(SOLVER *solver, DOF *u_h, DOF *f_h)
{
    int i, j;
    GRID *g = u_h->g;
    ELEMENT *e;

    assert(u_h->dim == 1);
    ForAllElements(g, e) {
        int N = DofGetNBas(u_h, e);	/* number of bases in the element */
        FLOAT A[N][N], rhs[N], buffer[N];
        INT I[N];

        /* compute \int \grad\phi_j \cdot \grad\phi_i making use of symmetry */
        for (i = 0; i < N; i++) {
            I[i] = phgSolverMapE2L(solver, 0, e, i);
            for (j = 0; j <= i; j++) {
                A[j][i] = A[i][j] =
                              /* stiffness */
                              phgQuadGradBasDotGradBas(e, u_h, j, u_h, i, QUAD_DEFAULT) +
                              /* mass */
                              a * phgQuadBasDotBas(e, u_h, j, u_h, i, QUAD_DEFAULT);
            }
        }

        /* loop on basis functions */
        for (i = 0; i < N; i++) {
            if (phgDofDirichletBC(u_h, e, i, func_u, buffer, rhs+i,
                                  DOF_PROJ_NONE)) {
                phgSolverAddMatrixEntries(solver, 1, I + i, N, I, buffer);
            }
            else {	/* interior node */
                /* right hand side = \int f * phi_i */
                phgQuadDofTimesBas(e, f_h, u_h, i, QUAD_DEFAULT, rhs + i);
                phgSolverAddMatrixEntries(solver, 1, I + i, N, I, A[i]);
            }
        }
        phgSolverAddRHSEntries(solver, N, I, rhs);
    }
コード例 #2
0
ファイル: moving_meshMB.c プロジェクト: tongzhangice/OpenICE
static void
getMoveDirection(MovingMesh *mmesh)
{
    GRID *g = _m->g;
    SIMPLEX *e;
    DOF *logical_move = _m->logical_move;
    DOF *logical_node = _m->logical_node;
    DOF *move = _m->move;
    DOF *logical_node_new, *grad_logical_node;
    INT i, j, k, l0, l1;
    SOLVER *solver;
    DOF *mass_lumping;
    FLOAT *v_move, *v_mass;
    FLOAT max_vol = -1e10, min_vol = 1e10;

    /* Get new monitor */
    _m->get_monitor(mmesh); DOF_SCALE(_m->monitor);

    logical_node_new = phgDofCopy(logical_node, NULL, NULL, "new logical node coordinates");
    grad_logical_node = phgDofGradient(logical_node, NULL, NULL, "grad logical node coordinates");
    /* if (logical_node_new->DB_mask == UNDEFINED) */
    /* 	phgError(1, "g->types_vert and DB_mask is VAILD in moving mesh method!!!"); */
    
    /* Create move solver */
    phgOptionsPush();
#if 0
    phgOptionsSetOptions("-default_solver mm_ml "
			 "-mm_ml_solver gmres "
			 "-mm_ml_pc mm_ml "
			 "-mm_ml_sweep0 6 "
			 "-solver_maxit 100 "
			 "-solver_rtol 1e-12 ");
#else
    phgOptionsSetOptions("-default_solver hypre "
			 "-hypre_solver gmres "
			 "-hypre_pc boomeramg "
			 "-solver_maxit 100 "
			 "-solver_rtol 1e-12 ");
#endif
    phgOptionsSetOptions(_mp->move_opts);

    setMoveConstrain(mmesh, logical_node_new);
    solver = phgSolverCreate(SOLVER_DEFAULT, logical_node_new, NULL);
    solver->mat->mv_data = phgAlloc(sizeof(*solver->mat->mv_data));
    solver->mat->mv_data[0] = (void *) mmesh;
    phgOptionsPop();

    /* build mat */
    ForAllElements(g, e) {
	int order = 1, q;
	int N = DofGetNBas(logical_node, e);	/* number of bases in the element */
	FLOAT A[N][Dim][N][Dim], rhs[N][Dim];
	INT I[N][Dim];
	QUAD *quad;
	const FLOAT *w, *lambda;
	FLOAT vol, mon;
	
	vol = phgGeomGetVolume(g, e);
	max_vol = MAX(max_vol, vol); 	
	min_vol = MIN(min_vol, vol); 

	for (i = 0; i < N; i++)
	    for (k = 0; k < Dim; k++)
		I[i][k] = phgMapE2L(solver->rhs->map, 0, e, i * Dim + k);

	bzero(A, sizeof(A));
	bzero(rhs, sizeof(rhs));

	quad = phgQuadGetQuad3D(order);
	mon = *DofElementData(_m->monitor, e->index); 
	//printf("mon:%e\n", mon);

	lambda = quad->points;
	w = quad->weights;
	assert(quad->npoints == 1);
	for (q = 0; q < quad->npoints; q++) {
	    for (i = 0; i < N; i++) {
		for (j = 0; j < N; j++) {
		    const FLOAT *ggi = 
			phgQuadGetBasisGradient(e, _m->move, i, quad) + q*Dim; /* grad phi_i */
		    const FLOAT *ggj = 
			phgQuadGetBasisGradient(e, _m->move, j, quad) + q*Dim; /* grad phi_j */
		    FLOAT a = vol*(*w) * mon * INNER_PRODUCT(ggj, ggi);
			
		    for (k = 0; k < Dim; k++) {
			A[i][k][j][k] += a;
		    }
		}
	    }
	    w++; lambda += Dim + 1;
	} /* end quad point */

	for (i = 0; i < N; i++) {
	    INT vert0 = e->verts[i];
	    if (_mp->fix_bdry || MM_FIXED(g->types_vert[vert0])) {
		/* no move */
		bzero(A[i], sizeof(A[i]));

		for (k = 0; k < Dim; k++) {
		    A[i][k][i][k] = 1.;
		    rhs[i][k] = logical_node->data[vert0 * Dim + k];
		}
	    } else if (g->types_vert[vert0] & MM_CONSTR) {
		VERT_CONSTRAIN *vert_constr = _m->vert_constr + _m->vert_constr_index[vert0];
		FLOAT *trans = vert_constr->Trans;
		FLOAT *bb = vert_constr->bb;
		assert(_m->vert_constr_index[vert0] >= 0);
		assert(vert0 == vert_constr->index);

		trans_left_ (&A[i][0][0][0], Dim*N, Dim*N, trans);
		trans_right_(&A[0][0][i][0], Dim*N, Dim*N, trans);

		if (vert_constr->n_constrain == 2) {
		    bzero(A[i][0], sizeof(A[i][0]));
		    bzero(A[i][1], sizeof(A[i][1]));
		    A[i][0][i][0] = 1.;
		    A[i][1][i][1] = 1.;
		    rhs[i][0] = bb[0];
		    rhs[i][1] = bb[1];
		} else if (vert_constr->n_constrain == 1) {
		    bzero(A[i][0], sizeof(A[i][0]));
		    A[i][0][i][0] = 1.;
		    rhs[i][0] = bb[0];
		} else {
		    abort();
		}
	    }
	}

	for (i = 0; i < N; i++)
	    phgSolverAddMatrixEntries(solver, Dim, &I[i][0], N * Dim, I[0], &A[i][0][0][0]);
	phgSolverAddRHSEntries(solver, N * Dim, &I[0][0], &rhs[0][0]);
    }