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