void mindist_trajectory(float* coords, float* box, int* groups1, int* groups2, int gn1, int gn2, int na, int nf, int pbc, float* dist) { float mindist; int a,b,g1,g2,n1,n2,g1atm,g2atm,f; float coo1[3], coo2[3]; int nf3 = nf*3; // Precalculate 3 * nframes for the coordinate lookup macro int groupprod = gn1*gn2; // Iterate over all frames for (f=0; f < nf; f++){ // Iterate over the two group sets for (g1=0; g1 < gn1; g1++){ for (g2=0; g2 < gn2; g2++){ mindist = -1; // Iterate over atoms in the two groups for (a = 0; a < na; a++) { g1atm = groups1[g1 * na + a]; if (g1atm == -1) break; //get_coords(coords, g1atm, f, nf, coo1); //const float* coo1 = &coords[g1atm*dim]; for (b=0; b < na; b++) { g2atm = groups2[g2 * na + b]; if (g2atm == -1) break; //get_coords(coords, g2atm, f, nf, coo2); //const float* coo2 = &coords[g2atm*dim]; float d[3]; d[0] = coords[Xf(g1atm,f,nf,nf3)]-coords[Xf(g2atm,f,nf,nf3)]; d[1] = coords[Yf(g1atm,f,nf,nf3)]-coords[Yf(g2atm,f,nf,nf3)]; d[2] = coords[Zf(g1atm,f,nf,nf3)]-coords[Zf(g2atm,f,nf,nf3)]; if (pbc){ d[0] = d[0] - box[0] * round(d[0] / box[0]); d[1] = d[1] - box[1] * round(d[1] / box[1]); d[2] = d[2] - box[2] * round(d[2] / box[2]); } //printf("coor: %f %f %f / %f %f %f\n", coo1[0], coo1[1], coo1[2], coo2[0], coo2[1], coo2[2]); float D = d[0]*d[0]+d[1]*d[1]+d[2]*d[2]; //printf("index: %d/%d dist: %f\n", g1atm, g2atm, sqrt(D)); if (D < mindist || mindist < 0) { mindist = D; } } } //printf("%d %d %d %d: %f\n", g1, gn2, g2, g1*gn2+g2, sqrt(mindist)); dist[g1*gn2+g2+(f*groupprod)] = sqrt(mindist); // Add here the f } } } }
//helper: computes a facet horizontal and vertical extensions void ComputeFacetExtensions(CCVector3& N, ccPolyline* facetContour, double& horizExt, double& vertExt) { //horizontal and vertical extensions horizExt = vertExt = 0; CCLib::GenericIndexedCloudPersist* vertCloud = facetContour->getAssociatedCloud(); if (vertCloud) { //oriRotMat.applyRotation(N); //DGM: oriRotMat is only for display! //we assume that at this point the "up" direction is always (0,0,1) CCVector3 Xf(1,0,0), Yf(0,1,0); //we get the horizontal vector on the plane CCVector3 D = CCVector3(0,0,1).cross(N); if (D.norm2() > ZERO_TOLERANCE) //otherwise the facet is horizontal! { Yf = D; Yf.normalize(); Xf = N.cross(Yf); } const CCVector3* G = CCLib::Neighbourhood(vertCloud).getGravityCenter(); ccBBox box; for (unsigned i=0; i<vertCloud->size(); ++i) { const CCVector3 P = *(vertCloud->getPoint(i)) - *G; CCVector3 p( P.dot(Xf), P.dot(Yf), 0 ); box.add(p); } vertExt = box.getDiagVec().x; horizExt = box.getDiagVec().y; } }
Foam::tmp<Foam::volScalarField> Foam::InterfaceCompositionModel<Thermo, OtherThermo>::dY ( const word& speciesName, const volScalarField& Tf ) const { return Yf(speciesName, Tf) - thermo_.composition().Y() [ thermo_.composition().species()[speciesName] ]; }
void parcel::setRelaxationTimes ( label celli, scalar& tauMomentum, scalarField& tauEvaporation, scalar& tauHeatTransfer, scalarField& tauBoiling, const spray& sDB, const scalar rho, const vector& Up, const scalar temperature, const scalar pressure, const scalarField& Yfg, const scalarField& m0, const scalar dt ) { const liquidMixture& fuels = sDB.fuels(); scalar mCell = rho*sDB.mesh().V()[cell()]; scalarField mfg(Yfg*mCell); label Ns = sDB.composition().Y().size(); label Nf = fuels.components().size(); // Tf is based on the 1/3 rule scalar Tf = T() + (temperature - T())/3.0; // calculate mixture properties scalar W = 0.0; scalar kMixture = 0.0; scalar cpMixture = 0.0; scalar muf = 0.0; for(label i=0; i<Ns; i++) { scalar Y = sDB.composition().Y()[i][celli]; W += Y/sDB.gasProperties()[i].W(); // Using mass-fractions to average... kMixture += Y*sDB.gasProperties()[i].kappa(Tf); cpMixture += Y*sDB.gasProperties()[i].Cp(Tf); muf += Y*sDB.gasProperties()[i].mu(Tf); } W = 1.0/W; scalarField Xf(Nf, 0.0); scalarField Yf(Nf, 0.0); scalarField psat(Nf, 0.0); scalarField msat(Nf, 0.0); for(label i=0; i<Nf; i++) { label j = sDB.liquidToGasIndex()[i]; scalar Y = sDB.composition().Y()[j][celli]; scalar Wi = sDB.gasProperties()[j].W(); Yf[i] = Y; Xf[i] = Y*W/Wi; psat[i] = fuels.properties()[i].pv(pressure, temperature); msat[i] = min(1.0, psat[i]/pressure)*Wi/W; } scalar nuf = muf/rho; scalar liquidDensity = fuels.rho(pressure, T(), X()); scalar liquidcL = fuels.cp(pressure, T(), X()); scalar heatOfVapour = fuels.hl(pressure, T(), X()); // calculate the partial rho of the fuel vapour // alternative is to use the mass fraction // however, if rhoFuelVap is small (zero) // d(mass)/dt = 0 => no evaporation... hmmm... is that good? NO! // Assume equilibrium at drop-surface => pressure @ surface // = vapour pressure to calculate fuel-vapour density @ surface scalar pressureAtSurface = fuels.pv(pressure, T(), X()); scalar rhoFuelVap = pressureAtSurface*fuels.W(X())/(specie::RR*Tf); scalarField Xs(sDB.fuels().Xs(pressure, temperature, T(), Xf, X())); scalarField Ys(Nf, 0.0); scalar Wliq = 0.0; for(label i=0; i<Nf; i++) { label j = sDB.liquidToGasIndex()[i]; scalar Wi = sDB.gasProperties()[j].W(); Wliq += Xs[i]*Wi; } for(label i=0; i<Nf; i++) { label j = sDB.liquidToGasIndex()[i]; scalar Wi = sDB.gasProperties()[j].W(); Ys[i] = Xs[i]*Wi/Wliq; } scalar Reynolds = Re(Up, nuf); scalar Prandtl = Pr(cpMixture, muf, kMixture); // calculate the characteritic times if(liquidCore_> 0.5) { // no drag for parcels in the liquid core.. tauMomentum = GREAT; } else { tauMomentum = sDB.drag().relaxationTime ( Urel(Up), d(), rho, liquidDensity, nuf, dev() ); } // store the relaxationTime since it is needed in some breakup models. tMom_ = tauMomentum; tauHeatTransfer = sDB.heatTransfer().relaxationTime ( liquidDensity, d(), liquidcL, kMixture, Reynolds, Prandtl ); // evaporation-properties are evaluated at averaged temperature // set the boiling conditions true if pressure @ surface is 99.9% // of the pressure // this is mainly to put a limit on the evaporation time, // since tauEvaporation is very very small close to the boiling point. for(label i=0; i<Nf; i++) { scalar Td = min(T(), 0.999*fuels.properties()[i].Tc()); bool boiling = fuels.properties()[i].pv(pressure, Td) >= 0.999*pressure; scalar Di = fuels.properties()[i].D(pressure, Td); scalar Schmidt = Sc(nuf, Di); scalar partialPressure = Xf[i]*pressure; // saturated vapour if(partialPressure > psat[i]) { tauEvaporation[i] = GREAT; } // not saturated vapour else { if (!boiling) { // for saturation evaporation, only use 99.99% for numerical robustness scalar dm = max(SMALL, 0.9999*msat[i] - mfg[i]); tauEvaporation[i] = sDB.evaporation().relaxationTime ( d(), fuels.properties()[i].rho(pressure, Td), rhoFuelVap, Di, Reynolds, Schmidt, Xs[i], Xf[i], m0[i], dm, dt ); } else { scalar Nusselt = sDB.heatTransfer().Nu(Reynolds, Prandtl); // calculating the boiling temperature of the liquid at ambient pressure scalar tBoilingSurface = Td; label Niter = 0; scalar deltaT = 10.0; scalar dp0 = fuels.properties()[i].pv(pressure, tBoilingSurface) - pressure; while ((Niter < 200) && (mag(deltaT) > 1.0e-3)) { Niter++; scalar pBoil = fuels.properties()[i].pv(pressure, tBoilingSurface); scalar dp = pBoil - pressure; if ( (dp > 0.0) && (dp0 > 0.0) ) { tBoilingSurface -= deltaT; } else { if ( (dp < 0.0) && (dp0 < 0.0) ) { tBoilingSurface += deltaT; } else { deltaT *= 0.5; if ( (dp > 0.0) && (dp0 < 0.0) ) { tBoilingSurface -= deltaT; } else { tBoilingSurface += deltaT; } } } dp0 = dp; } scalar vapourSurfaceEnthalpy = 0.0; scalar vapourFarEnthalpy = 0.0; for(label k = 0; k < sDB.gasProperties().size(); k++) { vapourSurfaceEnthalpy += sDB.composition().Y()[k][celli]*sDB.gasProperties()[k].H(tBoilingSurface); vapourFarEnthalpy += sDB.composition().Y()[k][celli]*sDB.gasProperties()[k].H(temperature); } scalar kLiquid = fuels.properties()[i].K(pressure, 0.5*(tBoilingSurface+T())); tauBoiling[i] = sDB.evaporation().boilingTime ( fuels.properties()[i].rho(pressure, Td), fuels.properties()[i].cp(pressure, Td), heatOfVapour, kMixture, Nusselt, temperature - T(), d(), liquidCore(), sDB.runTime().value() - ct(), Td, tBoilingSurface, vapourSurfaceEnthalpy, vapourFarEnthalpy, cpMixture, temperature, kLiquid ); } } } }