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); }
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); }
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); }
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; }
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; }
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; }