38 template<
class ParcelType>
41 Info<<
nl <<
"Constructing constant properties for" <<
endl;
42 constProps_.setSize(typeIdList_.size());
46 particleProperties_.subDict(
"moleculeProperties")
51 const word& id(typeIdList_[i]);
58 typename ParcelType::constantProperties::constantProperties(molDict);
63 template<
class ParcelType>
68 cellOccupancy_[cO].clear();
73 cellOccupancy_[iter().cell()].append(&iter());
78 template<
class ParcelType>
86 const scalar temperature
91 const vector velocity(dsmcInitialiseDict.
lookup(
"velocity"));
95 dsmcInitialiseDict.
subDict(
"numberDensities")
106 numberDensitiesDict.
lookup(molecules[i])
110 numberDensities /= nParticle_;
112 forAll(mesh_.cells(), cellI)
124 scalar tetVolume = tet.
mag();
128 const word& moleculeName(molecules[i]);
135 <<
"typeId " << moleculeName <<
"not defined." <<
nl
139 const typename ParcelType::constantProperties& cP =
142 scalar numberDensity = numberDensities[i];
145 scalar particlesRequired = numberDensity*tetVolume;
148 label nParticlesToInsert =
label(particlesRequired);
154 (particlesRequired - nParticlesToInsert)
158 nParticlesToInsert++;
161 for (
label pI = 0; pI < nParticlesToInsert; pI++)
165 vector U = equipartitionLinearVelocity
171 scalar Ei = equipartitionInternalEnergy
174 cP.internalDegreesOfFreedom()
200 const typename ParcelType::constantProperties& cP = constProps
205 sigmaTcRMax_.internalField() = cP.sigmaT()*maxwellianMostProbableSpeed
211 sigmaTcRMax_.correctBoundaryConditions();
215 template<
class ParcelType>
218 if (!binaryCollision().active())
226 scalar deltaT =
mesh().time().deltaTValue();
228 label collisionCandidates = 0;
230 label collisions = 0;
232 forAll(cellOccupancy_, cellI)
236 label nC(cellParcels.size());
252 const point& cC = mesh_.cellCentres()[cellI];
256 const ParcelType&
p = *cellParcels[i];
257 vector relPos =
p.position() - cC;
260 pos(relPos.
x()) + 2*
pos(relPos.
y()) + 4*
pos(relPos.
z());
262 subCells[subCell].
append(i);
263 whichSubCell[i] = subCell;
268 scalar sigmaTcRMax = sigmaTcRMax_[cellI];
270 scalar selectedPairs =
271 collisionSelectionRemainder_[cellI]
272 + 0.5*nC*(nC - 1)*nParticle_*sigmaTcRMax*deltaT
273 /mesh_.cellVolumes()[cellI];
275 label nCandidates(selectedPairs);
276 collisionSelectionRemainder_[cellI] = selectedPairs - nCandidates;
277 collisionCandidates += nCandidates;
279 for (
label c = 0;
c < nCandidates;
c++)
285 label candidateP = rndGen_.integer(0, nC - 1);
288 label candidateQ = -1;
290 List<label> subCellPs = subCells[whichSubCell[candidateP]];
301 candidateQ = subCellPs[rndGen_.integer(0, nSC - 1)];
302 }
while (candidateP == candidateQ);
312 candidateQ = rndGen_.integer(0, nC - 1);
313 }
while (candidateP == candidateQ);
333 ParcelType& parcelP = *cellParcels[candidateP];
334 ParcelType& parcelQ = *cellParcels[candidateQ];
336 scalar sigmaTcR = binaryCollision().sigmaTcR
346 if (sigmaTcR > sigmaTcRMax_[cellI])
348 sigmaTcRMax_[cellI] = sigmaTcR;
351 if ((sigmaTcR/sigmaTcRMax) > rndGen_.scalar01())
353 binaryCollision().collide
369 sigmaTcRMax_.correctBoundaryConditions();
371 if (collisionCandidates)
373 Info<<
" Collisions = "
375 <<
" Acceptance rate = "
376 << scalar(collisions)/scalar(collisionCandidates) <<
nl
386 template<
class ParcelType>
414 template<
class ParcelType>
421 scalarField& internalE = internalE_.internalField();
427 const ParcelType&
p = iter();
428 const label cellI =
p.cell();
431 rhoM[cellI] += constProps(
p.typeId()).mass();
433 linearKE[cellI] += 0.5*constProps(
p.typeId()).mass()*(
p.U() &
p.U());
434 internalE[cellI] +=
p.Ei();
435 iDof[cellI] += constProps(
p.typeId()).internalDegreesOfFreedom();
436 momentum[cellI] += constProps(
p.typeId()).mass()*
p.U();
439 rhoN *= nParticle_/
mesh().cellVolumes();
440 rhoN_.correctBoundaryConditions();
442 rhoM *= nParticle_/
mesh().cellVolumes();
443 rhoM_.correctBoundaryConditions();
445 dsmcRhoN_.correctBoundaryConditions();
447 linearKE *= nParticle_/
mesh().cellVolumes();
448 linearKE_.correctBoundaryConditions();
450 internalE *= nParticle_/
mesh().cellVolumes();
451 internalE_.correctBoundaryConditions();
453 iDof *= nParticle_/
mesh().cellVolumes();
454 iDof_.correctBoundaryConditions();
456 momentum *= nParticle_/
mesh().cellVolumes();
457 momentum_.correctBoundaryConditions();
463 template<
class ParcelType>
470 const label tetFaceI,
475 ParcelType* pPtr =
new ParcelType
487 this->addParticle(pPtr);
493 template<
class ParcelType>
510 mesh_.time().constant(),
516 typeIdList_(particleProperties_.lookup(
"typeIdList")),
517 nParticle_(
readScalar(particleProperties_.lookup(
"nEquivalentParticles"))),
518 cellOccupancy_(mesh_.nCells()),
523 this->
name() +
"SigmaTcRMax",
524 mesh_.time().timeName(),
531 collisionSelectionRemainder_
535 this->
name() +
":collisionSelectionRemainder",
536 mesh_.time().timeName(),
547 mesh_.time().timeName(),
559 mesh_.time().timeName(),
571 mesh_.time().timeName(),
583 mesh_.time().timeName(),
595 mesh_.time().timeName(),
607 mesh_.time().timeName(),
619 mesh_.time().timeName(),
631 mesh_.time().timeName(),
643 mesh_.time().timeName(),
659 mesh_.time().timeName(),
674 mesh_.time().timeName(),
682 binaryCollisionModel_
690 wallInteractionModel_
708 buildCellOccupancy();
712 forAll(collisionSelectionRemainder_, i)
714 collisionSelectionRemainder_[i] = rndGen_.scalar01();
724 template<
class ParcelType>
741 mesh_.time().constant(),
747 typeIdList_(particleProperties_.lookup(
"typeIdList")),
748 nParticle_(
readScalar(particleProperties_.lookup(
"nEquivalentParticles"))),
754 this->
name() +
"SigmaTcRMax",
755 mesh_.time().timeName(),
762 zeroGradientFvPatchScalarField::typeName
764 collisionSelectionRemainder_
768 this->
name() +
":collisionSelectionRemainder",
769 mesh_.time().timeName(),
780 mesh_.time().timeName(),
792 this->
name() +
"fD_",
793 mesh_.time().timeName(),
810 this->
name() +
"rhoN_",
811 mesh_.time().timeName(),
823 this->
name() +
"rhoM_",
824 mesh_.time().timeName(),
836 this->
name() +
"dsmcRhoN_",
837 mesh_.time().timeName(),
849 this->
name() +
"linearKE_",
850 mesh_.time().timeName(),
862 this->
name() +
"internalE_",
863 mesh_.time().timeName(),
875 this->
name() +
"iDof_",
876 mesh_.time().timeName(),
888 this->
name() +
"momentum_",
889 mesh_.time().timeName(),
911 mesh_.time().timeName(),
927 mesh_.time().timeName(),
941 binaryCollisionModel_(),
942 wallInteractionModel_(),
943 inflowBoundaryModel_()
947 initialise(dsmcInitialiseDict);
953 template<
class ParcelType>
960 template<
class ParcelType>
963 typename ParcelType::trackingData td(*
this);
970 this->dumpParticlePositions();
974 this->inflowBoundary().inflow();
980 buildCellOccupancy();
990 template<
class ParcelType>
993 label nDSMCParticles = this->size();
996 scalar nMol = nDSMCParticles*nParticle_;
998 vector linearMomentum = linearMomentumOfSystem();
1001 scalar linearKineticEnergy = linearKineticEnergyOfSystem();
1004 scalar internalEnergy = internalEnergyOfSystem();
1008 <<
" Number of dsmc particles = "
1014 Info<<
" Number of molecules = "
1016 <<
" Mass in system = "
1018 <<
" Average linear momentum = "
1019 << linearMomentum/nMol <<
nl
1020 <<
" |Average linear momentum| = "
1021 <<
mag(linearMomentum)/nMol <<
nl
1022 <<
" Average linear kinetic energy = "
1023 << linearKineticEnergy/nMol <<
nl
1024 <<
" Average internal energy = "
1025 << internalEnergy/nMol <<
nl
1026 <<
" Average total energy = "
1027 << (internalEnergy + linearKineticEnergy)/nMol
1033 template<
class ParcelType>
1044 rndGen_.GaussNormal(),
1045 rndGen_.GaussNormal(),
1046 rndGen_.GaussNormal()
1051 template<
class ParcelType>
1064 else if (iDof < 2.0 + SMALL && iDof > 2.0 - SMALL)
1071 scalar a = 0.5*iDof - 1;
1077 energyRatio = 10*rndGen_.scalar01();
1078 P =
pow((energyRatio/a), a)*
exp(a - energyRatio);
1079 }
while (P < rndGen_.scalar01());
1088 template<
class ParcelType>
1093 this->db().time().
path()/
"parcelPositions_"
1094 + this->
name() +
"_"
1095 + this->db().time().
timeName() +
".obj"
1100 const ParcelType&
p = iter();
1102 pObj<<
"v " <<
p.position().x()
1103 <<
" " <<
p.position().y()
1104 <<
" " <<
p.position().z()
1112 template<
class ParcelType>
1115 typedef typename ParcelType::trackingData tdType;
1120 cellOccupancy_.setSize(mesh_.nCells());
1121 buildCellOccupancy();
1124 this->inflowBoundary().autoMap(mapper);