Пример #1
0
/* TODO renumber doesn't work in parallel */
static INT RenumberVertices (MULTIGRID *theMG, INT min_level, INT max_level)
{
  INT l, i;

  ResetVertexFlags(theMG, min_level, max_level);

  /* reset used flags in vertices */
  i = 0;
  for (l=min_level; l<=max_level; l++)
  {
    NODE *theNode;
    GRID *theGrid = GRID_ON_LEVEL(theMG,l);

    /* reset USED flags in all vertices */
    for (theNode=FIRSTNODE(theGrid); theNode!=NULL; theNode=SUCCN(theNode))
    {
      if (USED(MYVERTEX(theNode))) continue;
      SETUSED(MYVERTEX(theNode),1);

      ID(MYVERTEX(theNode)) = i;
      i++;
    }
  }

  return(0);
}
Пример #2
0
Файл: ewn.c Проект: rolk/ug
static INT SetUnsymmetric (MULTIGRID *mg, INT fl, INT tl, const VECDATA_DESC *x, INT xclass, INT index)
{
  SHORT i,j;
  INT vtype;
  INT lev;

  for (lev=fl; lev<=tl; lev++)
    l_setindex(GRID_ON_LEVEL(mg,lev));
  j = 0;
  for (vtype=0; vtype<NVECTYPES; vtype++)
    if (VD_ISDEF_IN_TYPE(x,vtype))
    {
      SHORT ncomp = VD_NCMPS_IN_TYPE(x,vtype);
      VECTOR *v;
      DOUBLE_VECTOR pos;

      A_VLOOP__TYPE_CLASS(lev,fl,tl,v,mg,vtype,xclass)
      {
        for (i=0; i<ncomp; i++)
          VVALUE(v,VD_CMP_OF_TYPE(x,vtype,i)) = 0.0;
        if (VECSKIP(v) != 0) continue;
        if (j++ < index) continue;
        if (VINDEX(v) % (index+2) == 0) continue;
        VectorPosition(v,pos);
        for (i=0; i<ncomp; i++)
          VVALUE(v,VD_CMP_OF_TYPE(x,vtype,i)) = pos[i]+1.0/(1.0+index*VINDEX(v)*VINDEX(v));
      }
    }
        #ifdef ModelP
  if (a_vector_consistent(mg,fl,tl,x)) return(NUM_ERROR);
    #endif

  return (NUM_OK);
}
Пример #3
0
static INT ComputeSurfaceGridStats (MULTIGRID *theMG, COVISE_HEADER *covise)
{
  NODE *theNode;
  INT l, n_vertices, n_elem, n_conn;

  /* surface grid up to current level */
  n_vertices = n_elem = n_conn = 0;
  for (l=covise->min_level; l<=covise->max_level; l++)
  {
    ELEMENT *theElement;
    GRID *theGrid = GRID_ON_LEVEL(theMG,l);

    /* reset USED flags in all vertices to be counted */
    for (theNode=FIRSTNODE(theGrid); theNode!=NULL; theNode=SUCCN(theNode))
    {
      SETUSED(MYVERTEX(theNode),0);
    }

    /* count geometric objects */
    for (theElement=FIRSTELEMENT(theGrid);
         theElement!=NULL; theElement=SUCCE(theElement))
    {
      if ((EstimateHere(theElement)) || (l==covise->max_level))
      {
        int i, coe = CORNERS_OF_ELEM(theElement);
        n_elem++;

        for (i=0; i<coe; i++)
        {
          theNode = CORNER(theElement,i);

          n_conn++;

          if (USED(MYVERTEX(theNode))) continue;
          SETUSED(MYVERTEX(theNode),1);

          if ((SONNODE(theNode)==NULL) || (l==covise->max_level))
          {
                                                #ifdef ModelP
            if (PRIO(theNode) == PrioMaster)
                                                #endif
            n_vertices++;
          }
        }
      }
    }
  }
        #ifdef ModelP
  n_vertices = UG_GlobalSumINT(n_vertices);
  n_elem     = UG_GlobalSumINT(n_elem);
  n_conn     = UG_GlobalSumINT(n_conn);
        #endif
  covise->n_vertices = n_vertices;
  covise->n_elems    = n_elem;
  covise->n_conns    = n_conn;

  return(0);
}
Пример #4
0
INT NS_DIM_PREFIX CheckPartitioning (MULTIGRID *theMG)
{
  INT i,_restrict_;
  ELEMENT *theElement;
  ELEMENT *theFather;
  GRID    *theGrid;

  _restrict_ = 0;

  /* reset used flags */
  for (i=TOPLEVEL(theMG); i>0; i--)
  {
    theGrid = GRID_ON_LEVEL(theMG,i);
    for (theElement=FIRSTELEMENT(theGrid); theElement!=NULL;
         theElement=SUCCE(theElement))
    {
      if (LEAFELEM(theElement))
      {
        theFather = theElement;
        while (EMASTER(theFather) && ECLASS(theFather)!=RED_CLASS
               && LEVEL(theFather)>0)
        {
          theFather = EFATHER(theFather);
        }

        /* if element with red element class does not exist */
        /* or is ghost -> partitioning must be restricted   */
        if (!EMASTER(theFather))
        {
          UserWriteF(PFMT "elem=" EID_FMTX  " cannot be refined\n",
                     me,EID_PRTX(theFather));
          _restrict_ = 1;
          continue;
        }
        if (COARSEN(theFather))
        {
          /* level 0 elements cannot be coarsened */
          if (LEVEL(theFather)<=1) continue;
          if (!EMASTER(EFATHER(theFather)))
          {
            UserWriteF(PFMT "elem=" EID_FMTX " cannot be coarsened\n",
                       me,EID_PRTX(theFather));
            _restrict_ = 1;
          }
        }
      }
    }
  }

  _restrict_ = UG_GlobalMaxINT(_restrict_);
  if (me==master && _restrict_==1)
  {
    UserWriteF("CheckPartitioning(): partitioning is not valid for refinement\n");
    UserWriteF("                     cleaning up ...\n");
  }

  return(_restrict_);
}
Пример #5
0
Файл: pv3if.c Проект: rolk/ug
static void ClearVertexMarkers(MULTIGRID *mg)
{
  VERTEX *v;
  int i;

  for (i = 0; i <= TOPLEVEL(mg); i++)
    for (v = FIRSTVERTEX(GRID_ON_LEVEL(mg, i)); v != NULL; v = SUCCV(v))
      SETUSED(v,0);
}
Пример #6
0
static INT ResetVertexFlags (MULTIGRID *theMG, INT min_level, INT max_level)
{
  INT l;

  /* reset used flags in vertices */
  for (l=min_level; l<=max_level; l++)
  {
    NODE *theNode;
    GRID *theGrid = GRID_ON_LEVEL(theMG,l);

    /* reset USED flags in all vertices */
    for (theNode=FIRSTNODE(theGrid); theNode!=NULL; theNode=SUCCN(theNode))
    {
      SETUSED(MYVERTEX(theNode),0);
    }
  }

  return(0);       /* no error */
}
Пример #7
0
Файл: lbrcb.c Проект: rolk/ug
int NS_DIM_PREFIX BalanceGridRCB (MULTIGRID *theMG, int level)
{
  HEAP *theHeap = theMG->theHeap;
  GRID *theGrid = GRID_ON_LEVEL(theMG,level);       /* balance grid of level */
  LB_INFO *lbinfo;
  ELEMENT *e;
  int i, son;
  INT MarkKey;

  /* distributed grids cannot be redistributed by this function */
  if (me!=master && FIRSTELEMENT(theGrid) != NULL)
  {
    printf("Error: Redistributing distributed grids using recursive coordinate bisection is not implemented!\n");
    return (1);
  }

  if (me==master)
  {
    if (NT(theGrid) == 0)
    {
      UserWriteF("WARNING in BalanceGridRCB: no elements in grid\n");
      return (1);
    }

    Mark(theHeap,FROM_TOP,&MarkKey);
    lbinfo = (LB_INFO *)
             GetMemUsingKey(theHeap, NT(theGrid)*sizeof(LB_INFO), FROM_TOP, MarkKey);

    if (lbinfo==NULL)
    {
      Release(theHeap,FROM_TOP,MarkKey);
      UserWrite("ERROR in BalanceGridRCB: could not allocate memory from the MGHeap\n");
      return (1);
    }


    /* construct LB_INFO list */
    for (i=0, e=FIRSTELEMENT(theGrid); e!=NULL; i++, e=SUCCE(e))
    {
      lbinfo[i].elem = e;
      CenterOfMass(e, lbinfo[i].center);
    }


    /* apply coordinate bisection strategy */
    theRCB(lbinfo, NT(theGrid), 0, 0, DimX, DimY, 0);

    IFDEBUG(dddif,1)
    for (e=FIRSTELEMENT(theGrid); e!=NULL; e=SUCCE(e))
    {
      UserWriteF("elem %08x has dest=%d\n",
                 DDD_InfoGlobalId(PARHDRE(e)), PARTITION(e));
    }
    ENDDEBUG

    for (i=0, e=FIRSTELEMENT(theGrid); e!=NULL; i++, e=SUCCE(e))
    {
      InheritPartition (e);
    }

    Release(theHeap,FROM_TOP,MarkKey);
  }

  return 0;
}
Пример #8
0
Файл: amg_ug.c Проект: rolk/ug
static INT AMGSolver (NP_LINEAR_SOLVER *theNP, INT level,
                      VECDATA_DESC *x, VECDATA_DESC *b, MATDATA_DESC *A,
                      VEC_SCALAR abslimit, VEC_SCALAR reduction,
                      LRESULT *lresult)
{
  NP_AMG *theAMGC;
  VEC_SCALAR defect2reach;
  INT rv,i,bl,PrintID;
  char text[DISPLAY_WIDTH+4];
  VEC_SCALAR Factor_One;
  MULTIGRID *theMG;
  GRID *theGrid;
  INT converged=0;
  int xcomp,bcomp;
  VECTOR *theVector;
  int k;
  INT nComp_x,nComp_b;
  int blocksize;
  double ti;
  int ii;
        #ifdef ModelP
  double clock_start;
        #else
  clock_t clock_start;
        #endif

  /* prepare solving */
  theAMGC = (NP_AMG *) theNP;
  theMG = theAMGC->ls.base.mg;
  theGrid = GRID_ON_LEVEL(theMG,level);
  theAMGC->sc.red_factor=reduction[0];
  theAMGC->sc.dnorm_min=abslimit[0];

  if (theAMGC->AMG_Build_failed)
  {
    dset(NP_MG(theNP),level,level,ALL_VECTORS,x,0.0);
    return (0);
  }

  bl = 0;
  for (i=0; i<MAX_VEC_COMP; i++) Factor_One[i] = 1.0;

  /* allocate correction */
  if (AllocVDFromVD(theNP->base.mg,0,level,x,&theAMGC->c)) {
    lresult->error_code = __LINE__;
    return(1);
  }

  /* print defect */
  CenterInPattern(text,DISPLAY_WIDTH,ENVITEM_NAME(theAMGC),'*',"\n");
  if (PreparePCR(x,theAMGC->display,text,&PrintID)) {
    lresult->error_code = __LINE__;
    return(1);
  }
  for (i=0; i<VD_NCOMP(x); i++)
    lresult->first_defect[i] = lresult->last_defect[i];
  if (sc_mul_check(defect2reach,lresult->first_defect,reduction,b)) {
    lresult->error_code = __LINE__;
    return(1);
  }
  if (DoPCR(PrintID,lresult->first_defect,PCR_CRATE)) {
    lresult->error_code = __LINE__;
    return(1);
  }
  if (sc_cmp(lresult->first_defect,abslimit,b)) lresult->converged = 1;
  else lresult->converged = 0;

  CSTART(); ti=0; ii=0;

  /* fill values in x,b */
  xcomp = VD_ncmp_cmpptr_of_otype(theAMGC->c,NODEVEC,&nComp_x)[0];
  bcomp = VD_ncmp_cmpptr_of_otype(b,NODEVEC,&nComp_b)[0];
  blocksize = nComp_x;
  if (blocksize==0) goto exit;
  if (nComp_b!=blocksize) goto exit;
  for (theVector=FIRSTVECTOR(theGrid); theVector!= NULL; theVector=SUCCVC(theVector))
  {
    i = VINDEX(theVector);
    for (k=0; k<blocksize; k++)
    {
      AMG_VECTOR_ENTRY(theAMGC->b,i*blocksize+k,0)=VVALUE(theVector,bcomp+k);
    }
  }
        #ifdef ModelP
  /* only master solves */
  if (me == master)
  {
        #endif
  AMG_dset(theAMGC->x,0.0);
  if ((rv=AMG_Solve(theAMGC->x,theAMGC->b))<0)
  {
    lresult->error_code = __LINE__;
    lresult->converged = 0;
    goto exit;
  }
  lresult->converged = 1;
  lresult->number_of_linear_iterations = rv;

  /* write back solution values */
  for (theVector=FIRSTVECTOR(theGrid); theVector!= NULL; theVector=SUCCVC(theVector))
  {
    i = VINDEX(theVector);
    for (k=0; k<blocksize; k++)
      VVALUE(theVector,xcomp+k)=AMG_VECTOR_ENTRY(theAMGC->x,i*blocksize+k,0);
  }

  if (dmatmul_minus(theNP->base.mg,0,level,ON_SURFACE,b,A,theAMGC->c)
      != NUM_OK) {
    lresult->error_code = __LINE__;
    return(1);
  }
  if (daxpyx(theAMGC->ls.base.mg,0,level,
             ON_SURFACE,x,Factor_One,theAMGC->c) != NUM_OK) {
    lresult->error_code = __LINE__;
    return(1);
  }
        #ifdef ModelP
}
        #endif
  if (AMGSolverResiduum(theNP,bl,level,x,b,A,lresult))
    return(1);
  if (DoPCR(PrintID, lresult->last_defect,PCR_CRATE)) {
    lresult->error_code = __LINE__;
    return (1);
  }

  if (DoPCR(PrintID,lresult->last_defect,PCR_AVERAGE)) {
    lresult->error_code = __LINE__;
    return (1);
  }
  FreeVD(theNP->base.mg,0,level,theAMGC->c);
  if (PostPCR(PrintID,NULL)) {
    lresult->error_code = __LINE__;
    return (1);
  }
  CSTOP(ti,ii);
  if (theAMGC->sc.verbose>0)
  {
    if (lresult->number_of_linear_iterations != 0)
      UserWriteF("AMG : L=%2d N=%2d TSOLVE=%10.4g TIT=%10.4g\n",level,
                 lresult->number_of_linear_iterations,ti,
                 ti/lresult->number_of_linear_iterations);
    else
      UserWriteF("AMG : L=%2d N=%2d TSOLVE=%10.4g\n",level,
                 lresult->number_of_linear_iterations,ti);
  }

  return (0);

exit:
  return(1);
}
Пример #9
0
Файл: amg_ug.c Проект: rolk/ug
static INT AMGSolverPreProcess (NP_LINEAR_SOLVER *theNP, INT level,
                                VECDATA_DESC *VD_x, VECDATA_DESC *VD_b,
                                MATDATA_DESC *MD_A,
                                INT *baselevel, INT *result)
{
  MULTIGRID *theMG;
  GRID *theGrid;
  int n,nonzeros,blocksize;
  int Acomp;
  MATRIX *theMatrix;
  VECTOR *theVector;
  int i,j,block_i,block_j;
  int nRows_A,nCols_A,nComp_x,nComp_b;
  NP_AMG *theAMGC;
  double ti;
  int ii;
        #ifdef ModelP
  double clock_start;
        #else
  clock_t clock_start;
        #endif

  theAMGC = (NP_AMG *) theNP;

  /* prepare solving */
  theMG = theAMGC->ls.base.mg;
  theGrid = GRID_ON_LEVEL(theMG,level);

  /* mark heap for use by amg */
        #ifndef DYNAMIC_MEMORY_ALLOCMODEL
  Mark(MGHEAP(theMG),FROM_BOTTOM,&amg_MarkKey);
        #else
  Mark(MGHEAP(theMG),FROM_TOP,&amg_MarkKey);
        #endif
  mark_counter++;

  /* initialize sp package */
  AMG_InstallPrintHandler((AMG_PrintFuncPtr)UserWrite);
  amgMG=theMG;       /* make it global for memory handler */
  AMG_InstallMallocHandler((AMG_MallocFuncPtr)amgmalloc);

  /* get access to components */
  nRows_A = MD_ROWS_IN_RT_CT(MD_A,NODEVEC,NODEVEC);
  nCols_A = MD_COLS_IN_RT_CT(MD_A,NODEVEC,NODEVEC);
  nComp_x = VD_NCMPS_IN_TYPE(VD_x,NODEVEC);
  nComp_b = VD_NCMPS_IN_TYPE(VD_b,NODEVEC);
  blocksize = nComp_x;
  if (blocksize==0) goto exit;
  if (nComp_b!=blocksize) goto exit;
  if (nCols_A!=blocksize) goto exit;
  if (nRows_A!=blocksize) goto exit;
  Acomp = MD_MCMP_OF_RT_CT(MD_A,NODEVEC,NODEVEC,0);

  CSTART(); ti=0; ii=0;
  /* diagonal scaling */
  if (theAMGC->scale)
    if (DiagonalScaleSystem(theGrid,MD_A,MD_A,VD_b)!=NUM_OK)
    {
      UserWrite("Error in scaling system\n");
      goto exit;
    }

  /* gather some data for the matrix */
  n = nonzeros = 0;

  /* loop through all vectors, we assume there are only node vectors ! */
  for (theVector=FIRSTVECTOR(theGrid); theVector!= NULL; theVector=SUCCVC(theVector))
  {
    VINDEX(theVector) = n++;             /* renumber vectors just to be sure ... */
    /* now speed through this row */
    for (theMatrix=VSTART(theVector); theMatrix!=NULL; theMatrix = MNEXT(theMatrix))
      nonzeros++;
  }

#ifdef ModelP
  if (me == master)
  {
#endif
  /* now allocate fine grid vectors x and b */
  theAMGC->x = AMG_NewVector(n*blocksize,1,"x");
  if (theAMGC->x==NULL) {
    UserWrite("no memory for x\n");
    goto exit;
  }
  theAMGC->b = AMG_NewVector(n*blocksize,1,"b");
  if (theAMGC->b==NULL) {
    UserWrite("no memory for b\n");
    goto exit;
  }

  /* and a new matrix */
  theAMGC->A = AMG_NewMatrix(n*blocksize,1,nonzeros*blocksize*blocksize,blocksize,"fine grid A");
  if (theAMGC->A==NULL) {
    UserWrite("no memory for A\n");
    goto exit;
  }
                #ifdef ModelP
}
else
{
  /* no master vectors allowed */
  assert(n==0);
  /* only master builds up coarse levels */
  return (0);
}
                #endif

  /* now fill matrix */
  for (theVector=FIRSTVECTOR(theGrid); theVector!= NULL; theVector=SUCCVC(theVector))
  {
    i = VINDEX(theVector);

    /* count row length */
    nonzeros=0;
    for (theMatrix=VSTART(theVector); theMatrix!=NULL; theMatrix = MNEXT(theMatrix))
      nonzeros++;

    /* for each row */
    for (block_i=0; block_i<blocksize; block_i++)
    {
      /* allocate row */
      if (AMG_SetRowLength(theAMGC->A,i*blocksize+block_i,nonzeros*blocksize)!=AMG_OK)
      {
        UserWrite("Error in AMG_SetRowLength\n");
        goto exit;
      }

      /* the diagonal block, be careful to allocate the main diagonal first */
      theMatrix=VSTART(theVector);
      if (AMG_InsertValues(theAMGC->A,i*blocksize+block_i,i*blocksize+block_i,
                           &(MVALUE(theMatrix,Acomp+block_i*blocksize+block_i)))<0)
      {
        UserWrite("Error in AMG_InsertValues\n");
        goto exit;
      }
      for (block_j=0; block_j<blocksize; block_j++)
      {
        if (block_j==block_i) continue;
        if (AMG_InsertValues(theAMGC->A,i*blocksize+block_i,i*blocksize+block_j,
                             &(MVALUE(theMatrix,Acomp+block_i*blocksize+block_j)))<0)
        {
          UserWrite("Error in AMG_InsertValues\n");
          goto exit;
        }
      }

      /* all the offdiagonal blocks */
      for (theMatrix=MNEXT(VSTART(theVector)); theMatrix!=NULL; theMatrix = MNEXT(theMatrix))
      {
        j = VINDEX(MDEST(theMatrix));
        for (block_j=0; block_j<blocksize; block_j++)
        {
          if (AMG_InsertValues(theAMGC->A,i*blocksize+block_i,j*blocksize+block_j,
                               &(MVALUE(theMatrix,Acomp+block_i*blocksize+block_j)))<0)
          {
            UserWrite("Error in AMG_InsertValues\n");
            goto exit;
          }
        }
      }
    }
  }
  /*AMG_PrintMatrix(theAMGC->A,"Matrix");*/

  /* call algebraic multigrid solver */
  if (AMG_Build(&theAMGC->sc,&theAMGC->cc,theAMGC->A)!=AMG_OK) theAMGC->AMG_Build_failed=1;
  theAMGC->AMG_Build_failed=0;
  CSTOP(ti,ii);
  if (theAMGC->sc.verbose>0)
    UserWriteF("AMG : L=%2d BUILD=%10.4g\n",level,ti);

  return(0);       /* ok, matrix is set up */

exit: /* error */
  if (mark_counter>0) {
                #ifndef DYNAMIC_MEMORY_ALLOCMODEL
    Release(MGHEAP(theMG),FROM_BOTTOM,amg_MarkKey);
                #else
    Release(MGHEAP(theMG),FROM_TOP,amg_MarkKey);
                #endif
    mark_counter--;
  }
  return(1);
}
Пример #10
0
Файл: npcheck.c Проект: rolk/ug
INT NS_DIM_PREFIX CheckNP (MULTIGRID *theMG, INT argc, char **argv)
{
  MATDATA_DESC *A;
  VECDATA_DESC *x,*y;
  INT i,level,nerr;
  char value[VALUELEN];
  VEC_SCALAR damp;
  DOUBLE nrm,diff;

  if (ReadArgvChar("A",value,argc,argv) == 0) {
    A = GetMatDataDescByName(theMG,value);
    if (A == NULL) {
      UserWriteF("ERROR: no matrix %s in npckeck\n",value);
      return(1);
    }
    if (ReadArgvOption("S",argc,argv)) {
      for (level=theMG->bottomLevel; level<=TOPLEVEL(theMG); level++)
        if (CheckSymmetryOfMatrix(GRID_ON_LEVEL(theMG,level),A))
          UserWriteF("matrix %s not symmetric on level %d\n",
                     ENVITEM_NAME(A),level);
      return(0);
    }
    if (ReadArgvOption("G",argc,argv)) {
      if (ReadArgvChar("x",value,argc,argv)) {
        UserWriteF("ERROR: no vector in npckeck\n");
        return(1);
      }
      x = GetVecDataDescByName(theMG,value);
      if (x == NULL) {
        UserWriteF("ERROR: no vector %s in npckeck\n",value);
        return(1);
      }
      level = CURRENTLEVEL(theMG);
      if (level == BOTTOMLEVEL(theMG)) {
        UserWriteF("ERROR: no GalerkinCheck,"
                   "level %d is bottomlevel\n",level);
        return(1);
      }
      if (AllocVDFromVD(theMG,level-1,level,x,&y))
        return(1);
      dmatset(theMG,level-1,level-1,ALL_VECTORS,A,0.0);
      dset(theMG,level,level,ALL_VECTORS,x,0.0);
      dset(theMG,level-1,level,ALL_VECTORS,y,0.0);
      AssembleGalerkinByMatrix(GRID_ON_LEVEL(theMG,level),A,0);
      for (i=0; i<VD_NCOMP(x); i++) damp[i] = 1.0;
      InterpolateCorrectionByMatrix(GRID_ON_LEVEL(theMG,level),x,x,damp);
      if (dmatmul(theMG,level,level,ALL_VECTORS,y,A,x) != NUM_OK)
        return(1);
      RestrictByMatrix(GRID_ON_LEVEL(theMG,level),y,y,damp);
      IFDEBUG(np,1)
      UserWriteF("x %d\n",level-1);
      PrintVector(GRID_ON_LEVEL(theMG,level-1),x,3,3);
      UserWriteF("x %d\n",level);
      PrintVector(GRID_ON_LEVEL(theMG,level),x,3,3);
      UserWriteF("y %d\n",level);
      PrintVector(GRID_ON_LEVEL(theMG,level),y,3,3);
      UserWriteF("y %d\n",level-1);
      PrintVector(GRID_ON_LEVEL(theMG,level-1),y,3,3);
      ENDDEBUG
      if (dmatmul_minus(theMG,level-1,level-1,ALL_VECTORS,y,A,x)!=NUM_OK)
        return(1);
      IFDEBUG(np,1)
      UserWriteF("y %d\n",level-1);
      PrintVector(GRID_ON_LEVEL(theMG,level-1),y,3,3);
      ENDDEBUG
      dnrm2(theMG,level-1,level-1,ALL_VECTORS,x,&nrm);
      dnrm2(theMG,level-1,level-1,ALL_VECTORS,y,&diff);
      UserWriteF("Galerkin test: nrm(x) = %f nrm(Ax-RAPx) = %f\n",
                 nrm,diff);
      return(0);
    }
  }
Пример #11
0
static INT SendSolution (MULTIGRID *theMG, COVISE_HEADER *covise, INT idx_sol)
{
  INT l, remaining, sent, n_comp_sol;
  TokenBuffer tb;
  Message* msg = new Message;
  msg->type = (covise_msg_type)0;

  printf("CoviseIF: SendSolution start, idx_sol=%d\n", idx_sol);

  n_comp_sol = covise->solutions[idx_sol].n_components;

  /* reset vertex flags */
  ResetVertexFlags(theMG, covise->min_level, covise->max_level);


  /* start first buffer */
  tb.reset();
  remaining = MIN(covise->n_vertices,MAX_ITEMS_SENT);
  tb << MT_UGSCALAR;
  tb << idx_sol;
  tb << remaining;
  sent = 0;


  /* extract data, loop from max_level to min_level! */
  /* TODO: special handling in ModelP */
  for (l=covise->max_level; l>=covise->min_level; l--)
  {
    NODE *theNode;
    GRID *theGrid = GRID_ON_LEVEL(theMG,l);

    for (theNode=FIRSTNODE(theGrid); theNode!=NULL; theNode=SUCCN(theNode))
    {
      VECTOR *theVector;
      INT i;
      INT vid;

      if (USED(MYVERTEX(theNode))) continue;
      SETUSED(MYVERTEX(theNode),1);


      /* NOTE: vid is sent along with data! this increases msg sizes, but
         is the secure solution (resistent to message order a.s.o.) */
      vid = ID(MYVERTEX(theNode));
      tb << (INT32)vid;

      theVector = NVECTOR(theNode);

      /* extract data from vector */
      for(i=0; i<n_comp_sol; i++)
      {
        INT comp = covise->solutions[idx_sol].comps[i];
        tb << (FLOAT32) VVALUE(theVector,comp);
      }

      remaining--;
      sent++;

      if (remaining==0)
      {
        /* send this buffer */
        msg->data = (char*)tb.get_data();
        msg->length = tb.get_length();
        covise_connection->send_msg(msg);

        /* start next buffer */
        tb.reset();
        remaining = MIN(covise->n_vertices - sent, MAX_ITEMS_SENT);
        tb << MT_UGSCALAR;
        tb << idx_sol;
        tb << remaining;
      }
    }
  }

  delete msg;
  printf("CoviseIF: SendSolution stop\n");
  return(0);
}
Пример #12
0
static INT SendSurfaceGrid (MULTIGRID *theMG, COVISE_HEADER *covise)
{
  INT l, remaining, sent;
  TokenBuffer tb;
  Message* msg = new Message;
  msg->type = (covise_msg_type)0;
  printf("CoviseIF: SendSurfaceGrid start\n");

  /* renumber vertex IDs */
  /* TODO doesn't work in ModelP */
  RenumberVertices(theMG, covise->min_level, covise->max_level);

  /* send surface vertices, part1: set flags */
  ResetVertexFlags(theMG, covise->min_level, covise->max_level);

  /* send surface vertices, part2: send data */
  sent = 0;

  /* start first buffer */
  tb.reset();
  remaining = MIN(covise->n_vertices,MAX_ITEMS_SENT);
  tb << MT_UGGRIDV;
  tb << remaining;

  for (l=covise->min_level; l<=covise->max_level; l++)
  {
    NODE *theNode;
    GRID *theGrid = GRID_ON_LEVEL(theMG,l);

    for (theNode=FIRSTNODE(theGrid); theNode!=NULL; theNode=SUCCN(theNode))
    {
      INT vid;
      DOUBLE *pos;

      if (USED(MYVERTEX(theNode))) continue;
      SETUSED(MYVERTEX(theNode),1);

      /* extract data from vertex */
      /* TODO use VXGID in ModelP */
      vid = ID(MYVERTEX(theNode));
      pos = CVECT(MYVERTEX(theNode));

      tb << (INT32)vid;
      tb << (FLOAT32)pos[0];
      tb << (FLOAT32)pos[1];
      tb << (FLOAT32)pos[2];
      remaining--;
      sent++;

      if (remaining==0)
      {
        /* send this buffer */
        msg->data = (char*)tb.get_data();
        msg->length = tb.get_length();
        covise_connection->send_msg(msg);

        /* start next buffer */
        tb.reset();
        tb << MT_UGGRIDV;
        remaining = MIN(covise->n_vertices - sent, MAX_ITEMS_SENT);
        tb << remaining;
      }
    }
  }

  printf("CoviseIF: SendSurfaceGrid ...\n");

  /* next buffer */
  tb.reset();
  tb << MT_UGGRIDE;
  remaining = MIN(covise->n_elems,MAX_ITEMS_SENT);
  tb << remaining;
  sent = 0;

  /* send surface elems and connectivity */
  for (l=covise->min_level; l<=covise->max_level; l++)
  {
    ELEMENT *theElement;
    GRID *theGrid = GRID_ON_LEVEL(theMG,l);

    for (theElement=FIRSTELEMENT(theGrid);
         theElement!=NULL; theElement=SUCCE(theElement))
    {
      if ((EstimateHere(theElement)) || (l==covise->max_level))
      {
        int i, coe = CORNERS_OF_ELEM(theElement);

        tb << (INT32)coe;

        for (i=0; i<coe; i++)
        {
          NODE *theNode = CORNER(theElement,i);
          INT vid;

          vid = ID(MYVERTEX(theNode));
          /* TODO use VXGID in ModelP */
          tb << (INT32)vid;
        }

        remaining--;
        sent++;

        if (remaining==0)
        {
          /* send this buffer */
          msg->data = (char*)tb.get_data();
          msg->length = tb.get_length();
          covise_connection->send_msg(msg);

          /* start next buffer */
          tb.reset();
          tb << MT_UGGRIDE;
          remaining = MIN(covise->n_elems - sent, MAX_ITEMS_SENT);
          tb << remaining;
        }
      }
    }
  }

  /* cleanup */
  delete msg;

  printf("CoviseIF: SendSurfaceGrid stop\n");
  return(0);
}
Пример #13
0
INT NS_DIM_PREFIX RestrictPartitioning (MULTIGRID *theMG)
{
  INT i,j;
  ELEMENT *theElement;
  ELEMENT *theFather;
  ELEMENT *SonList[MAX_SONS];
  GRID    *theGrid;

  /* reset used flags */
  for (i=TOPLEVEL(theMG); i>=0; i--)
  {
    theGrid = GRID_ON_LEVEL(theMG,i);
    for (theElement=PFIRSTELEMENT(theGrid); theElement!=NULL;
         theElement=SUCCE(theElement))
    {
      SETUSED(theElement,0);
    }
  }

  /* set flags on elements which violate restriction */
  for (i=TOPLEVEL(theMG); i>=0; i--)
  {
    theGrid = GRID_ON_LEVEL(theMG,i);
    for (theElement=FIRSTELEMENT(theGrid); theElement!=NULL;
         theElement=SUCCE(theElement))
    {
      if (GLEVEL(theGrid) == 0) break;
      if (LEAFELEM(theElement) || USED(theElement))
      {
        theFather = theElement;
        while (EMASTER(theFather) && ECLASS(theFather)!=RED_CLASS
               && LEVEL(theFather)>0)
        {
          theFather = EFATHER(theFather);
        }

        /* if father with red refine class is not master */
        /* partitioning must be restricted                */
        if (!EMASTER(theFather))
        {
          /* the sons of father will be sent to partition of father */
          SETUSED(theFather,1);
        }

        /* if element is marked for coarsening and father    */
        /* of element is not master -> restriction is needed */
        if (COARSEN(theFather))
        {
          /* level 0 elements are not coarsened */
          if (LEVEL(theFather)<=1) continue;
          if (!EMASTER(EFATHER(theFather)))
            SETUSED(EFATHER(theFather),1);
        }
      }
    }
    /* transfer restriction flags to master copies of father */
    DDD_IFAOneway(ElementVHIF,GRID_ATTR(theGrid),IF_BACKWARD,sizeof(INT),
                  Gather_ElementRestriction, Scatter_ElementRestriction);
  }

  /* send restricted sons to partition of father */
  for (i=0; i<=TOPLEVEL(theMG); i++)
  {
    theGrid = GRID_ON_LEVEL(theMG,i);

    /* transfer (new) partitions of elements to non master copies */
    DDD_IFAOnewayX(ElementVHIF,GRID_ATTR(theGrid),IF_FORWARD,sizeof(INT),
                   Gather_RestrictedPartition, Scatter_RestrictedPartition);

    for (theElement=PFIRSTELEMENT(theGrid); theElement!=NULL;
         theElement=SUCCE(theElement))
    {
      if (!USED(theElement)) continue;

      /* push partition to the sons */
      GetAllSons(theElement,SonList);
      for (j=0; SonList[j]!=NULL; j++)
      {
        SETUSED(SonList[j],1);
        if (EMASTER(SonList[j]))
          PARTITION(SonList[j]) = PARTITION(theElement);
      }
    }
  }

  if (TransferGrid(theMG) != 0) RETURN(GM_FATAL);

  return(GM_OK);
}
Пример #14
0
Файл: tecplot.c Проект: rolk/ug
static INT TecplotCommand (INT argc, char **argv)
{
  INT i,j,k,v;                                  /* counters etc.							*/
  INT counter;                      /* for formatting output                    */
  char item[1024],it[256];      /* item buffers                             */
  INT ic=0;                     /* item length                              */
  VECTOR *vc;                                           /* a vector pointer							*/
  ELEMENT *el;                                  /* an element pointer						*/

  MULTIGRID *mg;                                /* our multigrid							*/
  char filename[NAMESIZE];      /* file name for output file				*/
  PFILE *pf;                    /* the output file pointer                  */


  INT nv;                                               /* number of variables (eval functions)		*/
  EVALUES *ev[MAXVARIABLES];            /* pointers to eval function descriptors	*/
  char ev_name[MAXVARIABLES][NAMESIZE];         /* names for eval functions     */
  char s[NAMESIZE];                             /* name of eval proc						*/
  char zonename[NAMESIZE+7] = "";               /* name for zone (initialized to
                                                                                empty string)						*/
  INT numNodes;                                 /* number of data points					*/
  INT numElements;                              /* number of elements						*/
  INT gnumNodes;                /* number of data points globally           */
  INT gnumElements;             /* number of elements globallay             */
  PreprocessingProcPtr pre;             /* pointer to prepare function				*/
  ElementEvalProcPtr eval;              /* pointer to evaluation function			*/
  DOUBLE *CornersCoord[MAX_CORNERS_OF_ELEM];       /* pointers to coordinates    */
  DOUBLE LocalCoord[DIM];               /* is one of the corners local coordinates	*/
  DOUBLE local[DIM];                            /* local coordinate in DOUBLE				*/
  DOUBLE value;                                 /* returned by user eval proc				*/
  INT oe,on;

  INT saveGeometry;                             /* save geometry flag						*/


  /* get current multigrid */
  mg = GetCurrentMultigrid();
  if (mg==NULL)
  {
    PrintErrorMessage('W',"tecplot","no multigrid open\n");
    return (OKCODE);
  }

  /* scan options */
  nv = 0; saveGeometry = 0;
  for(i=1; i<argc; i++)
  {
    switch(argv[i][0])
    {
    case 'e' :            /* read eval proc */
      if (nv>=MAXVARIABLES)
      {
        PrintErrorMessage('E',"tecplot","too many variables specified\n");
        break;
      }
      sscanf(argv[i],"e %s", s);
      ev[nv] = GetElementValueEvalProc(s);
      if (ev[nv]==NULL)
      {
        PrintErrorMessageF('E',"tecplot","could not find eval proc %s\n",s);
        break;
      }
      if (sscanf(argv[i+1],"s %s", s) == 1)
      {
        strcpy(ev_name[nv],s);
        i++;
      }
      else
        strcpy(ev_name[nv],ev[nv]->v.name);
      nv++;
      break;

    case 'z' :
      sscanf(argv[i],"z %s", zonename+3);
      memcpy(zonename, "T=\"", 3);
      memcpy(zonename+strlen(zonename), "\", \0", 4);
      break;

    case 'g' :
      sscanf(argv[i],"g %d", &saveGeometry);
      if (saveGeometry<0) saveGeometry=0;
      if (saveGeometry>1) saveGeometry=1;
      break;
    }
  }
  if (nv==0) UserWrite("tecplot: no variables given, printing mesh data only\n");

  /* get file name and open output file */
  if (sscanf(argv[0],expandfmt(CONCAT3(" tecplot %",NAMELENSTR,"[ -~]")),filename)!=1)
  {
    PrintErrorMessage('E',"tecplot","could not read name of logfile");
    return(PARAMERRORCODE);
  }
  pf = pfile_open(filename);
  if (pf==NULL) return(PARAMERRORCODE);

  /********************************/
  /* TITLE                                              */
  /********************************/

  ic = 0;
  sprintf(it,"TITLE = \"UG TECPLOT OUTPUT\"\n");
  strcpy(item+ic,it); ic+=strlen(it);
  sprintf(it,"VARIABLES = \"X\", \"Y\"");
  strcpy(item+ic,it); ic+=strlen(it);
  if (DIM==3) {
    sprintf(it,", \"Z\"");
    strcpy(item+ic,it); ic+=strlen(it);
  }
  for (i=0; i<nv; i++) {
    sprintf(it,", \"%s\"",ev[i]->v.name);
    strcpy(item+ic,it); ic+=strlen(it);
  }
  sprintf(it,"\n");
  strcpy(item+ic,it); ic+=strlen(it);
  pfile_master_puts(pf,item); ic=0;

  /********************************/
  /* compute sizes				*/
  /********************************/

  /* clear VCFLAG on all levels */
  for (k=0; k<=TOPLEVEL(mg); k++)
    for (vc=FIRSTVECTOR(GRID_ON_LEVEL(mg,k)); vc!=NULL; vc=SUCCVC(vc))
      SETVCFLAG(vc,0);

  /* run thru all levels of elements and set index */
  numNodes = numElements = 0;
  for (k=0; k<=TOPLEVEL(mg); k++)
    for (el=FIRSTELEMENT(GRID_ON_LEVEL(mg,k)); el!=NULL; el=SUCCE(el))
    {
      if (!EstimateHere(el)) continue;                          /* process finest level elements only */
      numElements++;                                            /* increase element counter */
      for (i=0; i<CORNERS_OF_ELEM(el); i++)
      {
        vc = NVECTOR(CORNER(el,i));
        if (VCFLAG(vc)) continue;                       /* we have this one already */

        VINDEX(vc) = ++numNodes;                        /* number of data points, begins with 1 ! */
        SETVCFLAG(vc,1);                                        /* tag vector as visited */
      }
    }

        #ifdef ModelP
  gnumNodes = TPL_GlobalSumINT(numNodes);
  gnumElements = TPL_GlobalSumINT(numElements);
  on=get_offset(numNodes);
  oe=get_offset(numElements);

  /* clear VCFLAG on all levels */
  for (k=0; k<=TOPLEVEL(mg); k++)
    for (vc=FIRSTVECTOR(GRID_ON_LEVEL(mg,k)); vc!=NULL; vc=SUCCVC(vc))
      SETVCFLAG(vc,0);

  /* number in unique way */
  for (k=0; k<=TOPLEVEL(mg); k++)
    for (el=FIRSTELEMENT(GRID_ON_LEVEL(mg,k)); el!=NULL; el=SUCCE(el))
    {
      if (!EstimateHere(el)) continue;                          /* process finest level elements only */
      for (i=0; i<CORNERS_OF_ELEM(el); i++)
      {
        vc = NVECTOR(CORNER(el,i));
        if (VCFLAG(vc)) continue;                       /* we have this one already */

        VINDEX(vc) += on;                                       /* add offset */
        SETVCFLAG(vc,1);                                        /* tag vector as visited */
      }
    }
    #else
  gnumNodes = numNodes;
  gnumElements = numElements;
  oe=on=0;
    #endif


  /********************************/
  /* write ZONE data				*/
  /* uses FEPOINT for data		*/
  /* uses QUADRILATERAL in 2D		*/
  /* and BRICK in 3D				*/
  /********************************/

  /* write zone record header */
  if (DIM==2) sprintf(it,"ZONE %sN=%d, E=%d, F=FEPOINT, ET=QUADRILATERAL\n", zonename, gnumNodes,gnumElements);
  if (DIM==3) sprintf(it,"ZONE %sN=%d, E=%d, F=FEPOINT, ET=BRICK\n", zonename, gnumNodes,gnumElements);
  strcpy(item+ic,it); ic+=strlen(it);
  pfile_master_puts(pf,item); ic=0;

  /* write data in FEPOINT format, i.e. all variables of a node per line*/

  for (k=0; k<=TOPLEVEL(mg); k++)
    for (vc=FIRSTVECTOR(GRID_ON_LEVEL(mg,k)); vc!=NULL; vc=SUCCVC(vc))
      SETVCFLAG(vc,0);           /* clear all flags */

  counter=0;
  for (k=0; k<=TOPLEVEL(mg); k++)
    for (el=FIRSTELEMENT(GRID_ON_LEVEL(mg,k)); el!=NULL; el=SUCCE(el))
    {
      if (!EstimateHere(el)) continue;                  /* process finest level elements only */

      for (i=0; i<CORNERS_OF_ELEM(el); i++)
        CornersCoord[i] = CVECT(MYVERTEX(CORNER(el,i)));                        /* x,y,z of corners */

      for (i=0; i<CORNERS_OF_ELEM(el); i++)
      {
        vc = NVECTOR(CORNER(el,i));
        if (VCFLAG(vc)) continue;                       /* we have this one alre ady */
        SETVCFLAG(vc,1);                                /* tag vector as visited */

        sprintf(it,"%g",(double)XC(MYVERTEX(CORNER(el,i))));
        strcpy(item+ic,it); ic+=strlen(it);
        sprintf(it," %g",(double)YC(MYVERTEX(CORNER(el,i))));
        strcpy(item+ic,it); ic+=strlen(it);
        if (DIM == 3)
        {
          sprintf(it," %g",(double)ZC(MYVERTEX(CORNER(el,i))));
          strcpy(item+ic,it); ic+=strlen(it);
        }

        /* now all the user variables */

        /* get local coordinate of corner */
        LocalCornerCoordinates(DIM,TAG(el),i,local);
        for (j=0; j<DIM; j++) LocalCoord[j] = local[j];

        for (v=0; v<nv; v++)
        {
          pre =  ev[v]->PreprocessProc;
          eval = ev[v]->EvalProc;

          /* execute prepare function */
          /* This is not really equivalent to
             the FEBLOCK-version sinc we call "pre" more
             often than there. D.Werner */

          if (pre!=NULL) pre(ev_name[v],mg);

          /* call eval function */
          value = eval(el,(const DOUBLE **)CornersCoord,LocalCoord);
          sprintf(it," %g",value);
          strcpy(item+ic,it); ic+=strlen(it);
        }
        sprintf(it,"\n");
        strcpy(item+ic,it); ic+=strlen(it);
        pfile_tagged_puts(pf,item,counter+on); ic=0;
        counter++;
      }
    }
  pfile_sync(pf);       /* end of segment */

  sprintf(it,"\n");
  strcpy(item+ic,it); ic+=strlen(it);
  pfile_master_puts(pf,item); ic=0;

  /* finally write the connectivity list */
  counter=0;
  for (k=0; k<=TOPLEVEL(mg); k++)
    for (el=FIRSTELEMENT(GRID_ON_LEVEL(mg,k)); el!=NULL; el=SUCCE(el))
    {
      if (!EstimateHere(el)) continue;           /* process finest level elements only */

      switch(DIM) {
      case 2 :
        switch(TAG(el)) {
        case TRIANGLE :
          sprintf(it,"%d %d %d %d\n",
                  VINDEX(NVECTOR(CORNER(el,0))),
                  VINDEX(NVECTOR(CORNER(el,1))),
                  VINDEX(NVECTOR(CORNER(el,2))),
                  VINDEX(NVECTOR(CORNER(el,2)))
                  );
          break;
        case QUADRILATERAL :
          sprintf(it,"%d %d %d %d\n",
                  VINDEX(NVECTOR(CORNER(el,0))),
                  VINDEX(NVECTOR(CORNER(el,1))),
                  VINDEX(NVECTOR(CORNER(el,2))),
                  VINDEX(NVECTOR(CORNER(el,3)))
                  );
          break;
        default :
          UserWriteF("tecplot: unknown 2D element type with tag(el) = %d detected. Aborting further processing of command tecplot\n", TAG(el));
          return CMDERRORCODE;
          break;
        }
        break;
      case 3 :
        switch(TAG(el)) {
        case HEXAHEDRON :
          sprintf(it,"%d %d %d %d "
                  "%d %d %d %d\n",
                  VINDEX(NVECTOR(CORNER(el,0))),
                  VINDEX(NVECTOR(CORNER(el,1))),
                  VINDEX(NVECTOR(CORNER(el,2))),
                  VINDEX(NVECTOR(CORNER(el,3))),
                  VINDEX(NVECTOR(CORNER(el,4))),
                  VINDEX(NVECTOR(CORNER(el,5))),
                  VINDEX(NVECTOR(CORNER(el,6))),
                  VINDEX(NVECTOR(CORNER(el,7)))
                  );
          break;
        case TETRAHEDRON :
          sprintf(it,"%d %d %d %d "
                  "%d %d %d %d\n",
                  VINDEX(NVECTOR(CORNER(el,0))),
                  VINDEX(NVECTOR(CORNER(el,1))),
                  VINDEX(NVECTOR(CORNER(el,2))),
                  VINDEX(NVECTOR(CORNER(el,2))),
                  VINDEX(NVECTOR(CORNER(el,3))),
                  VINDEX(NVECTOR(CORNER(el,3))),
                  VINDEX(NVECTOR(CORNER(el,3))),
                  VINDEX(NVECTOR(CORNER(el,3)))
                  );
          break;
        case PYRAMID :
          sprintf(it,"%d %d %d %d "
                  "%d %d %d %d\n",
                  VINDEX(NVECTOR(CORNER(el,0))),
                  VINDEX(NVECTOR(CORNER(el,1))),
                  VINDEX(NVECTOR(CORNER(el,2))),
                  VINDEX(NVECTOR(CORNER(el,3))),
                  VINDEX(NVECTOR(CORNER(el,4))),
                  VINDEX(NVECTOR(CORNER(el,4))),
                  VINDEX(NVECTOR(CORNER(el,4))),
                  VINDEX(NVECTOR(CORNER(el,4)))
                  );
          break;
        case PRISM :
          sprintf(it,"%d %d %d %d "
                  "%d %d %d %d\n",
                  VINDEX(NVECTOR(CORNER(el,0))),
                  VINDEX(NVECTOR(CORNER(el,1))),
                  VINDEX(NVECTOR(CORNER(el,2))),
                  VINDEX(NVECTOR(CORNER(el,2))),
                  VINDEX(NVECTOR(CORNER(el,3))),
                  VINDEX(NVECTOR(CORNER(el,4))),
                  VINDEX(NVECTOR(CORNER(el,5))),
                  VINDEX(NVECTOR(CORNER(el,5)))
                  );
          break;
        default :
          UserWriteF("tecplot: unknown 3D element type with tag(el) = %d detected. Aborting further processing of command tecplot\n", TAG(el));
          return CMDERRORCODE;
          break;
        }
        break;
      }
      strcpy(item+ic,it); ic+=strlen(it);
      pfile_tagged_puts(pf,item,counter+oe); ic=0;
      counter++;

    }

  pfile_sync(pf);       /* end of segment */

  /********************************/
  /* GEOMETRY                                   */
  /* we will do this later, since */
  /* domain interface will change */
  /********************************/

  pfile_close(pf);

  return(OKCODE);
}