void getDump(char *buf, size_t len, const char *prefix,
        const msm_rotator_data_info& rot) {
    char str[256] = {'\0'};
    snprintf(str, 256,
            "%s sessid=%u\n",
            prefix, rot.session_id);
    strlcat(buf, str, len);
    getDump(buf, len, "\tsrc", rot.src);
    getDump(buf, len, "\tdst", rot.dst);
}
void getDump(char *buf, size_t len, const char *prefix,
        const msm_rotator_img_info& rot) {
    char str[256] = {'\0'};
    snprintf(str, 256, "%s sessid=%u rot=%d, enable=%d downscale=%d\n",
            prefix, rot.session_id, rot.rotations, rot.enable,
            rot.downscale_ratio);
    strlcat(buf, str, len);
    getDump(buf, len, "\tsrc", rot.src);
    getDump(buf, len, "\tdst", rot.dst);
    getDump(buf, len, "\tsrc_rect", rot.src_rect);
}
void getDump(char *buf, size_t len, const char *prefix,
        const mdp_overlay& ov) {
    char str[256] = {'\0'};
    snprintf(str, 256,
            "%s id=%d z=%d alpha=%d mask=%d flags=0x%x H.Deci=%d,"
            "V.Deci=%d\n",
            prefix, ov.id, ov.z_order, ov.alpha,
            ov.transp_mask, ov.flags, ov.horz_deci, ov.vert_deci);
    strlcat(buf, str, len);
    getDump(buf, len, "\tsrc", ov.src);
    getDump(buf, len, "\tsrc_rect", ov.src_rect);
    getDump(buf, len, "\tdst_rect", ov.dst_rect);
}
Example #4
0
int main (int    argc,
	  char** argv)
// ---------------------------------------------------------------------------
// Driver.
// ---------------------------------------------------------------------------
{
  int_t            i, order = 2;
  real_t           roll = 0.0;
  char             type = 'B';
  istream*         input;
  vector<Data2DF*> u;

  Femlib::initialize (&argc, &argv);
  getargs (argc, argv, type, order, roll, input);
 
  while (getDump (*input, cout, u))
    for (i = 0; i < u.size(); i++) {
      if (type == 'P' || type == 'B')
	u[i] -> filter2D (roll, order);
      if (type == 'F' || type == 'B')
	u[i] -> DFT1D (FORWARD) . filter1D (roll, order) . DFT1D (INVERSE);
      cout << *u[i];
    }
  
  Femlib::finalize();
  return EXIT_SUCCESS;
}
void getDump(char *buf, size_t len, const char *prefix,
        const msmfb_overlay_data& ov) {
    char str[256] = {'\0'};
    snprintf(str, 256,
            "%s id=%d\n",
            prefix, ov.id);
    strlcat(buf, str, len);
    getDump(buf, len, "\tdata", ov.data);
}
Example #6
0
int main (int    argc,
	  char** argv)
// ---------------------------------------------------------------------------
// Driver.
// ---------------------------------------------------------------------------
{
  Geometry::CoordSys         system;
  char                       *session, *dump, *func, fields[StrMax];
  int_t                      i, j, k, p, q;
  int_t                      np, nz, nel, allocSize, NCOM, NDIM;
  int_t                      iAdd = 0;
  bool                       add[FLAG_MAX], need[FLAG_MAX], gradient;
  ifstream                   file;
  FEML*                      F;
  Mesh*                      M;
  BCmgr*                     B;
  Domain*                    D;
  vector<Element*>           elmt;
  AuxField                   *Ens, *Hel, *Div, *Disc, *Strain;
  AuxField                   *Func, *Vtx, *DivL, *Nrg, *work;
  vector<AuxField*>          velocity, vorticity, lamb, addField(FLDS_MAX);
  vector<vector<AuxField*> > Vij;     // -- Usually computed, for internal use.
  vector<vector<real_t*> >   VijData; // -- For pointwise access in Vij.

  vector<real_t*> VorData; // -- Ditto in vorticity.
  vector<real_t*> LamData; // -- Ditto in Lamb vector.

  real_t          *DisData, *DivData, *StrData, *VtxData, *HelData, *EnsData;
  real_t          vel[3], vort[3], tensor[9];

  Femlib::initialize (&argc, &argv);
  for (i = 0; i < FLAG_MAX; i++) add [i] = need [i] = false;

  // -- Read command line.

  getargs (argc, argv, session, dump, func, add);

  file.open (dump);
  if (!file) message (prog, "can't open input field file", ERROR);

  // -- Set up domain.

  F      = new FEML (session);
  M      = new Mesh (F);
  nel    = M -> nEl ();  
  np     =  Femlib::ivalue ("N_P");
  nz     =  Femlib::ivalue ("N_Z");
  system = (Femlib::ivalue ("CYLINDRICAL") ) ?
                       Geometry::Cylindrical : Geometry::Cartesian;
  Geometry::set (np, nz, nel, system);

  allocSize = Geometry::nTotal();

  elmt.resize (nel);
  for (i = 0; i < nel; i++) elmt[i] = new Element (i, np, M);

  B = new BCmgr  (F, elmt);
  D = new Domain (F, elmt, B);

  if      (strstr (D -> field, "uvw")) NCOM = 3;
  else if (strstr (D -> field, "uv"))  NCOM = 2;
  else message (prog, "lacking velocity components: is session valid?", ERROR);
  NDIM = Geometry::nDim();

  velocity.resize   (NCOM);
  vorticity.resize ((NDIM == 2) ? 1 : 3);
  for (i = 0; i < NCOM; i++) velocity[i] = D -> u[i];

  // -- From the requested fields, flag dependencies.

  // -- First, only allow the "coherent structures" measures for flows
  //    that are 3D.

  if  (NDIM == 2)
    add[HELICITY]=add[DISCRIMINANT]=add[VORTEXCORE]=add[DIVLAMB] = false;

  for (p = 0, i = 0; i < FLAG_MAX; i++) p += (add[i]) ? 1 : 0;
  if  (p == 0) message (prog, "nothing to be done", ERROR);

  // -- Check if we just have the (first two) cases not requiring derivatives.

  for (p = 0, i = 0; i < FLAG_MAX; i++) p += (add[i]) ? (i + 1) : 0;
  if (p <= 2) gradient = false; else gradient = true;

  for (i = 0; i < FLAG_MAX; i++) need[i] = add[i];

  // -- If any gradients need to be computed, we make all of them.
  //    Vij = du_j/dx_i.  So j labels velocity component and i labels
  //    spatial dimension.

  // -- Despite the fact that it's overkill we will take the
  //    simple-minded approach and always make Vij as a 3x3 tensor.
  //    That's a wasteful for anything which is 2D but presumably for
  //    those cases the memory can be afforded.

  // -- The velocity gradient tensor is initially just a naive matrix
  //    of derivatives.  In cylindrical coordinates we need to make
  //    modifications.
  
  if (gradient) {
    Vij    .resize (3);
    VijData.resize (3);
    for (i = 0; i < 3; i++) {
      Vij    [i].resize (3);
      VijData[i].resize (3);
      for (j = 0; j < 3; j++) {
	VijData[i][j] = new real_t [allocSize];
	Vij    [i][j] = new AuxField (VijData[i][j], nz, elmt);
	*Vij   [i][j] = 0.0;
      }
    }
  }
  
  // -- Fields without dependants.

  if (need[ENERGY]) {
    Nrg = new AuxField (new real_t[allocSize], nz, elmt, 'q');
    addField[iAdd++] = Nrg;
  }

  if (need[FUNCTION]) {
    Func = new AuxField (new real_t[allocSize], nz, elmt, 'f');
    addField[iAdd++] = Func;
  }

  if (need[DIVERGENCE]) {
    DivData = new real_t [allocSize];
    *(Div  =  new AuxField (DivData, nz, elmt, 'd')) = 0.0;
    addField[iAdd++] = Div;
  }

  if (need[DISCRIMINANT]) {
    DisData = new real_t [allocSize];
    *(Disc = new AuxField (DisData, nz, elmt, 'D')) = 0.0;
    addField[iAdd++] = Disc;
  }

  if (need[STRAINRATE]) {
    StrData = new real_t [allocSize];
    Strain  = new AuxField (StrData, nz, elmt, 'g');
    addField[iAdd++] = Strain;
  }

  if (need[VORTEXCORE]) {
    VtxData = new real_t [allocSize];
    Vtx = new AuxField (VtxData, nz, elmt, 'J');
    addField[iAdd++] = Vtx;
  }

  if (need[VORTICITY])
    if (NDIM == 2) {
      vorticity.resize (1);
      VorData  .resize (1);
      VorData[0]       = new real_t [allocSize];
      vorticity[0]     = new AuxField (VorData[0], nz, elmt, 't');
      addField[iAdd++] = vorticity[0];
    } else {
      vorticity.resize (3);
      VorData  .resize (3);
      for (i = 0; i < 3; i++) {
	VorData[i]       = new real_t [allocSize];
	vorticity[i]     = new AuxField (VorData[i], nz, elmt, 'r' + i);
	addField[iAdd++] = vorticity[i];
      }
    }

  if (add[DIVLAMB]) { 		// -- Know also NDIM == 3.
    lamb   .resize (3);
    LamData.resize (3);
    for (i = 0; i < 3; i++) {
      LamData[i] = new real_t [allocSize];
      lamb[i]    = new AuxField (LamData[i], nz, elmt, 'L');
    }
    addField[iAdd++] = lamb[0];	// -- Where divergence will get stored.
  }

  if (need[ENSTROPHY]) {
    EnsData = new real_t[allocSize];
    Ens = new AuxField (EnsData, nz, elmt, 'e');
    if (add[ENSTROPHY]) addField[iAdd++] = Ens;
  }
  
  if (need[HELICITY]) {
    HelData = new real_t [allocSize];
    Hel = new AuxField (HelData, nz, elmt, 'H');
    if (add[HELICITY]) addField[iAdd++] = Hel;
  }

  // -- Cycle through field dump, first (if required) making the only
  //    two things which just need the velocity and no gradients, then
  //    if needed computing the full VG tensor and work forward from
  //    there.  The order of computation is determined by
  //    dependencies.  Then write requested output, listed in
  //    addField.
  
  while (getDump (D, file)) {
        
    if (need[FUNCTION]) *Func = func;

    if (need[ENERGY]) ((*Nrg) . innerProduct (velocity, velocity)) *= 0.5;

    if (gradient) {		// -- All other things.

      // -- First make all VG components.

      for (i = 0; i < NDIM ; i++)
	for (j = 0; j < NCOM ; j++) {
	  *Vij[i][j] = *velocity[j];
	  if (i == 2) Vij[i][j] -> transform (FORWARD);
	  Vij[i][j] -> gradient (i);
	  if (i == 2) Vij[i][j] -> transform (INVERSE);
	}

      if (Geometry::cylindrical()) {
	work = new AuxField (new real_t[allocSize],  nz, elmt);
	if (NDIM == 3) for (j = 0; j < NCOM; j++) Vij[2][j] -> divY();
	(*work = *velocity[1]) . divY(); *Vij[2][2] += *work;
#if 1
	if (NCOM == 3) { (*work = *velocity[2]) . divY(); *Vij[1][2] += *work; }
#else
	if (NCOM == 3) { (*work = *velocity[2]) . divY(); *Vij[1][2] -= *work; }
#endif
      }

#if 1
      // -- Loop over every point in the mesh and compute everything
      //    from Vij.  Quite likely this could be made more efficient
      //    but for now simplicity is the aim.

      for (i = 0; i < allocSize; i++) {

	for (k = 0, p = 0; p < 3; p++) {
	  for (q = 0; q < 3; q++, k++)
	    tensor [k] = VijData [p][q][i];
	}

	// -- These operations produce a simple scalar result from Vij.

	if (need[DIVERGENCE])   DivData[i] = tensor3::trace      (tensor);
	if (need[ENSTROPHY])    EnsData[i] = tensor3::enstrophy  (tensor);
	if (need[DISCRIMINANT]) DisData[i] = tensor3::discrimi   (tensor);
	if (need[STRAINRATE])   StrData[i] = tensor3::strainrate (tensor);
	if (need[VORTEXCORE])   VtxData[i] = tensor3::lambda2    (tensor);

	// -- Vorticity could be considered scalar in 2D.

	if (need[VORTICITY]) {
	  tensor3::vorticity (tensor, vort);
	  if (NDIM == 2) 
	    VorData[0][i] = vort[2];
	  else { 
	    VorData[0][i] = vort[0]; 
	    VorData[1][i] = vort[1]; 
	    VorData[2][i] = vort[2];
	  }
	}

	if (!(need[HELICITY] || need[DIVLAMB])) continue;

	// -- Last two measures need velocity too, only made for NDIM = 3.

	vel[0] = velocity[0] -> data()[i];
	vel[1] = velocity[1] -> data()[i];
	vel[2] = velocity[2] -> data()[i];

	if (need[HELICITY]) HelData[i] = tensor3::helicity (tensor, vel);


	if (need[DIVLAMB]) {
	  tensor3::lambvector (tensor, vel, vort); // -- vort is a dummy.
	  LamData[0][i] = vort[0]; 
	  LamData[1][i] = vort[1]; 
	  LamData[2][i] = vort[2];
	}
      }

      // -- For this case, we still need to compute a divergence:
      
      if (need[DIVLAMB]) {
	lamb[0] -> gradient (0);
	(*lamb[2]) . transform (FORWARD) . gradient (2) . transform(INVERSE);
	if (Geometry::cylindrical()) lamb[2] -> divY();
	*lamb[0] += *lamb[2];
	if (Geometry::cylindrical()) *lamb[0] += (*lamb[2] = *lamb[1]) . divY();
	*lamb[0] += (*lamb[1]) . gradient (1);
      }
    }
#else

      if (need[DISCRIMINANT]) {

	// -- 2nd invariant (Q from Chong et al.).
	
	InvQ -> times      (*Vij[0][0], *Vij[1][1]);
	InvQ -> timesMinus (*Vij[0][1], *Vij[1][0]);
	InvQ -> timesPlus  (*Vij[0][0], *Vij[2][2]);

	InvQ -> timesMinus (*Vij[0][2], *Vij[2][0]);
	InvQ -> timesPlus  (*Vij[1][1], *Vij[2][2]);
	InvQ -> timesMinus (*Vij[1][2], *Vij[2][1]);

	// -- 3rd invariant: determinant of Vij (R from Chong et al.).

	work -> times      (*Vij[1][1], *Vij[2][2]);
	work -> timesMinus (*Vij[2][1], *Vij[1][2]);
	InvR -> times      (*work,      *Vij[0][0]);

	work -> times      (*Vij[1][2], *Vij[2][0]);
	work -> timesMinus (*Vij[2][2], *Vij[1][0]);
	InvR -> timesPlus  (*work,      *Vij[0][1]);

	work -> times      (*Vij[2][1], *Vij[1][0]);
	work -> timesMinus (*Vij[1][1], *Vij[2][0]);
	InvR -> timesPlus  (*work,      *Vij[0][2]);

	// -- Discriminant L of Vij.
	//    NB: DIVERGENCE (P from Chong et al.) ASSUMED = 0.

	work -> times (*InvQ, *InvQ);
	Disc -> times (*work, *InvQ);
	work -> times (*InvR, *InvR);
	*work *= 6.75;
	*Disc += *work;
      }

      if (need[DIVERGENCE])
	for (i = 0; i < nComponent; i++) *Div += *Vij[i][i];

    
      if (need[VORTICITY]) {
	if (nComponent == 2) {
	  *vorticity[0]  = *Vij[1][0];
	  *vorticity[0] -= *Vij[0][1];
	} else {
	  *vorticity[0]  = *Vij[2][1];
	  *vorticity[0] -= *Vij[1][2];
	  *vorticity[1]  = *Vij[0][2];
	  *vorticity[1] -= *Vij[2][0];
	  *vorticity[2]  = *Vij[1][0];
	  *vorticity[2] -= *Vij[0][1];
	}
      }

      if (need[DIVLAMB]) {
	if (nComponent == 2) {
	  *lamb[0] = 0.0;
	  lamb[0] -> timesMinus (*D -> u[1], *vorticity[0]);
	  lamb[1] -> times      (*D -> u[0], *vorticity[0]);
	  *DivL  = (*work = *lamb[0]) . gradient (0);
	  *DivL += (*work = *lamb[1]) . gradient (1);
	  if (Geometry::cylindrical())
	    *DivL += (*work = *lamb[1]) . divY();
	} else {
	  lamb[0] -> times      (*D -> u[2], *vorticity[1]);
	  lamb[0] -> timesMinus (*D -> u[1], *vorticity[2]);
	  lamb[1] -> times      (*D -> u[0], *vorticity[2]);
	  lamb[1] -> timesMinus (*D -> u[2], *vorticity[0]);
	  lamb[2] -> times      (*D -> u[1], *vorticity[0]);
	  lamb[2] -> timesMinus (*D -> u[0], *vorticity[1]);
	  *DivL  = (*work = *lamb[0]) . gradient (0);
	  *DivL += (*work = *lamb[1]) . gradient (1);
	  (*work = *lamb[2]).transform(FORWARD).gradient(2).transform(INVERSE);
	  if (Geometry::cylindrical()) {
	    *DivL += work -> divY();
	    *DivL += (*work = *lamb[1]) . divY();
	  } else
	    *DivL += *work;
	}
      }
    
      if (need[ENSTROPHY])
	Ens -> innerProduct (vorticity, vorticity) *= 0.5;

      if (need[HELICITY])
	Hel -> innerProduct (vorticity, velocity)  *= 0.5;

      if (need[STRAINTENSOR]) {
	for (i = 0; i < nComponent; i++)
	  for (j = i; j < nComponent; j++) {
	    *Sij[i][j]  = *Vij[i][j];
	    *Sij[i][j] += *Vij[j][i];
	    *Sij[i][j] *= 0.5;
	  }
      }

      if (need[STRAINRATE]) {
	*Strain = 0.0;
	for (i = 0; i < nComponent; i++)
	  for (j = 0; j < nComponent; j++)
	    Strain -> timesPlus (*Sij[i][j], *Sij[j][i]);
	(*Strain *= 2.0) . sqroot();
      }

      if (need[VORTEXCORE])	// -- Only done for 3-component fields.
	for (i = 0; i < allocSize; i++) {
	  for (k = 0, p = 0; p < 3; p++)
	    for (q = 0; q < 3; q++, k++)
	      tensor [k] = VijData[p][q][i];
	  VtxData[i] = lambda2 (tensor);
	}
    }
#endif
    // -- Finally, add mass-projection smoothing on everything.

    for (i = 0; i < iAdd; i++) D -> u[0] -> smooth (addField[i]);

    putDump (D, addField, iAdd, cout);
  }
Example #7
0
int main (int    argc,
	  char** argv)
// ---------------------------------------------------------------------------
// Driver.
// ---------------------------------------------------------------------------
{
  char              *session, *dump, *points = 0;
  int_t             NP, NZ,  NEL;
  int_t             np, nel, ntot;
  int_t             i, j, k, nf, step;
  ifstream          fldfile;
  istream*          pntfile;
  FEML*             F;
  Mesh*             M;
  real_t            c, time, timestep, kinvis, beta;
  vector<real_t>    r, s;
  vector<Point*>    point;
  vector<Element*>  elmt;
  vector<Element*>  Esys;
  vector<AuxField*> u;

  // -- Initialize.

  Femlib::initialize (&argc, &argv);
  getargs            (argc, argv, session, dump, points);

  fldfile.open (dump, ios::in);
  if (!fldfile) message (prog, "no field file", ERROR);

  // -- Set up 2D mesh information.
  
  F   = new FEML (session);
  M   = new Mesh (F);

  NEL = M -> nEl();  
  NP  = Femlib::ivalue ("N_P");
  NZ  = Femlib::ivalue ("N_Z");
  
  Geometry::set (NP, NZ, NEL, Geometry::Cartesian);
  Esys.resize   (NEL);

  for (k = 0; k < NEL; k++) Esys[k] = new Element (k, NP, M);
  
  // -- Construct the list of points, then find them in the Mesh.

  if (points) {
    pntfile = new ifstream (points);
    if (pntfile -> bad())
      message (prog, "unable to open point file", ERROR);
  } else 
    pntfile = &cin;

  np = nel = ntot = 0;

  loadPoints (*pntfile, np, nel, ntot, point);
  findPoints (point, Esys, elmt, r, s);

  // -- Load field file, interpolate within it.

  cout.precision (8);
  while (getDump (fldfile, u, Esys, NP, NZ, NEL,
		  step, time, timestep, kinvis, beta)) {

    if (np) putHeader (session, u,  np, NZ, nel,
		       step, time, timestep, kinvis, beta);

    nf = u.size();
    for (k = 0; k < NZ; k++)
      for (i = 0; i < ntot; i++) {
	for (j = 0; j < nf; j++) {
	  if   (elmt[i]) c = u[j] -> probe (elmt[i], r[i], s[i], k);
	  else           c = 0.0;
	  cout << setw(15) <<  c;
	}
	if (verbose && !((i + 1)% nreport))
	  cerr 
	    << "interp: plane " << k + 1 << ", "
	    << i + 1 << " points interpolated" << endl;
	cout << endl;
      }
  }

  Femlib::finalize();
  return EXIT_SUCCESS;
}
Example #8
0
int main (int    argc,
	  char** argv)
// ---------------------------------------------------------------------------
// Driver.
// ---------------------------------------------------------------------------
{
  Geometry::CoordSys         system;
  char                       *session, *dump, *func, fields[StrMax];
  int_t                      i, j, k, p, q;
  int_t                      np, nz, nel, allocSize, nComponent;
  int_t                      iAdd = 0;
  bool                       add[FLAG_MAX], need[FLAG_MAX], gradient;
  ifstream                   file;
  FEML*                      F;
  Mesh*                      M;
  BCmgr*                     B;
  Domain*                    D;
  vector<Element*>           elmt;
  AuxField                   *Ens, *Hel, *Div, *InvQ, *InvR, *Disc, *Strain;
  AuxField                   *Func, *Ell, *Egr, *Vtx, *work, *DivL, *Nrg;
  vector<AuxField*>          lamb, velocity, vorticity, addField(FLDS_MAX);
  vector<vector<AuxField*> > Sij;
  vector<vector<AuxField*> > Vij;     // -- Usually computed, for internal use.
  vector<vector<real_t*> >   VijData; // -- For pointwise access.
  real_t                     *egrow, *VtxData; // -- Ditto.
  real_t                     tensor[9];

  Femlib::initialize (&argc, &argv);
  for (i = 0; i < FLAG_MAX; i++) add [i] = need [i] = false;

  // -- Read command line.

  getargs (argc, argv, session, dump, func, add);

  file.open (dump);
  if (!file) message (prog, "can't open input field file", ERROR);

  // -- Set up domain.

  F      = new FEML (session);
  M      = new Mesh (F);
  nel    = M -> nEl ();  
  np     =  Femlib::ivalue ("N_P");
  nz     =  Femlib::ivalue ("N_Z");
  system = (Femlib::ivalue ("CYLINDRICAL") ) ?
                       Geometry::Cylindrical : Geometry::Cartesian;
  Geometry::set (np, nz, nel, system);
  if   (nz > 1) strcpy (fields, "uvwp");
  else          strcpy (fields, "uvp");
  nComponent = Geometry::nDim();
  allocSize  = Geometry::nTotal();

  elmt.resize (nel);
  for (i = 0; i < nel; i++) elmt[i] = new Element (i, np, M);

  B = new BCmgr  (F, elmt);
  D = new Domain (F, elmt, B);

  velocity.resize   (nComponent);
  vorticity.resize ((nComponent == 2) ? 1 : 3);
  for (i = 0; i < nComponent; i++) velocity[i] = D -> u[i];

  // -- From the requested fields, flag dependencies.

  if  (nComponent < 3)
    add[HELICITY] = add[DISCRIMINANT] = add[VORTEXCORE] = false;

  for (p = 0, i = 0; i < FLAG_MAX; i++) p += (add[i]) ? 1 : 0;
  if  (p == 0) message (prog, "nothing to be done", ERROR);

  for (p = 0, i = 0; i < FLAG_MAX; i++)
    p += (add[i]) ? (i + 1) : 0;
  if (p <= 3) gradient = false; else gradient = true;

  for (i = 0; i < FLAG_MAX; i++) need[i] = add[i];

  if (add[ENSTROPHY]) {
    need[VORTICITY]    = true;
    need[ENSTROPHY]    = true;
  }
  if (add[HELICITY]) {
    need[VORTICITY]    = true;
  }
  if (add[ELLIPTICITY]) {
    need[VORTICITY]    = true;
    need[ENSTROPHY]    = true;
    need[STRAINRATE]   = true;
    need[STRAINTENSOR] = true;
  }
  if (add[STRAINRATE]) {
    need[STRAINTENSOR] = true;
  }
  if (add[EGROWTH]) {
    need[VORTICITY]    = true;
    need[ENSTROPHY]    = true;
    need[STRAINRATE]   = true;
    need[STRAINTENSOR] = true;
    need[ELLIPTICITY]  = true;
  }
  if (add[LAMBVECTOR]) {
    need[VORTICITY]    = true;
    need[LAMBVECTOR]   = true;
  }

  // -- If any gradients need to be computed, we make all of them.
  
  if (gradient) {
    Vij    .resize (nComponent);
    VijData.resize (nComponent);
    for (i = 0; i < nComponent; i++) {
      Vij    [i].resize (nComponent);
      VijData[i].resize (nComponent);
      for (j = 0; j < nComponent; j++) {
	VijData[i][j] = new real_t [allocSize];
	Vij   [i][j] = new AuxField (VijData[i][j], nz, elmt);
	*Vij  [i][j] = 0.0;
      }
    }
  }
  
  // -- Fields without dependants.

  work = new AuxField (new real_t[allocSize], nz, elmt);

  if (need[ENERGY]) {
    Nrg = new AuxField (new real_t[allocSize], nz, elmt, 'q');
    addField[iAdd++] = Nrg;
  }

  if (need[FUNCTION]) {
    Func = new AuxField (new real_t[allocSize], nz, elmt, 'f');
    addField[iAdd++] = Func;
  }

  if (need[DIVERGENCE]) {
    Div  =  new AuxField (new real_t[allocSize], nz, elmt, 'd');
    *Div = 0.0;
    addField[iAdd++] = Div;
  }

  if (need[DISCRIMINANT]) {
    *(InvQ = new AuxField (new real_t[allocSize], nz, elmt, 'Q')) = 0.0;
    *(InvR = new AuxField (new real_t[allocSize], nz, elmt, 'R')) = 0.0;
    *(Disc = new AuxField (new real_t[allocSize], nz, elmt, 'L')) = 0.0;
    addField[iAdd++] = Disc;
  }

  if (need[VORTEXCORE]) {
    VtxData = new real_t [allocSize];
    Vtx = new AuxField (VtxData, nz, elmt, 'J');
    addField[iAdd++] = Vtx;
  }

  // -- Vorticity and its dependants.

  if (need[VORTICITY])
    if (nComponent == 2) {
      vorticity[0] = new AuxField (new real_t[allocSize], nz, elmt, 't');
      if (add[VORTICITY])
	addField[iAdd++] = vorticity[0];
    } else {
      for (i = 0; i < nComponent; i++)
	vorticity[i] = new AuxField (new real_t[allocSize], nz, elmt, 'r' + i);
      if (add[VORTICITY])
	for (i = 0; i < 3; i++) addField[iAdd++] = vorticity[i];
    }

  if (add[LAMBVECTOR]) {
    if (nComponent == 2) {
      lamb.resize(2);
      for (i = 0; i < nComponent; i++)
	lamb[i] = new AuxField (new real_t[allocSize], nz, elmt, 'm' + i);
      for (i = 0; i < 2; i++) addField[iAdd++] = lamb[i];
    } else {
      lamb.resize(3);
      for (i = 0; i < nComponent; i++)
	lamb[i] = new AuxField (new real_t[allocSize], nz, elmt, 'm' + i);
      for (i = 0; i < 3; i++) addField[iAdd++] = lamb[i];
    }
    DivL = new AuxField (new real_t[allocSize], nz, elmt, 'Q');
    addField[iAdd++] = DivL;
  }

  if (need[ENSTROPHY]) {
    Ens = new AuxField (new real_t[allocSize], nz, elmt, 'e');
    if (add[ENSTROPHY]) addField[iAdd++] = Ens;
  }
  
  if (need[HELICITY]) {
    Hel = new AuxField (new real_t[allocSize], nz, elmt, 'h');
    if (add[HELICITY]) addField[iAdd++] = Hel;
  }

  if (need[ELLIPTICITY]) {
    Ell = new AuxField (new real_t[allocSize], nz, elmt, 'b');
    if (add[ELLIPTICITY]) addField[iAdd++] = Ell;
  }

  // -- Rate of strain tensor and its dependants.

  if (need[STRAINTENSOR]) {
    Sij.resize (nComponent);
    for (k = 0, i = 0; i < nComponent; i++) {
      Sij[i].resize (nComponent);
      for (j = 0; j < nComponent; j++) {
	if (j >= i) {
	  Sij[i][j] = new AuxField (new real_t[allocSize], nz, elmt, 'i'+k++);
	} else
	  Sij[i][j] = Sij[j][i];
      }
    }
  }

  if (need[STRAINRATE]) {
    *(Strain = new AuxField (new real_t[allocSize], nz, elmt, 'g')) = 0.0;
    if (add[STRAINRATE]) addField[iAdd++] = Strain;
  }

  if (need[EGROWTH]) {
    egrow = new real_t[allocSize]; // -- A handle for direct access to data.
    Egr = new AuxField (egrow, nz, elmt, 'a');
    if (add[EGROWTH]) addField[iAdd++] = Egr;
  }
  
  // -- Cycle through field dump, first computing the velocity
  //    gradient tensor and then the needed quantities -- vorticity
  //    etc.  The order of computation is determined by dependencies.
  //    Then write requested output, listed in addField.
  
  while (getDump (D, file)) {
        
    if (need[FUNCTION]) *Func = func;

    // -- Velocity gradient tensor; transform required for z (2) gradient.  

    if (nComponent > 2) D -> transform (FORWARD);

    if (gradient)
      for (i = 0; i < nComponent ; i++)
	for (j = 0; j < nComponent ; j++) {
	  (*Vij[i][j] = *velocity[i]) . gradient (j);
	  Vij[i][j] -> transform (INVERSE);
	}

    if (need[ENERGY]) {
      *Nrg = 0.0;
      for (i = 0; i < nComponent ; i++)
	Nrg -> timesPlus (*D -> u[i], *D -> u[i]);
      *Nrg *= 0.5;
    }

    if (nComponent > 2) D -> transform (INVERSE);

    if (Geometry::cylindrical() && nComponent == 3) {
      for (i = 0; i < nComponent; i++) Vij[i][2] -> divY();
      (*work = *D -> u[2]) . divY();  *Vij[1][2] -= *work;
      (*work = *D -> u[1]) . divY();  *Vij[2][2] += *work;
    }
    
    if (need[DISCRIMINANT]) {

      // -- 2nd invariant (Q from Chong et al.).

      InvQ -> times      (*Vij[0][0], *Vij[1][1]);
      InvQ -> timesMinus (*Vij[0][1], *Vij[1][0]);
      InvQ -> timesPlus  (*Vij[0][0], *Vij[2][2]);
      InvQ -> timesMinus (*Vij[0][2], *Vij[2][0]);
      InvQ -> timesPlus  (*Vij[1][1], *Vij[2][2]);
      InvQ -> timesMinus (*Vij[1][2], *Vij[2][1]);

      // -- 3rd invariant: determinant of Vij (R from Chong et al.).

      work -> times      (*Vij[1][1], *Vij[2][2]);
      work -> timesMinus (*Vij[2][1], *Vij[1][2]);
      InvR -> times      (*work,      *Vij[0][0]);

      work -> times      (*Vij[1][2], *Vij[2][0]);
      work -> timesMinus (*Vij[2][2], *Vij[1][0]);
      InvR -> timesPlus  (*work,      *Vij[0][1]);

      work -> times      (*Vij[2][1], *Vij[1][0]);
      work -> timesMinus (*Vij[1][1], *Vij[2][0]);
      InvR -> timesPlus  (*work,      *Vij[0][2]);

      // -- Discriminant L of Vij.
      //    NB: DIVERGENCE (P from Chong et al.) ASSUMED = 0.

      work -> times (*InvQ, *InvQ);
      Disc -> times (*work, *InvQ);
      work -> times (*InvR, *InvR);
      *work *= 6.75;
      *Disc += *work;
    }
	
    if (need[DIVERGENCE])
      for (i = 0; i < nComponent; i++) *Div += *Vij[i][i];
    
    if (need[VORTICITY]) {
      if (nComponent == 2) {
	*vorticity[0]  = *Vij[1][0];
	*vorticity[0] -= *Vij[0][1];
      } else {
	*vorticity[0]  = *Vij[2][1];
	*vorticity[0] -= *Vij[1][2];
	*vorticity[1]  = *Vij[0][2];
	*vorticity[1] -= *Vij[2][0];
	*vorticity[2]  = *Vij[1][0];
 	*vorticity[2] -= *Vij[0][1];
      }
    }

    if (need[LAMBVECTOR]) {
      if (nComponent == 2) {
	*lamb[0] = 0.0;
	lamb[0] -> timesMinus (*D -> u[1], *vorticity[0]);
	lamb[1] -> times      (*D -> u[0], *vorticity[0]);
	*DivL  = (*work = *lamb[0]) . gradient (0);
	*DivL += (*work = *lamb[1]) . gradient (1);
	if (Geometry::cylindrical())
	  *DivL += (*work = *lamb[1]) . divY();
      } else {
	lamb[0] -> times      (*D -> u[2], *vorticity[1]);
	lamb[0] -> timesMinus (*D -> u[1], *vorticity[2]);
	lamb[1] -> times      (*D -> u[0], *vorticity[2]);
	lamb[1] -> timesMinus (*D -> u[2], *vorticity[0]);
	lamb[2] -> times      (*D -> u[1], *vorticity[0]);
	lamb[2] -> timesMinus (*D -> u[0], *vorticity[1]);
	*DivL  = (*work = *lamb[0]) . gradient (0);
	*DivL += (*work = *lamb[1]) . gradient (1);
	(*work = *lamb[2]).transform(FORWARD).gradient(2).transform(INVERSE);
	if (Geometry::cylindrical()) {
	  *DivL += work -> divY();
	  *DivL += (*work = *lamb[1]) . divY();
	} else
	  *DivL += *work;
      }
    }
    
    if (need[ENSTROPHY])
      Ens -> innerProduct (vorticity, vorticity) *= 0.5;

    if (need[HELICITY])
      Hel -> innerProduct (vorticity, velocity)  *= 0.5;

    if (need[STRAINTENSOR]) {
      for (i = 0; i < nComponent; i++)
	for (j = i; j < nComponent; j++) {
	  *Sij[i][j]  = *Vij[i][j];
	  *Sij[i][j] += *Vij[j][i];
	  *Sij[i][j] *= 0.5;
	}
    }

    if (need[STRAINRATE]) {
      *Strain = 0.0;
      for (i = 0; i < nComponent; i++)
	for (j = 0; j < nComponent; j++)
	  Strain -> timesPlus (*Sij[i][j], *Sij[j][i]);
      (*Strain *= 2.0) . sqroot();
    }

    if (need[ELLIPTICITY]) {
      ((*work = *Ens) . sqroot() *= 2.0) += 1.0e-1;
      Ell -> divide (*Strain, *work);
    }

    if (need[EGROWTH]) {
      *Egr = *Ell;
      Veclib::clip (allocSize, 0.0, 1.0, egrow, 1, egrow, 1);
      Veclib::spow (allocSize, 2.811,    egrow, 1, egrow, 1);
      Veclib::vneg (allocSize,           egrow, 1, egrow, 1);
      Veclib::sadd (allocSize, 1.0,      egrow, 1, egrow, 1);
      Veclib::spow (allocSize, 0.3914,   egrow, 1, egrow, 1);
      Veclib::smul (allocSize, 9.0/16.0, egrow, 1, egrow, 1);
      (*work = *Strain) *= sqrt (1.0/8.0);
      Egr -> times (*Egr, *work);
    }

    if (need[VORTEXCORE])	// -- Only done for 3-component fields.
      for (i = 0; i < allocSize; i++)
	for (k = 0, p = 0; p < 3; p++)
	  for (q = 0; q < 3; q++, k++) {
	    tensor [k] = VijData[p][q][i];
	    VtxData[i] = lambda2 (tensor);
	  }

    // -- Finally, add mass-projection smoothing on everything.

    for (i = 0; i < iAdd; i++) D -> u[0] -> smooth (addField[i]);

    putDump (D, addField, iAdd, cout);
  }
  
  file.close();
  Femlib::finalize();
  return EXIT_SUCCESS;
}
Example #9
0
int main (int    argc,
	  char** argv)
// ---------------------------------------------------------------------------
// Driver.
// ---------------------------------------------------------------------------
{
  Geometry::CoordSys         system;
  char*                      session;
  istream*                   file;
  FEML*                      F;
  Mesh*                      M;
  BCmgr*                     B;
  Domain*                    D;
  vector<Element*>           E;
  int_t                      _nwall, _nline, _npad, DIM;
  vector<real_t>             _work;

  Femlib::initialize (&argc, &argv);

  // -- Read command line.

  getargs (argc, argv, session, file);

  // -- Set up domain.

  preprocess (session, F, M, E, B, D);

  DIM = Geometry::nDim();

  // -- Loop over all dumps in field file, compute and print traction.

  while (getDump (D, *file)) {

    // -- Input was in physical space but we need Fourier.

    D -> transform (FORWARD);

    // -- Set up to compute wall shear stresses.    
    
    const int_t npr = Geometry::nProc();
    const int_t np  = Geometry::nP();
    const int_t nz  = Geometry::nZProc();

    // -- Allocate storage area: 3 = 1 normal component + 2 tangential.
    
    _nwall = B -> nWall();
    _nline = np * _nwall;
    _npad  = 3  * _nline;

    // -- Round up length for Fourier transform/exchange.

    if   (npr > 1) _npad += 2 * npr - _npad % (2 * npr);
    else           _npad += _npad % 2;

    _work.resize (_npad * nz);

    // --------------------------------------------------------------------

    const int_t    nP  = Geometry::nP();
    const int_t    nZ  = Geometry::nZ();
    int_t          i, j, k;
    real_t*        plane;
    vector<real_t> buffer (_nline);

    // -- Load the local storage area.

    Veclib::zero (_work.size(), &_work[0], 1);

    if (DIM == 3 || D -> nField() == 4)
      Field::traction (&_work[0], &_work[_nline], &_work[2*_nline], _nwall,
		       _npad, D->u[3],D->u[0],D->u[1],D->u[2]);
    else
      Field::traction (&_work[0], &_work[_nline], &_work[2*_nline], _nwall,
		       _npad, D->u[2],D->u[0],D->u[1]);

    // -- Inverse Fourier transform (like Field::bTransform).

    if (nZ > 1)
      if (nZ == 2)
	Veclib::copy (_npad, &_work[0], 1, &_work[_npad], 1);
      else
	Femlib::DFTr (&_work[0], nZ, _npad, INVERSE);

    // -- Write to file.
    
    // -- Header: this will be a lot like a standard header.
    //    Output normal and tangential tractions, 'n', 't', 's'.

    const char *Hdr_Fmt[] = { 
      "%-25s "                "Session\n",
      "%-25s "                "Created\n",
      "%-5d1    %-5d %-10d"   "Nr, Ns, Nz, Elements\n",
      "%-25d "                "Step\n",
      "%-25.6g "              "Time\n",
      "%-25.6g "              "Time step\n",
      "%-25.6g "              "Kinvis\n",
      "%-25.6g "              "Beta\n",
      "%-25s "                "Fields written\n",
      "%-25s "                "Format\n" };
      
    char   s1[StrMax], s2[StrMax];
    time_t tp (time (0));

    strftime (s2, 25, "%a %b %d %H:%M:%S %Y", localtime (&tp));
	
    sprintf (s1, Hdr_Fmt[0], D->name);                  cout << s1;
    sprintf (s1, Hdr_Fmt[1], s2);                       cout << s1;
    sprintf (s1, Hdr_Fmt[2], nP, nZ, _nwall);           cout << s1;
    sprintf (s1, Hdr_Fmt[3], D->step);                  cout << s1;
    sprintf (s1, Hdr_Fmt[4], D->time);                  cout << s1;
    sprintf (s1, Hdr_Fmt[5], Femlib::value ("D_T"));    cout << s1;
    sprintf (s1, Hdr_Fmt[6], Femlib::value ("KINVIS")); cout << s1;
    sprintf (s1, Hdr_Fmt[7], Femlib::value ("BETA"));   cout << s1;
    sprintf (s1, Hdr_Fmt[8], "nts");                    cout << s1;
    sprintf (s2, "binary "); Veclib::describeFormat  (s2 + strlen (s2));
    sprintf (s1, Hdr_Fmt[9], s2);                       cout << s1;

    // -- Data.
  
    for (j = 0; j < 3; j++)
      for (i = 0; i < nZ; i++) {
	plane = &_work[i*_npad + j*_nline];
	cout.write (reinterpret_cast<char*>(plane),
		    static_cast<int_t>(_nline * sizeof (real_t))); 
      }
  }
  
  Femlib::finalize();
  return EXIT_SUCCESS;
}