Exemple #1
0
void
Well_init(DOF *source)
{
	GRID *g = source->g;
	SIMPLEX *e;
	FLOAT *p_source;
	FLOAT vol_1 = 0, vol_2 =0;
	ForAllElements(g, e){
		if(e->region_mark == 2){
			vol_1 += phgGeomGetVolume(g, e);
		}
		else if(e->region_mark == 3)
		{
			vol_2 += phgGeomGetVolume(g, e);
		}
	}
#if USE_MPI
	FLOAT vol_10 = vol_1;
	FLOAT vol_20 = vol_2;
//	memcpy(vol0, vol, sizeof(FLOAT));
	MPI_Allreduce(&vol_10, &vol_1, 1, MPI_DOUBLE, MPI_SUM, g->comm);
	MPI_Allreduce(&vol_20, &vol_2, 1, MPI_DOUBLE, MPI_SUM, g->comm);
#endif
	ForAllElements(g, e){
		if(e->region_mark == 2){
			p_source = DofElementData(source, e->index);
			p_source[0] = - PRODUCTION / (vol_1+vol_2);
		}
		else if(e->region_mark == 3){
			p_source = DofElementData(source, e->index);
			p_source[0] = - PRODUCTION / (vol_2+vol_1);
		}
	}
}
Exemple #2
0
void
Well_Pressure(DOF *p_h, DOF *b_o, FLOAT *pressure, FLOAT *pwf)
{
	GRID *g = p_h->g;
	SIMPLEX *e;
	FLOAT *p_p, sum_vol = 0, sum_lambda = 0, sum_pressure = 0, *p_bo;
	INT count = 0;

	FLOAT	mu = 1e-9 / 3600, K = 1e-13, rw = 0.1, re = 10.; 
	ForAllElements(g, e){
		if(e->region_mark == 1){
			p_p = DofElementData(p_h, e->index);
			p_bo = DofElementData(b_o, e->index);
			sum_pressure += p_p[0] * phgGeomGetVolume(g, e);
			sum_lambda += p_bo[0] * phgGeomGetVolume(g, e); 
			sum_vol += phgGeomGetVolume(g, e);
		}
	}

#if USE_MPI
	FLOAT sum_vol0 = sum_vol, sum_lambda0 = sum_lambda, sum_pressure0 = sum_pressure;
	MPI_Allreduce(&sum_vol0, &sum_vol, 1, MPI_DOUBLE, MPI_SUM, g->comm);
	MPI_Allreduce(&sum_lambda0, &sum_lambda, 1, MPI_DOUBLE, MPI_SUM, g->comm);
	MPI_Allreduce(&sum_pressure0, &sum_pressure, 1, MPI_DOUBLE, MPI_SUM, g->comm);
#endif
	*pressure = sum_pressure / sum_vol;
	sum_lambda = sum_lambda / sum_vol;
    FLOAT tmp  = (-PRODUCTION * mu * sum_lambda * (log(re/rw) + 3 - 0.5)) / (2 * M_PI * K * MESH_HEIGHT); 
    *pwf = *pressure + tmp;
}
Exemple #3
0
void
create_kro(DOF *s_w, DOF *kro)
{
	GRID *g = s_w->g;
	SIMPLEX *e;
	FLOAT *p_sw, *p_kro;
	ForAllElements(g, e){
		p_sw = DofElementData(s_w, e->index);
		p_kro = DofElementData(kro, e->index);
		p_kro[0] = KRO_SWC * pow((1 - p_sw[0] - SORW) / (1 - SWC - SORW), NO);
	}
Exemple #4
0
void
create_kr(PHASE *oil, PHASE *water)
{
	GRID *g = water->Kr->g;
	SIMPLEX *e;
	FLOAT *p_so, *p_kro, *p_krw, S =0;
	ForAllElements(g, e){
		p_so = DofElementData(oil->S, e->index);
		p_kro = DofElementData(oil->Kr, e->index);
		p_krw = DofElementData(water->Kr, e->index);
		S = (1. - p_so[0] - SWC) / (1 - SWC - SOR);
		p_kro[0] =pow((1 - S), NO);
		p_krw[0] = pow(S, NW);
	}
static FLOAT
estimate_error(FLOAT lambda, DOF *u_h, DOF *error)
{
    GRID *g = u_h->g;
    ELEMENT *e;
    DOF *curl_u_h, *jump1, *jump2, *residual, *tmp;

    curl_u_h = phgDofCurl(u_h, NULL, NULL, NULL);
    residual = phgDofGetSameOrderDG(u_h, -1, NULL);
    phgDofCopy(u_h, &residual, NULL, "residual");
    jump2 = phgQuadFaceJump(residual, DOF_PROJ_DOT, NULL, QUAD_DEFAULT);
    tmp = phgDofCurl(curl_u_h, NULL, NULL, NULL);
    phgDofAXPBY(-1.0, tmp, lambda, &residual);
    phgDofFree(&tmp);
    jump1 = phgQuadFaceJump(curl_u_h, DOF_PROJ_CROSS, NULL, QUAD_DEFAULT);
    ForAllElements(g, e) {
	int i;
	FLOAT eta, h;
	FLOAT diam = phgGeomGetDiameter(g, e);
	e->mark = 0;		/* clear refinement mmark */
	eta = 0.0;
	for (i = 0; i < NFace; i++) {
	    if (e->bound_type[i] == DIRICHLET || e->bound_type[i] == NEUMANN)
		continue;	/* boundary face */
	    h = phgGeomGetFaceDiameter(g, e, i);
	    eta += (*DofFaceData(jump1, e->faces[i]) +
		    *DofFaceData(jump2, e->faces[i])) * h;
	}
	eta = eta + diam * diam * phgQuadDofDotDof(e, residual, residual,
						   QUAD_DEFAULT);
	*DofElementData(error, e->index) = eta;
    }
Exemple #6
0
void
Well_Pressure(DOF *p_h, FLOAT *pressure)
{
	GRID *g = p_h->g;
	SIMPLEX *e;
	FLOAT *p_p, sum = 0;
	INT count = 0, i, well_no, nbas = p_h->type->nbas;

	ForAllElements(g, e)
	{
		*pressure = 0.0;

		if(e->region_mark == 2){
			p_p = DofElementData(p_h, e->index);
			sum += p_p[0];
			count++;
		}
		else if (e->region_mark == 3){
			p_p = DofElementData(p_h, e->index);
			sum += p_p[0];
			count++;
		}
	}
static void
estimate_error(DOF *u, DOF *p, DOF *f, DOF *gradu, DOF *divu, DOF *e_H1)
/* compute error indicators L_H1(e_u) + L2(e_p). */
{
    int i;
    GRID *g = u->g;
    ELEMENT *e;
    DOF *jump, *residual, *tmp;
    FLOAT eta, d, h;
    FLOAT diam;

    /* RE = [[nu \grad u - p I]] */
    tmp = phgDofCopy(gradu, NULL, NULL, NULL);
    phgDofAFXPBY(-1.0, f_1to3, p, nu, &tmp);
    jump = phgQuadFaceJump(tmp, DOF_PROJ_DOT, "jumps", QUAD_DEFAULT);
    phgDofFree(&tmp);
    /* RT1 = f + nu \laplace u - (u \cdot \grad) u - \grad p
     * RT2 = \div u */
    tmp = phgDofDivergence(gradu, NULL, NULL, NULL);
    residual = phgDofGetSameOrderDG(u, -1, "residual 1");
    phgDofCopy(f, &residual, NULL, NULL);
    phgDofAXPBY(nu, tmp, 1.0, &residual);
    phgDofFree(&tmp);
    tmp = phgDofGradient(p, NULL, NULL, NULL);
    phgDofAXPY(-1.0, tmp, &residual);
    phgDofMM(MAT_OP_N, MAT_OP_T, 1, 3, 3, 1.0, u, -1, gradu, 1., &residual);
    phgDofFree(&tmp);

    ForAllElements(g, e) {
	diam = phgGeomGetDiameter(g, e);
	e->mark = 0;		/* clear refinement mmark */
	eta = 0.0;
	/* for each face F compute [grad_u \cdot n] */
	for (i = 0; i < NFace; i++) {
	    if (e->bound_type[i] & (DIRICHLET | NEUMANN))
		continue;	/* boundary face */
	    h = phgGeomGetFaceDiameter(g, e, i);
	    d = *DofFaceData(jump, e->faces[i]);
	    eta += d * h;
	}

	eta +=
	    diam * diam * phgQuadDofDotDof(e, residual, residual, QUAD_DEFAULT)
			+ phgQuadDofDotDof(e, divu, divu, QUAD_DEFAULT);

	/* add curved boundary errors (FIXME: how to normalize?) */
	eta += phgGetBoundaryError(g, e);

	*DofElementData(e_H1, e->index) = eta;
    }
Exemple #8
0
void
Well_init(DOF *source)
{
	GRID *g = source->g;
	SIMPLEX *e;
	FLOAT *p_source;
	FLOAT vol = 0;
	ForAllElements(g, e){
		if(e->region_mark == 1){
			vol += phgGeomGetVolume(g, e);
		}
	}
#if USE_MPI
	FLOAT vol0 = vol;
	MPI_Allreduce(&vol0, &vol, 1, MPI_DOUBLE, MPI_SUM, g->comm);
#endif
	ForAllElements(g, e){
		if(e->region_mark == 1){
			p_source = DofElementData(source, e->index);
			p_source[0] = - PRODUCTION / vol;
		}
	}
}
Exemple #9
0
DOF *
phgDofCopy_(DOF *src, DOF **dest_ptr, DOF_TYPE *newtype,
	    const char *name, const char *srcfile, int srcline)
/* returns a new DOF whose type is 'newtype', and whose values are evaluated
 * using 'src' (a copy of src). */
{
    GRID *g = src->g;
    SIMPLEX *e;
    FLOAT w = 1.0, *basvalues = NULL, *a, *d, *buffer = NULL;
    int i, k, dim, dim_new, count = 0, nvalues, nd;
    INT n;
    DOF *wgts = NULL;
    DOF *dest = (dest_ptr == NULL ? NULL : *dest_ptr);
    BYTE *flags0, *flags;
    char *auto_name;
    DOF_TYPE *oldtype;
    BOOLEAN basflag = FALSE;

    MagicCheck(DOF, dest)

    if (dest != NULL && newtype != NULL && dest->type != newtype) {
	phgDofFree(&dest);
	dest = NULL;
    }

    dim = DofDim(src);
    /* the name of dest */
    if ((auto_name = (void *)name) == NULL) {
#if 0
	auto_name = phgAlloc(strlen(src->name) + 8 + 1);
	sprintf(auto_name, "copy of %s", src->name);
#else
	auto_name = strdup(src->name);
#endif
    }

    if (dest == NULL) {
	if (newtype == NULL)
	    newtype = src->type;
	dim_new = (newtype == NULL ? DofTypeDim(src) : newtype->dim);
	assert(dim % dim_new == 0);
	dest = phgDofNew_(g, newtype, newtype == NULL ? src->hp : NULL,
			  dim / dim_new, auto_name, DofNoAction,
			  srcfile, srcline);
	if (dest_ptr != NULL)
	    *dest_ptr = dest;
    }
    else {
	assert(dim == DofDim(dest));
	phgFree(dest->name); dest->name = strdup(auto_name);
	dest->srcfile = srcfile;
	dest->srcline = srcline;
	phgFree(dest->cache_func); dest->cache_func = NULL;
	newtype = dest->type;
	if (!SpecialDofType(newtype))
	    memset(dest->data, 0, DofGetDataCount(dest) * sizeof(*dest->data));
    }
    if (auto_name != name)
	phgFree(auto_name);

    phgDofClearCache(NULL, dest, NULL, NULL, FALSE);

    dest->DB_mask = src->DB_mask;
    if (src->DB_masks != NULL) {
	if (dest->DB_masks == NULL)
	    dest->DB_masks = phgAlloc(dest->dim * sizeof(*dest->DB_masks));
	memcpy(dest->DB_masks, src->DB_masks, dest->dim * sizeof(*dest->DB_masks));
    }
    dest->invariant = src->invariant;

    if (SpecialDofType(newtype)) {
	assert(newtype == src->type);
	dest->userfunc = src->userfunc;
	dest->userfunc_lambda = src->userfunc_lambda;
	if (newtype == DOF_CONSTANT)
	    memcpy(dest->data, src->data, dim * sizeof(*dest->data));
	return dest;
    }

    if ((newtype != NULL && newtype == src->type) ||
	(newtype == NULL && src->hp == dest->hp)) {
	/* simply duplicate the data */
	size_t size = DofGetDataCount(dest);
	if (size > 0)
	    memcpy(dest->data, src->data, sizeof(FLOAT) * size);
	dest->userfunc = src->userfunc;
	dest->userfunc_lambda = src->userfunc_lambda;
	return dest;
    }

    if (src->type == DOF_ANALYTIC) {
	if (src->userfunc_lambda != NULL)
	    phgDofSetDataByLambdaFunction(dest, src->userfunc_lambda);
	else
	    phgDofSetDataByFunction(dest, src->userfunc);
	return dest;
    }

    if (newtype != NULL && newtype->BasFuncs == NULL)
	phgError(1, "phgDofCopy: basis funcs for DOF type \"%s\" undefined.\n",
		 newtype->name);

    dest->userfunc = src->userfunc;
    dest->userfunc_lambda = src->userfunc_lambda;

    oldtype = src->type;
    if (oldtype == NULL)
	oldtype = src->hp->info->types[src->hp->info->min_order];

    if (!SpecialDofType(oldtype) && newtype != NULL && newtype->points != NULL
	&& !DofIsHP(src)) {
	basflag = TRUE;
	count = oldtype->nbas * oldtype->dim;
	basvalues = phgAlloc(newtype->nbas * count * sizeof(*basvalues));

	if (oldtype->invariant == TRUE)
	    get_bas_funcs(src, dest, src->g->roots, basvalues);
    }

    if (newtype == NULL)
	newtype = dest->hp->info->types[dest->hp->max_order];

    flags0 = phgCalloc((newtype->np_vert > 0 ? g->nvert : 0)
		       + (newtype->np_edge > 0 ? g->nedge : 0)
		       + (newtype->np_face > 0 ? g->nface : 0),
		       sizeof(*flags0));

    if (!SpecialDofType(oldtype) && oldtype->continuity < 0) {
	static DOF_TYPE DOF_WGTS = {DofCache,
	    "Weights", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
	    phgDofInitFuncPoint, NULL, NULL, NULL, FE_None,
	    FALSE, FALSE, -1, 0, 0, -1, 1, 0, 0, 0, 0
	};
	DOF_WGTS.np_vert = (newtype->np_vert > 0) ? 1 : 0;
	DOF_WGTS.np_edge = (newtype->np_edge > 0) ? 1 : 0;
	DOF_WGTS.np_face = (newtype->np_face > 0) ? 1 : 0;
	DOF_WGTS.nbas = DOF_WGTS.np_vert * NVert + DOF_WGTS.np_edge * NEdge +
	    DOF_WGTS.np_face * NFace;
	if (DOF_WGTS.nbas > 0) {
	    /* Other cases will be implemented later when really needed */
	    wgts = phgDofNew(g, &DOF_WGTS, 1, "weights", DofNoAction);
	    phgDofSetDataByValue(wgts, 0.0);
	    phgDofSetDataByValue(dest, 0.0);
	    /* allocate buffer for storing weighted vertex/edge/face data */
	    if ((n = DofGetDataCount(dest) - DofGetElementDataCount(dest)) > 0)
		buffer = phgCalloc(n, sizeof(*buffer));
	}
    }

    nvalues = dest->dim;
    cache_dof = src;
    bas_count = count;
    ForAllElements(g, e) {
	if (wgts != NULL) {
#if 0
	    /* use element volume as weight */
	    w = phgGeomGetVolume(g, e);
#else
	    /* use 1 as weight */
	    w = 1.0;
#endif
	}

	if (basflag && oldtype->invariant == FALSE)
	    get_bas_funcs(src, dest, e, basvalues);
	bas = basvalues;
	flags = flags0;

	if (DofIsHP(dest))
	    newtype = dest->hp->info->types[dest->hp->elem_order[e->index]];

	if (newtype->np_vert > 0) {
	    nd = nvalues * newtype->np_vert;
	    for (k = 0; k < NVert; k++) {
		if (flags[n = e->verts[k]] && wgts == NULL) {
		    /* note: count==0 and bas==NULL for variable order DOF */
		    bas += count * newtype->np_vert;
		    continue;
		}
		flags[n] = TRUE;
		a = DofVertexData(dest, n);
		newtype->InitFunc(dest, e, VERTEX, k, NULL, func, NULL, a,
					NULL);
		if (wgts != NULL) {
		    d = buffer + (a - DofData(dest));
		    for (i = 0; i < nd; i++)
			*(d++) += *(a++) * w;
		    *DofVertexData(wgts, n) += w;
		}
	    }
	    flags += g->nvert;
	}

	if (newtype->np_edge > 0) {
	    nd = nvalues * newtype->np_edge;
	    for (k = 0; k < NEdge; k++) {
		if (flags[n = e->edges[k]] && wgts == NULL) {
		    /* note: count==0 and bas==NULL for variable order DOF */
		    bas += count * newtype->np_edge;
		    continue;
		}
		flags[n] = TRUE;
		a = DofEdgeData(dest, n);
		newtype->InitFunc(dest, e, EDGE, k, NULL, func, NULL, a,
					NULL);
		if (wgts != NULL) {
		    d = buffer + (a - DofData(dest));
		    if (DofIsHP(dest))
			nd = dest->dim * (dest->hp->edge_index[n + 1] -
					  dest->hp->edge_index[n]);
		    for (i = 0; i < nd; i++)
			*(d++) += *(a++) * w;
		    *DofEdgeData(wgts, n) += w;
		}
	    }
	    flags += g->nedge;
	}

	if (newtype->np_face > 0) {
	    nd = nvalues * newtype->np_face;
	    for (k = 0; k < NFace; k++) {
		if (flags[n = e->faces[k]] && wgts == NULL) {
		    /* note: count==0 and bas==NULL for variable order DOF */
		    bas += count * newtype->np_face;
		    continue;
		}
		flags[n] = TRUE;
		a = DofFaceData(dest, n);
		newtype->InitFunc(dest, e, FACE, k, NULL, func, NULL, a,
					NULL);
		if (wgts != NULL) {
		    d = buffer + (a - DofData(dest));
		    if (DofIsHP(dest))
			nd = dest->dim * (dest->hp->face_index[n + 1] -
						 dest->hp->face_index[n]);
		    for (i = 0; i < nd; i++)
			*(d++) += *(a++) * w;
		    *DofFaceData(wgts, n) += w;
		}
	    }
	}

	if (newtype->np_elem > 0) {
	    a = DofElementData(dest, e->index);
	    newtype->InitFunc(dest, e, ELEMENT, 0, NULL, func, NULL, a,
					NULL);
	}
    }

    phgFree(basvalues);
    phgFree(flags0);

    if (wgts == NULL)
	return dest;

    if ((n = DofGetDataCount(dest) - DofGetElementDataCount(dest)) > 0) {
	memcpy(DofData(dest), buffer, n * sizeof(*buffer));
	phgFree(buffer);
    }

    if (DofIsHP(dest))
	newtype = dest->hp->info->types[dest->hp->max_order];

    a = DofData(dest);
    d = DofData(wgts);

#if USE_MPI
    /* FIXME: directly interacting with the vector assembly code in solver.c
       is more efficient */
    if (g->nprocs > 1) {
	SOLVER *solver = phgSolverCreate(SOLVER_BUILTIN, dest, NULL);
	INT K = 0, I;
	int j;

	if (newtype->np_vert > 0) {
	    nd = dest->count_vert;
	    for (n = 0; n < g->nvert; n++, d++) {
		if (g->types_vert[n] == UNREFERENCED) {
		    K += nd;
		    a += nd;
		    continue;
		}
		for (j = 0; j < nd; j++, K++, a++) {
		    I = phgSolverMapD2L(solver, 0, K);
		    assert(I >= 0 && I < solver->mat->rmap->localsize);
		    phgSolverAddRHSEntry(solver, I, *a);
		    phgSolverAddMatrixEntry(solver, I, I, *d);
		}
	    }
	}

	if (newtype->np_edge > 0) {
	    nd = nvalues * newtype->np_edge;
	    for (n = 0; n < g->nedge; n++, d++) {
		if (DofIsHP(dest))
		    nd = dest->dim * (dest->hp->edge_index[n + 1] -
					     dest->hp->edge_index[n]);
		if (g->types_edge[n] == UNREFERENCED) {
		    K += nd;
		    a += nd;
		    continue;
		}
		for (j = 0; j < nd; j++, K++, a++) {
		    I = phgSolverMapD2L(solver, 0, K);
		    assert(I >= 0 && I < solver->mat->rmap->localsize);
		    phgSolverAddRHSEntry(solver, I, *a);
		    phgSolverAddMatrixEntry(solver, I, I, *d);
		}
	    }
	}

	if (newtype->np_face > 0) {
	    nd = nvalues * newtype->np_face;
	    for (n = 0; n < g->nface; n++, d++) {
		if (DofIsHP(dest))
		    nd = dest->dim * (dest->hp->face_index[n + 1] -
					     dest->hp->face_index[n]);
		if (g->types_face[n] == UNREFERENCED) {
		    K += nd;
		    a += nd;
		    continue;
		}
		for (j = 0; j < nd; j++, K++, a++) {
		    I = phgSolverMapD2L(solver, 0, K);
		    assert(I >= 0 && I < solver->mat->rmap->localsize);
		    phgSolverAddRHSEntry(solver, I, *a);
		    phgSolverAddMatrixEntry(solver, I, I, *d);
		}
	    }
	}

	if (newtype->np_elem > 0) {
	    nd = nvalues * newtype->np_elem;
	    for (n = 0; n < g->nelem; n++) {
		if (DofIsHP(dest))
		    nd = dest->dim * (dest->hp->elem_index[n + 1] -
					     dest->hp->elem_index[n]);
		if (g->types_elem[n] == UNREFERENCED) {
		    K += nd;
		    a += nd;
		    continue;
		}
		for (j = 0; j < nd; j++, K++, a++) {
		    I = phgSolverMapD2L(solver, 0, K);
		    assert(I >= 0 && I < solver->mat->rmap->localsize);
		    phgSolverAddRHSEntry(solver, I, *a);
		    phgSolverAddMatrixEntry(solver, I, I, 1.0);
		}
	    }
	}

	phgSolverSolve(solver, TRUE, dest, NULL);
	phgSolverDestroy(&solver);

	phgDofFree(&wgts);

	return dest;
    }
#endif

    if (newtype->np_vert > 0) {
	k = nvalues * newtype->np_vert;
	for (n = 0; n < g->nvert; n++) {
	    if ((w = *(d++)) == 0.0) {
		a += k;
	    }
	    else if (k == 1) {
		*(a++) /= w;
	    }
	    else {
		w = 1.0 / w;
		for (i = 0; i < k; i++)
		    *(a++) *= w;
	    }
	}
    }

    if (newtype->np_edge > 0) {
	k = nvalues * newtype->np_edge;
	for (n = 0; n < g->nedge; n++) {
	    if (DofIsHP(dest))
		k = dest->dim * (dest->hp->edge_index[n + 1] -
					dest->hp->edge_index[n]);
	    if ((w = *(d++)) == 0.0) {
		a += k;
	    }
	    else if (k == 1) {
		*(a++) /= w;
	    }
	    else {
		w = 1.0 / w;
		for (i = 0; i < k; i++)
		    *(a++) *= w;
	    }
	}
    }

    if (newtype->np_face > 0) {
	k = nvalues * newtype->np_face;
	for (n = 0; n < g->nface; n++) {
	    if (DofIsHP(dest))
		k = dest->dim * (dest->hp->face_index[n + 1] -
					dest->hp->face_index[n]);
	    if ((w = *(d++)) == 0.0) {
		a += k;
	    }
	    else if (k == 1) {
		*(a++) /= w;
	    }
	    else {
		w = 1.0 / w;
		for (i = 0; i < k; i++)
		    *(a++) *= w;
	    }
	}
    }

    phgDofFree(&wgts);

    return dest;
}
Exemple #10
0
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]);
    }
Exemple #11
0
/* build linear system */
static void
build_mat_vec(DOF *u_w, DOF *dp, DOF *p_nk, DOF *ds, DOF *s_w, DOF *s_w_l, DOF *b_o, DOF *b_o_l, DOF *kro, DOF *dot_kro, DOF *q_o, DOF *b_w, DOF *b_w_l, DOF *krw, DOF *dot_krw, DOF *q_w, DOF *phi, DOF *phi_l, MAP *map_u, MAP *map_p, MAT *A, MAT *B, MAT *TB, MAT *C, VEC *vec_f, VEC *vec_g)
{
    GRID *g = u_w->g;
    SIMPLEX *e;
    FLOAT *p_bo, *p_bw, *p_bol, *p_bwl, *p_kro, *p_dotkro, *p_krw, *p_dotkrw, *p_swl, *p_dp, *p_ds, *p_sw, *p_phi;
    INT N = u_w->type->nbas * u_w->dim;
    INT M = dp->type->nbas * dp->dim;
    INT I[N], J[M];
    FLOAT mat_A[N][N], mat_TB[N][M], mat_B[M][N], mat_C[M][M], rhs_f[N], rhs_g[M];
    phgVecDisassemble(vec_f);
    phgVecDisassemble(vec_g);
    int i, j, k;
    ForAllElements(g, e) {
        p_phi = DofElementData(phi, e->index);
        p_bo = DofElementData(b_o, e->index);
        p_bol = DofElementData(b_o_l, e->index);
        p_bw = DofElementData(b_w, e->index);
        p_bwl = DofElementData(b_w_l, e->index);
        p_sw = DofElementData(s_w, e->index);
        p_swl = DofElementData(s_w_l, e->index);
        p_kro  = DofElementData(kro, e->index);
        p_dotkro  = DofElementData(dot_kro, e->index);
        p_krw  = DofElementData(krw, e->index);
        p_dotkrw  = DofElementData(dot_krw, e->index);
        p_dp = DofElementData(dp, e->index);
        p_ds = DofElementData(ds, e->index);
        FLOAT T_o = 0, T_w = 0;
        T_w = K * p_krw[0] * p_bw[0] / MU_W + K * p_krw[0] * C_W / (MU_W * B0_W)  * p_dp[0] + K * p_bw[0] * p_dotkrw[0] / MU_W * p_ds[0];
        T_o = K * p_kro[0] * p_bo[0] / MU_O + K * p_kro[0] * C_O / (MU_O * B0_O)  * p_dp[0] + K * p_bo[0] * p_dotkro[0] / MU_O * p_ds[0];
        for (i = 0; i < N; i++) {
            for (j = 0; j < N; j++) {
                mat_A[i][j] = stime * phgQuadBasDotBas(e, u_w, i, u_w, j, QUAD_DEFAULT) / T_w;
            }
        }
        for (i = 0; i < N; i++) {
            for (j = 0; j < M; j++) {
                mat_TB[i][j] = -stime * phgQuadDivBasDotBas(e, u_w, i, dp, j, QUAD_DEFAULT);
            }
        }
        FLOAT wat_sw = 0, oil_sw = 0, wat_cp = 0, oil_cp = 0, beta = 0;
        for (i = 0; i < M; i++) {
            for (j = 0; j < M; j++) {
                wat_sw = p_phi[0] * p_bw[0] * phgQuadBasDotBas(e, ds, i, ds, j, QUAD_DEFAULT);
                oil_sw = p_phi[0] * p_bo[0] * phgQuadBasDotBas(e, ds, i, ds, j, QUAD_DEFAULT);
            }
        }
        wat_cp = p_sw[0] * (p_bw[0] * PHI0 * C_R + p_phi[0] * C_W / B0_W);
        oil_cp = (1. - p_sw[0]) * (p_bo[0] * PHI0 * C_R + p_phi[0] * C_O / B0_O);
        beta = 1. / wat_sw + T_o / (T_w * oil_sw);
        FLOAT quad = 0.;
        for (i = 0; i < M; i++) {
            for (j = 0; j < M; j++) {
                quad =  phgQuadBasDotBas(e, dp, i, dp, j, QUAD_DEFAULT);
                mat_C[i][j] = (wat_cp / wat_sw + oil_cp / oil_sw) * quad / beta;
            }
        }
        /*create oil rhs*/
        FLOAT quad_phi = 0., quad_phil = 0., quad_qo = 0, quad_qw = 0;
        FLOAT rhs_oil = 0., rhs_wat = 0.;
        for (i = 0; i < M; i++) {
            phgQuadDofTimesBas(e, q_o, dp, i, QUAD_DEFAULT, &quad_qo);
            phgQuadDofTimesBas(e, q_w, dp, i, QUAD_DEFAULT, &quad_qw);
            phgQuadDofTimesBas(e, phi, dp, i, QUAD_DEFAULT, &quad_phi);
            phgQuadDofTimesBas(e, phi_l, dp, i, QUAD_DEFAULT, &quad_phil);
            rhs_oil = -stime * quad_qo + p_bo[0] * (1. - p_sw[0]) * quad_phi - p_bol[0] * (1. - p_swl[0]) * quad_phil;
            rhs_wat = -stime * quad_qw + p_bw[0] * p_sw[0] * quad_phi - p_bwl[0] * p_swl[0] * quad_phil;
            rhs_g[i] = (rhs_wat / wat_sw + rhs_oil / oil_sw) / beta;
        }
        for (i = 0; i < N; i++) {
            rhs_f[i] = stime * phgQuadDofTimesDivBas(e, p_nk, u_w, i, QUAD_DEFAULT);
        }
        /* Handle Bdry Conditions*/
        for (i = 0; i < N; i++) {
            if (phgDofGetElementBoundaryType(u_w, e, i) & (NEUMANN | DIRICHLET)) {
                bzero(mat_A[i], N * sizeof(mat_A[i][0]));
                bzero(mat_TB[i], M * sizeof(mat_TB[i][0]));
                for (j = 0; j < N; j++) {
                    mat_A[j][i] = 0.;
                }
                mat_A[i][i] = 1.;
                rhs_f[i] = 0.;
            }
        }

        for (i = 0; i < N; i++) {
            for (j = 0; j < M; j++) {
                mat_B[j][i] = mat_TB[i][j];
            }
        }
        for (i = 0; i < N; i++) {
            I[i] = phgMapE2L(map_u, 0, e, i);
        }
        for (i = 0; i < M; i++) {
            J[i] = phgMapE2L(map_p, 0, e, i);
        }
        phgMatAddEntries(A, N, I, N, I, mat_A[0]);
        phgMatAddEntries(TB, N, I, M, J, mat_TB[0]);
        phgMatAddEntries(B, M, J, N, I, mat_B[0]);
        phgMatAddEntries(C, M, J, M, J, mat_C[0]);
        phgVecAddEntries(vec_f, 0, N, I, rhs_f);
        phgVecAddEntries(vec_g, 0, M, J, rhs_g);
    }
Exemple #12
0
static void
/*build_linear_system*/
build_mat_vec(DOF *dp, DOF *d_so, DOF *d_sw, DOF *dot_muo, DOF *dot_muw, DOF *dot_mug, DOF *dso_kro, DOF *dsw_kro, DOF *dsw_krw, DOF *dso_krg, DOF *dsw_krg, DOF *u_o, DOF *p_h, DOF *p_h_newton, DOF *s_o, DOF *s_o_l, DOF *mu_o, DOF *b_o, DOF *b_o_l, DOF *kro, DOF *dot_bo, DOF *q_o, DOF *s_w, DOF *s_w_l, DOF *mu_w, DOF *b_w, DOF *b_w_l, DOF *krw, DOF *dot_bw, DOF *q_w, DOF *phi, DOF *phi_l, DOF *dot_phi, DOF *Rs, DOF *Rs_l, DOF *dot_Rs, DOF *mu_g, DOF *b_g, DOF *b_g_l, DOF *krg, DOF *dot_bg, DOF *q_g, MAP *map_u, MAP *map_p, MAT *A, MAT *B, MAT *TB, MAT *C, VEC *vec_f, VEC *vec_g)
{
	GRID *g = u_o->g;
	SIMPLEX *e;
	FLOAT *p_so, *p_sol, *p_bo, *p_bol, *p_kro, *p_phi, *p_phil, *p_dotbo, *p_Rs, *p_dotRs, *p_bg, *p_bgl, *p_krg, *p_dotbg, *p_muo, *p_mug, *p_dotphi, *p_Rsl, *p_sw, *p_swl, *p_bw, *p_bwl, *p_krw, *p_dotbw, *p_muw;
	FLOAT *p_dotmuo, *p_dotmuw, *p_dotmug, *p_dsokro, *p_dswkro, *p_dswkrw, *p_dsokrg, *p_dswkrg, *p_dp, *p_dso, *p_dsw;
	INT N = u_o->type->nbas * u_o->dim;
	INT M = dp->type->nbas * dp->dim;
	INT I[N], J[M];
	FLOAT mat_A[N][N], mat_TB[N][M], mat_B[M][N], mat_C[M][M], rhs_f[N], rhs_g[M];
	phgVecDisassemble(vec_f);
	phgVecDisassemble(vec_g);
	int i, j, k;
	ForAllElements(g, e){
		p_so = DofElementData(s_o, e->index);
		p_sol = DofElementData(s_o_l, e->index);
		p_bo = DofElementData(b_o, e->index);
		p_bol = DofElementData(b_o_l, e->index);
		p_kro = DofElementData(kro, e->index);
		p_phi = DofElementData(phi, e->index);
		p_phil = DofElementData(phi_l, e->index);
		p_dotphi = DofElementData(dot_phi, e->index);
		p_dotbo = DofElementData(dot_bo, e->index);
		p_Rs = DofElementData(Rs, e->index);
		p_Rsl = DofElementData(Rs_l, e->index);
		p_dotRs = DofElementData(dot_Rs, e->index);
		p_bg = DofElementData(b_g, e->index);
		p_bgl = DofElementData(b_g_l, e->index);
		p_krg= DofElementData(krg, e->index);
		p_dotbg = DofElementData(dot_bg, e->index);
		p_muo = DofElementData(mu_o, e->index);
		p_muw = DofElementData(mu_w, e->index);
		p_mug = DofElementData(mu_g, e->index);
		p_sw = DofElementData(s_w, e->index);
		p_swl = DofElementData(s_w_l, e->index);
		p_bw = DofElementData(b_w, e->index);
		p_bwl = DofElementData(b_w_l, e->index);
		p_krw = DofElementData(krw, e->index);
		p_dotbw = DofElementData(dot_bw, e->index);
		/* Add Dofs For SS */
		p_dp = DofElementData(dp, e->index);
		p_dso = DofElementData(d_so, e->index);
		p_dsw = DofElementData(d_sw, e->index);
		p_dotmuo = DofElementData(dot_muo, e->index);
		p_dotmuw = DofElementData(dot_muw, e->index);
		p_dotmug = DofElementData(dot_mug, e->index);
		p_dsokro = DofElementData(dso_kro, e->index);
		p_dswkro = DofElementData(dsw_kro, e->index);
		p_dswkrw = DofElementData(dsw_krw, e->index);
		p_dsokrg = DofElementData(dso_krg, e->index);
		p_dswkrg = DofElementData(dsw_krg, e->index);
		/*Create inverse matrix*/
		FLOAT oil_so = 0., wat_sw = 0., gas_so = 0., gas_sw = 0.;
		for (i = 0; i < M; i++){
			for (j = 0; j < M; j++){
				oil_so = p_phi[0] * p_bo[0] * phgQuadBasDotBas(e, d_so, i, d_so, j, QUAD_DEFAULT);
				wat_sw = p_phi[0] * p_bw[0] * phgQuadBasDotBas(e, d_sw, i, d_sw, j, QUAD_DEFAULT);
				gas_so = p_phi[0] * (p_bg[0] - p_Rs[0] * p_bo[0]) * phgQuadBasDotBas(e, d_so, i, d_so, j, QUAD_DEFAULT);
				gas_sw = p_phi[0] * p_bg[0] * phgQuadBasDotBas(e, d_sw, i, d_sw, j, QUAD_DEFAULT);
			}
		}
#if SS
		FLOAT alpha_o = 0., alpha_w = 0., alpha_g = 0.;
		alpha_o = K * p_kro[0] * p_bo[0] * p_muo[0] + K * p_kro[0] * (p_bo[0] * p_dotmuo[0] + p_dotbo[0] * p_muo[0]) * p_dp[0] \ 
				+ K * p_bo[0] * p_muo[0] * (p_dsokro[0] * p_dso[0] + p_dswkro[0] * p_dsw[0]);
		alpha_w = K * p_krw[0] * p_bw[0] * p_muw[0] + K * p_krw[0] * (p_bw[0] * p_dotmuw[0] + p_dotbw[0] * p_muw[0]) * p_dp[0] \ 
				+ K * p_bw[0] * p_muw[0] * p_dswkrw[0] * p_dsw[0];
		alpha_g = K * p_krg[0] * p_bg[0] * p_mug[0] + K * p_krg[0] * (p_bg[0] * p_dotmug[0] + p_dotbg[0] * p_mug[0]) * p_dp[0] \ 
				+ K * p_bg[0] * p_mug[0] * (p_dsokrg[0] * p_dso[0] + p_dswkrg[0] * p_dsw[0]);
		for (i = 0; i < N; i++){
			for (j = 0; j < N; j++){
				mat_A[i][j] = stime * phgQuadBasDotBas(e, u_o, i, u_o, j, QUAD_DEFAULT) / alpha_o;
			}
		}
		FLOAT beta = 0;
		beta = gas_so / oil_so + gas_sw * alpha_w / (wat_sw * alpha_o) + (p_Rs[0] + alpha_g / alpha_o);
#endif
#if IMPES
		FLOAT T_o = 0, T_w = 0, T_g = 0;
		T_o = K * p_kro[0] * p_bo[0] * p_muo[0];
		T_w = K * p_krw[0] * p_bw[0] * p_muw[0];
		T_g = K * p_krg[0] * p_bg[0] * p_mug[0];
		for (i = 0; i < N; i++){
			for (j = 0; j < N; j++){
				mat_A[i][j] = stime * phgQuadBasDotBas(e, u_o, i, u_o, j, QUAD_DEFAULT) / T_o;
			}
		}
		FLOAT beta = 0;
		beta = gas_so / oil_so + gas_sw * T_w / (wat_sw * T_o) + (p_Rs[0] + T_g / T_o);
#endif
		for (i = 0; i < N; i++){
			for (j = 0; j < M; j++){
				mat_TB[i][j] = -stime * phgQuadDivBasDotBas(e, u_o, i, dp, j, QUAD_DEFAULT);
			}
		}
		FLOAT quad = 0., oil_cp = 0., wat_cp = 0., gas_cp = 0.;
		oil_cp = p_so[0] * (p_bo[0] * p_dotphi[0] + p_phi[0] * p_dotbo[0]);
		wat_cp = p_sw[0] * (p_bw[0] * p_dotphi[0] + p_phi[0] * p_dotbw[0]);
		gas_cp = p_so[0] * p_phi[0] * p_bo[0] * p_dotRs[0] + p_Rs[0] * oil_cp + (1. - p_so[0] - p_sw[0]) * (p_phi[0] * p_dotbg[0] + p_bg[0] * p_dotphi[0]);
		for (i = 0; i < M; i++){
			for (j = 0; j < M; j++){
				quad = phgQuadBasDotBas(e, dp, i, dp, j, QUAD_DEFAULT);
				mat_C[i][j] = (gas_so * oil_cp / oil_so + gas_sw * wat_cp / wat_sw + gas_cp) * quad / beta;
			}
		}
		/*Create rhs*/
		FLOAT quad_qo = 0;
		FLOAT quad_qw = 0.;
		FLOAT quad_qg = 0.;
		FLOAT quad_phi = 0, quad_phil = 0;
		FLOAT rhs_oil = 0, rhs_wat = 0., rhs_gas = 0;
		for (i = 0; i < M; i++){
			phgQuadDofTimesBas(e, q_o, dp, i, QUAD_DEFAULT, &quad_qo);
			phgQuadDofTimesBas(e, q_w, dp, i, QUAD_DEFAULT, &quad_qw);
			phgQuadDofTimesBas(e, q_g, dp, i, QUAD_DEFAULT, &quad_qg);
			phgQuadDofTimesBas(e, phi, dp, i, QUAD_DEFAULT, &quad_phi);
			phgQuadDofTimesBas(e, phi_l, dp, i, QUAD_DEFAULT, &quad_phil);
			rhs_oil = -stime * quad_qo  + p_so[0] * p_bo[0] * quad_phi - p_sol[0] * p_bol[0] * quad_phil;
			rhs_wat = -stime * quad_qw  + p_sw[0] * p_bw[0] * quad_phi - p_swl[0] * p_bwl[0] * quad_phil;
			rhs_gas = -stime * quad_qg  + (p_bg[0] * (1. - p_so[0] - p_sw[0]) + p_Rs[0] * p_so[0] * p_bo[0]) * quad_phi \
					  - (p_Rsl[0] * p_bol[0] * p_sol[0] + p_bgl[0] * (1. - p_sol[0] - p_swl[0])) * quad_phil;
			rhs_g[i] = (gas_so * rhs_oil / oil_so + gas_sw * rhs_wat / wat_sw + rhs_gas) / beta;
		}
		for (i = 0; i < N; i++){
			rhs_f[i] = stime * phgQuadDofTimesDivBas(e, p_h, u_o, i, QUAD_DEFAULT);
		}
		/* Handle Bdry Conditions */
		for (i = 0; i < N; i++){
			if (phgDofGetElementBoundaryType(u_o, e, i) & (NEUMANN | DIRICHLET)){
				bzero(mat_A[i], N *sizeof(mat_A[i][0]));
				bzero(mat_TB[i], M *sizeof(mat_TB[i][0]));
				for (j = 0; j < N; j++){
					mat_A[j][i] = 0.0;
				}
				mat_A[i][i] = 1.0;
				rhs_f[i] = 0.;
			}
		}
		for (i = 0; i < N; i++){
			for (j = 0; j < M; j++){
				mat_B[j][i] = mat_TB[i][j];
			}
		}
		for (i = 0; i < N; i++){
			I[i] = phgMapE2L(map_u, 0, e, i);
		}
		for (i = 0; i < M; i++){
			J[i] = phgMapE2L(map_p, 0, e, i);
		}
		phgMatAddEntries(A, N, I, N, I, mat_A[0]);
		phgMatAddEntries(TB, N, I, M, J, mat_TB[0]);
		phgMatAddEntries(B, M, J, N, I, mat_B[0]);
		phgMatAddEntries(C, M, J, M, J, mat_C[0]);
		phgVecAddEntries(vec_f, 0, N, I, rhs_f);
		phgVecAddEntries(vec_g, 0, M, J, rhs_g);
	}