コード例 #1
0
ファイル: elastic.c プロジェクト: 00liujj/PHG-On-Windows
static void
stiffness_matrix(ELEMENT *e, DOF *u, int m, int n, FLOAT E, FLOAT nu,
		 int lda, FLOAT *pA, QUAD *quad)
/* returns in 'A' the contribution of the m-th and n-th basis functions
 * to the element stiffness matrix. Elements of the 3x3 small matrix are
 * stored at A[j * lda + k] (j,k = 0,1,2) */
{
    int i;
    FLOAT (*A)[lda] = (void *)pA;
    const FLOAT *pm, *pn, *w;
    FLOAT a00, a01, a02, a10, a11, a12, a20, a21, a22;
    FLOAT a = nu / (1.0 - nu);
    FLOAT b = (1. - 2. * nu) / (2. * (1. - nu));
    FLOAT c = E * (1. - nu) / ((1. + nu) * (1. - 2. * nu)) *
		phgGeomGetVolume(u->g, e);
 
    pm = phgQuadGetBasisGradient(e, u, m, quad);
    pn = phgQuadGetBasisGradient(e, u, n, quad);
    w = quad->weights;

    a00 = a01 = a02 = a10 = a11 = a12 = a20 = a21 = a22 = 0.;
    for (i = 0; i < quad->npoints; i++) {
	a00 += (pm[0] * pn[0] + b * (pm[1] * pn[1] + pm[2] * pn[2])) * *w;
	a01 += (a * pm[0] * pn[1] + b * pm[1] * pn[0]) * *w;
	a02 += (a * pm[0] * pn[2] + b * pm[2] * pn[0]) * *w;

	a10 += (a * pm[1] * pn[0] + b * pm[0] * pn[1]) * *w;
	a11 += (pm[1] * pn[1] + b * (pm[0] * pn[0] + pm[2] * pn[2])) * *w;
	a12 += (a * pm[1] * pn[2] + b * pm[2] * pn[1]) * *w;

	a20 += (a * pm[2] * pn[0] + b * pm[0] * pn[2]) * *w;
	a21 += (a * pm[2] * pn[1] + b * pm[1] * pn[2]) * *w;
	a22 += (pm[2] * pn[2] + b * (pm[0] * pn[0] + pm[1] * pn[1])) * *w;
	pn += 3;
	pm += 3;
	w++;
    }

    A[0][0] = a00 * c;
    A[0][1] = a01 * c;
    A[0][2] = a02 * c;

    A[1][0] = a10 * c;
    A[1][1] = a11 * c;
    A[1][2] = a12 * c;

    A[2][0] = a20 * c;
    A[2][1] = a21 * c;
    A[2][2] = a22 * c;

/*printf("a%d%d=[%lg %lg %lg; %lg %lg %lg; %lg %lg %lg];\n", m, n, a00*c, a01*c, a02*c, a10*c, a11*c, a12*c, a20*c, a21*c, a22*c);*/

    return;
}
コード例 #2
0
/* *******************************************************
 * ( (u.\grad) phi_j, phi_i )
 * return 1 value
 *  */
FLOAT
phgQuadDofDotGradBasBas(ELEMENT *e, DOF *u, DOF *v, int m, int n, int order)
{
    int i;
    const FLOAT *g1, *g2, *gu, *w, *lambda;
    FLOAT d, d0;
    QUAD *quad;

    assert(u->dim == 3);

    if (order < 0)
	order = DofTypeOrder(u, e) +
	      BasisOrder(v, e, m) - 1 + BasisOrder(v, e, n);
    if (order < 0)
	order = 0;
    quad = phgQuadGetQuad3D(order);

    gu = phgQuadGetDofValues(e, u, quad);
    g1 = phgQuadGetBasisGradient(e, v, m, quad);
    g2 = phgQuadGetBasisValues(e, v, n, quad);
    d = 0.;
    lambda = quad->points;
    w = quad->weights;
    for (i = 0; i < quad->npoints; i++) {
	d0 = 0.;
	d0 += (*(gu++)) * (*(g1++)) * (*(g2));	/* u dphi_m/dx phi_n */
	d0 += (*(gu++)) * (*(g1++)) * (*(g2));	/* v dphi_m/dy phi_n */
	d0 += (*(gu++)) * (*(g1++)) * (*(g2));	/* w dphi_m/dz phi_n */
	g2++;
	d += d0 * (*(w++));
	lambda += Dim + 1;
    }

    return d * phgGeomGetVolume(u->g, e);
}
コード例 #3
0
/* *****************************
 * (grad(u_3), grad(\phi))
 * return 3 values.
 * */
void
phgQuadGradDof3GradBas(ELEMENT *e, DOF *gradu, DOF *u, int m, int order,
		       FLOAT *values)
{
    int i;
    const FLOAT *g2, *gu, *w, *lambda;
    FLOAT d1, d2, d3, dd1, dd2, dd3, vol;
    QUAD *quad;

    assert(gradu->dim == 9 && u->dim == 3);

    if (order < 0)
	order = 2 * BasisOrder(u, e, m) - 1;
    if (order < 0)
	order = 0;
    quad = phgQuadGetQuad3D(order);

    gu = phgQuadGetDofValues(e, gradu, quad);
    g2 = phgQuadGetBasisGradient(e, u, m, quad);
    dd1 = dd2 = dd3 = 0.;
    lambda = quad->points;
    w = quad->weights;
    for (i = 0; i < quad->npoints; i++) {
	d1 = d2 = d3 = 0.;

	d1 += (*(gu++)) * (*(g2));
	d1 += (*(gu++)) * (*(g2 + 1));
	d1 += (*(gu++)) * (*(g2 + 2));

	d2 += (*(gu++)) * (*(g2));
	d2 += (*(gu++)) * (*(g2 + 1));
	d2 += (*(gu++)) * (*(g2 + 2));

	d3 += (*(gu++)) * (*(g2));
	d3 += (*(gu++)) * (*(g2 + 1));
	d3 += (*(gu++)) * (*(g2 + 2));

	dd1 += d1 * (*w);
	dd2 += d2 * (*w);
	dd3 += d3 * (*w);

	g2 += 3;
	w++;
	lambda += Dim + 1;
    }

    vol = phgGeomGetVolume(u->g, e);
    values[0] = dd1 * vol;
    values[1] = dd2 * vol;
    values[2] = dd3 * vol;
    return;
}
コード例 #4
0
/* **********************
 * \grad phi_j \times \phi_i
 * return 3 values
 *  */
void
phgQuadGradBasDotBas3(ELEMENT *e, DOF *s, int m, DOF *v, int n,
		      FLOAT *values, int order)
{
    int i, j, nvalues = DofTypeDim(v);
    const FLOAT *g1, *g2, *w, *lambda;
    FLOAT d1, d2, d3, dd1, dd2, dd3;
    QUAD *quad;

    assert(!SpecialDofType(s->type) && !SpecialDofType(v->type));

    if (nvalues != DofTypeDim(s))
	phgError(1, "%s:%d, dimensions mismatch: grad(%s) <==> (%s)\n",
		 __FILE__, __LINE__, s->name, v->name);

    if (order < 0)
	order = BasisOrder(s, e, m) - 1 + BasisOrder(v, e, n);
    if (order < 0)
	order = 0;
    quad = phgQuadGetQuad3D(order);

    g1 = phgQuadGetBasisGradient(e, s, m, quad);
    g2 = phgQuadGetBasisValues(e, v, n, quad);
    dd1 = 0.;
    dd2 = 0.;
    dd3 = 0.;
    lambda = quad->points;
    w = quad->weights;
    for (i = 0; i < quad->npoints; i++) {
	d1 = d2 = d3 = 0.;
	for (j = 0; j < nvalues; j++) {
	    d1 += *(g1++) * *g2;
	    d2 += *(g1++) * *g2;
	    d3 += *(g1++) * *g2;
	    g2++;
	}
	dd1 += d1 * *w;
	dd2 += d2 * *w;
	dd3 += d3 * *w;
	w++;
	lambda += Dim + 1;
    }
    values[0] = dd1 * phgGeomGetVolume(s->g, e);
    values[1] = dd2 * phgGeomGetVolume(s->g, e);
    values[2] = dd3 * phgGeomGetVolume(s->g, e);
    return;
}
コード例 #5
0
/* ***********************
 * p \times \grad \phi_m
 * return 3 values.
 * */
void
phgQuadDofAGradBas3(ELEMENT *e, DOF *p, DOF *v, int m, int order, FLOAT *values)
{
    int i, j;
    const FLOAT *g1, *g2, *w;
    FLOAT d1, d2, d3, vol;
    QUAD *quad;

    assert(!SpecialDofType(v->type));
    assert(p->dim == 1);

    if (order < 0) {
	order = ((j = DofTypeOrder(p, e)) >= 0 ? j : BasisOrder(v, e, m));
	order += BasisOrder(v, e, m) - 1;
    }
    quad = phgQuadGetQuad3D(order);

    g1 = phgQuadGetDofValues(e, p, quad);
    g2 = phgQuadGetBasisGradient(e, v, m, quad);
    w = quad->weights;

    d1 = d2 = d3 = 0.;
    for (i = 0; i < quad->npoints; i++) {
	d1 += *(g1) * (*g2++) * (*w);
	d2 += *(g1) * (*g2++) * (*w);
	d3 += *(g1) * (*g2++) * (*w);
	g1++;
	w++;
    }

    vol = phgGeomGetVolume(p->g, e);
    values[0] = d1 * vol;
    values[1] = d2 * vol;
    values[2] = d3 * vol;
    return;
}
コード例 #6
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]);
    }