/*! @par Revision history: - c: 25.03.2008 */ int32 de_cauchy_stress( FMField *out, FMField *strain, FMField *mtxD, VolumeGeometry *vg, int32 mode ) { int32 ii, dim, sym, nQP, ret = RET_OK; FMField *stress = 0; nQP = vg->bfGM->nLev; dim = vg->bfGM->nRow; sym = (dim + 1) * dim / 2; fmf_createAlloc( &stress, 1, nQP, sym, 1 ); for (ii = 0; ii < out->nCell; ii++) { FMF_SetCell( out, ii ); FMF_SetCell( mtxD, ii ); FMF_SetCell( strain, ii ); FMF_SetCell( vg->det, ii ); fmf_mulAB_nn( stress, mtxD, strain ); fmf_sumLevelsMulF( out, stress, vg->det->val ); if (mode == 1) { FMF_SetCell( vg->volume, ii ); fmf_mulC( out, 1.0 / vg->volume->val[0] ); } ERR_CheckGo( ret ); } end_label: fmf_freeDestroy( &stress ); return( ret ); }
/*! @par Revision history: - 21.09.2006, c */ int32 de_cauchy_strain( FMField *out, FMField *strain, VolumeGeometry *vg, int32 mode ) { int32 ii, dim, sym, nQP, ret = RET_OK; nQP = vg->bfGM->nLev; dim = vg->bfGM->nRow; sym = (dim + 1) * dim / 2; for (ii = 0; ii < out->nCell; ii++) { FMF_SetCell( out, ii ); FMF_SetCell( strain, ii ); FMF_SetCell( vg->det, ii ); fmf_sumLevelsMulF( out, strain, vg->det->val ); if (mode == 1) { FMF_SetCell( vg->volume, ii ); fmf_mulC( out, 1.0 / vg->volume->val[0] ); } ERR_CheckGo( ret ); } end_label: return( ret ); }
int32 d_surface_flux( FMField *out, FMField *grad, FMField *mtxD, Mapping *sg, int32 mode ) { int32 ii, dim, nQP, ret = RET_OK; FMField *dgp = 0, *ntdgp = 0; nQP = sg->normal->nLev; dim = sg->normal->nRow; fmf_createAlloc( &dgp, 1, nQP, dim, 1 ); fmf_createAlloc( &ntdgp, 1, nQP, 1, 1 ); for (ii = 0; ii < out->nCell; ii++) { FMF_SetCell( out, ii ); FMF_SetCell( grad, ii ); FMF_SetCell( mtxD, ii ); FMF_SetCell( sg->normal, ii ); FMF_SetCell( sg->det, ii ); fmf_mulAB_nn( dgp, mtxD, grad ); fmf_mulATB_nn( ntdgp, sg->normal, dgp ); fmf_sumLevelsMulF( out, ntdgp, sg->det->val ); if (mode == 1) { FMF_SetCell( sg->volume, ii ); fmf_mulC( out, 1.0 / sg->volume->val[0] ); } ERR_CheckGo( ret ); } end_label: fmf_freeDestroy( &dgp ); fmf_freeDestroy( &ntdgp ); return( ret ); }
/* dR_dx has shape (dim, n_efun), transposed w.r.t. the Python version! */ int32 eval_nurbs_basis_tp(FMField *R, FMField *dR_dx, FMField *det, FMField *dR_dxi, FMField *dx_dxi, FMField *dxi_dx, FMField *B, FMField *dB_dxi, FMField *N, FMField *dN_dxi, FMField *qp, uint32 ie, FMField *control_points, FMField *weights, int32 *degrees, int32 dim, FMField *cs, int32 *conn, int32 n_el, int32 n_ep) { int32 ret = RET_OK; uint32 ii, jj, a, i0, i1, i2; uint32 n_efuns[3]; uint32 n_efun = 1; uint32 n_els[3]; uint32 ic[3]; int32 *ec; FMField *C, *N0, *N1, *N2, *dN0_dxi, *dN1_dxi, *dN2_dxi; float64 w, W, P; float64 dw_dxi[3]; #ifdef DEBUG_FMF if (!((dim == qp->nCol) && (dim <= 3))) { errput(ErrHead "inconsistent dimension! (%d == $d <= 3)", dim, qp->nCol); ERR_CheckGo(ret); } #endif for (ii = 0; ii < dim; ii++) { n_efuns[ii] = degrees[ii] + 1; n_efun *= n_efuns[ii]; } #ifdef DEBUG_FMF if (n_efun != n_ep) { errput(ErrHead "inconsistent number of bases! (%d == $d)", n_efun, n_ep); ERR_CheckGo(ret); } #endif // Element connectivity. ec = conn + n_ep * ie; // 1D Bernstein basis B, dB/dxi. for (ii = 0; ii < dim; ii++) { eval_bernstein_basis(B + ii, dB_dxi + ii, qp->val[ii], degrees[ii]); } // 1D B-spline basis N = CB, dN/dxi = C dB/dxi. for (ii = 0; ii < dim; ii++) { n_els[ii] = (cs + ii)->nCell; } unravel_index(ic, ie, n_els, dim); for (ii = 0; ii < dim; ii++) { C = cs + ii; FMF_SetCell(C, ic[ii]); fmf_mulAB_nn(N + ii, C, B + ii); fmf_mulAB_nn(dN_dxi + ii, C, dB_dxi + ii); } ERR_CheckGo(ret); // Numerators and denominator for tensor-product NURBS basis R, dR/dxi. w = 0; // w_b for (ii = 0; ii < dim; ii++) { dw_dxi[ii] = 0.0; // dw_b/dxi } a = 0; // Basis function index. if (dim == 3) { N0 = N + 0; N1 = N + 1; N2 = N + 2; dN0_dxi = dN_dxi + 0; dN1_dxi = dN_dxi + 1; dN2_dxi = dN_dxi + 2; for (i0 = 0; i0 < n_efuns[0]; i0++) { for (i1 = 0; i1 < n_efuns[1]; i1++) { for (i2 = 0; i2 < n_efuns[2]; i2++) { W = weights->val[ec[a]]; R->val[a] = N0->val[i0] * N1->val[i1] * N2->val[i2] * W; w += R->val[a]; dR_dxi->val[a+n_ep*0] = dN0_dxi->val[i0] * N1->val[i1] * N2->val[i2] * W; dw_dxi[0] += dR_dxi->val[a+n_ep*0]; dR_dxi->val[a+n_ep*1] = N0->val[i0] * dN1_dxi->val[i1] * N2->val[i2] * W; dw_dxi[1] += dR_dxi->val[a+n_ep*1]; dR_dxi->val[a+n_ep*2] = N0->val[i0] * N1->val[i1] * dN2_dxi->val[i2] * W; dw_dxi[2] += dR_dxi->val[a+n_ep*2]; a += 1; } } } } else if (dim == 2) { N0 = N + 0; N1 = N + 1; dN0_dxi = dN_dxi + 0; dN1_dxi = dN_dxi + 1; for (i0 = 0; i0 < n_efuns[0]; i0++) { for (i1 = 0; i1 < n_efuns[1]; i1++) { W = weights->val[ec[a]]; R->val[a] = N0->val[i0] * N1->val[i1] * W; w += R->val[a]; dR_dxi->val[a+n_ep*0] = dN0_dxi->val[i0] * N1->val[i1] * W; dw_dxi[0] += dR_dxi->val[a+n_ep*0]; dR_dxi->val[a+n_ep*1] = N0->val[i0] * dN1_dxi->val[i1] * W; dw_dxi[1] += dR_dxi->val[a+n_ep*1]; a += 1; } } } else { N0 = N + 0; dN0_dxi = dN_dxi + 0; for (i0 = 0; i0 < n_efuns[0]; i0++) { W = weights->val[ec[a]]; R->val[a] = N0->val[i0] * W; w += R->val[a]; dR_dxi->val[a+n_ep*0] = dN0_dxi->val[i0] * W; dw_dxi[0] += dR_dxi->val[a+n_ep*0]; a += 1; } } // Finish R <- R / w_b. fmf_mulC(R, 1.0 / w); // Finish dR/dxi. D == W C dB/dxi, dR/dxi = (D - R dw_b/dxi) / w_b. for (a = 0; a < dR_dxi->nCol; a++) { for (ii = 0; ii < dim; ii++) { dR_dxi->val[a+n_ep*ii] = (dR_dxi->val[a+n_ep*ii] - R->val[a] * dw_dxi[ii]) / w; } } // Mapping reference -> physical domain dxi/dx. // x = sum P_a R_a, dx/dxi = sum P_a dR_a/dxi, invert. for (ii = 0; ii < dim; ii++) { for (jj = 0; jj < dim; jj++) { dx_dxi->val[dim*ii+jj] = 0.0; for (a = 0; a < dR_dxi->nCol; a++) { P = control_points->val[dim*ec[a]+ii]; dx_dxi->val[dim*ii+jj] += P * dR_dxi->val[a+n_ep*jj]; } } } geme_det3x3(det->val, dx_dxi); geme_invert3x3(dxi_dx, dx_dxi); // dR/dx. fmf_mulATB_nn(dR_dx, dxi_dx, dR_dxi); end_label: return(ret); }
/*! @par Revision history: - 30.10.2007, c */ int32 dw_st_adj2_supg_p( FMField *out, FMField *gradU, FMField *stateR, FMField *coef, VolumeGeometry *vg_u, VolumeGeometry *vg_r, int32 *conn_r, int32 nEl_r, int32 nEP_r, int32 isDiff ) { int32 ii, dim, nQP, nEP_u, ret = RET_OK; FMField *stR = 0, *gUTg = 0, *fTgUTg = 0; FMField *outqp = 0; FMField stRv[1]; nQP = vg_u->bfGM->nLev; nEP_u = vg_u->bfGM->nCol; dim = vg_u->bfGM->nRow; stateR->val = FMF_PtrFirst( stateR ); fmf_createAlloc( &gUTg, 1, nQP, dim, nEP_r ); fmf_createAlloc( &fTgUTg, 1, nQP, nEP_u * dim, nEP_r ); if (isDiff == 0) { fmf_createAlloc( &outqp, 1, nQP, nEP_u * dim, 1 ); fmf_createAlloc( &stR, 1, 1, 1, nEP_r ); stRv->nAlloc = -1; fmf_pretend( stRv, 1, 1, nEP_r, 1, stR->val ); } for (ii = 0; ii < out->nCell; ii++) { FMF_SetCell( out, ii ); FMF_SetCell( gradU, ii ); FMF_SetCell( vg_r->bfGM, ii ); FMF_SetCell( vg_u->det, ii ); FMF_SetCell( coef, ii ); FMF_SetCellX1( vg_u->bf, ii ); // (grad u, grad). fmf_mulATB_nn( gUTg, gradU, vg_r->bfGM ); // (v grad u, grad). bf_actt( fTgUTg, vg_u->bf, gUTg ); if (isDiff == 1) { fmf_sumLevelsMulF( out, fTgUTg, vg_u->det->val ); } else { ele_extractNodalValuesDBD( stR, stateR, conn_r + nEP_r * ii ); // (v grad u, grad r). fmf_mulAB_n1( outqp, fTgUTg, stRv ); fmf_sumLevelsMulF( out, outqp, vg_u->det->val ); } fmf_mulC( out, coef->val[0] ); ERR_CheckGo( ret ); } end_label: fmf_freeDestroy( &gUTg ); fmf_freeDestroy( &fTgUTg ); if (isDiff == 0) { fmf_freeDestroy( &stR ); fmf_freeDestroy( &outqp ); } return( ret ); }
/*! @par Revision history: - 30.10.2007, c */ int32 dw_st_adj1_supg_p( FMField *out, FMField *stateW, FMField *gradP, FMField *coef, VolumeGeometry *vg_w, int32 *conn_w, int32 nEl_w, int32 nEP_w, int32 isDiff ) { int32 ii, dim, nQP, ret = RET_OK; FMField *stW = 0, *gPTgT = 0, *fTgPTgT = 0; FMField *outqp = 0; FMField stWv[1]; nQP = vg_w->bfGM->nLev; dim = vg_w->bfGM->nRow; stateW->val = FMF_PtrFirst( stateW ); fmf_createAlloc( &gPTgT, 1, nQP, dim, nEP_w * dim ); fmf_createAlloc( &fTgPTgT, 1, nQP, nEP_w * dim, nEP_w * dim ); if (isDiff == 0) { fmf_createAlloc( &outqp, 1, nQP, nEP_w * dim, 1 ); fmf_createAlloc( &stW, 1, 1, dim, nEP_w ); stWv->nAlloc = -1; fmf_pretend( stWv, 1, 1, nEP_w * dim, 1, stW->val ); } for (ii = 0; ii < out->nCell; ii++) { FMF_SetCell( out, ii ); FMF_SetCell( gradP, ii ); FMF_SetCell( vg_w->bfGM, ii ); FMF_SetCell( vg_w->det, ii ); FMF_SetCell( coef, ii ); FMF_SetCellX1( vg_w->bf, ii ); // (grad p, grad). convect_build_vtbg( gPTgT, vg_w->bfGM, gradP ); // (grad p, v grad). bf_actt( fTgPTgT, vg_w->bf, gPTgT ); if (isDiff == 1) { fmf_sumLevelsMulF( out, fTgPTgT, vg_w->det->val ); } else { ele_extractNodalValuesDBD( stW, stateW, conn_w + nEP_w * ii ); // (grad p, v grad w). fmf_mulAB_n1( outqp, fTgPTgT, stWv ); fmf_sumLevelsMulF( out, outqp, vg_w->det->val ); } fmf_mulC( out, coef->val[0] ); ERR_CheckGo( ret ); } end_label: fmf_freeDestroy( &gPTgT ); fmf_freeDestroy( &fTgPTgT ); if (isDiff == 0) { fmf_freeDestroy( &stW ); fmf_freeDestroy( &outqp ); } return( ret ); }
/*! @par Revision history: - 30.10.2007, c */ int32 dw_st_adj_supg_c( FMField *out, FMField *stateW, FMField *stateU, FMField *gradU, FMField *coef, VolumeGeometry *vg, int32 *conn, int32 nEl, int32 nEP, int32 isDiff ) { int32 ii, dim, nQP, ret = RET_OK; FMField *stW = 0, *gUfU = 0, *fUTg = 0; FMField *gUfUTg = 0, *fTgUfUTg = 0; FMField *gUfUTgT = 0, *fTgUfUTgT = 0; FMField *outdqp = 0, *outqp = 0, *out1qp = 0, *out2qp = 0; FMField stWv[1]; nQP = vg->bfGM->nLev; dim = vg->bfGM->nRow; stateW->val = FMF_PtrFirst( stateW ); fmf_createAlloc( &gUfU, 1, nQP, dim, 1 ); fmf_createAlloc( &gUfUTgT, 1, nQP, dim, nEP * dim ); fmf_createAlloc( &fTgUfUTgT, 1, nQP, nEP * dim, nEP * dim ); fmf_createAlloc( &fUTg, 1, nQP, dim, nEP * dim ); fmf_createAlloc( &gUfUTg, 1, nQP, dim, nEP * dim ); fmf_createAlloc( &fTgUfUTg, 1, nQP, nEP * dim, nEP * dim ); if (isDiff == 1) { fmf_createAlloc( &outdqp, 1, nQP, dim * nEP, dim * nEP ); } else { fmf_createAlloc( &stW, 1, 1, dim, nEP ); stWv->nAlloc = -1; fmf_pretend( stWv, 1, 1, nEP * dim, 1, stW->val ); fmf_createAlloc( &out1qp, 1, nQP, dim * nEP, 1 ); fmf_createAlloc( &out2qp, 1, nQP, dim * nEP, 1 ); fmf_createAlloc( &outqp, 1, nQP, dim * nEP, 1 ); } for (ii = 0; ii < out->nCell; ii++) { FMF_SetCell( out, ii ); FMF_SetCell( stateU, ii ); FMF_SetCell( gradU, ii ); FMF_SetCell( vg->bfGM, ii ); FMF_SetCell( vg->det, ii ); FMF_SetCell( coef, ii ); FMF_SetCellX1( vg->bf, ii ); // u grad u. fmf_mulAB_nn( gUfU, gradU, stateU ); // (u grad u, grad). convect_build_vtbg( gUfUTgT, vg->bfGM, gUfU ); // (u grad u, v grad). bf_actt( fTgUfUTgT, vg->bf, gUfUTgT ); // u grad. convect_build_vtg( fUTg, vg->bfGM, stateU ); // (grad u, u^T grad). fmf_mulAB_nn( gUfUTg, gradU, fUTg ); // (v grad u, u grad). bf_actt( fTgUfUTg, vg->bf, gUfUTg ); if (isDiff == 1) { fmf_addAB_nn( outdqp, fTgUfUTgT, fTgUfUTg ); fmf_sumLevelsMulF( out, outdqp, vg->det->val ); } else { ele_extractNodalValuesDBD( stW, stateW, conn + nEP * ii ); // (u grad u, v grad w). fmf_mulAB_n1( out1qp, fTgUfUTgT, stWv ); // (v grad u, u grad w). fmf_mulAB_n1( out2qp, fTgUfUTg, stWv ); fmf_addAB_nn( outqp, out1qp, out2qp ); fmf_sumLevelsMulF( out, outqp, vg->det->val ); } fmf_mulC( out, coef->val[0] ); ERR_CheckGo( ret ); } end_label: fmf_freeDestroy( &gUfU ); fmf_freeDestroy( &gUfUTgT ); fmf_freeDestroy( &fTgUfUTgT ); fmf_freeDestroy( &fUTg ); fmf_freeDestroy( &gUfUTg ); fmf_freeDestroy( &fTgUfUTg ); if (isDiff) { fmf_freeDestroy( &outdqp ); } else { fmf_freeDestroy( &stW ); fmf_freeDestroy( &out1qp ); fmf_freeDestroy( &out2qp ); fmf_freeDestroy( &outqp ); } return( ret ); }