/*! @par Revision history: - 04.05.2007, c - 30.05.2007 */ int32 sg_evaluateBFBGM( SurfaceGeometry *obj, FMField *bfBGR, float64 *coorIn, int32 nNod, int32 dim, int32 *fis, int32 nFa, int32 nFP, int32 *conn, int32 nEl, int32 nEP ) { int32 ii, iel, ifa, inod, idim, pos, nQP, ret = RET_OK; FMField *volCoor0 = 0, *mtxRM = 0, *mtxRMI = 0; nQP = obj->normal->nLev; /* output( "%d %d %d %d\n", dim, nQP, nEP, nNod ); */ fmf_createAlloc( &volCoor0, 1, 1, nEP, dim ); fmf_createAlloc( &mtxRM, 1, nQP, dim, dim ); fmf_createAlloc( &mtxRMI, 1, nQP, dim, dim ); for (ii = 0; ii < nFa; ii++) { iel = fis[ii*nFP+0]; ifa = fis[ii*nFP+1]; FMF_SetCell( obj->bfBGM, ii ); FMF_SetCell( bfBGR, ifa ); for (inod = 0; inod < nEP; inod++) { pos = dim*conn[nEP*iel+inod]; for (idim = 0; idim < dim; idim++ ) { volCoor0->val[dim*inod+idim] = coorIn[idim+pos]; } } fmf_mulAB_n1( mtxRM, bfBGR, volCoor0 ); geme_invert3x3( mtxRMI, mtxRM ); fmf_mulAB_nn( obj->bfBGM, mtxRMI, bfBGR ); /* fmf_mulATBT_1n( mtxRM, volCoor0, bfBGR ); */ /* geme_invert3x3( mtxRMI, mtxRM ); */ /* fmf_mulATB_nn( obj->bfBGM, mtxRMI, bfBGR ); */ /* output( "%d %d %d\n", ii, iel, ifa); */ /* fmf_print( bfBGR, stdout, 0 ); */ /* fmf_print( volCoor0, stdout, 0 ); */ /* fmf_print( obj->bfBGM, stdout, 0 ); */ /* sys_pause(); */ ERR_CheckGo( ret ); } end_label: fmf_freeDestroy( &volCoor0 ); fmf_freeDestroy( &mtxRM ); fmf_freeDestroy( &mtxRMI ); return( RET_OK ); }
/* 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: - 11.10.2005, c - 12.10.2005 - 05.06.2006 - 06.06.2006 */ int32 vg_describe( VolumeGeometry *obj, float64 *coorIn, int32 nNod, int32 dim, int32 *conn, int32 nEl, int32 nEP, FMField *bfGR, FMField *weight ) { int32 iel, inod, idim, pos, iqp, nQP, ret = RET_OK; FMField *mtxMR = 0, *mtxMRI = 0, *coor = 0; nQP = bfGR->nLev; if (!((nEl == obj->nEl) && (dim == obj->dim) && (nQP == obj->nQP) && (nEP == obj->nEP))) { output( "nNod: %d, dim: %d, nEl: %d, nEP: %d\n", nNod, dim, nEl, nEP ); fmf_print( obj->bfGM, stdout, 1 ); fmf_print( bfGR, stdout, 1 ); fmf_print( weight, stdout, 1 ); errput( "size mismatch!\n" ); return( RET_Fail ); } fmf_createAlloc( &mtxMR, 1, nQP, dim, dim ); fmf_createAlloc( &mtxMRI, 1, nQP, dim, dim ); fmf_createAlloc( &coor, 1, 1, nEP, dim ); obj->totalVolume = 0.0; /* output( "nCell %d\n", obj->bfGM->nCell ); */ for (iel = 0; iel < obj->bfGM->nCell; iel++) { FMF_SetCell( obj->bfGM, iel ); FMF_SetCell( obj->det, iel ); FMF_SetCell( obj->volume, iel ); for (inod = 0; inod < nEP; inod++) { pos = dim*conn[inod]; for (idim = 0; idim < dim; idim++ ) { coor->val[dim*inod+idim] = coorIn[idim+pos]; } } // Jacobi matrix from reference to material system. fmf_mulATBT_1n( mtxMR, coor, bfGR ); // Its determinant, preweighted. geme_det3x3( obj->det->val, mtxMR ); for (iqp = 0; iqp < nQP; iqp++) { if (obj->det->val[iqp] <= MachEps) { errput( "warp violation %e at (iel: %d, iqp: %d)!\n", obj->det->val[iqp], iel, iqp ); } } fmf_mul( obj->det, weight->val ); // Element volume. geme_elementVolume( obj->volume->val, obj->det->val, nQP ); obj->totalVolume += obj->volume->val[0]; // Inverse of Jacobi matrix reference to material system. geme_invert3x3( mtxMRI, mtxMR ); // Base function gradient w.r.t. material system. fmf_mulATB_nn( obj->bfGM, mtxMRI, bfGR ); conn += nEP; /* output( "cell %d\n", iel ); */ /* fmf_print( coor, stdout, 0 ); */ /* fmf_print( obj->det, stdout, 0 ); */ ERR_CheckGo( ret ); } end_label: fmf_freeDestroy( &mtxMR ); fmf_freeDestroy( &mtxMRI ); fmf_freeDestroy( &coor ); return( ret ); }