示例#1
0
文件: geommech.c 项目: Gkdnz/sfepy
/*!
  @par Revision history:
  - 21.11.2006, c
*/
int32 bf_buildFTF( FMField *ftf, FMField *ftf1 )
{
  int32 iqp, ir, ic, nEPR, nEPC, nQP, dim;
  float64 *pftf, *pftf1;
  float64 val;

  fmf_fillC( ftf, 0.0 );

  nEPR = ftf1->nRow;
  nEPC = ftf1->nCol;
  nQP = ftf1->nLev;
  dim = ftf->nRow / nEPR;

  for (iqp = 0; iqp < nQP; iqp++) {
    pftf1 = FMF_PtrLevel( ftf1, iqp );
    pftf = FMF_PtrLevel( ftf, iqp );
    for (ir = 0; ir < nEPR; ir++) {
      for (ic = 0; ic < nEPC; ic++) {
	val = pftf1[nEPC*ir+ic];

	pftf[dim*nEPC*ir+ic] = val;
	if (dim == 1) continue;
	pftf[dim*nEPC*(nEPR+ir)+ic+nEPC] = val;
	if (dim == 2) continue;
	pftf[dim*nEPC*(2*nEPR+ir)+ic+2*nEPC] = val;
      }
    }
  }

  return( RET_OK );
}
示例#2
0
文件: fmfield.c 项目: certik/sfepy
/*!
  @a objA^T.

  @par Revision history:
  - 23.05.2005, c
*/
int32 fmf_sumLevelsTMulF( FMField *objR, FMField *objA, float64 *val )
{
  int32 il, ir, ic, wr, wc;
  float64 *pa, *pr;

#ifdef DEBUG_FMF
  if ((objR->nRow != objA->nCol) || (objR->nCol != objA->nRow)
      || (objR->nLev != 1)) {
    errput( ErrHead "ERR_BadMatch (%d == %d, %d == %d, %d == 1)\n",
	    objR->nRow, objA->nCol, objR->nCol, objA->nRow, objR->nLev );
  }
#endif

  wr = objR->nCol;
  pr = objR->val;
  wc = objA->nCol;

  fmf_fillC( objR, 0.0 );
  for (il = 0; il < objA->nLev; il++) {
    pa = objA->val + objA->nCol * objA->nRow * il;
    for (ir = 0; ir < objR->nRow; ir++) {
      for (ic = 0; ic < objR->nCol; ic++) {
	pr[wr*ir+ic] += pa[wc*ic+ir] * val[il];
      }
    }
  }

  return( RET_OK );
}
示例#3
0
文件: geommech.c 项目: Gkdnz/sfepy
/*!
  @a in is a state vector stored as matrix (dim, nEP) - in->nLev == 1.

  @par Revision history:
  - 12.12.2005, c
  - 14.12.2005
*/
int32 bf_act( FMField *out, FMField *bf, FMField *in )
{
  int32 iqp, ir, ic, nEP, nQP, dim;
  float64 *pout, *pbf;

  nEP = bf->nCol;
  nQP = bf->nLev;
  dim = in->nRow;

#ifdef DEBUG_FMF
  if ((out->nRow != dim) || (out->nCol != 1)
      || (out->nLev != bf->nLev) || (in->nCol != nEP)) {
    errput( ErrHead "ERR_BadMatch: (%d %d %d), (%d %d %d), (%d %d %d)\n",
	    out->nLev, out->nRow, out->nCol,
	    bf->nLev, bf->nRow, bf->nCol,
	    in->nLev, in->nRow, in->nCol );
  }
#endif

  fmf_fillC( out, 0.0 );
  for (iqp = 0; iqp < nQP; iqp++) {
    pbf = FMF_PtrLevel( bf, iqp );
    pout = FMF_PtrLevel( out, iqp );

    for (ic = 0; ic < dim; ic++ ) {
      for (ir = 0; ir < nEP; ir++) {
	pout[ic] += pbf[ir] * in->val[nEP*ic+ir];
      }
    }
  }

  return( RET_OK );
}
示例#4
0
int32 eval_bernstein_basis(FMField *funs, FMField *ders,
                           float64 x, uint32 degree)
{
  uint32 ip, ifun;
  uint32 n_fun = degree + 1;
  float64 prev, tmp;

  fmf_fillC(funs, 0.0);
  fmf_fillC(ders, 0.0);

  funs->val[0] = 1.0;

  if (degree == 0) {
    return(RET_OK);
  }

  for (ip = 1; ip < n_fun - 1; ip++) {
    prev = 0.0;
    for (ifun = 0; ifun < ip + 1; ifun++) {
      tmp = x * funs->val[ifun];
      funs->val[ifun] = (1.0 - x) * funs->val[ifun] + prev;
      prev = tmp;
    }
  }

  ders->val[0] = degree * (- funs->val[0]);
  for (ifun = 1; ifun < n_fun; ifun++) {
    ders->val[ifun] = degree * (funs->val[ifun - 1] - funs->val[ifun]);
  }

  prev = 0.0;
  for (ifun = 0; ifun < n_fun; ifun++) {
    tmp = x * funs->val[ifun];
    funs->val[ifun] = (1.0 - x) * funs->val[ifun] + prev;
    prev = tmp;
  }

  return(RET_OK);
}
示例#5
0
/*!
  @par Revision history:
  - 28.11.2005, c
  - 30.05.2007
*/
int32 laplace_build_gtg( FMField *out, FMField *gc )
{
  int32 iqp, ir, ic, nEP, nQP, nCol;
  float64 *pout, *pg1, *pg2, *pg3;

  nEP = gc->nCol;
  nQP = gc->nLev;
  nCol = out->nCol;

  fmf_fillC( out, 0.0 );
  switch (gc->nRow) {
  case 3:
    for (iqp = 0; iqp < nQP; iqp++) {
      pg1 = FMF_PtrLevel( gc, iqp );
      pg2 = pg1 + nEP;
      pg3 = pg2 + nEP;

      pout = FMF_PtrLevel( out, iqp );

      for (ir = 0; ir < nEP; ir++) {
	for (ic = 0; ic < nEP; ic++) {
	  pout[ic] = pg1[ir] * pg1[ic] + pg2[ir] * pg2[ic] + pg3[ir] * pg3[ic];
	}
	pout += nCol;
      }
    }
    break;
    
  case 2:
    for (iqp = 0; iqp < nQP; iqp++) {
      pg1 = FMF_PtrLevel( gc, iqp );
      pg2 = pg1 + nEP;

      pout = FMF_PtrLevel( out, iqp );

      for (ir = 0; ir < nEP; ir++) {
	for (ic = 0; ic < nEP; ic++) {
	  pout[ic] = pg1[ir] * pg1[ic] + pg2[ir] * pg2[ic];
	}
	pout += nCol;
      }
    }
    break;
    
  default:
    errput( ErrHead "ERR_Switch\n" );
    return( RET_Fail );
  }    
  return( RET_OK );
}
示例#6
0
文件: geommech.c 项目: Gkdnz/sfepy
/*!
  Act transposed.

  @par Revision history:
  - 12.12.2005, c
  - 20.12.2005
*/
int32 bf_actt( FMField *out, FMField *bf, FMField *in )
{
  int32 iqp, ir, ic, ii, nEP, nQP, dim;
  float64 *pout, *pbf, *pin;

  nEP = bf->nCol;
  nQP = bf->nLev;
  dim = in->nRow;

#ifdef DEBUG_FMF
  if ((out->nCol != in->nCol) || (out->nRow != (dim * nEP))
      || (out->nLev != bf->nLev)) {
    errput( ErrHead "ERR_BadMatch: (%d %d %d), (%d %d %d), (%d %d %d)\n",
	    out->nLev, out->nRow, out->nCol,
	    bf->nLev, bf->nRow, bf->nCol,
	    in->nLev, in->nRow, in->nCol );
  }
#endif

  fmf_fillC( out, 0.0 );
  for (iqp = 0; iqp < nQP; iqp++) {
    pbf = FMF_PtrLevel( bf, iqp );
    pout = FMF_PtrLevel( out, iqp );
    pin = FMF_PtrLevel( in, iqp );

    for (ir = 0; ir < dim; ir++) {
      for (ic = 0; ic < out->nCol; ic++) {
	for (ii = 0; ii < nEP; ii++) {
	  pout[out->nCol*ii+ic] = pbf[ii] * (*pin);
	}
	pin++;
      }
      pout += out->nCol * nEP;
    }
  }

  return( RET_OK );
}
示例#7
0
文件: fmfield.c 项目: certik/sfepy
/*!
  @par Revision history:
  - 26.04.2001, c
  - 19.01.2004, adopted from rcfem2
*/
int32 fmf_sumLevelsMulF( FMField *objR, FMField *objA, float64 *val )
{
  int32 il, i;
  float64 *pa;

#ifdef DEBUG_FMF
  if ((objR->nRow != objA->nRow) || (objR->nCol != objA->nCol)
      || (objR->nLev != 1)) {
    errput( ErrHead "ERR_BadMatch (%d == %d, %d == %d, %d == 1)\n",
	    objR->nRow, objA->nRow, objR->nCol, objA->nCol, objR->nLev );
  }
#endif

  fmf_fillC( objR, 0.0 );
  for (il = 0; il < objA->nLev; il++) {
    pa = objA->val + objA->nCol * objA->nRow * il;
    for (i = 0; i < (objR->nRow * objR->nCol); i++) {
      objR->val[i] += pa[i] * val[il];
    }
  }

  return( RET_OK );
}
示例#8
0
文件: refcoors.c 项目: Gkdnz/sfepy
int32 refc_find_ref_coors(FMField *ref_coors,
                          int32 *cells, int32 n_cells,
                          int32 *status, int32 n_status,
                          FMField *coors,
                          Mesh *mesh,
                          int32 *candidates, int32 n_candidates,
                          int32 *offsets, int32 n_offsets,
                          int32 allow_extrapolation,
                          float64 qp_eps,
                          float64 close_limit,
                          void *_ctx)
{
  BasisContext *ctx = (BasisContext *) _ctx;

  int32 ip, ic, ii, imin, ok, xi_ok, ret = RET_OK;
  int32 D = mesh->topology->max_dim;
  int32 nc = mesh->geometry->dim;
  float64 d_min, dist;
  float64 *mesh_coors = mesh->geometry->coors;
  float64 buf3[3];
  FMField point[1], e_coors[1], xi[1];
  Indices cell_vertices[1];
  MeshEntity cell_ent[1];
  MeshConnectivity *cD0 = 0; // D -> 0

  mesh_setup_connectivity(mesh, D, 0);
  cD0 = mesh->topology->conn[IJ(D, D, 0)];

  fmf_pretend_nc(point, coors->nRow, 1, 1, nc, coors->val);

  fmf_pretend_nc(xi, 1, 1, 1, nc, buf3);
  fmf_fillC(xi, 0.0);

  ctx->is_dx = 0;

  for (ip = 0; ip < coors->nRow; ip++) {
    FMF_SetCell(point, ip);

    if (offsets[ip] == offsets[ip+1]) {
      status[ip] = 5;
      cells[ip] = 0;
      for (ii = 0; ii < nc; ii++) {
        ref_coors->val[nc*ip+ii] = 0.0;
      }
      continue;
    }

    ok = xi_ok = 0;
    d_min = 1e10;
    imin = candidates[offsets[ip]];

    for (ic = offsets[ip]; ic < offsets[ip+1]; ic++) {
      /* output("***** %d %d %d\n", ip, ic, candidates[ic]); */

      ctx->iel = candidates[ic];
      cell_ent->ii = candidates[ic];
      me_get_incident2(cell_ent, cell_vertices, cD0);

      _get_cell_coors(e_coors, cell_vertices, mesh_coors, nc,
                      ctx->e_coors_max->val);
      xi_ok = ctx->get_xi_dist(&dist, xi, point, e_coors, ctx);

      if (xi_ok) {
        if (dist < qp_eps) {
          imin = cell_ent->ii;
          ok = 1;
          break;
        } else if (dist < d_min) {
          d_min = dist;
          imin = cell_ent->ii;
        }
      } else if (dist < d_min) {
        d_min = dist;
        imin = cell_ent->ii;
      }
    }
    /* output("-> %d %d %d %.3e\n", imin, xi_ok, ok, d_min); */

    cells[ip] = imin;

    if (ok != 1) {
      if (!xi_ok) {
        status[ip] = 4;
      } else if (allow_extrapolation) {
        if (sqrt(d_min) < close_limit) {
          status[ip] = 1;
        } else {
          status[ip] = 2;
        }
      } else {
        status[ip] = 3;
      }
    } else {
      status[ip] = 0;
    }

    for (ii = 0; ii < nc; ii++) {
      ref_coors->val[nc*ip+ii] = xi->val[ii];
    }
    ERR_CheckGo(ret);
  }

 end_label:
  return(ret);
}
示例#9
0
文件: refcoors.c 项目: Gkdnz/sfepy
int32 refc_find_ref_coors_convex(FMField *ref_coors,
                                 int32 *cells, int32 n_cells,
                                 int32 *status, int32 n_status,
                                 FMField *coors,
                                 Mesh *mesh,
                                 FMField *centroids,
                                 FMField *normals0,
                                 FMField *normals1,
                                 int32 *ics, int32 n_ics,
                                 int32 allow_extrapolation,
                                 float64 qp_eps,
                                 float64 close_limit,
                                 void *_ctx)
{
  BasisContext *ctx = (BasisContext *) _ctx;
  int32 ip, ic, icell, icell_max = 0, ii, imin, ik, ok, ret = RET_OK;
  int32 xi_ok, hexa_reverse;
  int32 D = mesh->topology->max_dim;
  int32 dim = D - 1;
  int32 nc = mesh->geometry->dim;
  uint32 tri0[] = {0, 1, 3};
  uint32 tri1[] = {2, 3, 1};
  uint32 cell, cell0, cell00, facet;
  uint32 *noffs, *foffs, aux[2];
  uint32 *cell_types = mesh->topology->cell_types;
  float64 d_min, tmin, tt, dist;
  float64 *mesh_coors = mesh->geometry->coors;
  float64 buf3[3];
  float64 buf9[9];
  FMField point[1], centroid[1], _normals0[1], _normals1[1], e_coors[1], xi[1];
  Indices cell_vertices[1];
  MeshEntity cell_ent[1];
  MeshConnectivity *cD0 = 0; // D -> 0
  MeshConnectivity *c0D = 0; // 0 -> D
  MeshConnectivity *cDd = 0; // cell -> facet
  MeshConnectivity *cdD = 0; // facet -> cell
  MeshConnectivity *loc = 0;
  MeshConnectivity **locs = 0;

  mesh_setup_connectivity(mesh, D, 0);
  cD0 = mesh->topology->conn[IJ(D, D, 0)];

  mesh_setup_connectivity(mesh, 0, D);
  c0D = mesh->topology->conn[IJ(D, 0, D)];

  mesh_setup_connectivity(mesh, D, dim);
  cDd = mesh->topology->conn[IJ(D, D, dim)];
  noffs = cDd->offsets;

  mesh_setup_connectivity(mesh, dim, D);
  cdD = mesh->topology->conn[IJ(D, dim, D)];

  // Local entities - reference cell edges or faces.
  locs = (dim == 1) ? mesh->entities->edges : mesh->entities->faces;

  fmf_pretend_nc(point, coors->nRow, 1, 1, nc, coors->val);
  fmf_pretend_nc(centroid, centroids->nRow, 1, 1, nc, centroids->val);

  fmf_pretend_nc(xi, 1, 1, 1, nc, buf3);
  fmf_fillC(xi, 0.0);

  ctx->is_dx = 0;

  for (ip = 0; ip < coors->nRow; ip++) {
    ic = ics[ip];
    /* output("***** %d %d\n", ip, ic); */

    FMF_SetCell(point, ip);
    /* fmf_print(point, stdout, 0); */

    cell = cell0 = cell00 = c0D->indices[c0D->offsets[ic]];

    ok = icell = hexa_reverse = imin = 0;
    d_min = 1e10;
    while (1) {
      /* output("*** %d %d %d\n", icell, cell, hexa_reverse); */
      FMF_SetCell(centroid, cell);
      /* fmf_print(centroid, stdout, 0); */

      ctx->iel = cell;
      cell_ent->ii = cell;
      me_get_incident2(cell_ent, cell_vertices, cD0);

      loc = locs[cell_types[cell]];
      foffs = loc->offsets;

      if (cell_types[cell] != 4) { // No hexahedron -> planar facet.
        fmf_pretend_nc(_normals0, noffs[cell+1] - noffs[cell], 1, 1, nc,
                       normals0->val + nc * noffs[cell]);

        tmin = 1e10;
        for (ii = 0; ii < loc->num; ii++) {
          FMF_SetCell(_normals0, ii);
          ik = loc->indices[foffs[ii]];

          _intersect_line_plane(&tt, centroid->val, point->val,
                                mesh_coors + nc * cell_vertices->indices[ik],
                                _normals0->val, nc);
          if ((tt >= -qp_eps) && (tt < (tmin + qp_eps))) {
            imin = ii;
            tmin = tt;
          }
        }

        if (tmin >= (1.0 - qp_eps)) {
          _get_cell_coors(e_coors, cell_vertices, mesh_coors, nc,
                          ctx->e_coors_max->val);
          /* fmf_print(e_coors, stdout, 0); */

          xi_ok = ctx->get_xi_dist(&dist, xi, point, e_coors, ctx);

          d_min = Min(dist, d_min);
          if (xi_ok && (dist < qp_eps)) {
            ok = 1;
          }
          break;
        }

      } else { // Hexahedron -> non-planar facet in general.
        fmf_pretend_nc(_normals0, noffs[cell+1] - noffs[cell], 1, 1, nc,
                       normals0->val + nc * noffs[cell]);
        fmf_pretend_nc(_normals1, noffs[cell+1] - noffs[cell], 1, 1, nc,
                       normals1->val + nc * noffs[cell]);
        for (ii = 0; ii < loc->num; ii++) {
          FMF_SetCell(_normals0, ii);
          _get_tri_coors(buf9, loc->indices, foffs[ii],
                         tri0, mesh_coors, cell_vertices->indices);
          _intersect_line_triangle(&tt, centroid->val, point->val,
                                   buf9, _normals0->val);
          if ((tt >= -qp_eps) && (tt < 1e10)) {
            ok = 2;
            imin = ii;
            if ((tt >= (1.0 - qp_eps)) || hexa_reverse) {
              _get_cell_coors(e_coors, cell_vertices, mesh_coors, nc,
                              ctx->e_coors_max->val);

              xi_ok = ctx->get_xi_dist(&dist, xi, point, e_coors, ctx);

              d_min = Min(dist, d_min);
              if (xi_ok && (dist < qp_eps)) {
                ok = 1;
              } else {
                hexa_reverse = 1;
              }
            }
            break;
          }

          FMF_SetCell(_normals1, ii);
          _get_tri_coors(buf9, loc->indices, foffs[ii],
                         tri1, mesh_coors, cell_vertices->indices);
          _intersect_line_triangle(&tt, centroid->val, point->val,
                                   buf9, _normals1->val);
          if ((tt >= -qp_eps) && (tt < 1e10)) {
            ok = 2;
            imin = ii;
            if ((tt >= (1.0 - qp_eps)) || hexa_reverse) {
              _get_cell_coors(e_coors, cell_vertices, mesh_coors, nc,
                              ctx->e_coors_max->val);

              xi_ok = ctx->get_xi_dist(&dist, xi, point, e_coors, ctx);

              d_min = Min(dist, d_min);
              if (xi_ok && (dist < qp_eps)) {
                ok = 1;
              } else {
                hexa_reverse = 1;
              }
            }
            break;
          }
        }
        if (ok == 1) {
          break;
        }
        if (ok == 0) {
          errput("cannot intersect bilinear faces!\n");
          ERR_CheckGo(ret);
        }
      }

      facet = cDd->indices[cDd->offsets[cell] + imin];
      if ((cdD->offsets[facet+1] - cdD->offsets[facet]) == 2) {
        aux[0] = cdD->indices[cdD->offsets[facet]];
        aux[1] = cdD->indices[cdD->offsets[facet]+1];
        cell00 = cell0;
        cell0 = cell;
        cell = (aux[0] == cell) ? aux[1] : aux[0];

        if (cell == cell00) { // Ping-pong between two cells.
          hexa_reverse = 1;
        }

      } else { // Boundary facet.
        ctx->iel = cell;
        cell_ent->ii = cell;
        me_get_incident2(cell_ent, cell_vertices, cD0);

        _get_cell_coors(e_coors, cell_vertices, mesh_coors, nc,
                        ctx->e_coors_max->val);
        xi_ok = ctx->get_xi_dist(&dist, xi, point, e_coors, ctx);

        d_min = Min(dist, d_min);
        if (xi_ok && (dist < qp_eps)) {
          ok = 1;
        } else {
          ok = 0;
        }
        break;
      }

      icell++;
      icell_max = Max(icell, icell_max);
      if (icell > 10000) {
        errput("cannot find containing cell!\n");
        ERR_CheckGo(ret);
      }
    }

    /* fmf_print(xi, stdout, 0); */
    /* output("-> %d %d %d %.3e\n", cell, xi_ok, ok, d_min); */

    cells[ip] = cell;

    if (ok != 1) {
      if (!xi_ok) {
        status[ip] = 4;
      } else if (allow_extrapolation) {
        // Try using minimum distance xi.
        if (sqrt(d_min) < close_limit) {
          status[ip] = 1;
        } else {
          status[ip] = 2;
        }
      } else {
        status[ip] = 3;
      }
    } else {
      status[ip] = 0;
    }

    for (ii = 0; ii < nc; ii++) {
      ref_coors->val[nc*ip+ii] = xi->val[ii];
    }
  }
  /* output("%d\n", icell_max); */

 end_label:
  return(ret);
}