Exemple #1
0
void ApplyBCsElement(PetscInt mx,PetscInt my, PetscInt mz, PetscInt i, PetscInt j, PetscInt k,PetscScalar *jacobian)
{
  PetscInt ii,jj,kk,ll,ei,ej,ek,el;
  for (kk=0;kk<NB;kk++){
    for (jj=0;jj<NB;jj++) {
      for (ii=0;ii<NB;ii++) {
        for(ll = 0;ll<3;ll++) {
          PetscInt tridx = ll + 3*(ii + jj*NB + kk*NB*NB);
          for (ek=0;ek<NB;ek++){
            for (ej=0;ej<NB;ej++) {
              for (ei=0;ei<NB;ei++) {
                for (el=0;el<3;el++) {
                  if (OnBoundary(i+ii,j+jj,k+kk,mx,my,mz) || OnBoundary(i+ei,j+ej,k+ek,mx,my,mz)) {
                    PetscInt teidx = el + 3*(ei + ej*NB + ek*NB*NB);
                    if (teidx == tridx) {
                      jacobian[tridx + NPB*teidx] = 1.;
                    } else {
                      jacobian[tridx + NPB*teidx] = 0.;
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
Exemple #2
0
void GatherElementData(PetscInt mx,PetscInt my,PetscInt mz,Field ***x,CoordField ***c,PetscInt i,PetscInt j,PetscInt k,Field *ex,CoordField *ec,AppCtx *user)
{
  PetscInt m;
  PetscInt ii,jj,kk;
  /* gather the data -- loop over element unknowns */
  for (kk=0;kk<NB;kk++){
    for (jj=0;jj<NB;jj++) {
      for (ii=0;ii<NB;ii++) {
        PetscInt idx = ii + jj*NB + kk*NB*NB;
        /* decouple the boundary nodes for the displacement variables */
        if (OnBoundary(i+ii,j+jj,k+kk,mx,my,mz)) {
          BoundaryValue(i+ii,j+jj,k+kk,mx,my,mz,ex[idx],user);
        } else {
          for (m=0;m<3;m++) {
            ex[idx][m] = x[k+kk][j+jj][i+ii][m];
          }
        }
        for (m=0;m<3;m++) {
          ec[idx][m] = c[k+kk][j+jj][i+ii][m];
        }
      }
    }
  }
}
Exemple #3
0
bool CListContour::CompactStrips()
{
    CLineStrip* pStrip;
    CLineStrip* pStripBase;
    size_t i;
    CLineStripList::iterator pos,pos2;
    CLineStripList newList;
    bool again, changed;

    const double weldDist = 10*(m_dDx*m_dDx+m_dDy*m_dDy);

    const size_t size = m_vStripLists.size();
    assert__( size == GetNPlanes() );
    for ( i = 0; i < size; i++ )
    {
        if ( i == size / 2 )
            mProgress( 1 );

        again=true;
        while(again)
        {
            // REPEAT COMPACT PROCESS UNTILL LAST PROCESS MAKES NO CHANGE

            again=false;
            // building compacted list
            assert__(newList.empty());
            for (pos=m_vStripLists[i].begin(); pos!=m_vStripLists[i].end(); pos++)
            {
                pStrip=(*pos);
                for (pos2=newList.begin(); pos2!=newList.end(); pos2++)
                {
                    pStripBase=(*pos2);
                    changed=MergeStrips(pStripBase,pStrip);
                    if (changed)
                        again=true;
                    if (pStrip->empty())
                        break;
                }
                if (pStrip->empty())
                    delete pStrip;
                else
                    newList.insert(newList.begin(),pStrip);
            }


            // deleting old list
            m_vStripLists[i].clear();
            // Copying all
            for (pos2=newList.begin(); pos2 != newList.end(); pos2++)
            {
                pStrip=(*pos2);
                CLineStrip::iterator pos1 = pStrip->begin(),pos3;
                while (pos1!=pStrip->end())
                {
                    pos3 = pos1;
                    pos3++;
                    if ( pos3 != pStrip->end() && (*pos1) == (*pos3))	//femm, from if ( (*pos1) == (*pos3))
                        pStrip->erase(pos3);
                    else
                        pos1++;
                }

                //if (!(pStrip->front()==pStrip->back() && pStrip->size()==2))
                if (pStrip->size()!=1)
                    m_vStripLists[i].insert(m_vStripLists[i].begin(),pStrip );
                else
                    delete pStrip;
            }
            // emptying temp list
            newList.clear();

        } // OF WHILE(AGAIN) (LAST COMPACT PROCESS MADE NO CHANGES)


        if (m_vStripLists[i].empty())
            continue;
        ///////////////////////////////////////////////////////////////////////
        // compact more
        long_t Nstrip,j,index,count;

        Nstrip = m_vStripLists[i].size();
        std::vector<bool> closed(Nstrip);
        double x,y;

        // First let's find the open and closed lists in m_vStripLists
        for(pos2 = m_vStripLists[i].begin(), j=0, count=0; pos2 != m_vStripLists[i].end(); pos2++, j++)
        {
            pStrip = (*pos2);

            // is it open ?
            if (pStrip->front() != pStrip->back())
            {
                index = pStrip->front();
                x = GetXi(index);
                y = GetYi(index);
                index = pStrip->back();
                x -= GetXi(index);
                y -= GetYi(index);

                // is it "almost closed" ?
                if ( x*x+y*y < weldDist)
                    closed[j] = true;
                else
                {
                    closed[j] = false;
                    // updating not closed counter...
                    count ++;
                }
            }
            else
                closed[j] = true;
        }

        // is there any open strip ?
        if (count > 1)
        {
            // Merge the open strips into NewList
            pos = m_vStripLists[i].begin();
            for(j=0; j<Nstrip; j++)
            {
                if (closed[j] == false )
                {
                    pStrip = (*pos);
                    newList.insert(newList.begin(),pStrip);
                    pos = m_vStripLists[i].erase(pos);
                }
                else
                    pos ++;
            }

            // are they open strips to process ?
            while(newList.size()>1)
            {
                pStripBase = newList.front();

                // merge the rest to pStripBase
                again = true;
                while (again)
                {
                    again = false;
                    pos = newList.begin();
                    for(pos++; pos!=newList.end();)
                    {
                        pStrip = (*pos);
                        changed = ForceMerge(pStripBase,pStrip);
                        if (changed)
                        {
                            again = true;
                            delete pStrip;
                            pos = newList.erase(pos);
                        }
                        else
                            pos ++;
                    }
                } // while(again)

                index = pStripBase->front();
                x = GetXi(index);
                y = GetYi(index);
                index = pStripBase->back();
                x -= GetXi(index);
                y -= GetYi(index);

                // if pStripBase is closed or not
                if (x*x+y*y < weldDist)
                {
                    m_vStripLists[i].insert(m_vStripLists[i].begin(),pStripBase);
                    newList.pop_front();
                }
                else
                {
                    if (OnBoundary(pStripBase))
                    {
                        LOG_TRACE("# open strip ends on boundary, continue.\n");
                        m_vStripLists[i].insert(m_vStripLists[i].begin(),pStripBase);
                        newList.pop_front();
                    }
                    else
                    {
                        LOG_TRACE("unpaired open strip at 1!");
                        //newList.pop_front();//femmfemmfemmefemm
                        //continue;			//femmfemmfemmefemm
                        return false;
                    }
                }
            } // while(newList.size()>1);


            if (newList.size() ==1)
            {
                pStripBase = newList.front();
                if (OnBoundary(pStripBase))
                {
                    LOG_TRACE("# open strip ends on boundary, continue.\n");
                    m_vStripLists[i].insert(m_vStripLists[i].begin(),pStripBase);
                    newList.pop_front();
                }
                else
                {
                    LOG_TRACE("unpaired open strip at 2!");
                    DumpPlane(i);
                    return false;
                }
            }

            newList.clear();

        }
        else if (count == 1)
        {
            pos = m_vStripLists[i].begin();
            for(j=0; j<Nstrip; j++)
            {
                if (closed[j] == false )
                {
                    pStripBase = (*pos);
                    break;
                }
                pos ++;
            }
            if (OnBoundary(pStripBase))
            {
                LOG_TRACE("# open strip ends on boundary, continue.\n");
            }
            else
            {
                LOG_TRACE("unpaired open strip at 3!");
                DumpPlane(i);
                return false;
            }
        }

        //////////////////////////////////////////////////////////////////////////////////////////////////
    }

    return true;
}
Exemple #4
0
PetscErrorCode NonlinearGS(SNES snes,Vec X,Vec B,void *ptr)
{
  /* values for each basis function at each quadrature point */
  AppCtx         *user = (AppCtx*)ptr;
  PetscInt       i,j,k,l,m,n,s;
  PetscInt       pi,pj,pk;
  Field          ef[1];
  Field          ex[8];
  PetscScalar    ej[9];
  CoordField     ec[8];
  PetscScalar    pjac[9],pjinv[9];
  PetscScalar    pf[3],py[3];
  PetscErrorCode ierr;
  PetscInt       xs,ys,zs;
  PetscInt       xm,ym,zm;
  PetscInt       mx,my,mz;
  DM             cda;
  CoordField     ***c;
  Vec            C;
  DM             da;
  Vec            Xl,Bl;
  Field          ***x,***b;
  PetscInt       sweeps,its;
  PetscReal      atol,rtol,stol;
  PetscReal      fnorm0 = 0.0,fnorm,ynorm,xnorm = 0.0;

  PetscFunctionBegin;
  ierr    = SNESNGSGetSweeps(snes,&sweeps);CHKERRQ(ierr);
  ierr    = SNESNGSGetTolerances(snes,&atol,&rtol,&stol,&its);CHKERRQ(ierr);

  ierr = SNESGetDM(snes,&da);CHKERRQ(ierr);
  ierr = DMGetLocalVector(da,&Xl);CHKERRQ(ierr);
  if (B) {
    ierr = DMGetLocalVector(da,&Bl);CHKERRQ(ierr);
  }
  ierr = DMGlobalToLocalBegin(da,X,INSERT_VALUES,Xl);CHKERRQ(ierr);
  ierr = DMGlobalToLocalEnd(da,X,INSERT_VALUES,Xl);CHKERRQ(ierr);
  if (B) {
    ierr = DMGlobalToLocalBegin(da,B,INSERT_VALUES,Bl);CHKERRQ(ierr);
    ierr = DMGlobalToLocalEnd(da,B,INSERT_VALUES,Bl);CHKERRQ(ierr);
  }
  ierr = DMDAVecGetArray(da,Xl,&x);CHKERRQ(ierr);
  if (B) ierr = DMDAVecGetArray(da,Bl,&b);CHKERRQ(ierr);

  ierr = DMGetCoordinateDM(da,&cda);CHKERRQ(ierr);
  ierr = DMGetCoordinatesLocal(da,&C);CHKERRQ(ierr);
  ierr = DMDAVecGetArray(cda,C,&c);CHKERRQ(ierr);
  ierr = DMDAGetInfo(da,0,&mx,&my,&mz,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr);
  ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr);

  for (s=0;s<sweeps;s++) {
    for (k=zs; k<zs+zm; k++) {
      for (j=ys; j<ys+ym; j++) {
        for (i=xs; i<xs+xm; i++) {
          if (OnBoundary(i,j,k,mx,my,mz)) {
            BoundaryValue(i,j,k,mx,my,mz,x[k][j][i],user);
          } else {
            for (n=0;n<its;n++) {
              for (m=0;m<9;m++) pjac[m] = 0.;
              for (m=0;m<3;m++) pf[m] = 0.;
              /* gather the elements for this point */
              for (pk=-1; pk<1; pk++) {
                for (pj=-1; pj<1; pj++) {
                  for (pi=-1; pi<1; pi++) {
                    /* check that this element exists */
                    if (i+pi >= 0 && i+pi < mx-1 && j+pj >= 0 && j+pj < my-1 && k+pk >= 0 && k+pk < mz-1) {
                      /* create the element function and jacobian */
                      GatherElementData(mx,my,mz,x,c,i+pi,j+pj,k+pk,ex,ec,user);
                      FormPBJacobian(-pi,-pj,-pk,ex,ec,ef,ej,user);
                      /* extract the point named by i,j,k from the whole element jacobian and function */
                      for (l=0;l<3;l++) {
                        pf[l] += ef[0][l];
                        for (m=0;m<3;m++) {
                          pjac[3*m+l] += ej[3*m+l];
                        }
                      }
                    }
                  }
                }
              }
              /* invert */
              InvertTensor(pjac,pjinv,NULL);
              /* apply */
              if (B) for (m=0;m<3;m++) {
                  pf[m] -= b[k][j][i][m];
                }
              TensorVector(pjinv,pf,py);
              xnorm=0.;
              for (m=0;m<3;m++) {
                x[k][j][i][m] -= py[m];
                xnorm += PetscRealPart(x[k][j][i][m]*x[k][j][i][m]);
              }
              fnorm = PetscRealPart(pf[0]*pf[0]+pf[1]*pf[1]+pf[2]*pf[2]);
              if (n==0) fnorm0 = fnorm;
              ynorm = PetscRealPart(py[0]*py[0]+py[1]*py[1]+py[2]*py[2]);
              if (fnorm < atol*atol || fnorm < rtol*rtol*fnorm0 || ynorm < stol*stol*xnorm) break;
            }
          }
        }
      }
    }
  }
  ierr = DMDAVecRestoreArray(da,Xl,&x);CHKERRQ(ierr);
  ierr = DMLocalToGlobalBegin(da,Xl,INSERT_VALUES,X);CHKERRQ(ierr);
  ierr = DMLocalToGlobalEnd(da,Xl,INSERT_VALUES,X);CHKERRQ(ierr);
  ierr = DMRestoreLocalVector(da,&Xl);CHKERRQ(ierr);
  if (B) {
    ierr = DMDAVecRestoreArray(da,Bl,&b);CHKERRQ(ierr);
    ierr = DMRestoreLocalVector(da,&Bl);CHKERRQ(ierr);
  }
  ierr = DMDAVecRestoreArray(cda,C,&c);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
Exemple #5
0
PetscErrorCode FormFunctionLocal(DMDALocalInfo *info,Field ***x,Field ***f,void *ptr)
{
  /* values for each basis function at each quadrature point */
  AppCtx         *user = (AppCtx*)ptr;
  PetscInt       i,j,k,l;
  PetscInt       ii,jj,kk;

  Field          ef[NEB];
  Field          ex[NEB];
  CoordField     ec[NEB];

  PetscErrorCode ierr;
  PetscInt       xs=info->xs,ys=info->ys,zs=info->zs;
  PetscInt       xm=info->xm,ym=info->ym,zm=info->zm;
  PetscInt       xes,yes,zes,xee,yee,zee;
  PetscInt       mx=info->mx,my=info->my,mz=info->mz;
  DM             cda;
  CoordField     ***c;
  Vec            C;

  PetscFunctionBegin;
  ierr = DMGetCoordinateDM(info->da,&cda);CHKERRQ(ierr);
  ierr = DMGetCoordinatesLocal(info->da,&C);CHKERRQ(ierr);
  ierr = DMDAVecGetArray(cda,C,&c);CHKERRQ(ierr);
  ierr = DMDAGetInfo(info->da,0,&mx,&my,&mz,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr);
  ierr = DMDAGetCorners(info->da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr);

  /* loop over elements */
  for (k=zs; k<zs+zm; k++) {
    for (j=ys; j<ys+ym; j++) {
      for (i=xs; i<xs+xm; i++) {
        for (l=0;l<3;l++) {
          f[k][j][i][l] = 0.;
        }
      }
    }
  }
  /* element starts and ends */
  xes = xs;
  yes = ys;
  zes = zs;
  xee = xs+xm;
  yee = ys+ym;
  zee = zs+zm;
  if (xs > 0) xes = xs - 1;
  if (ys > 0) yes = ys - 1;
  if (zs > 0) zes = zs - 1;
  if (xs+xm == mx) xee = xs+xm-1;
  if (ys+ym == my) yee = ys+ym-1;
  if (zs+zm == mz) zee = zs+zm-1;
  for (k=zes; k<zee; k++) {
    for (j=yes; j<yee; j++) {
      for (i=xes; i<xee; i++) {
        GatherElementData(mx,my,mz,x,c,i,j,k,ex,ec,user);
        FormElementJacobian(ex,ec,ef,NULL,user);
        /* put this element's additions into the residuals */
        for (kk=0;kk<NB;kk++){
          for (jj=0;jj<NB;jj++) {
            for (ii=0;ii<NB;ii++) {
              PetscInt idx = ii + jj*NB + kk*NB*NB;
              if (k+kk >= zs && j+jj >= ys && i+ii >= xs && k+kk < zs+zm && j+jj < ys+ym && i+ii < xs+xm) {
                if (OnBoundary(i+ii,j+jj,k+kk,mx,my,mz)) {
                  for (l=0;l<3;l++)
                    f[k+kk][j+jj][i+ii][l] = x[k+kk][j+jj][i+ii][l] - ex[idx][l];
                } else {
                  for (l=0;l<3;l++)
                    f[k+kk][j+jj][i+ii][l] += ef[idx][l];
                }
              }
            }
          }
        }
      }
    }
  }
  ierr = DMDAVecRestoreArray(cda,C,&c);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
Exemple #6
0
PetscErrorCode FormJacobianLocal(DMDALocalInfo *info,Field ***x,Mat jacpre,Mat jac,void *ptr)
{
  /* values for each basis function at each quadrature point */
  AppCtx         *user = (AppCtx*)ptr;
  PetscInt       i,j,k,m,l;
  PetscInt       ii,jj,kk;
  PetscScalar    ej[NPB*NPB];
  PetscScalar    vals[NPB*NPB];
  Field          ex[NEB];
  CoordField     ec[NEB];

  PetscErrorCode ierr;
  PetscInt       xs=info->xs,ys=info->ys,zs=info->zs;
  PetscInt       xm=info->xm,ym=info->ym,zm=info->zm;
  PetscInt       xes,yes,zes,xee,yee,zee;
  PetscInt       mx=info->mx,my=info->my,mz=info->mz;
  DM             cda;
  CoordField     ***c;
  Vec            C;
  PetscInt       nrows;
  MatStencil     col[NPB],row[NPB];
  PetscScalar    v[9];
  
  PetscFunctionBegin;
  ierr = DMGetCoordinateDM(info->da,&cda);CHKERRQ(ierr);
  ierr = DMGetCoordinatesLocal(info->da,&C);CHKERRQ(ierr);
  ierr = DMDAVecGetArray(cda,C,&c);CHKERRQ(ierr);
  ierr = MatScale(jac,0.0);CHKERRQ(ierr);

  xes = xs;
  yes = ys;
  zes = zs;
  xee = xs+xm;
  yee = ys+ym;
  zee = zs+zm;
  if (xs > 0) xes = xs-1;
  if (ys > 0) yes = ys-1;
  if (zs > 0) zes = zs-1;
  if (xs+xm == mx) xee = xs+xm-1;
  if (ys+ym == my) yee = ys+ym-1;
  if (zs+zm == mz) zee = zs+zm-1;
  for (k=zes; k<zee; k++) {
    for (j=yes; j<yee; j++) {
      for (i=xes; i<xee; i++) {
        GatherElementData(mx,my,mz,x,c,i,j,k,ex,ec,user);
        FormElementJacobian(ex,ec,NULL,ej,user);
        ApplyBCsElement(mx,my,mz,i,j,k,ej);
        nrows = 0.;
        for (kk=0;kk<NB;kk++){
          for (jj=0;jj<NB;jj++) {
            for (ii=0;ii<NB;ii++) {
              PetscInt idx = ii + jj*2 + kk*4;
              for (m=0;m<3;m++) {
                col[3*idx+m].i = i+ii;
                col[3*idx+m].j = j+jj;
                col[3*idx+m].k = k+kk;
                col[3*idx+m].c = m;
                if (i+ii >= xs && i+ii < xm+xs && j+jj >= ys && j+jj < ys+ym && k+kk >= zs && k+kk < zs+zm) {
                  row[nrows].i = i+ii;
                  row[nrows].j = j+jj;
                  row[nrows].k = k+kk;
                  row[nrows].c = m;
                  for (l=0;l<NPB;l++) vals[NPB*nrows + l] = ej[NPB*(3*idx+m) + l];
                  nrows++;
                }
              }
            }
          }
        }
        ierr = MatSetValuesStencil(jac,nrows,row,NPB,col,vals,ADD_VALUES);CHKERRQ(ierr);
      }
    }
  }

  ierr = MatAssemblyBegin(jac,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr);
  ierr = MatAssemblyEnd(jac,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr);

  /* set the diagonal */
  v[0] = 1.;v[1] = 0.;v[2] = 0.;v[3] = 0.;v[4] = 1.;v[5] = 0.;v[6] = 0.;v[7] = 0.;v[8] = 1.;
  for (k=zs; k<zs+zm; k++) {
    for (j=ys; j<ys+ym; j++) {
      for (i=xs; i<xs+xm; i++) {
        if (OnBoundary(i,j,k,mx,my,mz)) {
          for (m=0; m<3;m++) {
            col[m].i = i;
            col[m].j = j;
            col[m].k = k;
            col[m].c = m;
          }
          ierr = MatSetValuesStencil(jac,3,col,3,col,v,INSERT_VALUES);CHKERRQ(ierr);
        }
      }
    }
  }

  ierr = MatAssemblyBegin(jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  ierr = MatAssemblyEnd(jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);

  ierr = DMDAVecRestoreArray(cda,C,&c);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}