void EulerianParticleVelocityForce ( cfdemCloud& sm, const fvMesh& mesh, volVectorField& Uf_, volVectorField& Up_, volScalarField& rho_, volScalarField& alpf_, volScalarField& Pg_, volVectorField& MappedDragForce_, const labelListList& particleList_, const bool& weighting_ ) { // Neighbouring cells CPCCellToCellStencil neighbourCells(mesh); // get viscosity field #ifdef comp const volScalarField nufField = sm.turbulence().mu()/rho_; #else const volScalarField& nufField = sm.turbulence().nu(); #endif // Gas pressure gradient volVectorField gradPg_ = fvc::grad(Pg_); interpolationCellPoint<vector> gradPgInterpolator_(gradPg_); // Local variables label cellID(-1); vector drag(0,0,0); vector Ufluid(0,0,0); vector position(0,0,0); scalar voidfraction(1); vector Up(0,0,0); vector Ur(0,0,0); scalar ds(0); scalar nuf(0); scalar rhof(0); vector WenYuDrag(0,0,0); interpolationCellPoint<scalar> voidfractionInterpolator_(alpf_); interpolationCellPoint<vector> UInterpolator_(Uf_); scalar dist_s(0); scalar sumWeights(0); scalarField weightScalar(27,scalar(0.0)); Field <Field <scalar> > particleWeights(particleList_.size(),weightScalar); //Info << " particle size " << particleList_.size() << endl; // Number of particle in a cell scalarField np(mesh.cells().size(),scalar(0)); // Particle volume scalar Volp(0); vector gradPg_int(0,0,0); for(int ii = 0; ii < particleList_.size(); ii++) { int index = particleList_[ii][0]; cellID = sm.cellIDs()[index][0]; position = sm.position(index); Ufluid = UInterpolator_.interpolate(position,cellID); Up = sm.velocity(index); Ur = Ufluid-Up; ds = 2*sm.radius(index); // Calculate WenYu Drag voidfraction = voidfractionInterpolator_.interpolate(position,cellID); nuf = nufField[cellID]; rhof = rho_[cellID]; WenYuDragForce(Ur,ds,rhof,nuf,voidfraction,WenYuDrag); Volp = ds*ds*ds*M_PI/6; gradPg_int = gradPgInterpolator_.interpolate(position,cellID); //if (cellID > -1) // particle centre is in domain //{ if(weighting_) { labelList& cellsNeigh = neighbourCells[cellID]; sumWeights = 0; dist_s = 0; //Info << " index = " << index << " ii = " << ii << " cellID = " << cellID << endl; forAll(cellsNeigh,jj) { // Find distances between particle and neighbouring cells dist_s = mag(sm.mesh().C()[cellsNeigh[jj]]-position)/pow(sm.mesh().V()[cellsNeigh[jj]],1./3.); if(dist_s <= 0.5) { particleWeights[ii][jj] = 1./4.*pow(dist_s,4)-5./8.*pow(dist_s,2)+115./192.; } else if (dist_s > 0.5 && dist_s <= 1.5) { particleWeights[ii][jj] = -1./6.*pow(dist_s,4)+5./6.*pow(dist_s,3)-5./4.*pow(dist_s,2)+5./24.*dist_s+55./96.; } else if (dist_s > 1.5 && dist_s <= 2.5) { particleWeights[ii][jj] = pow(2.5-dist_s,4)/24.; } else { particleWeights[ii][jj] = 0; } sumWeights += particleWeights[ii][jj]; } forAll(cellsNeigh,jj) { if ( sumWeights != 0 ) { Up_[cellID] += Up*particleWeights[ii][jj]/sumWeights; MappedDragForce_[cellID] += (WenYuDrag + Volp * gradPg_int) * particleWeights[ii][jj]/sumWeights; } else { Up_[cellID] = vector(0,0,0); MappedDragForce_[cellID] = vector(0,0,0); } } } else {
void CalculateDragForce ( cfdemCloud& sm, const volScalarField& alpf_, const volVectorField& Uf_, const volScalarField& rho_, const bool& verbose_, vectorField& DragForce_, const labelListList& particleList_ ) { // get viscosity field #ifdef comp const volScalarField nufField = sm.turbulence().mu()/rho_; #else const volScalarField& nufField = sm.turbulence().nu(); #endif // Local variables label cellI(-1); vector drag(0,0,0); vector Ufluid(0,0,0); vector position(0,0,0); scalar voidfraction(1); vector Up(0,0,0); vector Ur(0,0,0); scalar ds(0); scalar nuf(0); scalar rhof(0); vector WenYuDrag(0,0,0); interpolationCellPoint<scalar> voidfractionInterpolator_(alpf_); interpolationCellPoint<vector> UInterpolator_(Uf_); // //_AO_Parallel DragForce_.resize(particleList_.size()); for(int ii =0; ii < particleList_.size(); ii++) { int index = particleList_[ii][0]; cellI = sm.cellIDs()[index][0]; drag = vector(0,0,0); Ufluid = vector(0,0,0); WenYuDrag = vector(0,0,0); DragForce_[ii] = vector(0,0,0); if (cellI > -1) // particle Found { position = sm.position(index); if ( alpf_[cellI] > 1. ) Pout << " voidfraction > 1 " << alpf_[cellI] << endl; voidfraction = voidfractionInterpolator_.interpolate(position,cellI); Ufluid = UInterpolator_.interpolate(position,cellI); if ( voidfraction > 1. ) { Pout << " Int. voidfraction > 1 " << " value= " << voidfraction; voidfraction = alpf_[cellI]; Pout << " mod. value = " << voidfraction << endl; } Up = sm.velocity(index); Ur = Ufluid-Up; ds = 2*sm.radius(index); rhof = rho_[cellI]; nuf = nufField[cellI]; // Drag force WenYuDragForce(Ur,ds,rhof,nuf,voidfraction,WenYuDrag); if(verbose_ && index <= 1) { Info << "" << endl; Pout << " index = " << index << endl; Pout << " position = " << position << endl; Pout << " Up = " << Up << endl; Pout << " Ur = " << Ur << endl; Pout << " dp = " << ds << endl; Pout << " rho = " << rhof << endl; Pout << " nuf = " << nuf << endl; Pout << " voidfraction = " << voidfraction << endl; Pout << " drag = " << WenYuDrag << endl; Info << " " << endl; } } for(int j=0;j<3;j++) DragForce_[ii][j] = WenYuDrag[j]; } }
void createParcels ( const fvMesh& mesh, cfdemCloud& sm, const int& parcelSize_, int**& parcelCloud_, double**& parcelPositions_, double**& parcelVelocities_, int*& parcelNparts_, double** & parcelKinStress_, scalar& aveSubQparcel2_, vector& meanParcelVel_, const bool verbose_ ) { if ( parcelSize_ * parcelSize_ * parcelSize_ > sm.numberOfParticles() ) { FatalError << " Number of particles in a parcel > number of particles" << abort(FatalError); } if ( parcelSize_ < 1 ) { FatalError << " Number of particles < 0 in a parcel " << abort(FatalError); } // Number of particles in a parcel int k = parcelSize_ * parcelSize_ * parcelSize_; // Dimensions, exact OR approximate int dim =3; double eps = 0; // Number of points int nPts; nPts = sm.numberOfParticles(); // Data points ANNpointArray dataPts; // Query points ANNpoint queryPt; ANNidxArray nnIdx; // near neighbour indices ANNdistArray dists; // near neighbour distances ANNkd_tree* kdTree; // search structure // Allocate queryPt = annAllocPt(dim); dataPts = annAllocPts(nPts, dim); nnIdx = new ANNidx[k]; dists = new ANNdist[k]; for(int index = 0; index < sm.numberOfParticles(); index++) { dataPts[index][0] = sm.position(index).x(); dataPts[index][1] = sm.position(index).y(); dataPts[index][2] = sm.position(index).z(); } kdTree = new ANNkd_tree(dataPts, nPts, dim); // Initialize sub-parcel agitation aveSubQparcel2_ = 0.; // Initialize parcel velocity meanParcelVel_ = vector(0,0,0); for(int index = 0; index < sm.numberOfParticles(); index++) { // Particle neighbouring search distance scalar sqRad = parcelSize_ * sm.radius(index); queryPt[0] = sm.position(index).x(); queryPt[1] = sm.position(index).y(); queryPt[2] = sm.position(index).z(); kdTree->annkFRSearch( queryPt, // query point sqRad, // squared radius k, // number of the near neighbours to return nnIdx, // nearest neighbor array dists, // dist to near neighbours eps ); int nParts = 0; scalar dist = 0; // Initialize parcel velocities & positions & kinetic stresses for(int j=0;j<3;j++) { parcelVelocities_[index][j] = 0.; parcelPositions_[index][j] = 0.; parcelKinStress_[index][j] = 0.; parcelKinStress_[index][2*j] = 0.; } for (int i = 0; i < k; i++) { parcelCloud_[index][i] = nnIdx[i]; dist = mag( sm.position(nnIdx[i]) - sm.position(index) ) - sqRad; if ( dist < SMALL ) { for(int j=0;j<3;j++) { // Parcel velocity parcelVelocities_[index][j] += sm.velocity(nnIdx[i])[j]; // Parcel center of mass parcelPositions_[index][j] += sm.position(nnIdx[i])[j]; } nParts++; } } for(int j=0;j<3;j++) parcelPositions_[index][j] /= nParts; parcelNparts_[index] = nParts; // Parcel kinetic stresses for(int i = 0; i < parcelNparts_[index]; i++) { int particleID = parcelCloud_[index][i]; // U'xU'x parcelKinStress_[index][0] += ( sm.velocity(particleID)[0] - parcelVelocities_[index][0] ) *( sm.velocity(particleID)[0] - parcelVelocities_[index][0] ); // U'yU'y parcelKinStress_[index][1] += ( sm.velocity(particleID)[1] - parcelVelocities_[index][1] ) *( sm.velocity(particleID)[1] - parcelVelocities_[index][1] ); // U'zU'z parcelKinStress_[index][2] += ( sm.velocity(particleID)[2] - parcelVelocities_[index][2] ) *( sm.velocity(particleID)[2] - parcelVelocities_[index][2] ); // U'xU'y parcelKinStress_[index][3] += ( sm.velocity(particleID)[0] - parcelVelocities_[index][0] ) *( sm.velocity(particleID)[1] - parcelVelocities_[index][1] ); // U'xU'z parcelKinStress_[index][4] += ( sm.velocity(particleID)[0] - parcelVelocities_[index][0] ) *( sm.velocity(particleID)[2] - parcelVelocities_[index][2] ); // U'yU'z parcelKinStress_[index][5] += ( sm.velocity(particleID)[1] - parcelVelocities_[index][1] ) *( sm.velocity(particleID)[2] - parcelVelocities_[index][2] ); } // Mean parcel velocity for(int j=0;j<3;j++) meanParcelVel_[j] += parcelVelocities_[index][j]; // Domain-averaged parcel agitation aveSubQparcel2_ += 1./2. * ( parcelKinStress_[index][0] + parcelKinStress_[index][1] + parcelKinStress_[index][2] ); } for(int j=0;j<3;j++) meanParcelVel_[j] /= sm.numberOfParticles(); if ( verbose_ ) { int index = 0; Info << " Parcel particle list "; for (int i = 0; i < parcelNparts_[index]; i++) { Info << parcelCloud_[index][i] << " " ; } Info << endl; Info << " Parcel center " << parcelPositions_[index][0] << "," << parcelPositions_[index][1] << "," << parcelPositions_[index][2] << endl; Info << " Parcel velocity " << parcelVelocities_[index][0] << "," << parcelVelocities_[index][1] << "," << parcelVelocities_[index][2] << endl; for (int i = 0; i < parcelNparts_[index]; i++) { Info << " Particle " << parcelCloud_[index][i] << endl; Info << " Particle center " << sm.position(parcelCloud_[index][i]) << endl; Info << " Particle velocity " << sm.velocity(parcelCloud_[index][i]) << endl; } } }