Exemplo n.º 1
0
/**
 * \param mesh pointer toward the mesh structure.
 * \param met pointer toward the sol structure.
 * \param nconf configuration.
 * \param ilist number of tetrahedra in the shell of the edge that we want
 *  to swap.
 * \param list pointer toward the shell of the edge that we want to swap.
 * \param bucket pointer toward the bucket structure in Delaunay mode,
 * NULL pointer in pattern mode.
 * \return -1 if lack of memory, 0 if fail to swap, 1 otherwise.
 *
 * Perform swap of edge whose shell is passed according to configuration nconf.
 *
 */
int _MMG5_swpgen(MMG5_pMesh mesh,MMG5_pSol met,int nconf,int ilist,int *list,_MMG5_pBucket bucket) {
  MMG5_pTetra    pt;
  MMG5_pPoint    p0,p1;
  int       iel,na,nb,np,nball,ret,start;
  double    m[3];
  char      ia,ip,iq;
  int       ier;

  iel = list[0] / 6;
  ia  = list[0] % 6;

  pt = &mesh->tetra[iel];
  na = pt->v[_MMG5_iare[ia][0]];
  nb = pt->v[_MMG5_iare[ia][1]];
  p0 = &mesh->point[na];
  p1 = &mesh->point[nb];

  /* Temporarily create midpoint at swapped edge */
  m[0] = 0.5*(p0->c[0] + p1->c[0]);
  m[1] = 0.5*(p0->c[1] + p1->c[1]);
  m[2] = 0.5*(p0->c[2] + p1->c[2]);

  np  = _MMG5_newPt(mesh,m,0);
  if(!np){
    if ( bucket ) {
      _MMG5_POINT_AND_BUCKET_REALLOC(mesh,met,np,mesh->gap,
                                     printf("  ## Error: unable to allocate a new point\n");
                                     _MMG5_INCREASE_MEM_MESSAGE();
                                     return(-1)
                                     ,m,0);
    }
    else {
      _MMG5_POINT_REALLOC(mesh,met,np,mesh->gap,
                          printf("  ## Error: unable to allocate a new point\n");
                          _MMG5_INCREASE_MEM_MESSAGE();
                          return(-1)
                          ,m,0);
    }
  }
Exemplo n.º 2
0
/**
 * \param mesh pointer toward the mesh structure.
 * \param met pointer toward the metric structure.
 * \param *warn \a warn is set to 1 if we don't have enough memory to complete mesh.
 * \return -1 if failed.
 * \return number of new points.
 *
 * Split edges of length bigger than _MMG5_LOPTL.
 *
 */
static int _MMG5_adpspl(MMG5_pMesh mesh,MMG5_pSol met, int* warn) {
    MMG5_pTetra     pt;
    MMG5_pxTetra    pxt;
    MMG5_Tria       ptt;
    MMG5_pPoint     p0,p1,ppt;
    MMG5_pxPoint    pxp;
    double     dd,len,lmax,o[3],to[3],ro[3],no1[3],no2[3],v[3];
    int        k,ip,ip1,ip2,list[_MMG5_LMAX+2],ilist,ns,ref,ier;
    char       imax,tag,j,i,i1,i2,ifa0,ifa1;

    *warn=0;
    ns = 0;
    for (k=1; k<=mesh->ne; k++) {
        pt = &mesh->tetra[k];
        if ( !MG_EOK(pt) || (pt->tag & MG_REQ) )   continue;
        pxt = pt->xt ? &mesh->xtetra[pt->xt] : 0;

        /* find longest edge */
        imax = -1; lmax = 0.0;
        for (i=0; i<6; i++) {
            if ( pt->xt && (pxt->tag[i] & MG_REQ) )  continue;
            ip1  = _MMG5_iare[i][0];
            ip2  = _MMG5_iare[i][1];
            len = _MMG5_lenedg(mesh,met,pt->v[ip1],pt->v[ip2]);
            if ( len > lmax ) {
                lmax = len;
                imax = i;
            }
        }
        if ( imax==-1 )
            fprintf(stdout,"%s:%d: Warning: all edges of tetra %d are required or of length null.\n",
                    __FILE__,__LINE__,k);
        if ( lmax < _MMG5_LOPTL )  continue;

        /* proceed edges according to lengths */
        ifa0 = _MMG5_ifar[imax][0];
        ifa1 = _MMG5_ifar[imax][1];
        i  = (pt->xt && (pxt->ftag[ifa1] & MG_BDY)) ? ifa1 : ifa0;
        j  = _MMG5_iarfinv[i][imax];
        i1 = _MMG5_idir[i][_MMG5_inxt2[j]];
        i2 = _MMG5_idir[i][_MMG5_iprv2[j]];
        ip1 = pt->v[i1];
        ip2 = pt->v[i2];
        p0  = &mesh->point[ip1];
        p1  = &mesh->point[ip2];

        /* Case of a boundary face */
        if ( pt->xt && (pxt->ftag[i] & MG_BDY) ) {
            if ( !(MG_GET(pxt->ori,i)) ) continue;
            ref = pxt->edg[_MMG5_iarf[i][j]];
            tag = pxt->tag[_MMG5_iarf[i][j]];
            if ( tag & MG_REQ )  continue;
            tag |= MG_BDY;
            ilist = _MMG5_coquil(mesh,k,imax,list);
            if ( !ilist )  continue;
            else if ( ilist < 0 )
                return(-1);
            if ( tag & MG_NOM ){
                if( !_MMG5_BezierNom(mesh,ip1,ip2,0.5,o,no1,to) )
                    continue;
                else if ( MG_SIN(p0->tag) && MG_SIN(p1->tag) ) {
                    _MMG5_tet2tri(mesh,k,i,&ptt);
                    _MMG5_nortri(mesh,&ptt,no1);
                    if ( !MG_GET(pxt->ori,i) ) {
                        no1[0] *= -1.0;
                        no1[1] *= -1.0;
                        no1[2] *= -1.0;
                    }
                }
            }
            else if ( tag & MG_GEO ) {
                if ( !_MMG5_BezierRidge(mesh,ip1,ip2,0.5,o,no1,no2,to) )
                    continue;
                if ( MG_SIN(p0->tag) && MG_SIN(p1->tag) ) {
                    _MMG5_tet2tri(mesh,k,i,&ptt);
                    _MMG5_nortri(mesh,&ptt,no1);
                    no2[0] = to[1]*no1[2] - to[2]*no1[1];
                    no2[1] = to[2]*no1[0] - to[0]*no1[2];
                    no2[2] = to[0]*no1[1] - to[1]*no1[0];
                    dd = no2[0]*no2[0] + no2[1]*no2[1] + no2[2]*no2[2];
                    if ( dd > _MMG5_EPSD2 ) {
                        dd = 1.0 / sqrt(dd);
                        no2[0] *= dd;
                        no2[1] *= dd;
                        no2[2] *= dd;
                    }
                }
            }
            else if ( tag & MG_REF ) {
                if ( !_MMG5_BezierRef(mesh,ip1,ip2,0.5,o,no1,to) )
                    continue;
            }
            else {
                if ( !_MMG5_norface(mesh,k,i,v) )  continue;
                if ( !_MMG5_BezierReg(mesh,ip1,ip2,0.5,v,o,no1) )
                    continue;
            }
            ier = _MMG5_simbulgept(mesh,list,ilist,o);
            if ( !ier ) {
                ier = _MMG5_dichoto1b(mesh,list,ilist,o,ro);
                memcpy(o,ro,3*sizeof(double));
            }
            ip = _MMG5_newPt(mesh,o,tag);
            if ( !ip ) {
                /* reallocation of point table */
                _MMG5_POINT_REALLOC(mesh,met,ip,mesh->gap,
                              *warn=1;
                              break
                              ,o,tag);
            }
            //CECILE
            if ( met->m )
                met->m[ip] = 0.5 * (met->m[ip1]+met->m[ip2]);
            //CECILE
            ier = _MMG5_split1b(mesh,met,list,ilist,ip,1);
            /* if we realloc memory in _MMG5_split1b pt and pxt pointers are not valid */
            pt = &mesh->tetra[k];
            pxt = pt->xt ? &mesh->xtetra[pt->xt] : 0;

            if ( ier < 0 ) {
                fprintf(stdout," ## Error: unable to split.\n");
                return(-1);
            }
            else if ( !ier ) {
                _MMG5_delPt(mesh,ip);
                continue;
            }
            ns++;
            ppt = &mesh->point[ip];
            if ( MG_EDG(tag) || (tag & MG_NOM) )
                ppt->ref = ref;
            else
                ppt->ref = pxt->ref[i];
            if ( met->m )
                met->m[ip] = 0.5 * (met->m[ip1]+met->m[ip2]);

            pxp = &mesh->xpoint[ppt->xp];
            if ( tag & MG_NOM ){
                memcpy(pxp->n1,no1,3*sizeof(double));
                memcpy(pxp->t,to,3*sizeof(double));
            }
            else if ( tag & MG_GEO ) {
                memcpy(pxp->n1,no1,3*sizeof(double));
                memcpy(pxp->n2,no2,3*sizeof(double));
                memcpy(pxp->t,to,3*sizeof(double));
            }
            else if ( tag & MG_REF ) {
                memcpy(pxp->n1,no1,3*sizeof(double));
                memcpy(pxp->t,to,3*sizeof(double));
            }
            else
                memcpy(pxp->n1,no1,3*sizeof(double));
        }

        /* Case of an internal face */
        else {
            if ( (p0->tag & MG_BDY) && (p1->tag & MG_BDY) ) continue;