Exemplo n.º 1
0
/*
  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);
}
Exemplo n.º 2
0
/*!
  @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 );
}